🚨 CRITICAL: Fixed deployment blockers by adding missing core directories: **Community System (CRITICAL)** - includes/community/ - Login_Handler and all community classes - templates/community/ - Community login forms **Certificate System (CRITICAL)** - includes/certificates/ - 8+ certificate classes and handlers - templates/certificates/ - Certificate reports and generation templates **Core Individual Classes (CRITICAL)** - includes/class-hvac-event-summary.php - includes/class-hvac-trainer-profile-manager.php - includes/class-hvac-master-dashboard-data.php - Plus 40+ other individual HVAC classes **Major Feature Systems (HIGH)** - includes/database/ - Training leads database tables - includes/find-trainer/ - Find trainer directory and MapGeo integration - includes/google-sheets/ - Google Sheets integration system - includes/zoho/ - Complete Zoho CRM integration - includes/communication/ - Communication templates system **Template Infrastructure** - templates/attendee/, templates/email-attendees/ - templates/event-summary/, templates/status/ - templates/template-parts/ - Shared template components **Impact:** - 70+ files added covering 10+ missing directories - Resolves ALL deployment blockers and feature breakdowns - Plugin activation should now work correctly - Multi-machine deployment fully supported 🔧 Generated with Claude Code Co-Authored-By: Ben Reed <ben@tealmaker.com>
		
			
				
	
	
		
			596 lines
		
	
	
		
			No EOL
		
	
	
		
			22 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			596 lines
		
	
	
		
			No EOL
		
	
	
		
			22 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * HVAC Community Events - Communication Scheduler
 | |
|  *
 | |
|  * Main controller for automated communication scheduling system.
 | |
|  * Handles creation, management, and execution of scheduled communications.
 | |
|  *
 | |
|  * @package HVAC_Community_Events
 | |
|  * @subpackage Communication
 | |
|  * @version 1.0.0
 | |
|  */
 | |
| 
 | |
| // Exit if accessed directly
 | |
