From 0dcdcfc8295267d7242af0b13f158d146f84a7dc Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 25 Jun 2026 16:45:03 -0400 Subject: [PATCH] Implement promoteur hub integration and UI enhancements This commit introduces the promoteur hub functionality by adding new checks and redirects based on the user's account type. It updates the account management logic to handle promoteur hub users, ensuring proper navigation and access. Additionally, it enhances the CSS for promoteur hub elements, improving the visual presentation. These changes aim to streamline user experience for promoteur hub accounts and ensure proper access management. --- compte.php | 27 +- css/style.css | 8 + php/inc_fx_compte.php | 16 +- php/inc_fx_promoteur_hub.php | 411 ++++++++++++++++++++++++++++++ php/inc_settings.php | 4 +- sql/MSIN-promoteur-hub-phase1.sql | 51 ++++ 6 files changed, 509 insertions(+), 8 deletions(-) create mode 100644 php/inc_fx_promoteur_hub.php create mode 100644 sql/MSIN-promoteur-hub-phase1.sql diff --git a/compte.php b/compte.php index db684e3..a9b46c9 100644 --- a/compte.php +++ b/compte.php @@ -23,6 +23,7 @@ require_once('superadm/php/inc_fx_excell.php'); require_once('php/inc_fx_liste_attente.php'); require_once('php/inc_fx_inscriptions_mobile.php'); require_once('php/inc_fx_eve_acces.php'); +require_once('php/inc_fx_promoteur_hub.php'); global $objDatabase, $vPage, $vDomaine; // vérifier les paramètres @@ -53,11 +54,22 @@ else if (!empty($_GET['code'])) $strCode = 'compte_' . $_GET['code']; else { - if (isset($_SESSION['com_id'])) - $strCode = "compte_accueil"; - else - $strCode = "compte_login"; + if (isset($_SESSION['com_id'])) { + if (fxPromoteurHubComUsesV2($_SESSION['com_id'])) { + $strCode = 'compte_promoteur_hub'; + } else { + $strCode = 'compte_accueil'; + } + } else { + $strCode = 'compte_login'; + } } + +if ($strCode === 'compte_promoteur_hub' && (!isset($_SESSION['com_id']) || !fxPromoteurHubComUsesV2($_SESSION['com_id']))) { + header('Location: ' . $vDomaine . '/' . ($strLangue === 'fr' ? 'compte' : 'account')); + exit; +} + $recPage = fxGetPage($strCode); if (count($recPage) < 1) { @@ -321,7 +333,8 @@ if (isset($_GET['promoteur_eve_id'])) { header('Location: ' . $vDomaine . '/' . $strPage); exit; } - } elseif (!fxIsPromoteur($_SESSION['com_id'], $intEveIdbase)) { + } elseif (!fxIsPromoteur($_SESSION['com_id'], $intEveIdbase) + && !fxEveAccesComHasV2ForEvent($_SESSION['com_id'], $intEveIdbase)) { header('Location: ' . $vDomaine . '/' . $strPage); exit; } @@ -476,6 +489,10 @@ require_once("inc_header.php"); case 'compte_annuler_inscription': include_once('annuler_inscription.php'); break; + case 'compte_promoteur_hub': + $blnBoutonRetour = false; + echo fxShowPromoteurHub($_SESSION['com_id'], $strLangue); + break; case 'compte_accueil': //MSIN-4371 if (fxEveAccesCanQrTest($_SESSION['com_id'])) { ?> diff --git a/css/style.css b/css/style.css index 8305424..a80139b 100644 --- a/css/style.css +++ b/css/style.css @@ -3094,3 +3094,11 @@ a.ms1-trad-link.btn-aide-trad{ color:#212529; } } + +.promoteur-hub-card-archived { + opacity: 0.72; +} + +.promoteur-hub-annonces .ms1-doc-trigger { + flex-shrink: 0; +} diff --git a/php/inc_fx_compte.php b/php/inc_fx_compte.php index fa29651..77438dc 100644 --- a/php/inc_fx_compte.php +++ b/php/inc_fx_compte.php @@ -1273,6 +1273,14 @@ function fxLoginCompte($infoLogin, $strLangue) else $strPage = 'account'; + if (($arrRetour['state'] ?? '') === 'true' && !empty($infoCompte['com_id'])) { + require_once dirname(__FILE__) . '/inc_fx_promoteur_hub.php'; + if (fxPromoteurHubComUsesV2($infoCompte['com_id'])) { + header('Location: ' . fxPromoteurHubUrl($strLangue)); + exit; + } + } + //header("Location: " . $vDomaine . '/' . $strPage); header("Location: " . fxGetReferer()); } @@ -1477,7 +1485,13 @@ function fxShowMenuCompte($arrCompteClient, $strLangue) '; } - // menu promoteur + // menu promoteur v2 (hub) — comptes migres uniquement + if (!function_exists('fxPromoteurHubComUsesV2')) { + require_once dirname(__FILE__) . '/inc_fx_promoteur_hub.php'; + } + $strRetour .= fxShowPromoteurHubMenuLink($arrCompteClient, $strLangue); + + // menu promoteur legacy if (trim($arrCompteClient['com_eve_promoteur']) != '' || trim($arrCompteClient['com_rapports']) != '') { // si le compte client a des événements dont il est le promoteur $arrEvePromoteur = explode(',', $arrCompteClient['com_eve_promoteur']); diff --git a/php/inc_fx_promoteur_hub.php b/php/inc_fx_promoteur_hub.php new file mode 100644 index 0000000..0fe23da --- /dev/null +++ b/php/inc_fx_promoteur_hub.php @@ -0,0 +1,411 @@ + 0) ? max($intDebut, $intFin) : $intDebut; + + if ($intRef <= 0) { + return 0; + } + + return strtotime('+14 days', $intRef); +} + +function fxPromoteurHubFormatEventDate($arrEvent, $strLangue) +{ + $strDebut = trim($arrEvent['eve_date_debut'] ?? ''); + $strFin = trim($arrEvent['eve_date_fin'] ?? ''); + + if ($strDebut === '' || strpos($strDebut, '0000-00-00') === 0) { + return ''; + } + + $strFmtDebut = date('Y-m-d', fxPromoteurHubParseDateTs($strDebut)); + $intFin = fxPromoteurHubParseDateTs($strFin); + + if ($intFin <= 0 || $strFmtDebut === date('Y-m-d', $intFin)) { + return $strFmtDebut; + } + + return $strFmtDebut . ' — ' . date('Y-m-d', $intFin); +} + +function fxPromoteurHubGetRoleLabelsByEvent($intComId) +{ + global $objDatabase; + + $arrByEve = array(); + $tabRows = fxEveAccesListByComId(intval($intComId)); + + if (!is_array($tabRows)) { + return $arrByEve; + } + + for ($i = 1; $i <= count($tabRows); $i++) { + $row = $tabRows[$i]; + if (($row['ea_statut'] ?? '') !== 'actif') { + continue; + } + + $intEveId = intval($row['eve_id'] ?? 0); + if ($intEveId <= 0) { + continue; + } + + $strLabel = trim($row['role_label_fr'] ?? ''); + if ($strLabel === '') { + $strLabel = trim($row['role_code'] ?? ''); + } + + if ($strLabel === '') { + continue; + } + + if (!isset($arrByEve[$intEveId])) { + $arrByEve[$intEveId] = array(); + } + + if (!in_array($strLabel, $arrByEve[$intEveId], true)) { + $arrByEve[$intEveId][] = $strLabel; + } + } + + return $arrByEve; +} + +function fxPromoteurHubGetEvents($intComId, $strLangue = 'fr') +{ + global $objDatabase, $vDomaine, $vRepertoireFichiers; + + $arrHighlight = array(); + $arrArchived = array(); + $arrEventIds = fxEveAccesGetEventIds(intval($intComId)); + + if (empty($arrEventIds)) { + return array('highlight' => $arrHighlight, 'archived' => $arrArchived); + } + + $arrIds = array_values(array_unique(array_filter(array_map('intval', $arrEventIds), function ($v) { + return $v > 0; + }))); + + if (empty($arrIds)) { + return array('highlight' => $arrHighlight, 'archived' => $arrArchived); + } + + $strLang = in_array($strLangue, array('fr', 'en'), true) ? $strLangue : 'fr'; + $strAlt = ($strLang === 'fr') ? 'en' : 'fr'; + $arrRoles = fxPromoteurHubGetRoleLabelsByEvent(intval($intComId)); + $intToday = strtotime(date('Y-m-d')); + + $sql = " + SELECT e.eve_id, e.eve_nom_fr, e.eve_nom_en, e.eve_date_debut, e.eve_date_fin, + e.eve_lieu_fr, e.eve_lieu_en, e.eve_photo_fr, e.eve_photo_en, + t.te_icone + FROM inscriptions_evenements e + JOIN inscriptions_types_evenements t ON t.te_id = e.te_id + WHERE e.eve_actif = 1 + AND e.eve_id IN (" . implode(',', $arrIds) . ") + ORDER BY e.eve_date_debut ASC, e.eve_nom_fr ASC + "; + $tabEvents = $objDatabase->fxGetResults($sql); + + if (!is_array($tabEvents)) { + return array('highlight' => $arrHighlight, 'archived' => $arrArchived); + } + + for ($i = 1; $i <= count($tabEvents); $i++) { + $row = $tabEvents[$i]; + $intEveId = intval($row['eve_id']); + $strNom = trim($row['eve_nom_' . $strLang] ?? ''); + + if ($strNom === '') { + $strNom = trim($row['eve_nom_' . $strAlt] ?? ''); + } + + $strLieu = trim($row['eve_lieu_' . $strLang] ?? ''); + if ($strLieu === '') { + $strLieu = trim($row['eve_lieu_' . $strAlt] ?? ''); + } + + if (intval($row['eve_id']) === 175 && trim($row['eve_photo_' . $strLang] ?? '') !== '') { + $strIcon = $vDomaine . $vRepertoireFichiers . '/images/evenements/' . $row['eve_photo_' . $strLang]; + } else { + $strIcon = $vDomaine . '/images/' . ($row['te_icone'] ?? ''); + } + + $intHighlightUntil = fxPromoteurHubHighlightUntilTs($row['eve_date_debut'] ?? '', $row['eve_date_fin'] ?? ''); + $blnHighlight = ($intHighlightUntil <= 0) || ($intToday <= $intHighlightUntil); + + $arrItem = array( + 'eve_id' => $intEveId, + 'nom' => $strNom, + 'lieu' => $strLieu, + 'date_label' => fxPromoteurHubFormatEventDate($row, $strLang), + 'ts_debut' => fxPromoteurHubParseDateTs($row['eve_date_debut'] ?? ''), + 'icon' => $strIcon, + 'roles' => $arrRoles[$intEveId] ?? array(), + 'url_promoteur' => fxPromoteurHubCanAccessPromoteurWeb($intComId, $intEveId) + ? fxPromoteurHubPromoteurTableUrl($intEveId, $strLang) + : '', + 'url_mobile' => '', + ); + + if (!function_exists('fxInscrMobileCanAccess')) { + require_once __DIR__ . '/inc_fx_inscriptions_mobile.php'; + } + + if (fxInscrMobileCanAccess(intval($intComId), $intEveId)) { + $arrItem['url_mobile'] = fxInscrMobileBaseUrl($strLang, false) + . '?promoteur_eve_id=' . urlencode(base64_encode($intEveId)); + } + + if ($blnHighlight) { + $arrHighlight[] = $arrItem; + } else { + $arrArchived[] = $arrItem; + } + } + + usort($arrHighlight, function ($a, $b) { + $ta = intval($a['ts_debut'] ?? 0); + $tb = intval($b['ts_debut'] ?? 0); + if ($ta === $tb) { + return strcasecmp($a['nom'], $b['nom']); + } + if ($ta <= 0) { + return 1; + } + if ($tb <= 0) { + return -1; + } + return $ta <=> $tb; + }); + + usort($arrArchived, function ($a, $b) { + $ta = intval($a['ts_debut'] ?? 0); + $tb = intval($b['ts_debut'] ?? 0); + if ($ta === $tb) { + return strcasecmp($b['nom'], $a['nom']); + } + return $tb <=> $ta; + }); + + return array('highlight' => $arrHighlight, 'archived' => $arrArchived); +} + +function fxPromoteurHubEsc($str) +{ + return htmlspecialchars((string)$str, ENT_QUOTES, 'UTF-8'); +} + +function fxPromoteurHubRenderEventCard($arrItem, $strLangue, $blnArchived = false) +{ + $strCardClass = 'card box_participant mb-3' . ($blnArchived ? ' promoteur-hub-card-archived' : ''); + + $html = '
'; + $html .= '
'; + $html .= '
'; + $html .= '
'; + $html .= '

