<?php
|
namespace JVBase\registry;
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
|
use JVBase\registry\providers\CalendarFieldProvider;
|
use JVBase\registry\providers\CommonFieldProvider;
|
use JVBase\registry\providers\FieldProviderInterface;
|
use JVBase\utility\Features;
|
use JVBase\registry\providers\IntegrationFieldProvider;
|
|
class FieldRegistry
|
{
|
private static ?self $instance = null;
|
private array $fieldCache = [];
|
private array $fieldProviders = [];
|
|
/**
|
* Get singleton instance
|
*/
|
public static function getInstance(): self
|
{
|
if (self::$instance === null) {
|
self::$instance = new self();
|
}
|
return self::$instance;
|
}
|
|
private function __construct()
|
{
|
$this->registerFieldProviders();
|
}
|
|
/**
|
* Register all field providers
|
*/
|
private function registerFieldProviders(): void
|
{
|
// Core field providers
|
$this->addFieldProvider('common', new CommonFieldProvider());
|
$this->addFieldProvider('calendar', new CalendarFieldProvider());
|
$this->addFieldProvider('integration', new IntegrationFieldProvider());
|
|
// Allow extensions to add providers
|
do_action(BASE . 'register_field_providers', $this);
|
}
|
|
/**
|
* Add a field provider
|
*/
|
public function addFieldProvider(string $key, FieldProviderInterface $provider): void
|
{
|
$this->fieldProviders[$key] = $provider;
|
}
|
|
/**
|
* Get fields for a specific type
|
*/
|
public function getFields(string $type, ?string $object_type = null): array
|
{
|
$type = $this->normalizeType($type);
|
|
if (!$this->isValidType($type)) {
|
return [];
|
}
|
|
if (!$object_type) {
|
$object_type = $this->getObjectType($type);
|
}
|
|
$cacheKey = "{$type}_{$object_type}";
|
// Check cache first
|
if (isset($this->fieldCache[$cacheKey]) && !JVB_TESTING) {
|
return $this->fieldCache[$cacheKey];
|
}
|
$key = BASE.$cacheKey.'_fields';
|
$fields = get_option($key, false);
|
if ($fields) {
|
return $fields;
|
}
|
|
// Build fields
|
$fields = $this->buildFields($type, $object_type);
|
|
// Cache the result
|
$this->fieldCache[$cacheKey] = $fields;
|
update_option($key, $fields);
|
|
return $fields;
|
}
|
|
/**
|
* Build fields for a type
|
*/
|
private function buildFields(string $type, string $object_type): array
|
{
|
$config = $this->getConfig($type, $object_type);
|
|
if (!$config) {
|
return [];
|
}
|
|
$fields = $config['fields'] ?? [];
|
|
// Process common fields
|
if (array_key_exists('common', $fields) && !empty($fields['common'])) {
|
$fields = $this->processCommonFields($fields, $fields['common']);
|
unset($fields['common']);
|
}
|
|
|
// Apply integration fields
|
$fields = $this->applyIntegrationFields($fields, $config, $type);
|
|
// Apply filters for extensibility
|
$fields = apply_filters(BASE . 'fields', $fields, $type, $object_type);
|
return apply_filters(BASE . "{$type}_fields", $fields, $object_type);
|
}
|
|
/**
|
* Process common fields
|
*/
|
private function processCommonFields(array $fields, array $common): array
|
{
|
if (!isset($this->fieldProviders['common'])) {
|
return $fields;
|
}
|
|
$provider = $this->fieldProviders['common'];
|
|
foreach ($common as $field => $config) {
|
if (!is_numeric($field)) {
|
$commonFields = $provider->getFields($field, $config);
|
} else {
|
$commonFields = $provider->getFields($config);
|
}
|
$fields = array_merge($fields, $commonFields);
|
}
|
|
return $fields;
|
}
|
|
/**
|
* Apply integration fields based on configuration
|
*/
|
private function applyIntegrationFields(array $fields, array $config, string $type): array
|
{
|
if (array_key_exists('integrations', $config)) {
|
if (isset($this->fieldProviders['integration'])) {
|
$fields = array_merge($fields, $this->fieldProviders['integration']->getFields($config));
|
}
|
}
|
|
// Calendar fields
|
if (jvbCheck('is_calendar', $config)) {
|
if (isset($this->fieldProviders['calendar'])) {
|
$fields = array_merge($fields, $this->fieldProviders['calendar']->getFields());
|
}
|
}
|
|
if (Features::hasIntegration('helcim') && jvbCheck('use_helcim', $config)) {
|
$helcim = JVB()->connect('helcim');
|
if ($helcim) {
|
$contentType = $config['integrations']['helcim']['content_type'] ?? $helcim->getDefaultContentType();
|
$fields = array_merge($fields, $helcim->getHelcimMeta($contentType));
|
}
|
}
|
|
return $fields;
|
}
|
|
/**
|
* Get configuration for a type
|
*/
|
private function getConfig(string $type, string $object_type): ?array
|
{
|
switch ($object_type) {
|
case 'post':
|
return JVB_CONTENT[$type] ?? null;
|
case 'term':
|
return JVB_TAXONOMY[$type] ?? null;
|
case 'user':
|
return JVB_USER[$type] ?? null;
|
case 'options':
|
return JVB_OPTIONS;
|
default:
|
return null;
|
}
|
}
|
|
/**
|
* Initialize fields on plugin load
|
*/
|
public function initializeFields(): void
|
{
|
// Pre-populate cache for all registered types
|
foreach (JVB_CONTENT as $slug => $config) {
|
$this->getFields($slug, 'post');
|
}
|
|
foreach (JVB_TAXONOMY as $slug => $config) {
|
$this->getFields($slug, 'term');
|
}
|
|
foreach (JVB_USER as $slug => $config) {
|
$this->getFields($slug, 'user');
|
}
|
|
if (!empty(JVB_OPTIONS)) {
|
$this->getFields('options', 'options');
|
}
|
}
|
|
private function normalizeType(string $type): string
|
{
|
return str_replace('-', '_', jvbNoBase($type));
|
}
|
|
private function isValidType(string $type): bool
|
{
|
return array_key_exists($type, JVB_CONTENT) ||
|
array_key_exists($type, JVB_TAXONOMY) ||
|
array_key_exists($type, JVB_USER) ||
|
$type === 'options';
|
}
|
|
private function getObjectType(string $type): string
|
{
|
if (array_key_exists($type, JVB_CONTENT)) {
|
return 'post';
|
} elseif (array_key_exists($type, JVB_TAXONOMY)) {
|
return 'term';
|
} elseif (array_key_exists($type, JVB_USER)) {
|
return 'user';
|
} elseif ($type === 'options') {
|
return 'options';
|
}
|
|
return '';
|
}
|
}
|