get_charset_collate(); // Table des personnes (pour les participants non-bénéficiaires) $persons_table = $wpdb->prefix . 'crvi_agenda_persons'; $sql_persons = "CREATE TABLE IF NOT EXISTS `{$persons_table}` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nom` varchar(255) NOT NULL, `prenom` varchar(255) NOT NULL, `langue` varchar(100) DEFAULT NULL, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_nom_prenom` (`nom`, `prenom`) ) {$charset_collate};"; // Table des présences $presence_table = $wpdb->prefix . 'crvi_agenda_presence'; $sql_presence = "CREATE TABLE IF NOT EXISTS `{$presence_table}` ( `id` int(11) NOT NULL AUTO_INCREMENT, `event_id` int(11) NOT NULL, `person_id` int(11) DEFAULT NULL, `beneficiaire_id` int(11) DEFAULT NULL, `is_present` tinyint(1) NOT NULL DEFAULT 0, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_event_id` (`event_id`), KEY `idx_person_id` (`person_id`), KEY `idx_beneficiaire_id` (`beneficiaire_id`) ) {$charset_collate};"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql_persons); dbDelta($sql_presence); } /** * Insère ou récupère une personne dans la table wp_crvi_agenda_persons * Si une personne avec le même nom et prénom existe déjà, retourne son ID * Sinon, crée une nouvelle entrée * * @param string $nom * @param string $prenom * @param string $langue * @return int L'ID de la personne */ public static function save_person(string $nom, string $prenom, string $langue): int { global $wpdb; $table_name = $wpdb->prefix . 'crvi_agenda_persons'; // Nettoyer les données $nom = sanitize_text_field(trim($nom)); $prenom = sanitize_text_field(trim($prenom)); $langue = sanitize_text_field(trim($langue)); if (empty($nom) || empty($prenom)) { throw new \InvalidArgumentException('Le nom et le prénom sont requis'); } // Vérifier si une personne avec le même nom et prénom existe déjà $existing = $wpdb->get_var($wpdb->prepare( "SELECT id FROM $table_name WHERE nom = %s AND prenom = %s LIMIT 1", $nom, $prenom )); if ($existing) { // Mettre à jour la langue si elle est différente $wpdb->update( $table_name, ['langue' => $langue], ['id' => $existing], ['%s'], ['%d'] ); return (int) $existing; } // Créer une nouvelle personne $result = $wpdb->insert( $table_name, [ 'nom' => $nom, 'prenom' => $prenom, 'langue' => $langue ], ['%s', '%s', '%s'] ); if ($result === false) { throw new \RuntimeException('Erreur lors de l\'insertion de la personne'); } return (int) $wpdb->insert_id; } /** * Enregistre ou met à jour une présence dans la table wp_crvi_agenda_presence * Si une présence existe déjà pour cet event_id et person_id/beneficiaire_id, elle est mise à jour * Sinon, une nouvelle entrée est créée * * @param int $event_id * @param int|null $person_id ID de la personne (si ce n'est pas un bénéficiaire existant) * @param bool $is_present * @param int|null $beneficiaire_id ID du bénéficiaire (si c'est un bénéficiaire existant) * @return int L'ID de la présence (nouvelle ou mise à jour) */ public static function save_presence(int $event_id, ?int $person_id, bool $is_present, ?int $beneficiaire_id = null): int { global $wpdb; $table_name = $wpdb->prefix . 'crvi_agenda_presence'; // Vérifier si la table a le champ beneficiaire_id, sinon l'ajouter self::ensure_beneficiaire_id_column($table_name); // Si beneficiaire_id est fourni, utiliser beneficiaire_id, sinon utiliser person_id if ($beneficiaire_id !== null) { // Vérifier si une présence existe déjà pour cet événement et ce bénéficiaire $existing = $wpdb->get_var($wpdb->prepare( "SELECT id FROM $table_name WHERE event_id = %d AND beneficiaire_id = %d LIMIT 1", $event_id, $beneficiaire_id )); if ($existing) { // Mettre à jour la présence existante $wpdb->update( $table_name, ['is_present' => $is_present ? 1 : 0], ['id' => $existing], ['%d'], ['%d'] ); return (int) $existing; } // Créer une nouvelle présence avec beneficiaire_id $result = $wpdb->insert( $table_name, [ 'event_id' => $event_id, 'person_id' => 0, // 0 ou NULL pour indiquer que c'est un bénéficiaire 'beneficiaire_id' => $beneficiaire_id, 'is_present' => $is_present ? 1 : 0 ], ['%d', '%d', '%d', '%d'] ); } else { // Utiliser person_id (comportement original) if ($person_id === null) { throw new \InvalidArgumentException('person_id ou beneficiaire_id doit être fourni'); } // Vérifier si une présence existe déjà pour cet événement et cette personne $existing = $wpdb->get_var($wpdb->prepare( "SELECT id FROM $table_name WHERE event_id = %d AND person_id = %d AND (beneficiaire_id IS NULL OR beneficiaire_id = 0) LIMIT 1", $event_id, $person_id )); if ($existing) { // Mettre à jour la présence existante $wpdb->update( $table_name, ['is_present' => $is_present ? 1 : 0], ['id' => $existing], ['%d'], ['%d'] ); return (int) $existing; } // Créer une nouvelle présence avec person_id $result = $wpdb->insert( $table_name, [ 'event_id' => $event_id, 'person_id' => $person_id, 'beneficiaire_id' => null, 'is_present' => $is_present ? 1 : 0 ], ['%d', '%d', '%d', '%d'] ); } if ($result === false) { throw new \RuntimeException('Erreur lors de l\'insertion de la présence'); } return (int) $wpdb->insert_id; } /** * Vérifie et ajoute la colonne beneficiaire_id si elle n'existe pas * @param string $table_name */ private static function ensure_beneficiaire_id_column(string $table_name): void { global $wpdb; // Vérifier si la colonne existe (le nom de la table est sûr car il vient de $wpdb->prefix) $column_exists = $wpdb->get_results( "SHOW COLUMNS FROM `{$table_name}` LIKE 'beneficiaire_id'" ); if (empty($column_exists)) { // Ajouter la colonne beneficiaire_id $wpdb->query("ALTER TABLE `{$table_name}` ADD COLUMN `beneficiaire_id` int(11) DEFAULT NULL AFTER `person_id`"); // Ajouter un index pour améliorer les performances $wpdb->query("ALTER TABLE `{$table_name}` ADD INDEX `idx_beneficiaire_id` (`beneficiaire_id`)"); } } /** * Récupère toutes les présences pour un événement donné * * @param int $event_id * @return array Tableau associatif avec les données des présences et des personnes */ public static function get_presences_by_event(int $event_id): array { global $wpdb; $presence_table = $wpdb->prefix . 'crvi_agenda_presence'; $persons_table = $wpdb->prefix . 'crvi_agenda_persons'; $results = $wpdb->get_results($wpdb->prepare( "SELECT p.id as presence_id, p.event_id, p.person_id, p.is_present, per.nom, per.prenom, per.langue FROM $presence_table p INNER JOIN $persons_table per ON p.person_id = per.id WHERE p.event_id = %d ORDER BY per.nom, per.prenom", $event_id ), ARRAY_A); return $results ?: []; } /** * Supprime toutes les présences pour un événement donné * * @param int $event_id * @return bool True si succès, false sinon */ public static function delete_presences_by_event(int $event_id): bool { global $wpdb; $table_name = $wpdb->prefix . 'crvi_agenda_presence'; $result = $wpdb->delete( $table_name, ['event_id' => $event_id], ['%d'] ); return $result !== false; } }