' . fxPromoteurHubEsc($arrItem['nom']) . '

'; + + if ($arrItem['date_label'] !== '') { + $html .= '
' . fxPromoteurHubEsc($arrItem['date_label']) . '
'; + } + + if ($arrItem['lieu'] !== '') { + $html .= '
' . fxPromoteurHubEsc($arrItem['lieu']) . '
'; + } + + if (!empty($arrItem['roles'])) { + $html .= '
' . fxPromoteurHubEsc(implode(' · ', $arrItem['roles'])) . '
'; + } + + $html .= '
'; + $html .= '
'; + + if ($arrItem['url_promoteur'] !== '') { + $html .= ''; + $html .= '' . fxPromoteurHubEsc(afficheTexte('promoteur_hub_btn_tableau', 0)); + $html .= ''; + } + + if ($arrItem['url_mobile'] !== '') { + $html .= ''; + $html .= '' . fxPromoteurHubEsc(afficheTexte('promoteur_hub_btn_mobile', 0)); + $html .= ''; + } + + $html .= '
'; + + return $html; +} + +function fxPromoteurHubRenderEventSection($arrItems, $strTitleClef, $strLangue, $blnArchived = false) +{ + if (empty($arrItems)) { + return ''; + } + + $html = '

' . fxPromoteurHubEsc(afficheTexte($strTitleClef, 0)) . '

