prefix . 'crvi_event_permission'; $charset_collate = $wpdb->get_charset_collate(); // Vérifier si la table existe déjà if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name) { return; // La table existe déjà } $sql = "CREATE TABLE $table_name ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, event_id BIGINT(20) UNSIGNED NOT NULL, jours_permis TEXT DEFAULT NULL, plages_horaires TEXT DEFAULT NULL, indisponibilites TEXT DEFAULT NULL, -- Disponibilités traducteur (si présent) traducteur_jours_permis TEXT DEFAULT NULL, traducteur_indisponibilites TEXT DEFAULT NULL, -- Disponibilités local local_indisponibilites TEXT DEFAULT NULL, locaux_autories TEXT DEFAULT NULL, departements_autories TEXT DEFAULT NULL, types_intervention_autories TEXT DEFAULT NULL, traducteurs_disponibles_par_langue TEXT DEFAULT NULL COMMENT 'Présets traducteurs disponibles par langue (JSON)', date_creation DATETIME NOT NULL, date_modification DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, cree_par BIGINT(20) UNSIGNED DEFAULT NULL, modifie_par BIGINT(20) UNSIGNED DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY event_id (event_id), KEY event_id_index (event_id) ) $charset_collate;"; // Si la table existe déjà, ajouter les nouvelles colonnes si nécessaire if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name) { // Ajouter les colonnes pour traducteur et local si elles n'existent pas $columns_to_add = [ 'traducteur_jours_permis' => 'ALTER TABLE ' . $table_name . ' ADD COLUMN traducteur_jours_permis TEXT DEFAULT NULL', 'traducteur_indisponibilites' => 'ALTER TABLE ' . $table_name . ' ADD COLUMN traducteur_indisponibilites TEXT DEFAULT NULL', 'local_indisponibilites' => 'ALTER TABLE ' . $table_name . ' ADD COLUMN local_indisponibilites TEXT DEFAULT NULL', 'traducteurs_disponibles_par_langue' => 'ALTER TABLE ' . $table_name . ' ADD COLUMN traducteurs_disponibles_par_langue TEXT DEFAULT NULL', ]; foreach ($columns_to_add as $column => $sql_add) { $column_exists = $wpdb->get_results($wpdb->prepare( "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = %s", DB_NAME, $table_name, $column )); if (empty($column_exists)) { $wpdb->query($sql_add); } } return; // Table existe, colonnes ajoutées si nécessaire } dbDelta($sql); } /** * Crée les disponibilités à partir de l'intervenant, traducteur et local lors de la création d'un événement * * Stocke : * - Les jours de la semaine disponibles (intervenant, traducteur) * - Les plages horaires disponibles (intervenant) * - Les indisponibilités ponctuelles (intervenant, traducteur, local) * - Les traducteurs disponibles par langue (preset pour optimisation) * * @param int $event_id ID de l'événement * @param int $intervenant_id ID de l'intervenant * @param array|null $plages_horaires Plages horaires spécifiques (optionnel, pour les permanences) * @param int|null $traducteur_id ID du traducteur (optionnel) * @param int|null $local_id ID du local (optionnel) * @param string|null $langue_slug Slug de la langue de l'événement (pour précalculer traducteurs disponibles) * @param string|null $date_rdv Date de l'événement (pour précalculer traducteurs disponibles) * @return bool|WP_Error */ public static function create_from_intervenant($event_id, $intervenant_id, $plages_horaires = null, $traducteur_id = null, $local_id = null, $langue_slug = null, $date_rdv = null) { global $wpdb; $intervenant = CRVI_Intervenant_Model::load($intervenant_id); if (!$intervenant) { return new \WP_Error('intervenant_not_found', 'Intervenant introuvable', ['status' => 404]); } // Extraire les jours de la semaine disponibles de l'intervenant (lundi, mardi, etc. - PAS des dates) $jours_disponibles = get_field('jours_de_disponibilite', 'user_' . $intervenant_id); $jours_permis = is_array($jours_disponibles) ? json_encode($jours_disponibles) : json_encode([]); // Extraire les indisponibilités ponctuelles de l'intervenant $indisponibilites_acf = get_field('indisponibilitee_ponctuelle', 'user_' . $intervenant_id); $indisponibilites = is_array($indisponibilites_acf) ? json_encode($indisponibilites_acf) : json_encode([]); // Extraire les départements et types d'intervention $departements_autories = !empty($intervenant->departements_ids) ? json_encode($intervenant->departements_ids) : json_encode([]); $types_intervention_autories = !empty($intervenant->types_intervention_ids) ? json_encode($intervenant->types_intervention_ids) : json_encode([]); // Plages horaires : si fournies, les utiliser, sinon null $plages_horaires_json = null; if ($plages_horaires !== null && is_array($plages_horaires)) { $plages_horaires_json = json_encode($plages_horaires); } // Traducteur : jours et indisponibilités (si présent) $traducteur_jours_permis = null; $traducteur_indisponibilites = null; if ($traducteur_id) { $traducteur = CRVI_Traducteur_Model::load($traducteur_id); if ($traducteur) { // Jours de disponibilité du traducteur $traducteur_jours = get_field('jours_de_disponibilite', $traducteur_id); $traducteur_jours_permis = is_array($traducteur_jours) ? json_encode($traducteur_jours) : json_encode([]); // Indisponibilités ponctuelles du traducteur $traducteur_indispo_acf = get_field('indisponibilitee_ponctuelle', $traducteur_id); $traducteur_indisponibilites = is_array($traducteur_indispo_acf) ? json_encode($traducteur_indispo_acf) : json_encode([]); } } // Local : indisponibilités (si présent) $local_indisponibilites = null; if ($local_id) { $local = CRVI_Local_Model::load($local_id); if ($local) { // Indisponibilités ponctuelles du local (si le champ existe) $local_indispo_acf = get_field('indisponibilitee_ponctuelle', $local_id); $local_indisponibilites = is_array($local_indispo_acf) ? json_encode($local_indispo_acf) : json_encode([]); } } // Précalculer les traducteurs disponibles par langue (preset pour optimisation) $traducteurs_disponibles_par_langue = null; if ($langue_slug && $date_rdv) { $traducteurs_disponibles_par_langue = self::precalculate_traducteurs_par_langue($date_rdv, $langue_slug); } // Créer l'entrée de permission $table_name = $wpdb->prefix . 'crvi_event_permission'; $result = $wpdb->insert($table_name, [ 'event_id' => $event_id, 'jours_permis' => $jours_permis, 'plages_horaires' => $plages_horaires_json, 'indisponibilites' => $indisponibilites, 'traducteur_jours_permis' => $traducteur_jours_permis, 'traducteur_indisponibilites' => $traducteur_indisponibilites, 'local_indisponibilites' => $local_indisponibilites, 'departements_autories' => $departements_autories, 'types_intervention_autories' => $types_intervention_autories, 'traducteurs_disponibles_par_langue' => $traducteurs_disponibles_par_langue, 'date_creation' => current_time('mysql'), 'cree_par' => get_current_user_id(), ], [ '%d', // event_id '%s', // jours_permis '%s', // plages_horaires '%s', // indisponibilites '%s', // traducteur_jours_permis '%s', // traducteur_indisponibilites '%s', // local_indisponibilites '%s', // departements_autories '%s', // types_intervention_autories '%s', // traducteurs_disponibles_par_langue '%s', // date_creation '%d', // cree_par ]); return $result !== false; } /** * Précalcule les IDs des traducteurs disponibles par langue pour une date donnée * * Retourne un tableau JSON avec les IDs des traducteurs disponibles pour chaque langue : * {"fr": [1,2,3], "en": [4,5], "es": [2,6]} * * @param string $date_rdv Date au format Y-m-d * @param string|null $langue_slug Slug de la langue principale (si null, calcule pour toutes les langues) * @return string|null JSON string ou null */ private static function precalculate_traducteurs_par_langue($date_rdv, $langue_slug = null) { // Récupérer toutes les langues ou seulement celle demandée $langues_to_check = []; if ($langue_slug) { $term = get_term_by('slug', $langue_slug, 'langue'); if ($term) { $langues_to_check[] = [ 'slug' => $langue_slug, 'term_id' => $term->term_id, ]; } } else { // Récupérer toutes les langues $terms = get_terms([ 'taxonomy' => 'langue', 'hide_empty' => false, ]); foreach ($terms as $term) { $langues_to_check[] = [ 'slug' => $term->slug, 'term_id' => $term->term_id, ]; } } if (empty($langues_to_check)) { return null; } // Pour chaque langue, récupérer les traducteurs disponibles $result = []; foreach ($langues_to_check as $langue_info) { $traducteurs_disponibles = CRVI_Traducteur_Model::filtrer_disponibles( $date_rdv, $langue_info['slug'] ); // Extraire les IDs des traducteurs disponibles $ids = []; foreach ($traducteurs_disponibles as $traducteur) { if (isset($traducteur->id)) { $ids[] = (int)$traducteur->id; } } if (!empty($ids)) { $result[$langue_info['slug']] = $ids; } } return !empty($result) ? json_encode($result) : null; } /** * Crée les disponibilités pour une permanence à partir des jours et heures sélectionnés dans le formulaire * * Stocke directement les jours et plages horaires sélectionnés dans le formulaire de création de permanences, * sans charger les disponibilités générales de l'intervenant. * * @param int $event_id ID de l'événement (permanence) * @param int $intervenant_id ID de l'intervenant * @param array $jours_permis Jours de la semaine sélectionnés (ex: ["lundi", "mardi"]) * @param array $plages_horaires Plages horaires sélectionnées (ex: [{"debut":"11:00","fin":"15:00"}]) * @return bool|WP_Error */ public static function create_for_permanence($event_id, $intervenant_id, $jours_permis = [], $plages_horaires = []) { global $wpdb; // Vérifier que l'intervenant existe $intervenant = CRVI_Intervenant_Model::load($intervenant_id); if (!$intervenant) { return new \WP_Error('intervenant_not_found', 'Intervenant introuvable', ['status' => 404]); } // Convertir les jours et plages horaires en JSON $jours_permis_json = is_array($jours_permis) ? json_encode($jours_permis) : json_encode([]); $plages_horaires_json = is_array($plages_horaires) ? json_encode($plages_horaires) : json_encode([]); // Charger les indisponibilités ponctuelles de l'intervenant (pour les vérifications) $indisponibilites_acf = get_field('indisponibilitee_ponctuelle', 'user_' . $intervenant_id); $indisponibilites = is_array($indisponibilites_acf) ? json_encode($indisponibilites_acf) : json_encode([]); // Extraire les départements et types d'intervention $departements_autories = !empty($intervenant->departements_ids) ? json_encode($intervenant->departements_ids) : json_encode([]); $types_intervention_autories = !empty($intervenant->types_intervention_ids) ? json_encode($intervenant->types_intervention_ids) : json_encode([]); // Créer l'entrée de permission avec les jours et heures sélectionnés $table_name = $wpdb->prefix . 'crvi_event_permission'; $result = $wpdb->insert($table_name, [ 'event_id' => $event_id, 'jours_permis' => $jours_permis_json, 'plages_horaires' => $plages_horaires_json, 'indisponibilites' => $indisponibilites, 'traducteur_jours_permis' => null, 'traducteur_indisponibilites' => null, 'local_indisponibilites' => null, 'departements_autories' => $departements_autories, 'types_intervention_autories' => $types_intervention_autories, 'date_creation' => current_time('mysql'), 'cree_par' => get_current_user_id(), ], [ '%d', // event_id '%s', // jours_permis '%s', // plages_horaires '%s', // indisponibilites '%s', // traducteur_jours_permis '%s', // traducteur_indisponibilites '%s', // local_indisponibilites '%s', // departements_autories '%s', // types_intervention_autories '%s', // date_creation '%d', // cree_par ]); return $result !== false; } /** * Vérifie rapidement si une date/heure est disponible selon les disponibilités stockées * * Vérifie : * - Si le jour de la semaine de la date correspond aux jours disponibles * - Si l'heure est dans les plages horaires autorisées * - Si la date n'est pas dans une période d'indisponibilité * * OPTIMISÉ : Une seule requête SQL, pas de chargement de modèle Intervenant * * @param int $event_id ID de l'événement * @param string $date Date au format Y-m-d * @param string $heure Heure au format H:i (optionnel, pour vérifier les plages horaires) * @return bool|null true=disponible, false=non disponible, null=pas de disponibilité définie (fallback requis) */ public static function is_date_heure_authorized($event_id, $date, $heure = null) { global $wpdb; $table_name = $wpdb->prefix . 'crvi_event_permission'; // Requête optimisée : une seule requête SQL pour toutes les disponibilités // Récupère intervenant, traducteur et local en une seule fois (si présents dans la table) $permission = $wpdb->get_row($wpdb->prepare( "SELECT jours_permis, plages_horaires, indisponibilites, traducteur_jours_permis, traducteur_indisponibilites, local_indisponibilites FROM $table_name WHERE event_id = %d", $event_id ), ARRAY_A); if (!$permission) { // Pas de permission définie, fallback vers l'intervenant return null; } // Vérifier le jour de la semaine (lundi, mardi, etc. - pas une date spécifique) $timestamp = strtotime($date); if ($timestamp === false) { return false; } $jour_semaine = (int)date('w', $timestamp); // 0=dimanche, 1=lundi, etc. // Mapping jours français vers numériques (jours de la semaine) $jours_mapping = [ 'dimanche' => 0, 'lundi' => 1, 'mardi' => 2, 'mercredi' => 3, 'jeudi' => 4, 'vendredi' => 5, 'samedi' => 6, ]; // Vérifier si ce jour de la semaine est disponible $jours_permis_json = $permission['jours_permis'] ?? '[]'; $jours_permis = json_decode($jours_permis_json, true) ?? []; if (!empty($jours_permis)) { $jours_permis_numeriques = []; foreach ($jours_permis as $jour) { $jour_lower = strtolower($jour); if (isset($jours_mapping[$jour_lower])) { $jours_permis_numeriques[] = $jours_mapping[$jour_lower]; } } // Vérifier si le jour de la semaine de la date est dans les jours disponibles if (!in_array($jour_semaine, $jours_permis_numeriques, true)) { return false; // Ce jour de la semaine n'est pas disponible } } // Vérifier les indisponibilités ponctuelles $indisponibilites_json = $permission['indisponibilites'] ?? '[]'; $indisponibilites = json_decode($indisponibilites_json, true) ?? []; foreach ($indisponibilites as $indispo) { $debut_str = $indispo['debut'] ?? $indispo['date_debut'] ?? ''; $fin_str = $indispo['fin'] ?? $indispo['date_fin'] ?? ''; if (empty($debut_str) || empty($fin_str)) { continue; } // Convertir les dates ACF (format d/m/Y) en timestamp $debut_timestamp = self::parse_acf_date($debut_str); $fin_timestamp = self::parse_acf_date($fin_str); if ($debut_timestamp && $fin_timestamp && $timestamp >= $debut_timestamp && $timestamp <= $fin_timestamp) { return false; // Date dans une période d'indisponibilité } } // Vérifier les plages horaires si une heure est fournie if ($heure !== null && !empty($permission['plages_horaires'])) { $plages_json = $permission['plages_horaires']; $plages = json_decode($plages_json, true) ?? []; if (!empty($plages)) { $heure_timestamp = strtotime($heure); $heure_autorisee = false; foreach ($plages as $plage) { $debut_plage = strtotime($plage['debut'] ?? ''); $fin_plage = strtotime($plage['fin'] ?? ''); if ($debut_plage && $fin_plage && $heure_timestamp >= $debut_plage && $heure_timestamp <= $fin_plage) { $heure_autorisee = true; break; } } if (!$heure_autorisee) { return false; // Heure non dans les plages autorisées } } } // Vérifier les disponibilités du traducteur (si présent dans les permissions stockées) // OPTIMISATION : Si les données sont dans la table, on les utilise, sinon on laisse fallback if (!empty($permission['traducteur_jours_permis']) || !empty($permission['traducteur_indisponibilites'])) { // Vérifier le jour de la semaine pour le traducteur $traducteur_jours_json = $permission['traducteur_jours_permis'] ?? '[]'; $traducteur_jours = json_decode($traducteur_jours_json, true) ?? []; if (!empty($traducteur_jours)) { $traducteur_jours_numeriques = []; foreach ($traducteur_jours as $jour) { $jour_lower = strtolower($jour); if (isset($jours_mapping[$jour_lower])) { $traducteur_jours_numeriques[] = $jours_mapping[$jour_lower]; } } if (!in_array($jour_semaine, $traducteur_jours_numeriques, true)) { return false; // Ce jour de la semaine n'est pas disponible pour le traducteur } } // Vérifier les indisponibilités ponctuelles du traducteur $traducteur_indispo_json = $permission['traducteur_indisponibilites'] ?? '[]'; $traducteur_indispo = json_decode($traducteur_indispo_json, true) ?? []; foreach ($traducteur_indispo as $indispo) { $debut_str = $indispo['debut'] ?? $indispo['date_debut'] ?? ''; $fin_str = $indispo['fin'] ?? $indispo['date_fin'] ?? ''; if (empty($debut_str) || empty($fin_str)) { continue; } $debut_timestamp = self::parse_acf_date($debut_str); $fin_timestamp = self::parse_acf_date($fin_str); if ($debut_timestamp && $fin_timestamp && $timestamp >= $debut_timestamp && $timestamp <= $fin_timestamp) { return false; // Date dans une période d'indisponibilité du traducteur } } } // Si traducteur pas dans la table, on laisse le fallback dans update_event() le gérer // Vérifier les disponibilités du local (si présent dans les permissions stockées) // OPTIMISATION : Si les données sont dans la table, on les utilise, sinon on laisse fallback if (!empty($permission['local_indisponibilites'])) { $local_indispo_json = $permission['local_indisponibilites'] ?? '[]'; $local_indispo = json_decode($local_indispo_json, true) ?? []; foreach ($local_indispo as $indispo) { $debut_str = $indispo['debut'] ?? $indispo['date_debut'] ?? ''; $fin_str = $indispo['fin'] ?? $indispo['date_fin'] ?? ''; if (empty($debut_str) || empty($fin_str)) { continue; } $debut_timestamp = self::parse_acf_date($debut_str); $fin_timestamp = self::parse_acf_date($fin_str); if ($debut_timestamp && $fin_timestamp && $timestamp >= $debut_timestamp && $timestamp <= $fin_timestamp) { return false; // Date dans une période d'indisponibilité du local } } } // Si local pas dans la table, on laisse le fallback dans update_event() le gérer return true; // Autorisé (intervenant, traducteur et local disponibles) } /** * Parse une date ACF (format d/m/Y ou Y-m-d) * @param string $date_str * @return int|false Timestamp ou false */ private static function parse_acf_date($date_str) { // Essayer le format ACF (d/m/Y) $date = \DateTime::createFromFormat('d/m/Y', $date_str); if ($date) { return $date->getTimestamp(); } // Essayer le format standard (Y-m-d) $date = \DateTime::createFromFormat('Y-m-d', $date_str); if ($date) { return $date->getTimestamp(); } // Fallback : strtotime $timestamp = strtotime($date_str); return $timestamp !== false ? $timestamp : false; } /** * Met à jour les disponibilités d'un événement (ex: après modification de l'intervenant, traducteur ou local) * * Met à jour : * - Les jours de la semaine disponibles (intervenant, traducteur) * - Les indisponibilités ponctuelles (intervenant, traducteur, local) * - Les départements/types d'intervention * - Les traducteurs disponibles par langue (preset) * * Les plages horaires existantes sont conservées par défaut (utile pour les permanences) * * @param int $event_id * @param int|null $intervenant_id Si null, utilise l'intervenant de l'événement * @param bool $preserve_plages_horaires Si true, conserve les plages horaires existantes (défaut: true) * @param int|null $traducteur_id ID du traducteur (si changé) * @param int|null $local_id ID du local (si changé) * @param string|null $langue_slug Slug de la langue de l'événement (pour précalculer traducteurs disponibles) * @param string|null $date_rdv Date de l'événement (pour précalculer traducteurs disponibles) * @return bool */ public static function update_from_intervenant($event_id, $intervenant_id = null, $preserve_plages_horaires = true, $traducteur_id = null, $local_id = null, $langue_slug = null, $date_rdv = null) { global $wpdb; // Si pas d'intervenant fourni, le récupérer depuis l'événement if ($intervenant_id === null) { $event = CRVI_Event_Model::load($event_id); if (!$event || !$event->id_intervenant) { return false; } $intervenant_id = $event->id_intervenant; } // Si traducteur/local non fournis, les récupérer depuis l'événement if ($traducteur_id === null || $local_id === null) { if (!$event) { $event = CRVI_Event_Model::load($event_id); } if ($event) { if ($traducteur_id === null) { $traducteur_id = $event->id_traducteur ?? null; } if ($local_id === null) { $local_id = $event->id_local ?? null; } } } $table_name = $wpdb->prefix . 'crvi_event_permission'; // Vérifier si la permission existe déjà $existing = $wpdb->get_row($wpdb->prepare( "SELECT id, plages_horaires, traducteur_jours_permis, traducteur_indisponibilites, local_indisponibilites FROM $table_name WHERE event_id = %d", $event_id ), ARRAY_A); $intervenant = CRVI_Intervenant_Model::load($intervenant_id); if (!$intervenant) { return false; } // Récupérer les nouvelles données depuis l'intervenant $jours_disponibles = get_field('jours_de_disponibilite', 'user_' . $intervenant_id); $jours_permis = is_array($jours_disponibles) ? json_encode($jours_disponibles) : json_encode([]); $indisponibilites_acf = get_field('indisponibilitee_ponctuelle', 'user_' . $intervenant_id); $indisponibilites = is_array($indisponibilites_acf) ? json_encode($indisponibilites_acf) : json_encode([]); $departements_autories = !empty($intervenant->departements_ids) ? json_encode($intervenant->departements_ids) : json_encode([]); $types_intervention_autories = !empty($intervenant->types_intervention_ids) ? json_encode($intervenant->types_intervention_ids) : json_encode([]); // Récupérer les disponibilités du traducteur si présent $traducteur_jours_permis = null; $traducteur_indisponibilites = null; if ($traducteur_id) { $traducteur = CRVI_Traducteur_Model::load($traducteur_id); if ($traducteur) { $traducteur_jours = get_field('jours_de_disponibilite', $traducteur_id); $traducteur_jours_permis = is_array($traducteur_jours) ? json_encode($traducteur_jours) : json_encode([]); $traducteur_indispo_acf = get_field('indisponibilitee_ponctuelle', $traducteur_id); $traducteur_indisponibilites = is_array($traducteur_indispo_acf) ? json_encode($traducteur_indispo_acf) : json_encode([]); } } // Récupérer les indisponibilités du local si présent $local_indisponibilites = null; if ($local_id) { $local = CRVI_Local_Model::load($local_id); if ($local) { $local_indispo_acf = get_field('indisponibilitee_ponctuelle', $local_id); $local_indisponibilites = is_array($local_indispo_acf) ? json_encode($local_indispo_acf) : json_encode([]); } } // Précalculer les traducteurs disponibles par langue si langue et date fournies $traducteurs_disponibles_par_langue = null; if ($langue_slug && $date_rdv) { $traducteurs_disponibles_par_langue = self::precalculate_traducteurs_par_langue($date_rdv, $langue_slug); } if ($existing) { // Mettre à jour l'existant $update_data = [ 'jours_permis' => $jours_permis, 'indisponibilites' => $indisponibilites, 'traducteur_jours_permis' => $traducteur_jours_permis, 'traducteur_indisponibilites' => $traducteur_indisponibilites, 'local_indisponibilites' => $local_indisponibilites, 'departements_autories' => $departements_autories, 'types_intervention_autories' => $types_intervention_autories, 'traducteurs_disponibles_par_langue' => $traducteurs_disponibles_par_langue, 'date_modification' => current_time('mysql'), 'modifie_par' => get_current_user_id(), ]; // Conserver les plages horaires existantes si demandé if ($preserve_plages_horaires && !empty($existing['plages_horaires'])) { $update_data['plages_horaires'] = $existing['plages_horaires']; $formats = ['%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d']; // Avec plages_horaires } else { $formats = ['%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d']; // Sans plages_horaires } $result = $wpdb->update( $table_name, $update_data, ['event_id' => $event_id], $formats, ['%d'] // Format pour WHERE ); return $result !== false; } else { // Créer une nouvelle entrée return self::create_from_intervenant($event_id, $intervenant_id, null, $traducteur_id, $local_id, $langue_slug, $date_rdv) !== false; } } /** * Supprime les permissions d'un événement (lors de la suppression de l'événement) * @param int $event_id * @return bool */ public static function delete_by_event_id($event_id) { global $wpdb; $table_name = $wpdb->prefix . 'crvi_event_permission'; return $wpdb->delete($table_name, ['event_id' => $event_id], ['%d']) !== false; } }