system = $system; $this->data = $data; $this->setMarque(); $this->setCampus(); $this->setSchool(); $this->checkIfSF(); $this->po = $this->get_po(); $this->po_mba = $this->get_po_mba(); } /** * checkSystem */ private function checkSystem($champ, $object = null){ if(!empty($object) && isset($this->system->{$object})){ if (isset($this->system->{$object}->{$champ})) return $this->system->{$object}->{$champ}; } else if (empty($object) && isset($this->system->{$champ})){ return $this->system->{$champ}; } return null; } /** * setSchool */ private function setSchool(){ $this->school = $this->checkSystem("school"); } /** * setMarque */ private function setMarque(){ $this->marque = $this->checkSystem( "SF_marque", "schoolGroup"); } /** * setCampus */ private function setCampus(){ $this->campus = $this->checkSystem("SF_campus"); } /** * Supprime les accents d'une chaîne de caractères * @param string $string * @return string */ private function removeAccents($string){ $accents = array( 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'Ç'=>'C', 'ç'=>'c', 'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'Ñ'=>'N', 'ñ'=>'n', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'u', 'Ý'=>'Y', 'ý'=>'y', 'ÿ'=>'y', 'Œ'=>'OE', 'œ'=>'oe', 'Æ'=>'AE', 'æ'=>'ae' ); return strtr($string, $accents); } /** * Mappe les noms de villes spécifiques pour correspondance avec l'API * Convertit les noms de l'API vers les noms affichés * @param string $cityName * @return string */ private function mapCityName($cityName){ $cityMapping = [ 'CHASSENEUIL DU POITOU' => 'POITIERS', 'MONT SAINT AIGNAN' => 'ROUEN', 'MONTROUGE' => 'PARIS', 'RANELAGH' => 'PARIS' ]; $upperCityName = strtoupper(trim($cityName)); return isset($cityMapping[$upperCityName]) ? $cityMapping[$upperCityName] : $cityName; } /** * Compare deux noms de villes en tenant compte du mapping et des accents * @param string $apiCityName - Nom de la ville provenant de l'API * @param string $boCityName - Nom de la ville provenant du BO * @return bool */ private function compareCityNames($apiCityName, $boCityName){ // Mapper les deux noms de villes $mappedApiCity = $this->mapCityName($apiCityName); $mappedBoCity = $this->mapCityName($boCityName); // Supprimer les accents et comparer en minuscules $normalizedApiCity = strtolower($this->removeAccents($mappedApiCity)); $normalizedBoCity = strtolower($this->removeAccents($mappedBoCity)); return $normalizedApiCity === $normalizedBoCity; } /** * checkIfSF */ private function checkIfSF(){ if($this->isSF = (!empty($this->marque) || !empty($this->campus))) { // Chargement du fichier require_once( $GLOBALS[THEME]->access_core->themeCore->inc->path . '/class/recuperationDonnees.php'); } } /** * Récupère les données des portes ouvertes */ public function get_po(){ if ($this->isSF) { $this->get_po_by_marque(); return $this->datas; } return false; } /** * Récupération des événements par marque (PPA uniquement) */ private function get_po_by_marque( $limit = 20, $types = null ){ $this->datas = $this->getSFData([ "route"=>"recuperationEvenement", "marque"=>$this->marque, "MBA"=>"false", "reseau"=>"ges", "return"=>"true", "limit"=>$limit ])->result; } /** * Récupération des événements MBA pour Paris */ private function get_po_by_marque_mba( $limit = 20, $types = null ){ $cacheData = $this->getSFData([ "route"=>"recuperationEvenement", "marque"=>$this->marque, "MBA"=>"true", "reseau"=>"ges", "return"=>"true", "limit"=>$limit ]); return $cacheData->result ?? null; } /** * Récupère les données des portes ouvertes MBA */ public function get_po_mba(){ if ($this->isSF) { return $this->get_po_by_marque_mba(); } return false; } /** * Récupère les données SF */ private function getSFData($args){ $poData = new recuperationDonnees( new ThemeCore_API(), $args ); switch($args['route']){ case 'recuperationGroupeEcoles': $poData->ecolesCache(); return $poData->cache; break; case 'recuperationEvenement': $poData->JPOCache(); return $poData->cache; break; } } /** * Récupère les événements par ville */ public function get_po_by_city( $city ){ if( $this->datas !== null ){ foreach( $this->datas as $data){ if( $data->school_name === 'PPA-'.strtoupper($city) || $data->school_name === 'PPA-'.$city ){ return $data->events; } } } return false; } /** * Récupère les campus disponibles pour le select ACF */ public function getCampusList(): array { $campusList = []; if (!empty($this->po)) { foreach ($this->po as $campus_po) { if (isset($campus_po->city) && !empty($campus_po->city)) { $campusList[$campus_po->city] = $campus_po->city; } } } // Trier alphabétiquement asort($campusList); return $campusList; } /** * Récupère les événements filtrés par type et campus */ public function getEventsByTypeAndCampus($eventType, $campus, $useMBA = false): array { $events = []; // Choisir la source de données (PPA ou MBA) $dataSource = $useMBA ? $this->po_mba : $this->po; if (empty($dataSource) || empty($eventType) || empty($campus)) { return $events; } foreach ($this->po as $campus_po) { if(empty($campus_po->events)){ //verifie si des events existent continue; } // Vérifier si c'est le bon campus (avec mapping des villes et suppression des accents) if (!$this->compareCityNames($campus_po->city, $campus)) { continue; } if (!is_array($campus_po->events)) { continue; } foreach ($campus_po->events as $event) { if (!is_object($event)) { continue; } // Vérifier le type d'événement $eventTypeToCheck = strtolower($event->type ?? ''); if ($eventTypeToCheck === 'immersion' && $eventType === 'jdi') { $eventTypeToCheck = 'jdi'; } if ($eventTypeToCheck === strtolower($eventType)) { // Formater les données de date $date = $this->recuperation_jour_mois($event->date_formatted); $event->date_jour = $date['jour']; $event->date_mois = $date['mois']; $event->date_numero_jour = $date['numero_jour']; $event->date_annee = $date['annee']; $events[] = $event; } } } return $events; } /** * Formate les dates personnalisées */ public function formatCustomDates($datesPersonnalisees): array { $formattedDates = []; if (empty($datesPersonnalisees) || !is_array($datesPersonnalisees)) { return $formattedDates; } foreach ($datesPersonnalisees as $dateData) { if (empty($dateData['date'])) { continue; } // Convertir la date $date = DateTime::createFromFormat('d/m/Y', $dateData['date']); if (!$date) { continue; } $dateFormatted = $this->recuperation_jour_mois($date->format('Y-m-d')); $formattedDates[] = [ 'date_jour' => $dateFormatted['jour'], 'date_numero_jour' => $dateFormatted['numero_jour'], 'date_mois' => $dateFormatted['mois'], 'date_annee' => $dateFormatted['annee'], 'horaires' => $dateData['horaires'] ?? '', 'lien' => $dateData['lien'] ?? null ]; } return $formattedDates; } /** * Récupère le jour et le mois à partir d'une date */ private function recuperation_jour_mois(string $dateString): array { $date = new DateTime($dateString); // Vérifier si IntlDateFormatter est disponible et PHP >= 8.1 if (class_exists('IntlDateFormatter') && version_compare(PHP_VERSION, '8.1.0', '>=')) { $formatter = new IntlDateFormatter( 'fr_FR', IntlDateFormatter::FULL, IntlDateFormatter::NONE, 'Europe/Paris' ); $formatter->setPattern('EEEE'); $jour = $formatter->format($date); $formatter->setPattern('MMMM'); $mois = $formatter->format($date); return [ 'jour' => $jour, 'mois' => $mois, 'numero_jour' => $date->format('d'), 'annee' => $date->format('Y') ]; } else { // Solution de repli avec tableaux de traduction $jours = [ 'Monday' => 'lundi', 'Tuesday' => 'mardi', 'Wednesday' => 'mercredi', 'Thursday' => 'jeudi', 'Friday' => 'vendredi', 'Saturday' => 'samedi', 'Sunday' => 'dimanche' ]; $mois = [ 'January' => 'janvier', 'February' => 'février', 'March' => 'mars', 'April' => 'avril', 'May' => 'mai', 'June' => 'juin', 'July' => 'juillet', 'August' => 'août', 'September' => 'septembre', 'October' => 'octobre', 'November' => 'novembre', 'December' => 'décembre' ]; return [ 'jour' => $jours[$date->format('l')], 'mois' => $mois[$date->format('F')], 'numero_jour' => $date->format('d'), 'annee' => $date->format('Y') ]; } } /** * Traite les données pour le template - UNE SEULE CARTE */ public function processData(): array { $typeConfiguration = $this->data['type_configuration'] ?? 'dynamique'; $result = [ 'type_configuration' => $typeConfiguration, 'events' => [], 'lien' => null, 'couleur_fond_date' => $this->data['couleur_fond_date'] ?? 'blanc' ]; if ($typeConfiguration === 'dynamique') { // Récupération des données depuis le groupe dynamique $groupeDynamique = $this->data['groupe_dynamique'] ?? []; $typeEvenement = $groupeDynamique['type_evenement'] ?? $this->data['type_evenement'] ?? ''; $campusData = $groupeDynamique['campus_selection'] ?? $this->data['campus_selection'] ?? null; // Extraire le nom du campus depuis l'objet terme ou string $campus = ''; if (is_object($campusData)) { $campus = $campusData->name ?? ''; } elseif (is_string($campusData)) { $campus = $campusData; } if (!empty($typeEvenement) && !empty($campus)) { $result['events'] = $this->getEventsByTypeAndCampus($typeEvenement, $campus); $result['lien'] = $groupeDynamique['lien_dynamique'] ?? $this->data['lien_dynamique'] ?? null; } } else if ($typeConfiguration === 'personnalise') { // Récupération des données depuis le groupe personnalisé $groupePersonnalise = $this->data['groupe_personnalise'] ?? []; $datePersonnalisee = [ 'date' => $groupePersonnalise['date_personnalisee'] ?? '', 'horaires' => $groupePersonnalise['horaires_personnalises'] ?? '', 'lien' => $groupePersonnalise['lien_personnalise'] ?? null ]; if (!empty($datePersonnalisee['date'])) { $result['events'] = [$this->formatSingleCustomDate($datePersonnalisee)]; } } return $result; } /** * Génère plusieurs cartes pour le blockGrid */ public function generateMultipleCards(): array { $typeConfiguration = $this->data['type_configuration'] ?? 'dynamique'; $cartes = []; if ($typeConfiguration === 'dynamique') { // Récupération depuis le groupe dynamique $groupeDynamique = $this->data['groupe_dynamique'] ?? []; $typeEvenement = $groupeDynamique['type_evenement'] ?? $this->data['type_evenement'] ?? ''; $campusData = $groupeDynamique['campus_selection'] ?? $this->data['campus_selection'] ?? null; $nombreCartes = intval($groupeDynamique['nombre_cartes_dynamique'] ?? $this->data['nombre_cartes_dynamique'] ?? 1); $lien = $groupeDynamique['lien_dynamique'] ?? $this->data['lien_dynamique'] ?? null; // Extraire le nom du campus depuis l'objet terme ou string $campus = ''; if (is_object($campusData)) { $campus = $campusData->name ?? ''; } elseif (is_string($campusData)) { $campus = $campusData; } if (!empty($typeEvenement) && !empty($campus)) { // Cas spécial Paris : alterner PPA et MBA $isParis = (strtolower($campus) === 'paris'); if ($isParis && $nombreCartes >= 2) { // Récupérer tous les événements PPA et MBA pour Paris $eventsPPA = $this->getEventsByTypeAndCampus($typeEvenement, $campus, false); $eventsMBA = $this->getEventsByTypeAndCampus($typeEvenement, 'Montrouge', true); $countPPA = count($eventsPPA); $countMBA = count($eventsMBA); // Vérifier si MBA Montrouge a au moins 1 événement if ($countMBA >= 1) { // Cas 1 : Afficher 1 PPA + 1 MBA if (!empty($eventsPPA[0])) { $cartes[] = [ 'type_configuration' => 'dynamique', 'events' => [$eventsPPA[0]], 'lien' => $lien, 'couleur_fond_date' => $this->data['couleur_fond_date'] ?? 'blanc' ]; } if (!empty($eventsMBA[0])) { $cartes[] = [ 'type_configuration' => 'dynamique', 'events' => [$eventsMBA[0]], 'lien' => $lien, 'couleur_fond_date' => $this->data['couleur_fond_date'] ?? 'blanc' ]; } } else { // Cas 2 : Pas d'événement MBA, afficher 2 PPA if (!empty($eventsPPA[0])) { $cartes[] = [ 'type_configuration' => 'dynamique', 'events' => [$eventsPPA[0]], 'lien' => $lien, 'couleur_fond_date' => $this->data['couleur_fond_date'] ?? 'blanc' ]; } if (!empty($eventsPPA[1])) { $cartes[] = [ 'type_configuration' => 'dynamique', 'events' => [$eventsPPA[1]], 'lien' => $lien, 'couleur_fond_date' => $this->data['couleur_fond_date'] ?? 'blanc' ]; } } } else { // Cas normal : PPA uniquement (ou Paris avec 1 seule carte) $events = $this->getEventsByTypeAndCampus($typeEvenement, $campus, false); // Générer X cartes avec les X premiers événements for ($i = 0; $i < min($nombreCartes, count($events)); $i++) { $cartes[] = [ 'type_configuration' => 'dynamique', 'events' => [$events[$i]], 'lien' => $lien, 'couleur_fond_date' => $this->data['couleur_fond_date'] ?? 'blanc' ]; } } } } else if ($typeConfiguration === 'personnalise') { // Récupération depuis le groupe personnalisé (une seule carte maintenant) $groupePersonnalise = $this->data['groupe_personnalise'] ?? []; $datePersonnalisee = [ 'date' => $groupePersonnalise['date_personnalisee'] ?? '', 'horaires' => $groupePersonnalise['horaires_personnalises'] ?? '', 'lien' => $groupePersonnalise['lien_personnalise'] ?? null ]; // Une seule carte en mode personnalisé if (!empty($datePersonnalisee['date'])) { $cartes[] = [ 'type_configuration' => 'personnalise', 'events' => [$this->formatSingleCustomDate($datePersonnalisee)], 'lien' => null, // Le lien est dans l'événement 'couleur_fond_date' => $this->data['couleur_fond_date'] ?? 'blanc' ]; } } return $cartes; } /** * Formate une seule date personnalisée */ private function formatSingleCustomDate($dateData): array { if (empty($dateData['date'])) { return []; } // Convertir la date $date = DateTime::createFromFormat('d/m/Y', $dateData['date']); if (!$date) { return []; } $dateFormatted = $this->recuperation_jour_mois($date->format('Y-m-d')); return [ 'date_jour' => $dateFormatted['jour'], 'date_numero_jour' => $dateFormatted['numero_jour'], 'date_mois' => $dateFormatted['mois'], 'date_annee' => $dateFormatted['annee'], 'horaires' => $dateData['horaires'] ?? '', 'lien' => $dateData['lien'] ?? null ]; } } /** * Fonction globale pour traiter les données d'UNE carte date * Utilisée dans le template Twig individuel */ if (!function_exists('process_carte_date_data')) { function process_carte_date_data($fields) { try { // Récupération du système global $system = $GLOBALS[THEME]->config_default->system ?? null; if (!$system) { return [ 'type_configuration' => 'dynamique', 'events' => [], 'lien' => null ]; } $helper = new carteDateHelpers($fields, $system); return $helper->processData(); } catch (Exception $e) { error_log("Erreur process_carte_date_data: " . $e->getMessage()); return [ 'type_configuration' => 'dynamique', 'events' => [], 'lien' => null ]; } } } /** * Fonction globale pour générer plusieurs cartes date pour le blockGrid * Utilisée dans le contrôleur du blockGrid */ if (!function_exists('generate_carte_date_cards')) { function generate_carte_date_cards($fields) { try { // Récupération du système global $system = $GLOBALS[THEME]->config_default->system ?? null; if (!$system) { return [ 'cartes' => [], 'nombre_cartes' => 0 ]; } $helper = new carteDateHelpers($fields, $system); $cartes = $helper->generateMultipleCards(); // Retourner les cartes + le nombre pour le blockGrid return [ 'cartes' => $cartes, 'nombre_cartes' => count($cartes), 'nombre_cartes_choisi' => intval($fields['nombre_cartes_dynamique'] ?? 1) ]; } catch (Exception $e) { error_log("Erreur generate_carte_date_cards: " . $e->getMessage()); return [ 'cartes' => [], 'nombre_cartes' => 0 ]; } } } // Le champ campus_selection utilise maintenant Taxonomy au lieu de Select // Plus besoin de hook ACF pour peupler les choix }