'; + $html .= '
'; + + foreach ($arrItems as $arrItem) { + $html .= fxPromoteurHubRenderEventCard($arrItem, $strLangue, $blnArchived); + } + + $html .= '
'; + + return $html; +} + +function fxShowPromoteurHub($intComId, $strLangue = 'fr') +{ + $arrBuckets = fxPromoteurHubGetEvents(intval($intComId), $strLangue); + $html = ''; + + $html .= '
'; + $html .= '

' . fxPromoteurHubEsc(afficheTexte('promoteur_hub_intro', 0)) . '

'; + $html .= ''; + $html .= '' . fxPromoteurHubEsc(afficheTexte('promoteur_hub_link_participant', 0)); + $html .= ''; + $html .= '
'; + + if (function_exists('fxDocRenderBlock')) { + $strDoc = fxDocRenderBlock('promoteur_hub_annonces'); + if ($strDoc !== '') { + $html .= '
'; + $html .= '
' . fxPromoteurHubEsc(afficheTexte('promoteur_hub_annonces_titre', 0)) . '
'; + $html .= $strDoc; + $html .= '
'; + } + } + + $html .= fxPromoteurHubRenderEventSection($arrBuckets['highlight'], 'promoteur_hub_section_highlight', $strLangue, false); + $html .= fxPromoteurHubRenderEventSection($arrBuckets['archived'], 'promoteur_hub_section_archived', $strLangue, true); + + if (empty($arrBuckets['highlight']) && empty($arrBuckets['archived'])) { + $html .= '
' . fxPromoteurHubEsc(afficheTexte('promoteur_hub_empty', 0)) . '
'; + } + + return $html; +} + +function fxShowPromoteurHubMenuLink($arrCompteClient, $strLangue) +{ + global $vDomaine; + + if (!fxPromoteurHubComUsesV2(intval($arrCompteClient['com_id'] ?? 0))) { + return ''; + } + + $arrIds = fxEveAccesGetEventIds(intval($arrCompteClient['com_id'])); + $intNb = count($arrIds); + $strNb = ''; + + if ($intNb > 0) { + $strNb = '(' . $intNb . ' '; + $strNb .= ($intNb > 1) ? afficheTexte('compte_evenement_pluriel', 0) : afficheTexte('compte_evenement_singulier', 0); + $strNb .= ')'; + } + + return ' + + '; +} diff --git a/php/inc_settings.php b/php/inc_settings.php index e0f7e5a..4a441dc 100644 --- a/php/inc_settings.php +++ b/php/inc_settings.php @@ -7,8 +7,8 @@ * Constantes * * **************/ -define('_VERSION_CODE', '4.72.699'); -define('_DATE_CODE', '2026-06-22'); +define('_VERSION_CODE', '4.72.700'); +define('_DATE_CODE', '2026-06-25'); //MSIN-4290 define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe'); // Outil temporaire ms1_kc_set.php — modifier key_chain_http (lien /kc/{pk}/) diff --git a/sql/MSIN-promoteur-hub-phase1.sql b/sql/MSIN-promoteur-hub-phase1.sql new file mode 100644 index 0000000..081b9d5 --- /dev/null +++ b/sql/MSIN-promoteur-hub-phase1.sql @@ -0,0 +1,51 @@ +-- Hub promoteur — page compte + libelles (acces v2 uniquement) +SET NAMES utf8mb4; + +DELETE FROM inscriptions_pages WHERE pag_code = 'compte_promoteur_hub'; + +INSERT INTO inscriptions_pages ( + pag_code, pag_label_fr, pag_label_en, + pag_titre_fr, pag_titre_en, + pag_texte_fr, pag_texte_en, + pag_keywords_fr, pag_keywords_en, + pag_tri, pag_maj, pag_menu, pag_actif +) VALUES ( + 'compte_promoteur_hub', + 'Promoteur', 'Promoter', + 'Mes evenements', 'My events', + '', '', + '', '', + 0, NOW(), 0, 1 +); + +DELETE FROM info WHERE info_clef IN ( + 'promoteur_hub_menu', + 'promoteur_hub_intro', + 'promoteur_hub_link_participant', + 'promoteur_hub_annonces_titre', + 'promoteur_hub_section_highlight', + 'promoteur_hub_section_archived', + 'promoteur_hub_btn_tableau', + 'promoteur_hub_btn_mobile', + 'promoteur_hub_empty' +) AND info_prg = 'compte.php'; + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) VALUES +('promoteur_hub_menu', 'fr', 'Mes evenements (promoteur)', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_menu', 'en', 'My events (promoter)', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_intro', 'fr', 'Acces a vos tableaux de bord par evenement.', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_intro', 'en', 'Access your event dashboards.', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_link_participant', 'fr', 'Mon espace participant', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_link_participant', 'en', 'My participant space', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_annonces_titre', 'fr', 'Nouveautes MS1', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_annonces_titre', 'en', 'MS1 updates', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_section_highlight', 'fr', 'En vedette', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_section_highlight', 'en', 'Highlights', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_section_archived', 'fr', 'Evenements passes', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_section_archived', 'en', 'Past events', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_btn_tableau', 'fr', 'Tableau de bord', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_btn_tableau', 'en', 'Dashboard', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_btn_mobile', 'fr', 'Inscriptions mobile', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_btn_mobile', 'en', 'Mobile registrations', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_empty', 'fr', 'Aucun evenement accessible pour le moment.', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('promoteur_hub_empty', 'en', 'No accessible events at this time.', '', 'compte.php', '', 0, 1, '', '', '', NOW());