486 lines
19 KiB
PHP
486 lines
19 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace ESI_CRVI_AGENDA\controllers;
|
|
|
|
use ESI_CRVI_AGENDA\models\Event_Model;
|
|
use ESI_CRVI_AGENDA\helpers\Api_Helper;
|
|
use ESI_CRVI_AGENDA\models\CRVI_Event_Model;
|
|
use ESI_CRVI_AGENDA\models\CRVI_Traducteur_Model;
|
|
use ESI_CRVI_AGENDA\models\CRVI_Intervenant_Model;
|
|
use ESI_CRVI_AGENDA\controllers\Intervenant_Controller;
|
|
|
|
class CRVI_Event_Controller {
|
|
public static function register_routes() {
|
|
|
|
register_rest_route('crvi/v1', '/agenda/permissions', [
|
|
[
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_user_permissions'],
|
|
'permission_callback' => '__return_true',
|
|
],
|
|
]);
|
|
|
|
register_rest_route('crvi/v1', '/agenda/disponibilites', [
|
|
[
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_disponibilites'],
|
|
'permission_callback' => '__return_true',
|
|
],
|
|
[
|
|
'methods' => 'POST',
|
|
'callback' => [self::class, 'get_disponibilites'],
|
|
'permission_callback' => '__return_true',
|
|
],
|
|
]);
|
|
|
|
\register_rest_route('crvi/v1', '/events/(?P<id>\\d+)/conflits', [
|
|
[
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'conflits_item'],
|
|
'permission_callback' => [self::class, 'can_edit'],
|
|
],
|
|
]);
|
|
|
|
\register_rest_route('crvi/v1', '/events/export', [
|
|
[
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'export_items'],
|
|
'permission_callback' => [self::class, 'can_edit'],
|
|
],
|
|
]);
|
|
|
|
// --- Filtres dynamiques ---
|
|
\register_rest_route('crvi/v1', '/filters/departements', [
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_departements'],
|
|
'permission_callback' => '__return_true',
|
|
]);
|
|
\register_rest_route('crvi/v1', '/filters/types-intervention', [
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_types_intervention'],
|
|
'permission_callback' => '__return_true',
|
|
]);
|
|
\register_rest_route('crvi/v1', '/filters/langues', [
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_langues'],
|
|
'permission_callback' => '__return_true',
|
|
]);
|
|
\register_rest_route('crvi/v1', '/filters/langues-beneficiaire', [
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_langues_beneficiaire'],
|
|
'permission_callback' => '__return_true',
|
|
]);
|
|
\register_rest_route('crvi/v1', '/filters/statuts', [
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_statuts'],
|
|
'permission_callback' => '__return_true',
|
|
]);
|
|
|
|
// --- CRUD Events ---
|
|
\register_rest_route('crvi/v1', '/events', [
|
|
[
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_events'],
|
|
'permission_callback' => '__return_true',
|
|
],
|
|
[
|
|
'methods' => 'POST',
|
|
'callback' => [self::class, 'create_event'],
|
|
'permission_callback' => [self::class, 'can_edit'],
|
|
],
|
|
]);
|
|
\register_rest_route('crvi/v1', '/events/(?P<id>\\d+)', [
|
|
[
|
|
'methods' => 'GET',
|
|
'callback' => [self::class, 'get_event'],
|
|
'permission_callback' => '__return_true',
|
|
],
|
|
[
|
|
'methods' => 'PUT,PATCH',
|
|
'callback' => [self::class, 'update_event'],
|
|
'permission_callback' => [self::class, 'can_edit'],
|
|
],
|
|
[
|
|
'methods' => 'DELETE',
|
|
'callback' => [self::class, 'delete_event'],
|
|
'permission_callback' => [self::class, 'can_edit'],
|
|
],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Endpoint global pour récupérer les entités disponibles à une date/créneau donné.
|
|
* @param \WP_REST_Request $request
|
|
* @return \WP_REST_Response
|
|
*/
|
|
public static function get_disponibilites($request) {
|
|
// Récupérer les paramètres depuis query string ou JSON body
|
|
$params = $request->get_params();
|
|
$json_params = $request->get_json_params() ?: [];
|
|
|
|
// Fusionner les paramètres (JSON body a priorité sur query string)
|
|
$all_params = array_merge($params, $json_params);
|
|
|
|
$date = $all_params['date'] ?? $all_params['date_rdv'] ?? null;
|
|
$heure = $all_params['heure'] ?? $all_params['heure_rdv'] ?? null;
|
|
$langue = $all_params['langue'] ?? null;
|
|
$departement = $all_params['departement'] ?? null;
|
|
$specialisation = $all_params['specialisation'] ?? null;
|
|
$type = $all_params['type'] ?? null;
|
|
$event_id = $all_params['event_id'] ?? null;
|
|
|
|
// Appel aux méthodes de chaque controller
|
|
$traducteurs = \ESI_CRVI_AGENDA\models\CRVI_Traducteur_Model::filtrer_disponibles($date, $langue, $event_id);
|
|
$intervenants = \ESI_CRVI_AGENDA\models\CRVI_Intervenant_Model::filtrer_disponibles($date, $departement, $specialisation, $event_id);
|
|
|
|
// Récupérer les locaux selon le type de RDV
|
|
$type_rdv = $all_params['type_rdv'] ?? null;
|
|
if ($type_rdv && in_array($type_rdv, ['individuel', 'groupe'])) {
|
|
$locaux = \ESI_CRVI_AGENDA\models\CRVI_Local_Model::get_locaux_par_type($type_rdv);
|
|
} else {
|
|
// Si pas de type spécifié, récupérer tous les locaux
|
|
$locals_posts = get_posts([
|
|
'post_type' => 'local',
|
|
'numberposts' => -1,
|
|
'post_status' => 'publish',
|
|
]);
|
|
|
|
$locaux = [];
|
|
foreach ($locals_posts as $local_post) {
|
|
$type_local = get_post_meta($local_post->ID, 'type_de_local', true);
|
|
$capacite = get_post_meta($local_post->ID, 'capacite', true);
|
|
|
|
// Filtrer par type de RDV si spécifié
|
|
if ($type_rdv && in_array($type_rdv, ['individuel', 'groupe'])) {
|
|
// Logique de filtrage basée sur le type de local
|
|
if ($type_rdv === 'individuel' && $type_local === 'individuel') {
|
|
$locaux[] = [
|
|
'id' => $local_post->ID,
|
|
'nom' => $local_post->post_title,
|
|
'type_de_local' => $type_local,
|
|
'capacite' => $capacite,
|
|
];
|
|
} elseif ($type_rdv === 'groupe' && $type_local === 'groupe') {
|
|
$locaux[] = [
|
|
'id' => $local_post->ID,
|
|
'nom' => $local_post->post_title,
|
|
'type_de_local' => $type_local,
|
|
'capacite' => $capacite,
|
|
];
|
|
}
|
|
} else {
|
|
// Si pas de type spécifié, récupérer tous les locaux
|
|
$locaux[] = [
|
|
'id' => $local_post->ID,
|
|
'nom' => $local_post->post_title,
|
|
'type_de_local' => $type_local,
|
|
'capacite' => $capacite,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Récupérer tous les bénéficiaires
|
|
$beneficiaire_model = new \ESI_CRVI_AGENDA\models\CRVI_Beneficiaire_Model();
|
|
$beneficiaires_objects = $beneficiaire_model->get_all_beneficiaires();
|
|
$beneficiaires = [];
|
|
foreach ($beneficiaires_objects as $beneficiaire) {
|
|
$beneficiaires[] = [
|
|
'id' => $beneficiaire->id,
|
|
'nom' => $beneficiaire->nom . ' ' . $beneficiaire->prenom,
|
|
];
|
|
}
|
|
|
|
return Api_Helper::json_success([
|
|
'traducteurs' => $traducteurs,
|
|
'intervenants' => $intervenants,
|
|
'locaux' => $locaux,
|
|
'beneficiaires' => $beneficiaires,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Endpoint pour récupérer les permissions de l'utilisateur courant.
|
|
* @param WP_REST_Request $request
|
|
* @return WP_REST_Response
|
|
*/
|
|
public static function get_user_permissions($request) {
|
|
$permissions = Api_Helper::get_user_permissions();
|
|
return Api_Helper::json_success($permissions);
|
|
}
|
|
|
|
public static function conflits_item($request) {
|
|
$id = (int) $request['id'];
|
|
$date = $request->get_param('date');
|
|
$heure = $request->get_param('heure');
|
|
$id_intervenant = $request->get_param('id_intervenant');
|
|
$id_traducteur = $request->get_param('id_traducteur');
|
|
$id_local = $request->get_param('id_local');
|
|
|
|
$model = new CRVI_Event_Model();
|
|
$result = $model->get_conflits($date, $heure, $id_intervenant, $id_traducteur, $id_local);
|
|
return Api_Helper::json_success($result);
|
|
}
|
|
|
|
public static function export_items($request) {
|
|
$model = new CRVI_Event_Model();
|
|
$params = $request->get_params();
|
|
|
|
// Support de la pagination pour l'export
|
|
$date_debut = $params['start'] ?? $params['date_debut'] ?? null;
|
|
$date_fin = $params['end'] ?? $params['date_fin'] ?? null;
|
|
|
|
// Filtrer les paramètres pour éviter les conflits
|
|
$filters = array_diff_key($params, array_flip(['start', 'end', 'date_debut', 'date_fin']));
|
|
|
|
$result = $model->get_events_by('date_rdv', null, $filters, $date_debut, $date_fin);
|
|
return Api_Helper::json_success($result);
|
|
}
|
|
|
|
// --- CRUD ---
|
|
public static function get_events($request) {
|
|
$params = $request->get_params();
|
|
$model = new CRVI_Event_Model();
|
|
$events = $model->get_events_by_filters($params);
|
|
return Api_Helper::json_success($events);
|
|
}
|
|
public static function get_event($request) {
|
|
$id = (int) $request['id'];
|
|
$event = CRVI_Event_Model::load($id);
|
|
if (!$event) {
|
|
return Api_Helper::json_error('Événement introuvable', 404);
|
|
}
|
|
return Api_Helper::json_success($event);
|
|
}
|
|
public static function create_event($request) {
|
|
$data = $request->get_json_params();
|
|
$model = new CRVI_Event_Model();
|
|
$result = $model->create_event($data);
|
|
if (is_wp_error($result)) {
|
|
return Api_Helper::json_error($result->get_error_message(), 400);
|
|
}
|
|
return Api_Helper::json_success(['id' => $result, 'message' => 'Événement créé avec succès']);
|
|
}
|
|
public static function update_event($request) {
|
|
$id = (int) $request['id'];
|
|
$data = $request->get_json_params();
|
|
$model = new CRVI_Event_Model();
|
|
$result = $model->update_event($id, $data);
|
|
if (is_wp_error($result)) {
|
|
return Api_Helper::json_error($result->get_error_message(), 400);
|
|
}
|
|
return Api_Helper::json_success(['id' => $id, 'message' => 'Événement modifié avec succès']);
|
|
}
|
|
public static function delete_event($request) {
|
|
$id = (int) $request['id'];
|
|
$model = new CRVI_Event_Model();
|
|
$result = $model->delete_event($id);
|
|
if (is_wp_error($result)) {
|
|
return Api_Helper::json_error($result->get_error_message(), 400);
|
|
}
|
|
return Api_Helper::json_success(['id' => $id, 'message' => 'Événement supprimé avec succès']);
|
|
}
|
|
|
|
// --- Avancés ---
|
|
public static function cloture_event($request) {
|
|
$id = (int) $request['id'];
|
|
$data = $request->get_json_params();
|
|
$model = new CRVI_Event_Model();
|
|
$result = $model->cloture_event($id, $data['statut'] ?? '');
|
|
if (is_wp_error($result)) {
|
|
return Api_Helper::json_error($result->get_error_message(), 400);
|
|
}
|
|
return Api_Helper::json_success(['id' => $id, 'message' => 'Événement clôturé avec succès']);
|
|
}
|
|
public static function change_statut($request) {
|
|
$id = (int) $request['id'];
|
|
$data = $request->get_json_params();
|
|
$model = new CRVI_Event_Model();
|
|
$result = $model->change_statut($id, $data);
|
|
if (is_wp_error($result)) {
|
|
return Api_Helper::json_error($result->get_error_message(), 400);
|
|
}
|
|
return Api_Helper::json_success(['id' => $id, 'message' => 'Statut modifié avec succès']);
|
|
}
|
|
|
|
/**
|
|
* Retourne la couleur selon le statut
|
|
*/
|
|
private static function get_status_color($statut) {
|
|
switch ($statut) {
|
|
case 'prevu':
|
|
return '#28a745'; // Vert
|
|
case 'annule':
|
|
return '#dc3545'; // Rouge
|
|
case 'non_tenu':
|
|
return '#ffc107'; // Jaune
|
|
case 'cloture':
|
|
return '#6c757d'; // Gris
|
|
case 'absence':
|
|
return '#fd7e14'; // Orange
|
|
default:
|
|
return '#007bff'; // Bleu
|
|
}
|
|
}
|
|
|
|
public static function get_events_fullcalendar($request) {
|
|
$model = new CRVI_Event_Model();
|
|
$params = $request->get_params();
|
|
|
|
// Support de la pagination FullCalendar
|
|
$date_debut = $params['start'] ?? $params['date_debut'] ?? null;
|
|
$date_fin = $params['end'] ?? $params['date_fin'] ?? null;
|
|
|
|
// Filtrer les paramètres pour éviter les conflits
|
|
$filters = array_diff_key($params, array_flip(['start', 'end', 'date_debut', 'date_fin']));
|
|
|
|
// Récupérer les événements pour cette période
|
|
$events = $model->get_events_by('date_rdv', null, $filters, $date_debut, $date_fin);
|
|
|
|
// Formater pour FullCalendar
|
|
$formatted_events = [];
|
|
foreach ($events as $event) {
|
|
// Récupérer les détails des entités liées
|
|
$details = $model->get_details($event['id']);
|
|
|
|
$formatted_events[] = [
|
|
'id' => $event['id'],
|
|
'title' => ($details->beneficiaire->nom ?? '') . ' ' . ($details->beneficiaire->prenom ?? '') . ' - ' .
|
|
($details->intervenant->nom ?? '') . ' ' . ($details->intervenant->prenom ?? ''),
|
|
'start' => $event['date_rdv'] . 'T' . $event['heure_rdv'],
|
|
'end' => $event['date_fin'] . 'T' . $event['heure_fin'],
|
|
'backgroundColor' => self::get_status_color($event['statut']),
|
|
'borderColor' => self::get_status_color($event['statut']),
|
|
'textColor' => $event['statut'] === 'non_tenu' ? '#000' : '#fff',
|
|
'extendedProps' => [
|
|
'type' => $event['type'],
|
|
'statut' => $event['statut'],
|
|
'langue' => $event['langue'],
|
|
'beneficiaire' => ($details->beneficiaire->nom ?? '') . ' ' . ($details->beneficiaire->prenom ?? ''),
|
|
'intervenant' => ($details->intervenant->nom ?? '') . ' ' . ($details->intervenant->prenom ?? ''),
|
|
'traducteur' => ($details->traducteur->nom ?? '') . ' ' . ($details->traducteur->prenom ?? ''),
|
|
'local' => $details->local->nom ?? '',
|
|
'commentaire' => $event['commentaire'],
|
|
'id_beneficiaire' => $event['id_beneficiaire'],
|
|
'id_intervenant' => $event['id_intervenant'],
|
|
'id_traducteur' => $event['id_traducteur'],
|
|
'id_local' => $event['id_local']
|
|
]
|
|
];
|
|
}
|
|
|
|
return Api_Helper::json_success($formatted_events);
|
|
}
|
|
public static function get_events_stats($request) {
|
|
$params = $request->get_params();
|
|
$model = new CRVI_Event_Model();
|
|
$stats = $model->get_events_stats($params);
|
|
return Api_Helper::json_success($stats);
|
|
}
|
|
public static function get_event_historique($request) {
|
|
$id = (int) $request['id'];
|
|
$model = new CRVI_Event_Model();
|
|
$historique = $model->get_historique();
|
|
return Api_Helper::json_success($historique);
|
|
}
|
|
|
|
// --- Filtres dynamiques ---
|
|
public static function get_departements($request) {
|
|
$departements = get_terms([
|
|
'taxonomy' => 'departement',
|
|
'hide_empty' => false,
|
|
]);
|
|
$result = [];
|
|
foreach ($departements as $departement) {
|
|
$result[] = [
|
|
'id' => $departement->term_id,
|
|
'name' => $departement->name,
|
|
'slug' => $departement->slug,
|
|
];
|
|
}
|
|
return Api_Helper::json_success($result);
|
|
}
|
|
public static function get_types_intervention($request) {
|
|
$types = get_terms([
|
|
'taxonomy' => 'type_intervention',
|
|
'hide_empty' => false,
|
|
]);
|
|
|
|
$result = [];
|
|
foreach ($types as $type) {
|
|
$result[] = [
|
|
'id' => $type->term_id,
|
|
'name' => $type->name,
|
|
'slug' => $type->slug,
|
|
];
|
|
}
|
|
|
|
return Api_Helper::json_success($result);
|
|
}
|
|
public static function get_langues($request) {
|
|
$langues = get_terms([
|
|
'taxonomy' => 'langue',
|
|
'hide_empty' => false,
|
|
]);
|
|
$result = [];
|
|
foreach ($langues as $langue) {
|
|
$result[] = [
|
|
'id' => $langue->term_id,
|
|
'name' => $langue->name,
|
|
'slug' => $langue->slug,
|
|
];
|
|
}
|
|
return Api_Helper::json_success($result);
|
|
}
|
|
|
|
public static function get_langues_beneficiaire($request) {
|
|
$langues = \ESI_CRVI_AGENDA\helpers\Api_Helper::get_languages(true);
|
|
return Api_Helper::json_success($langues);
|
|
}
|
|
public static function get_statuts($request) {
|
|
$statuts = [
|
|
['id' => 'prevu', 'label' => 'Prévu'],
|
|
['id' => 'annule', 'label' => 'Annulé'],
|
|
['id' => 'non_tenu', 'label' => 'Non tenu'],
|
|
['id' => 'cloture', 'label' => 'Clôturé'],
|
|
['id' => 'absence', 'label' => 'Absence'],
|
|
];
|
|
return Api_Helper::json_success($statuts);
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur peut modifier un événement
|
|
* @param \WP_REST_Request $request
|
|
* @return bool
|
|
*/
|
|
public static function can_edit($request = null) {
|
|
// Si admin ou rôle ayant edit_posts : accès total
|
|
if (current_user_can('edit_posts')) {
|
|
return true;
|
|
}
|
|
|
|
// Récupérer l'id_intervenant depuis la requête ou l'événement
|
|
$id_intervenant = null;
|
|
if ($request) {
|
|
// Si on modifie un événement existant, récupérer l'ID depuis l'événement
|
|
if ($request->get_param('id')) {
|
|
$event = \ESI_CRVI_AGENDA\models\CRVI_Event_Model::load((int)$request->get_param('id'));
|
|
if ($event && isset($event->id_intervenant)) {
|
|
$id_intervenant = $event->id_intervenant;
|
|
}
|
|
}
|
|
// Sinon, essayer de le prendre dans les paramètres de la requête (création)
|
|
if (!$id_intervenant) {
|
|
$data = $request->get_json_params();
|
|
if ($data && isset($data['id_intervenant'])) {
|
|
$id_intervenant = $data['id_intervenant'];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Appel à la logique intervenant
|
|
return CRVI_Intervenant_Controller::can_edit_own_event($id_intervenant);
|
|
}
|
|
} |