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()); // if (jvbSiteUsesHelcim()) { // $this->addFieldProvider('helcim', new HelcimFieldProvider()); // } // 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); $fields = apply_filters(BASE . "{$type}_fields", $fields, $object_type); return $fields; } /** * 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()); } } 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 ''; } }