| if ( ! defined( 'ABSPATH' ) ) {
 | |
|     exit;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Class HVAC_Communication_Scheduler
 | |
|  *
 | |
|  * Core scheduling system for automated email communications.
 | |
|  */
 | |
| class HVAC_Communication_Scheduler {
 | |
| 
 | |
|     /**
 | |
|      * Singleton instance
 | |
|      */
 | |
|     private static $instance = null;
 | |
| 
 | |
|     /**
 | |
|      * Schedule manager instance
 | |
|      */
 | |
|     private $schedule_manager;
 | |
| 
 | |
|     /**
 | |
|      * Trigger engine instance
 | |
|      */
 | |
|     private $trigger_engine;
 | |
| 
 | |
|     /**
 | |
|      * Communication logger instance
 | |
|      */
 | |
|     private $logger;
 | |
| 
 | |
|     /**
 | |
|      * Get singleton instance
 | |
|      */
 | |
|     public static function instance() {
 | |
|         if ( null === self::$instance ) {
 | |
|             self::$instance = new self();
 | |
|         }
 | |
|         return self::$instance;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Constructor
 | |
|      */
 | |
|     private function __construct() {
 | |
|         $this->init_dependencies();
 | |
|         $this->register_hooks();
 | |
|         
 | |
|         // Debug logging
 | |
|         if ( class_exists( 'HVAC_Logger' ) ) {
 | |
|             HVAC_Logger::info( 'HVAC_Communication_Scheduler initialized', 'Scheduler' );
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Initialize dependencies
 | |
|      */
 | |
|     private function init_dependencies() {
 | |
|         require_once HVAC_PLUGIN_DIR . 'includes/communication/class-communication-schedule-manager.php';
 | |
|         require_once HVAC_PLUGIN_DIR . 'includes/communication/class-communication-trigger-engine.php';
 | |
|         require_once HVAC_PLUGIN_DIR . 'includes/communication/class-communication-logger.php';
 | |
| 
 | |
|         $this->schedule_manager = new HVAC_Communication_Schedule_Manager();
 | |
|         $this->trigger_engine = new HVAC_Communication_Trigger_Engine();
 | |
|         $this->logger = new HVAC_Communication_Logger();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Register WordPress hooks
 | |
|      */
 | |
|     private function register_hooks() {
 | |
|         // Cron hooks
 | |
|         add_action( 'hvac_process_communication_schedules', array( $this, 'process_scheduled_communications' ) );
 | |
|         
 | |
|         // Event-based triggers
 | |
|         add_action( 'tribe_events_event_save_after', array( $this, 'on_event_saved' ) );
 | |
|         add_action( 'event_tickets_after_add_attendee', array( $this, 'on_attendee_registered' ) );
 | |
|         add_action( 'wp', array( $this, 'check_event_date_changes' ) );
 | |
|         
 | |
|         // AJAX handlers
 | |
|         add_action( 'wp_ajax_hvac_create_schedule', array( $this, 'ajax_create_schedule' ) );
 | |
|         add_action( 'wp_ajax_hvac_update_schedule', array( $this, 'ajax_update_schedule' ) );
 | |
|         add_action( 'wp_ajax_hvac_delete_schedule', array( $this, 'ajax_delete_schedule' ) );
 | |
|         add_action( 'wp_ajax_hvac_get_schedules', array( $this, 'ajax_get_schedules' ) );
 | |
|         add_action( 'wp_ajax_hvac_toggle_schedule', array( $this, 'ajax_toggle_schedule' ) );
 | |
|         add_action( 'wp_ajax_hvac_preview_recipients', array( $this, 'ajax_preview_recipients' ) );
 | |
|         
 | |
|         // Custom cron schedules
 | |
|         add_filter( 'cron_schedules', array( $this, 'add_custom_cron_schedules' ) );
 | |
|         
 | |
|         // Initialize cron if not scheduled
 | |
|         add_action( 'wp_loaded', array( $this, 'setup_cron_schedules' ) );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add custom cron schedules
 | |
|      */
 | |
|     public function add_custom_cron_schedules( $schedules ) {
 | |
|         $schedules['hvac_every_5_minutes'] = array(
 | |
|             'interval' => 300,
 | |
|             'display' => __( 'Every 5 minutes', 'hvac-community-events' )
 | |
|         );
 | |
|         
 | |
|         $schedules['hvac_every_15_minutes'] = array(
 | |
|             'interval' => 900,
 | |
|             'display' => __( 'Every 15 minutes', 'hvac-community-events' )
 | |
|         );
 | |
|         
 | |
|         return $schedules;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Setup cron schedules
 | |
|      */
 | |
|     public function setup_cron_schedules() {
 | |
|         if ( ! wp_next_scheduled( 'hvac_process_communication_schedules' ) ) {
 | |
|             wp_schedule_event( time(), 'hvac_every_15_minutes', 'hvac_process_communication_schedules' );
 | |
|             
 | |
|             if ( class_exists( 'HVAC_Logger' ) ) {
 | |
|                 HVAC_Logger::info( 'Communication scheduler cron job set up', 'Scheduler' );
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Create a new communication schedule
 | |
|      *
 | |
|      * @param array $schedule_data Schedule configuration
 | |
|      * @return int|WP_Error Schedule ID on success, WP_Error on failure
 | |
|      */
 | |
|     public function create_schedule( $schedule_data ) {
 | |
|         // Validate schedule data
 | |
|         $validation_result = $this->schedule_manager->validate_schedule_data( $schedule_data );
 | |
|         if ( is_wp_error( $validation_result ) ) {
 | |
|             return $validation_result;
 | |
|         }
 | |
| 
 | |
|         // Check for conflicts
 | |
|         $conflict_check = $this->schedule_manager->check_schedule_conflicts( $schedule_data );
 | |
|         if ( is_wp_error( $conflict_check ) ) {
 | |
|             return $conflict_check;
 | |
|         }
 | |
| 
 | |
|         // Calculate next run time
 | |
|         $next_run = $this->calculate_next_run_time( $schedule_data );
 | |
|         $schedule_data['next_run'] = $next_run;
 | |
| 
 | |
|         // Save schedule
 | |
|         $schedule_id = $this->schedule_manager->save_schedule( $schedule_data );
 | |
|         
 | |
|         if ( $schedule_id && class_exists( 'HVAC_Logger' ) ) {
 | |
|             HVAC_Logger::info( "Communication schedule created: ID $schedule_id", 'Scheduler' );
 | |
|         }
 | |
| 
 | |
|         return $schedule_id;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Update an existing communication schedule
 | |
|      *
 | |
|      * @param int $schedule_id Schedule ID
 | |
|      * @param array $schedule_data Updated schedule configuration
 | |
|      * @return bool|WP_Error Success status
 | |
|      */
 | |
|     public function update_schedule( $schedule_id, $schedule_data ) {
 | |
|         // Verify ownership
 | |
|         if ( ! $this->schedule_manager->user_can_edit_schedule( $schedule_id ) ) {
 | |
|             return new WP_Error( 'permission_denied', __( 'You do not have permission to edit this schedule.', 'hvac-community-events' ) );
 | |
|         }
 | |
| 
 | |
|         // Validate data
 | |
|         $validation_result = $this->schedule_manager->validate_schedule_data( $schedule_data );
 | |
|         if ( is_wp_error( $validation_result ) ) {
 | |
|             return $validation_result;
 | |
|         }
 | |
| 
 | |
|         // Recalculate next run time if trigger settings changed
 | |
|         $existing_schedule = $this->schedule_manager->get_schedule( $schedule_id );
 | |
|         $trigger_changed = ( 
 | |
|             $existing_schedule['trigger_type'] !== $schedule_data['trigger_type'] ||
 | |
|             $existing_schedule['trigger_value'] !== $schedule_data['trigger_value'] ||
 | |
|             $existing_schedule['trigger_unit'] !== $schedule_data['trigger_unit']
 | |
|         );
 | |
| 
 | |
|         if ( $trigger_changed ) {
 | |
|             $schedule_data['next_run'] = $this->calculate_next_run_time( $schedule_data );
 | |
|         }
 | |
| 
 | |
|         return $this->schedule_manager->update_schedule( $schedule_id, $schedule_data );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Delete a communication schedule
 | |
|      *
 | |
|      * @param int $schedule_id Schedule ID
 | |
|      * @return bool|WP_Error Success status
 | |
|      */
 | |
|     public function delete_schedule( $schedule_id ) {
 | |
|         // Verify ownership
 | |
|         if ( ! $this->schedule_manager->user_can_edit_schedule( $schedule_id ) ) {
 | |
|             return new WP_Error( 'permission_denied', __( 'You do not have permission to delete this schedule.', 'hvac-community-events' ) );
 | |
|         }
 | |
| 
 | |
|         $result = $this->schedule_manager->delete_schedule( $schedule_id );
 | |
|         
 | |
|         if ( $result && class_exists( 'HVAC_Logger' ) ) {
 | |
|             HVAC_Logger::info( "Communication schedule deleted: ID $schedule_id", 'Scheduler' );
 | |
|         }
 | |
| 
 | |
|         return $result;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get schedules for a trainer
 | |
|      *
 | |
|      * @param int $trainer_id Trainer user ID
 | |
|      * @param int $event_id Optional specific event ID
 | |
|      * @return array Array of schedules
 | |
|      */
 | |
|     public function get_trainer_schedules( $trainer_id, $event_id = null ) {
 | |
|         return $this->schedule_manager->get_schedules_by_trainer( $trainer_id, $event_id );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Process all due scheduled communications
 | |
|      */
 | |
|     public function process_scheduled_communications() {
 | |
|         $due_schedules = $this->schedule_manager->get_due_schedules();
 | |
|         
 | |
|         if ( class_exists( 'HVAC_Logger' ) ) {
 | |
|             HVAC_Logger::info( 'Processing ' . count( $due_schedules ) . ' due communication schedules', 'Scheduler' );
 | |
|         }
 | |
| 
 | |
|         foreach ( $due_schedules as $schedule ) {
 | |
|             $this->execute_schedule( $schedule['schedule_id'] );
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Calculate next run time for a schedule
 | |
|      *
 | |
|      * @param array $schedule Schedule configuration
 | |
|      * @return string MySQL datetime string
 | |
|      */
 | |
|     public function calculate_next_run_time( $schedule ) {
 | |
|         if ( ! empty( $schedule['event_id'] ) ) {
 | |
|             // Event-based scheduling
 | |
|             $event_date = get_post_meta( $schedule['event_id'], '_EventStartDate', true );
 | |
|             if ( ! $event_date ) {
 | |
|                 return null;
 | |
|             }
 | |
| 
 | |
|             return $this->trigger_engine->calculate_trigger_time( $event_date, $schedule );
 | |
|         } else {
 | |
|             // Immediate or custom date scheduling
 | |
|             if ( $schedule['trigger_type'] === 'custom_date' && ! empty( $schedule['custom_date'] ) ) {
 | |
|                 return $schedule['custom_date'];
 | |
|             } elseif ( $schedule['trigger_type'] === 'on_registration' ) {
 | |
|                 // This will be triggered immediately on registration
 | |
|                 return null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return null;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Execute a specific schedule
 | |
|      *
 | |
|      * @param int $schedule_id Schedule ID
 | |
|      * @return bool Success status
 | |
|      */
 | |
|     public function execute_schedule( $schedule_id ) {
 | |
|         $schedule = $this->schedule_manager->get_schedule( $schedule_id );
 | |
|         if ( ! $schedule ) {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         try {
 | |
|             // Get recipients
 | |
|             $recipients = $this->trigger_engine->get_schedule_recipients( $schedule );
 | |
|             
 | |
|             if ( empty( $recipients ) ) {
 | |
|                 $this->logger->log_schedule_execution( $schedule_id, 'skipped', array(
 | |
|                     'reason' => 'No recipients found'
 | |
|                 ) );
 | |
|                 return true;
 | |
|             }
 | |
| 
 | |
|             // Execute communication
 | |
|             $result = $this->trigger_engine->execute_communication( $schedule, $recipients );
 | |
| 
 | |
|             // Update schedule run tracking
 | |
|             $this->schedule_manager->update_schedule_run_tracking( $schedule_id );
 | |
| 
 | |
|             // Log execution
 | |
|             $this->logger->log_schedule_execution( $schedule_id, 'sent', array(
 | |
|                 'recipient_count' => count( $recipients ),
 | |
|                 'success' => $result
 | |
|             ) );
 | |
| 
 | |
|             return $result;
 | |
| 
 | |
|         } catch ( Exception $e ) {
 | |
|             $this->logger->log_schedule_execution( $schedule_id, 'failed', array(
 | |
|                 'error' => $e->getMessage()
 | |
|             ) );
 | |
|             
 | |
|             if ( class_exists( 'HVAC_Logger' ) ) {
 | |
|                 HVAC_Logger::error( "Schedule execution failed: " . $e->getMessage(), 'Scheduler' );
 | |
|             }
 | |
| 
 | |
|             return false;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Handle event saved/updated
 | |
|      *
 | |
|      * @param int $event_id Event ID
 | |
|      */
 | |
|     public function on_event_saved( $event_id ) {
 | |
|         $schedules = $this->schedule_manager->get_schedules_by_event( $event_id );
 | |
|         
 | |
|         foreach ( $schedules as $schedule ) {
 | |
|             // Recalculate next run time if event date changed
 | |
|             $new_next_run = $this->calculate_next_run_time( $schedule );
 | |
|             
 | |
|             if ( $new_next_run !== $schedule['next_run'] ) {
 | |
|                 $this->schedule_manager->update_schedule( $schedule['schedule_id'], array(
 | |
|                     'next_run' => $new_next_run
 | |
|                 ) );
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Handle attendee registration
 | |
|      *
 | |
|      * @param int $attendee_id Attendee ID
 | |
|      * @param int $event_id Event ID
 | |
|      */
 | |
|     public function on_attendee_registered( $attendee_id, $event_id ) {
 | |
|         // Process immediate registration triggers
 | |
|         $this->trigger_engine->process_registration_triggers( $attendee_id, $event_id );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Check for event date changes
 | |
|      */
 | |
|     public function check_event_date_changes() {
 | |
|         // This will be called on wp hook to check for any event date changes
 | |
|         // and update corresponding schedules
 | |
|         if ( ! is_admin() || ! current_user_can( 'edit_posts' ) ) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         // Process any date change updates
 | |
|         $this->trigger_engine->process_event_date_changes();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * AJAX: Create schedule
 | |
|      */
 | |
|     public function ajax_create_schedule() {
 | |
|         check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );
 | |
| 
 | |
|         if ( ! is_user_logged_in() ) {
 | |
|             wp_send_json_error( array( 'message' => __( 'You must be logged in to create schedules.', 'hvac-community-events' ) ) );
 | |
|         }
 | |
| 
 | |
|         $schedule_data = $this->sanitize_schedule_data( $_POST );
 | |
|         $schedule_data['trainer_id'] = get_current_user_id();
 | |
| 
 | |
|         $result = $this->create_schedule( $schedule_data );
 | |
| 
 | |
|         if ( is_wp_error( $result ) ) {
 | |
|             wp_send_json_error( array( 'message' => $result->get_error_message() ) );
 | |
|         }
 | |
| 
 | |
|         wp_send_json_success( array(
 | |
|             'schedule_id' => $result,
 | |
|             'message' => __( 'Schedule created successfully.', 'hvac-community-events' )
 | |
|         ) );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * AJAX: Update schedule
 | |
|      */
 | |
|     public function ajax_update_schedule() {
 | |
|         check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );
 | |
| 
 | |
|         if ( ! is_user_logged_in() ) {
 | |
|             wp_send_json_error( array( 'message' => __( 'You must be logged in to update schedules.', 'hvac-community-events' ) ) );
 | |
|         }
 | |
| 
 | |
|         $schedule_id = intval( $_POST['schedule_id'] );
 | |
|         $schedule_data = $this->sanitize_schedule_data( $_POST );
 | |
| 
 | |
|         $result = $this->update_schedule( $schedule_id, $schedule_data );
 | |
| 
 | |
|         if ( is_wp_error( $result ) ) {
 | |
|             wp_send_json_error( array( 'message' => $result->get_error_message() ) );
 | |
|         }
 | |
| 
 | |
|         wp_send_json_success( array( 'message' => __( 'Schedule updated successfully.', 'hvac-community-events' ) ) );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * AJAX: Delete schedule
 | |
|      */
 | |
|     public function ajax_delete_schedule() {
 | |
|         check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );
 | |
| 
 | |
|         if ( ! is_user_logged_in() ) {
 | |
|             wp_send_json_error( array( 'message' => __( 'You must be logged in to delete schedules.', 'hvac-community-events' ) ) );
 | |
|         }
 | |
| 
 | |
|         $schedule_id = intval( $_POST['schedule_id'] );
 | |
|         $result = $this->delete_schedule( $schedule_id );
 | |
| 
 | |
|         if ( is_wp_error( $result ) ) {
 | |
|             wp_send_json_error( array( 'message' => $result->get_error_message() ) );
 | |
|         }
 | |
| 
 | |
|         wp_send_json_success( array( 'message' => __( 'Schedule deleted successfully.', 'hvac-community-events' ) ) );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * AJAX: Get schedules
 | |
|      */
 | |
|     public function ajax_get_schedules() {
 | |
|         check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );
 | |
| 
 | |
|         if ( ! is_user_logged_in() ) {
 | |
|             wp_send_json_error( array( 'message' => __( 'You must be logged in to view schedules.', 'hvac-community-events' ) ) );
 | |
|         }
 | |
| 
 | |
|         $trainer_id = get_current_user_id();
 | |
|         $event_id = isset( $_POST['event_id'] ) ? intval( $_POST['event_id'] ) : null;
 | |
|         $status_filter = isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : null;
 | |
| 
 | |
|         $schedules = $this->get_trainer_schedules( $trainer_id, $event_id );
 | |
| 
 | |
|         if ( $status_filter && $status_filter !== 'all' ) {
 | |
|             $schedules = array_filter( $schedules, function( $schedule ) use ( $status_filter ) {
 | |
|                 return $schedule['status'] === $status_filter;
 | |
|             } );
 | |
|         }
 | |
| 
 | |
|         wp_send_json_success( array( 'schedules' => array_values( $schedules ) ) );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * AJAX: Toggle schedule status
 | |
|      */
 | |
|     public function ajax_toggle_schedule() {
 | |
|         check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );
 | |
| 
 | |
|         if ( ! is_user_logged_in() ) {
 | |
|             wp_send_json_error( array( 'message' => __( 'You must be logged in to toggle schedules.', 'hvac-community-events' ) ) );
 | |
|         }
 | |
| 
 | |
|         $schedule_id = intval( $_POST['schedule_id'] );
 | |
|         $schedule = $this->schedule_manager->get_schedule( $schedule_id );
 | |
| 
 | |
|         if ( ! $schedule ) {
 | |
|             wp_send_json_error( array( 'message' => __( 'Schedule not found.', 'hvac-community-events' ) ) );
 | |
|         }
 | |
| 
 | |
|         $new_status = ( $schedule['status'] === 'active' ) ? 'paused' : 'active';
 | |
|         
 | |
|         $result = $this->update_schedule( $schedule_id, array( 'status' => $new_status ) );
 | |
| 
 | |
|         if ( is_wp_error( $result ) ) {
 | |
|             wp_send_json_error( array( 'message' => $result->get_error_message() ) );
 | |
|         }
 | |
| 
 | |
|         wp_send_json_success( array(
 | |
|             'status' => $new_status,
 | |
|             'message' => sprintf( __( 'Schedule %s.', 'hvac-community-events' ), $new_status )
 | |
|         ) );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * AJAX: Preview recipients
 | |
|      */
 | |
|     public function ajax_preview_recipients() {
 | |
|         check_ajax_referer( 'hvac_scheduler_nonce', 'nonce' );
 | |
| 
 | |
|         if ( ! is_user_logged_in() ) {
 | |
|             wp_send_json_error( array( 'message' => __( 'You must be logged in to preview recipients.', 'hvac-community-events' ) ) );
 | |
|         }
 | |
| 
 | |
|         $schedule_data = $this->sanitize_schedule_data( $_POST );
 | |
|         $schedule_data['trainer_id'] = get_current_user_id();
 | |
| 
 | |
|         $recipients = $this->trigger_engine->get_schedule_recipients( $schedule_data );
 | |
| 
 | |
|         wp_send_json_success( array(
 | |
|             'recipients' => $recipients,
 | |
|             'count' => count( $recipients )
 | |
|         ) );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sanitize schedule data from form input
 | |
|      *
 | |
|      * @param array $raw_data Raw POST data
 | |
|      * @return array Sanitized schedule data
 | |
|      */
 | |
|     private function sanitize_schedule_data( $raw_data ) {
 | |
|         return array(
 | |
|             'schedule_name' => isset( $raw_data['schedule_name'] ) ? sanitize_text_field( $raw_data['schedule_name'] ) : '',
 | |
|             'event_id' => isset( $raw_data['event_id'] ) ? intval( $raw_data['event_id'] ) : null,
 | |
|             'template_id' => isset( $raw_data['template_id'] ) ? intval( $raw_data['template_id'] ) : 0,
 | |
|             'trigger_type' => isset( $raw_data['trigger_type'] ) ? sanitize_text_field( $raw_data['trigger_type'] ) : '',
 | |
|             'trigger_value' => isset( $raw_data['trigger_value'] ) ? intval( $raw_data['trigger_value'] ) : 0,
 | |
|             'trigger_unit' => isset( $raw_data['trigger_unit'] ) ? sanitize_text_field( $raw_data['trigger_unit'] ) : 'days',
 | |
|             'target_audience' => isset( $raw_data['target_audience'] ) ? sanitize_text_field( $raw_data['target_audience'] ) : 'all_attendees',
 | |
|             'custom_recipient_list' => isset( $raw_data['custom_recipient_list'] ) ? sanitize_textarea_field( $raw_data['custom_recipient_list'] ) : '',
 | |
|             'is_recurring' => isset( $raw_data['is_recurring'] ) ? (bool) $raw_data['is_recurring'] : false,
 | |
|             'recurring_interval' => isset( $raw_data['recurring_interval'] ) ? intval( $raw_data['recurring_interval'] ) : null,
 | |
|             'recurring_unit' => isset( $raw_data['recurring_unit'] ) ? sanitize_text_field( $raw_data['recurring_unit'] ) : null,
 | |
|             'max_runs' => isset( $raw_data['max_runs'] ) ? intval( $raw_data['max_runs'] ) : null,
 | |
|             'status' => isset( $raw_data['status'] ) ? sanitize_text_field( $raw_data['status'] ) : 'active'
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get default schedule templates
 | |
|      *
 | |
|      * @return array Default schedule configurations
 | |
|      */
 | |
|     public function get_default_schedule_templates() {
 | |
|         return array(
 | |
|             'event_reminder_24h' => array(
 | |
|                 'name' => __( '24-Hour Event Reminder', 'hvac-community-events' ),
 | |
|                 'trigger_type' => 'before_event',
 | |
|                 'trigger_value' => 1,
 | |
|                 'trigger_unit' => 'days',
 | |
|                 'template_category' => 'event_reminder',
 | |
|                 'target_audience' => 'confirmed_attendees',
 | |
|                 'description' => __( 'Send reminder 24 hours before event starts', 'hvac-community-events' )
 | |
|             ),
 | |
|             'welcome_on_registration' => array(
 | |
|                 'name' => __( 'Welcome Email on Registration', 'hvac-community-events' ),
 | |
|                 'trigger_type' => 'on_registration',
 | |
|                 'trigger_value' => 0,
 | |
|                 'trigger_unit' => 'minutes',
 | |
|                 'template_category' => 'pre_event',
 | |
|                 'target_audience' => 'all_attendees',
 | |
|                 'description' => __( 'Send welcome email immediately when someone registers', 'hvac-community-events' )
 | |
|             ),
 | |
|             'post_event_followup' => array(
 | |
|                 'name' => __( 'Post-Event Follow-up', 'hvac-community-events' ),
 | |
|                 'trigger_type' => 'after_event',
 | |
|                 'trigger_value' => 2,
 | |
|                 'trigger_unit' => 'days',
 | |
|                 'template_category' => 'post_event',
 | |
|                 'target_audience' => 'all_attendees',
 | |
|                 'description' => __( 'Send follow-up email 2 days after event', 'hvac-community-events' )
 | |
|             ),
 | |
|             'certificate_notification' => array(
 | |
|                 'name' => __( 'Certificate Ready Notification', 'hvac-community-events' ),
 | |
|                 'trigger_type' => 'after_event',
 | |
|                 'trigger_value' => 3,
 | |
|                 'trigger_unit' => 'days',
 | |
|                 'template_category' => 'certificate',
 | |
|                 'target_audience' => 'confirmed_attendees',
 | |
|                 'description' => __( 'Notify attendees when certificates are ready', 'hvac-community-events' )
 | |
|             )
 | |
|         );
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Initialize the scheduler
 | |
| function hvac_communication_scheduler() {
 | |
|     return HVAC_Communication_Scheduler::instance();
 | |
| }
 | |
| 
 | |
| // Initialize after plugins loaded
 | |
| add_action( 'plugins_loaded', 'hvac_communication_scheduler' ); |