280 lines
9.9 KiB
PHP
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;
|
|
}
|
|
}
|
|
|