private function create_tables() { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); // Check if we need to upgrade $installed_version = get_option( 'sp_db_version', '0' ); if ( version_compare( $installed_version, $this->db_version, '<' ) ) { $this->upgrade_database( $installed_version ); } require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); // Services table $table_name = $wpdb->prefix . 'sp_services'; $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, name varchar(255) NOT NULL, description text, duration int(11) NOT NULL DEFAULT 60, price decimal(10,2) NOT NULL DEFAULT 0.00, category varchar(100), is_active tinyint(1) NOT NULL DEFAULT 1, created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY category (category), KEY is_active (is_active) ) $charset_collate;"; dbDelta( $sql ); // Staff table $table_name = $wpdb->prefix . 'sp_staff'; $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, name varchar(255) NOT NULL, email varchar(255), phone varchar(20), specialties text, schedule text, is_active tinyint(1) NOT NULL DEFAULT 1, created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY email (email), KEY is_active (is_active) ) $charset_collate;"; dbDelta( $sql ); // Customers table $table_name = $wpdb->prefix . 'sp_customers'; $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, name varchar(255) NOT NULL, email varchar(255), phone varchar(20), address text, notes text, last_visit date, created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY email (email), KEY phone (phone), KEY last_visit (last_visit) ) $charset_collate;"; dbDelta( $sql ); // Appointments table $table_name = $wpdb->prefix . 'sp_appointments'; $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, customer_id mediumint(9) NOT NULL, staff_id mediumint(9) NOT NULL, service_id mediumint(9) NOT NULL, appointment_date date NOT NULL, appointment_time time NOT NULL, status varchar(20) NOT NULL DEFAULT 'confirmed', notes text, created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY customer_id (customer_id), KEY staff_id (staff_id), KEY service_id (service_id), KEY appointment_date (appointment_date), KEY status (status), KEY appointment_datetime (appointment_date, appointment_time), CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES {$wpdb->prefix}sp_customers(id) ON DELETE CASCADE, CONSTRAINT fk_staff FOREIGN KEY (staff_id) REFERENCES {$wpdb->prefix}sp_staff(id) ON DELETE CASCADE, CONSTRAINT fk_service FOREIGN KEY (service_id) REFERENCES {$wpdb->prefix}sp_services(id) ON DELETE CASCADE ) $charset_collate;"; dbDelta( $sql ); update_option( 'sp_db_version', $this->db_version ); } private function upgrade_database( $installed_version ) { global $wpdb; // Database upgrade routines for future versions // Version 1.1 upgrades (example for future use) if ( version_compare( $installed_version, '1.1', '<' ) ) { // Example: Add payment status column // $wpdb->query( "ALTER TABLE {$wpdb->prefix}sp_appointments ADD COLUMN payment_status varchar(20) DEFAULT 'pending'" ); } // Version 1.2 upgrades (example for future use) if ( version_compare( $installed_version, '1.2', '<' ) ) { // Example: Add reminder_sent column // $wpdb->query( "ALTER TABLE {$wpdb->prefix}sp_appointments ADD COLUMN reminder_sent tinyint(1) DEFAULT 0" ); } // Version 2.0 upgrades - major version changes if ( version_compare( $installed_version, '2.0', '<' ) ) { // Convert boolean fields to tinyint for better MySQL compatibility $wpdb->query( "ALTER TABLE {$wpdb->prefix}sp_services MODIFY COLUMN is_active tinyint(1) NOT NULL DEFAULT 1" ); $wpdb->query( "ALTER TABLE {$wpdb->prefix}sp_staff MODIFY COLUMN is_active tinyint(1) NOT NULL DEFAULT 1" ); // Add composite index for appointment datetime (MySQL compatible syntax) $wpdb->query( "ALTER TABLE {$wpdb->prefix}sp_appointments ADD KEY idx_appointment_datetime (appointment_date, appointment_time)" ); } // Always run this for any version upgrade $this->ensure_table_integrity(); } private function ensure_table_integrity() { global $wpdb; // Prevent infinite loops static $integrity_checked = false; if ( $integrity_checked ) { return; } $integrity_checked = true; // Check if all required tables exist and have correct structure $required_tables = array( $wpdb->prefix . 'sp_services', $wpdb->prefix . 'sp_staff', $wpdb->prefix . 'sp_customers', $wpdb->prefix . 'sp_appointments' ); $missing_tables = array(); foreach ( $required_tables as $table ) { if ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) !== $table ) { $missing_tables[] = $table; } } if ( ! empty( $missing_tables ) ) { // Tables missing, log and recreate error_log( "Salons Profit: Missing tables: " . implode( ', ', $missing_tables ) ); // Reset version to force recreation delete_option( 'sp_db_version' ); // Don't call create_tables() again to avoid infinite loop // Instead, let the next page load handle it } }