Crvi/app/models/CRVI_Presence_Model.php
2026-01-20 07:54:37 +01:00

280 lines
9.9 KiB
PHP

<?php
declare(strict_types=1);
namespace ESI_CRVI_AGENDA\models;
/**
* Modèle pour la gestion des présences et des personnes
*/
class CRVI_Presence_Model {
/**
* Crée les tables nécessaires pour les présences
*/
public static function create_tables(): void {
global $wpdb;
$charset_collate = $wpdb->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;
}
}