"\033[32m", // Green 'error' => "\033[31m", // Red 'warning' => "\033[33m", // Yellow 'info' => "\033[36m", // Cyan 'reset' => "\033[0m", // Reset ]; echo $colors[$type] . "[" . strtoupper($type) . "] " . $message . $colors['reset'] . PHP_EOL; } // Function to check and create certificate tables function check_and_create_certificate_tables() { global $wpdb; print_status("Checking certificate tables..."); // Define table name $table_name = $wpdb->prefix . 'hvac_certificates'; // Check if the table exists $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name; if (!$table_exists) { print_status("Certificate table does not exist. Creating it now...", 'warning'); // Create the table with proper schema $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( certificate_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, event_id BIGINT(20) UNSIGNED NOT NULL, attendee_id BIGINT(20) UNSIGNED NOT NULL, user_id BIGINT(20) UNSIGNED DEFAULT NULL, certificate_number VARCHAR(50) NOT NULL, file_path VARCHAR(255) NOT NULL, date_generated DATETIME NOT NULL, generated_by BIGINT(20) UNSIGNED NOT NULL, revoked TINYINT(1) NOT NULL DEFAULT 0, revoked_date DATETIME DEFAULT NULL, revoked_by BIGINT(20) UNSIGNED DEFAULT NULL, revoked_reason TEXT DEFAULT NULL, email_sent TINYINT(1) NOT NULL DEFAULT 0, email_sent_date DATETIME DEFAULT NULL, PRIMARY KEY (certificate_id), UNIQUE KEY event_attendee (event_id, attendee_id), KEY event_id (event_id), KEY attendee_id (attendee_id), KEY user_id (user_id), KEY certificate_number (certificate_number), KEY revoked (revoked) ) $charset_collate;"; // Use dbDelta to create or update table $result = dbDelta($sql); // Check if table was created $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name; if ($table_exists) { print_status("Table created successfully!", 'success'); update_option('hvac_certificates_db_version', '1.0.0'); } else { print_status("Failed to create table. Error: " . $wpdb->last_error, 'error'); return false; } } else { print_status("Certificate table exists: $table_name", 'success'); // Check if the table has the expected structure print_status("Checking table structure...", 'info'); // Get columns $columns = $wpdb->get_results("DESCRIBE $table_name"); $column_names = array_map(function($col) { return $col->Field; }, $columns); // Expected columns $expected_columns = [ 'certificate_id', 'event_id', 'attendee_id', 'user_id', 'certificate_number', 'file_path', 'date_generated', 'generated_by', 'revoked', 'revoked_date', 'revoked_by', 'revoked_reason', 'email_sent', 'email_sent_date' ]; // Check for missing columns $missing_columns = array_diff($expected_columns, $column_names); if (!empty($missing_columns)) { print_status("Table is missing columns: " . implode(", ", $missing_columns), 'warning'); // Create migration to add missing columns print_status("Attempting to fix missing columns...", 'info'); // Use dbDelta to update table structure $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( certificate_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, event_id BIGINT(20) UNSIGNED NOT NULL, attendee_id BIGINT(20) UNSIGNED NOT NULL, user_id BIGINT(20) UNSIGNED DEFAULT NULL, certificate_number VARCHAR(50) NOT NULL, file_path VARCHAR(255) NOT NULL, date_generated DATETIME NOT NULL, generated_by BIGINT(20) UNSIGNED NOT NULL, revoked TINYINT(1) NOT NULL DEFAULT 0, revoked_date DATETIME DEFAULT NULL, revoked_by BIGINT(20) UNSIGNED DEFAULT NULL, revoked_reason TEXT DEFAULT NULL, email_sent TINYINT(1) NOT NULL DEFAULT 0, email_sent_date DATETIME DEFAULT NULL, PRIMARY KEY (certificate_id), UNIQUE KEY event_attendee (event_id, attendee_id), KEY event_id (event_id), KEY attendee_id (attendee_id), KEY user_id (user_id), KEY certificate_number (certificate_number), KEY revoked (revoked) ) $charset_collate;"; $result = dbDelta($sql); // Check if fix was successful $columns = $wpdb->get_results("DESCRIBE $table_name"); $column_names = array_map(function($col) { return $col->Field; }, $columns); $missing_columns = array_diff($expected_columns, $column_names); if (empty($missing_columns)) { print_status("Table structure fixed successfully!", 'success'); update_option('hvac_certificates_db_version', '1.0.0'); } else { print_status("Failed to fix all columns. Still missing: " . implode(", ", $missing_columns), 'error'); return false; } } else { print_status("Table structure is correct.", 'success'); } } // Check and create certificate directory print_status("Checking certificate directory...", 'info'); $upload_dir = wp_upload_dir(); $cert_dir = $upload_dir['basedir'] . '/' . get_option('hvac_certificate_storage_path', 'hvac-certificates'); if (!file_exists($cert_dir)) { print_status("Certificate directory does not exist. Creating it now...", 'warning'); wp_mkdir_p($cert_dir); if (file_exists($cert_dir)) { print_status("Certificate directory created: $cert_dir", 'success'); } else { print_status("Failed to create certificate directory.", 'error'); return false; } } else { print_status("Certificate directory exists: $cert_dir", 'success'); } // Check and set certificate options print_status("Checking certificate options...", 'info'); if (false === get_option('hvac_certificate_counter')) { add_option('hvac_certificate_counter', 0); print_status("Added hvac_certificate_counter option", 'success'); } if (false === get_option('hvac_certificate_prefix')) { add_option('hvac_certificate_prefix', 'HVAC-'); print_status("Added hvac_certificate_prefix option", 'success'); } if (false === get_option('hvac_certificate_storage_path')) { add_option('hvac_certificate_storage_path', 'hvac-certificates'); print_status("Added hvac_certificate_storage_path option", 'success'); } return true; } // Fix certificate template closing PHP tag issue function fix_template_closing_tags() { print_status("Checking template-certificate-reports.php for syntax issues...", 'info'); $plugin_dir = WP_CONTENT_DIR . '/plugins/hvac-community-events/'; $template_file = $plugin_dir . 'templates/certificates/template-certificate-reports.php'; if (file_exists($template_file)) { $content = file_get_contents($template_file); // Find and fix HTML comment tags (