[ 'type' => 'datetime-local', 'class' => 'hvac-datetime-field', 'validate' => ['datetime'], 'sanitize' => 'datetime', ], 'event-title' => [ 'type' => 'text', 'class' => 'hvac-event-title', 'validate' => ['min_length' => 3, 'max_length' => 200], 'sanitize' => 'text', ], 'event-description' => [ 'type' => 'textarea', 'class' => 'hvac-event-description', 'validate' => ['max_length' => 2000], 'sanitize' => 'textarea', ], 'venue-select' => [ 'type' => 'select', 'class' => 'hvac-venue-select', 'options' => [], 'validate' => [], 'sanitize' => 'int', ], 'organizer-select' => [ 'type' => 'select', 'class' => 'hvac-organizer-select', 'options' => [], 'validate' => [], 'sanitize' => 'int', ], 'capacity' => [ 'type' => 'number', 'class' => 'hvac-capacity-field', 'validate' => ['min_value' => 1, 'max_value' => 10000], 'sanitize' => 'int', ], 'cost' => [ 'type' => 'number', 'step' => '0.01', 'class' => 'hvac-cost-field', 'validate' => ['min_value' => 0], 'sanitize' => 'float', ], 'template-selector' => [ 'type' => 'template-select', 'class' => 'hvac-template-selector', 'options' => [], 'validate' => [], 'sanitize' => 'text', ], ]; /** * Cache instance for performance optimization (optional) * * @var mixed */ private $cache = null; /** * Constructor * * @param string $nonce_action Nonce action for form security * @param bool $enable_templates Whether to enable template functionality */ public function __construct(string $nonce_action, bool $enable_templates = true) { parent::__construct($nonce_action); $this->template_manager = HVAC_Event_Template_Manager::instance(); $this->template_mode_enabled = $enable_templates; // Initialize cache if available (not implemented yet) // $this->cache = class_exists('HVAC_Event_Cache') ? HVAC_Event_Cache::instance() : null; $this->init_event_form_hooks(); } /** * Initialize event form specific hooks */ private function init_event_form_hooks(): void { if ($this->template_mode_enabled) { add_action('wp_enqueue_scripts', [$this, 'enqueue_template_assets']); add_action('wp_ajax_hvac_load_template_data', [$this, 'ajax_load_template_data']); add_action('wp_ajax_hvac_save_as_template', [$this, 'ajax_save_as_template']); } } /** * Create complete event form with template integration * * @param array $config Form configuration options * @return self */ public function create_event_form(array $config = []): self { $defaults = [ 'include_template_selector' => $this->template_mode_enabled, 'include_venue_fields' => true, 'include_organizer_fields' => true, 'include_cost_fields' => true, 'include_capacity_fields' => true, 'include_datetime_fields' => true, 'template_categories' => ['general', 'training', 'workshop'], ]; $config = array_merge($defaults, $config); // Add template selector first if enabled if ($config['include_template_selector']) { $this->add_template_selector($config['template_categories']); } // Basic event fields $this->add_basic_event_fields(); // Optional field groups if ($config['include_datetime_fields']) { $this->add_datetime_fields(); } if ($config['include_venue_fields']) { $this->add_venue_fields(); } if ($config['include_organizer_fields']) { $this->add_organizer_fields(); } if ($config['include_capacity_fields']) { $this->add_capacity_field(); } if ($config['include_cost_fields']) { $this->add_cost_fields(); } // Template actions if enabled if ($this->template_mode_enabled) { $this->add_template_actions(); } return $this; } /** * Add template selector field * * @param array $categories Template categories to include */ public function add_template_selector(array $categories = []): self { if (!$this->template_mode_enabled) { return $this; } // Get available templates $filters = []; if (!empty($categories)) { $templates = []; foreach ($categories as $category) { $category_templates = $this->template_manager->get_templates(['category' => $category]); $templates = array_merge($templates, $category_templates); } } else { $templates = $this->template_manager->get_templates(); } // Prepare template options $template_options = ['0' => '-- Select a Template --']; foreach ($templates as $template) { $template_options[$template['id']] = esc_html($template['name']) . ' (' . ucfirst($template['category']) . ')'; } $template_field = array_merge($this->event_field_defaults['template-selector'], [ 'name' => 'event_template', 'label' => 'Use Template', 'options' => $template_options, 'description' => 'Select a template to pre-fill form fields', 'wrapper_class' => 'form-row template-selector-row', ]); $this->add_field($template_field); return $this; } /** * Add basic event fields */ public function add_basic_event_fields(): self { // Event title $title_field = array_merge($this->event_field_defaults['event-title'], [ 'name' => 'event_title', 'label' => 'Event Title', 'placeholder' => 'Enter event title...', 'required' => true, ]); // Event description $description_field = array_merge($this->event_field_defaults['event-description'], [ 'name' => 'event_description', 'label' => 'Event Description', 'placeholder' => 'Describe your event...', 'rows' => 6, ]); $this->add_field($title_field); $this->add_field($description_field); return $this; } /** * Add datetime fields for event scheduling */ public function add_datetime_fields(): self { // Start date/time $start_datetime_field = array_merge($this->event_field_defaults['datetime-local'], [ 'name' => 'event_start_datetime', 'label' => 'Start Date & Time', 'required' => true, 'wrapper_class' => 'form-row datetime-row start-datetime', ]); // End date/time $end_datetime_field = array_merge($this->event_field_defaults['datetime-local'], [ 'name' => 'event_end_datetime', 'label' => 'End Date & Time', 'required' => true, 'wrapper_class' => 'form-row datetime-row end-datetime', ]); // Timezone $timezone_field = [ 'type' => 'select', 'name' => 'event_timezone', 'label' => 'Timezone', 'options' => $this->get_timezone_options(), 'value' => wp_timezone_string(), 'class' => 'hvac-timezone-select', 'wrapper_class' => 'form-row timezone-row', ]; $this->add_field($start_datetime_field); $this->add_field($end_datetime_field); $this->add_field($timezone_field); return $this; } /** * Add venue selection and management fields */ public function add_venue_fields(): self { // Get venue options with caching $venue_options = $this->get_venue_options(); $venue_field = array_merge($this->event_field_defaults['venue-select'], [ 'name' => 'event_venue', 'label' => 'Venue', 'options' => $venue_options, 'description' => 'Select an existing venue or create a new one', 'wrapper_class' => 'form-row venue-row', ]); $this->add_field($venue_field); // Add venue creation fields (initially hidden) $this->add_venue_creation_fields(); return $this; } /** * Add organizer selection and management fields */ public function add_organizer_fields(): self { // Get organizer options with caching $organizer_options = $this->get_organizer_options(); $organizer_field = array_merge($this->event_field_defaults['organizer-select'], [ 'name' => 'event_organizer', 'label' => 'Organizer', 'options' => $organizer_options, 'description' => 'Select an existing organizer or create a new one', 'wrapper_class' => 'form-row organizer-row', ]); $this->add_field($organizer_field); // Add organizer creation fields (initially hidden) $this->add_organizer_creation_fields(); return $this; } /** * Add capacity field */ public function add_capacity_field(): self { $capacity_field = array_merge($this->event_field_defaults['capacity'], [ 'name' => 'event_capacity', 'label' => 'Capacity', 'placeholder' => 'Maximum attendees', 'min' => 1, 'max' => 10000, 'wrapper_class' => 'form-row capacity-row', ]); $this->add_field($capacity_field); return $this; } /** * Add cost-related fields */ public function add_cost_fields(): self { $cost_field = array_merge($this->event_field_defaults['cost'], [ 'name' => 'event_cost', 'label' => 'Event Cost ($)', 'placeholder' => '0.00', 'min' => 0, 'wrapper_class' => 'form-row cost-row', ]); $this->add_field($cost_field); return $this; } /** * Add template action buttons */ public function add_template_actions(): self { if (!$this->template_mode_enabled) { return $this; } // Save as template button $save_template_field = [ 'type' => 'button', 'name' => 'save_as_template', 'label' => '', 'value' => 'Save as Template', 'class' => 'button button-secondary hvac-save-template', 'wrapper_class' => 'form-row template-actions', 'onclick' => 'hvacSaveAsTemplate(event)', ]; $this->add_field($save_template_field); return $this; } /** * Load template data into form * * @param string $template_id Template ID to load * @return bool Success status */ public function load_template(string $template_id): bool { if (!$this->template_mode_enabled) { return false; } $template = $this->template_manager->get_template($template_id); if (!$template) { return false; } $this->current_template = $template; // Set form data from template if (!empty($template['field_data'])) { $this->set_data($template['field_data']); } // Apply template-specific validation rules if (!empty($template['validation_rules'])) { $this->apply_template_validation_rules($template['validation_rules']); } return true; } /** * Save current form configuration as template * * @param array $template_config Template configuration * @return array Result with success status */ public function save_as_template(array $template_config): array { if (!$this->template_mode_enabled) { return [ 'success' => false, 'error' => __('Template functionality is not enabled', 'hvac-community-events') ]; } // Get current form data $current_data = $this->get_current_form_data(); // Prepare template data $template_data = [ 'name' => sanitize_text_field($template_config['name']), 'description' => sanitize_textarea_field($template_config['description']), 'category' => sanitize_text_field($template_config['category']), 'is_public' => (bool) ($template_config['is_public'] ?? false), 'field_data' => $current_data, 'meta_data' => $template_config['meta_data'] ?? [], ]; return $this->template_manager->create_template($template_data); } /** * Get current form data from fields * * @return array Current form data */ private function get_current_form_data(): array { // This would typically be called after form submission // For now, return empty array - implement based on specific needs return []; } /** * Apply template validation rules to form fields * * @param array $validation_rules Template validation rules */ private function apply_template_validation_rules(array $validation_rules): void { // Apply additional validation rules from template foreach ($validation_rules as $field_name => $rules) { // Find field and update validation rules foreach ($this->fields as &$field) { if ($field['name'] === $field_name) { $field['validate'] = array_merge($field['validate'], $rules); break; } } } } /** * Get timezone options for select field * * @return array Timezone options */ private function get_timezone_options(): array { // Check cache first $cached_timezones = $this->cache->get_timezone_list(); if ($cached_timezones !== false) { return $cached_timezones; } // Generate timezone options $timezone_options = []; $zones = wp_timezone_choice('UTC'); if (preg_match_all('/