# Documentation Technique - Projet HolyBus ## 1. Vue d'ensemble du projet ### Objectifs et problématiques adressées Le projet HolyBus est une plateforme de gestion multi-services déployée sur une architecture de sous-domaines. Chaque dossier représente un service indépendant accessible via un sous-domaine spécifique, permettant une organisation modulaire et une maintenance simplifiée. ### Contexte métier et utilisateurs cibles - **Clients** : Interface utilisateur principale pour les services de transport - **Administration** : Back-office pour la gestion des services - **Services mobiles** : Applications dédiées aux différents partenaires de transport (Touriscar, Artis, Evolity, CCVA, Procars, Hegobus) - **Statistiques** : Système de collecte et analyse de données - **URL** : Service de gestion et redirection d'URLs ### Architecture technique globale ``` holybus/ ├── main/ # Site principal (domaine racine) ├── www/ # Service web principal ├── client/ # Interface client ├── admin/ # Back-office administrateur ├── mobile/ # Services mobiles par partenaire │ ├── touriscar/ │ ├── artis/ │ ├── evolity/ │ ├── ccva/ │ ├── procars/ │ └── hegobus/ ├── stats/ # Service de statistiques └── url/ # Service de gestion d'URLs ``` ## 2. Stack technologique ### Technologies principales - **Backend** : PHP (Framework NOOP custom) - **Frontend** : JavaScript, jQuery 2.1.3, HTML5, CSS3 - **Base de données** : MySQL - **Serveur web** : Apache (.htaccess) ### Bibliothèques et frameworks - **NOOP Framework** : Framework PHP custom (version 2.0.1) avec architecture MVC - **jQuery 2.1.3** : Bibliothèque JavaScript principale - **jQuery UI 1.11.2** : Interface utilisateur avancée - **D3.js 3.5.3** : Visualisation de données - **C3.js 0.4.22** : Graphiques basés sur D3 - **Modernizr** : Détection des fonctionnalités navigateur - **TinyColorPicker** : Sélecteur de couleurs ### Infrastructure - **Hébergement** : Infomaniak (154clm.myd.infomaniak.com) - **Base de données** : MySQL (154clm_admin, 154clm_url) - **Utilisateur MySQL** : 154clm_holybus - **Environnement de développement** : Local (serveurweb, 192.168.2.200) ## 3. Framework NOOP - Architecture personnalisée ### Caractéristiques principales - **Version** : NOOP 2.0.1 (MIT License, Dimitri Avenel) - **Architecture** : MVC avec routing automatique - **Configuration** : Système de configuration centralisé - **Gestion des erreurs** : Handler d'exceptions personnalisé - **Cache** : Système de cache intégré pour les vues - **Base de données** : Abstraction PDO multi-base ### Structure de fonctionnement ```php // Configuration type noop::config(array( 'pdo' => array('db' => 'mysql,host=...;dbname=...,user,password'), 'path' => array( 'controller' => 'secure/control', 'view' => 'secure/view' ) )); // Démarrage de l'application noop::start(); ``` ## 4. Structure du code ### Organisation des services #### Service Client (`client/`) - **Point d'entrée** : `index.php` - **Configuration** : Session management, configuration base de données - **Bibliothèques** : `lib/` (jQuery, CSS, ressources visuelles) - **Sécurité** : `secure/` (contrôleurs, vues, fonctions) #### Service Admin (`admin/`) - **Point d'entrée** : `index.php` - **Configuration** : `secure/global.ini` - **Gestion** : Interface d'administration complète #### Services Mobiles (`mobile/`) Chaque partenaire possède sa propre instance : - **Structure identique** : `index.php`, `secure/`, `lib/`, `img/`, `perso/` - **Partenaires** : touriscar, artis, evolity, ccva, procars, hegobus - **Documentation** : `mobile/doc/` avec assets CSS/JS ### Conventions de nommage - **Fichiers de configuration** : `.ini`, `.htaccess`, `.php-ini` - **Contrôleurs** : `secure/control/` - **Vues** : `secure/view/` - **Ressources** : `lib/`, `img/` - **Personnalisation** : `perso/` ## 5. Configuration et environnements ### Configuration base de données (Production) ```ini [pdo] db = "mysql,host=154clm.myd.infomaniak.com;dbname=154clm_admin,154clm_holybus,89hG?#56m-wRF" db2 = "mysql,host=154clm.myd.infomaniak.com;dbname=154clm_url,154clm_holybus,89hG?#56m-wRF" ``` **Format** : `mysql,host=HOST;dbname=DATABASE,USER,PASSWORD` ### Détection d'environnement ```php define('DEV', (in_array($_SERVER['HTTP_HOST'], array('serveurweb', '192.168.2.200')))); ``` ### Configuration par environnement - **Production** : Debug OFF, base Infomaniak - **Développement** : Debug ON, base locale ## 5. Base de données - Spécificité de chaque DB ### Architecture multi-bases Le système utilise 2 bases de données MySQL distinctes avec des rôles spécifiques : #### **154clm_admin** - Base de gestion - **Fonction** : Gestion administrative principale - **Usage** : Services client, admin, mobile - **Tables principales** : - `admin_clients` : Gestion des clients transport - `admin_campagnes` : Campagnes de communication - `admin_codes` : Codes QR et contenus associés - **Connexions** : Utilisée par tous les services sauf URL #### **154clm_url** - Base de redirection - **Fonction** : Service de raccourcissement d'URLs - **Usage** : Service URL uniquement - **Tables principales** : - `url` : Mapping code -> URL longue - **Processus** : Redirection automatique via miniurl ### Authentification MySQL - **Utilisateur** : `154clm_holybus` - **Mot de passe** : `89hG?#56m-wRF` - **Accès** : Permissions sur les deux bases de données ### Flux de données inter-bases #### Synchronisation automatique (mobile/cron.php) ```php // Processus de synchronisation des codes QR $pdo = new PDO('154clm_admin'); // Source : clients et campagnes $pdo2 = new PDO('154clm_url'); // Destination : URLs courtes // Mapping automatique : QR Code -> URL mobile foreach ($clients as $client) { // Lecture fichier QRCodes.txt du client // Mise à jour table url pour redirection // Mise à jour admin_codes avec contenu JSON } ``` #### Configuration par service - **Client/Admin** : `db` (admin), accès données clients/campagnes - **URL** : `db` (url), `dbadmin` (admin) pour les références - **Mobile** : `db` (admin) pour authentification et données ### Patterns d'utilisation #### Service Client ```php // Accès base admin pour données clients 'pdo' => array('db' => '154clm_admin') ``` #### Service URL ```php // Double accès pour redirection et logging 'pdo' => array( 'db' => '154clm_url', // URLs courtes 'dbadmin' => '154clm_admin' // Référentiel clients ) ``` #### Services Mobile ```php // Accès admin pour authentification partenaires 'pdo' => array('db' => '154clm_admin') ``` ### Intégrations spécifiques #### Génération d'URLs mobiles ``` QR Code [12345] → Fichier QRCodes.txt → Base admin_codes → Base url → Redirection : url.holybus.fr/12345 → m.holybus.fr/client/arret/LOC ``` #### Authentification centralisée - **Base admin** : Référentiel utilisateurs - **Sessions** : Partagées entre services - **Permissions** : Gestion par service selon le dossier client ## 6. Gestion des erreurs et logging ### System d'exception personnalisé - **Classes** : `NoopException`, `NoopConfigException`, `NoopControllerException`, `NoopViewException` - **Handler** : `exception_callback()` avec notification par email - **Logging** : Classe `Logger` pour traçabilité - **Monitoring** : Headers X-Benchmark pour performances ### Email de notification d'erreurs ```php mail( 'webmaster@domain.com', 'Error '.$code.': '.$message, $stackTrace, 'Content-type: text/html; charset=utf-8' ); ``` ## 7. Sécurité ### Authentification - **Admin** : Login/password dans `global.ini` - **Sessions** : Gestion centralisée avec timeout - **API** : Authentification basic pour service URL ### Protection des données - **Stripslashes** : Nettoyage automatique des données - **PDO** : Requêtes préparées - **Headers** : Configuration sécurisée (.htaccess) ### Accès aux fichiers - **Dossiers secure/** : Protégés par .htaccess - **Configuration** : Fichiers .ini protégés - **Environnement** : Détection automatique dev/prod ## 8. Déploiement et maintenance ### Structure de déploiement Chaque service est déployé sur son sous-domaine : - `www.holybus.fr` → `main/` - `client.holybus.fr` → `client/` - `admin.holybus.fr` → `admin/` - `touriscar.holybus.fr` → `mobile/touriscar/` - Etc. ### Maintenance - **Logs** : Système de logging centralisé - **Monitoring** : Headers de performance automatiques - **Cache** : Invalidation manuelle via `?no-cache` ## 9. Commande batchCampagne.php - Génération de campagnes QR ### Vue d'ensemble Le script `admin/secure/control/batchCampagne.php` est l'outil principal pour générer massivement des campagnes de codes QR pour les clients transport. Il automatise la création de codes QR, miniURLs, et fichiers de production. ### Fonctionnalités principales #### 1. Génération automatique de codes ```php // Configuration par campagne $id_campagne = 271; $societe = 'evolity'; $lot = '11cm'; $destination_url = 'https://evolity.holybus.fr/'; ``` #### 2. Processus de génération 1. **Récupération de la campagne** : Lecture des paramètres depuis `admin_campagnes` 2. **Vérification des codes existants** : Calcul du nombre de codes manquants 3. **Création des miniURLs** : Insertion dans la base `154clm_url` 4. **Génération des codes QR** : Création des enregistrements `admin_codes` 5. **Production des fichiers** : CSV, QR Codes PNG, mapping InDesign #### 3. Sorties générées ##### Fichiers CSV ``` holybus-campagne-271_11cm.csv # Liste des codes générés holybus-campagne-271_11cm-indesign.csv # Chemins pour InDesign ``` ##### QR Codes PNG ``` out/qrcodes-271_11cm/ ├── code-12345.png ├── code-12346.png └── ... ``` ##### Structure des données ```json { "url": "https://evolity.holybus.fr/", "miniurl": "https://url.holybus.fr/12345" } ``` ### Script d'import (import.php) #### Utilisation avec CSV ```bash # Upload d'un mapping ID miniURL <-> ID SIRI curl -k -F "csv=@./holybus-campagne-269-idSiri.csv" \ https://admin.holytag.org/import ``` **Note** : Pas d'authentification requise pour l'endpoint import #### Processus d'import 1. **Lecture du CSV** : `[id_code, siri_code]` 2. **Génération d'URLs** : `https://m.holybus.fr/societe/arret/SIRI_CODE` 3. **Mise à jour des bases** : `admin_codes` + `url` 4. **Génération QR** : Codes PNG individuels 5. **Export InDesign** : Chemins macOS pour intégration PAO ### Workflow complet - Ajout d'un client et campagne SIRI cf. https://app.asana.com/1/1530398085277/project/1205755380967232/task/1209326056812982?focus=true #### Phase 1 : Préparation administrative 1. **Ajouter le client** dans l'interface admin 2. **Créer une campagne** avec un nombre maximal de codes 3. **Configuration des scripts** : - Modifier `admin/secure/control/batchCampagne.php` - Modifier `admin/secure/control/import.php` - Paramètres requis : - Nom du client (pour URL cible - nom du projet) - ID de la campagne #### Phase 2 : Génération initiale des codes ```bash # Accès navigateur pour générer codes + QR Codes + liste associations https://admin.holytag.org/batchCampagne ``` **Sorties générées** : - Codes en base de données - QR Codes PNG individuels - Liste des associations `code = miniURL` #### Phase 3 : Mapping des codes SIRI 1. **Créer un fichier CSV** : `"ID miniURL" + "ID SIRI"` 2. **Format** : `holybus-campagne-[ID]-idSiri.csv` 3. **Import définitif** : ```bash curl -k -F "csv=@./holybus-campagne-269-idSiri.csv" \ https://admin.holytag.org/import ``` #### Phase 4 : Résultat final - **Base de données** : Mapping complet codes QR ↔ arrêts SIRI - **Redirection** : `url.holybus.fr/12345` → `m.holybus.fr/client/arret/SIRI_CODE` - **Assets** : QR Codes PNG + CSV InDesign pour impression ### Intégration système QR #### Service de génération QR ```php class QR { const URL = 'http://qr.lca.fr/'; const AUTH = 'webmaster:ChrAle09lca'; static public function generate($data) { // Appel API externe pour génération PNG // Paramètres : size=4, ecc=L, margin=2 } } ``` #### Chaîne de redirection ``` QR Code physique → url.holybus.fr/12345 → m.holybus.fr/client/arret/LOC ``` ### Points d'attention #### Sécurité - Credentials hard-codés dans les scripts - Accès API QR externe non sécurisé - Upload CSV sans validation stricte #### Maintenance - Chemins InDesign hard-codés pour macOS - Dépendance API externe qr.lca.fr - Pas de système de rollback #### Performance - `usleep(300)` pour éviter la surcharge API - Génération séquentielle (non parallélisée) - Stockage fichiers local uniquement ## 10. API et intégrations ### Service URL - **Endpoint** : `https://url.holybus.fr/` - **Authentification** : Basic Auth (webmaster:password) - **Fonction** : Gestion et redirection d'URLs courtes ### Configuration API ```php 'api' => array( 'url' => 'https://url.holybus.fr/', 'url-auth' => 'webmaster:ChrAle09lca' ) ``` ## 10. Ressources et contacts ### Fichiers de configuration clés - `admin/secure/global.ini` : Configuration principale - `client/index.php` : Configuration client - `*/noop.php` : Framework core ### Patterns de développement - **MVC** : Contrôleurs dans `secure/control/`, vues dans `secure/view/` - **Configuration** : Centralisée avec héritage - **Cache** : MD5 hash des paramètres + timestamp - **Routing** : Automatique basé sur l'arborescence ### Points d'attention - **Credentials** : Présents en dur dans les fichiers de configuration - **Framework** : NOOP est un framework custom, documentation interne nécessaire - **Multi-tenant** : Architecture distribuée sur sous-domaines - **Legacy** : Code datant de 2010-2014, nécessite migration progressive --- *Documentation générée automatiquement - Projet HolyBus* ## Tips & parachutes Si jamais les URLs cibles sont identiques et pointent sur l'accueil du site client, c'est qu'il y a eu un manquement dans l'utilisation du **batchCampagne**. Il convient donc de regénérer les URLs en prenant le code de l'arrêt indiqué au début du libellé de admin_codes. Ce travail peut se faire en masse (cf. chat [Holybus - mise à jour en masse des URLs cibles](https://chatgpt.com/c/68c14467-3e80-8331-ad4b-310c4db94010)) via le SQL suivant (à adapter bien-sûr) : ```sql UPDATE 154clm_admin.admin_codes AS ac JOIN 154clm_url.url AS u ON u.code = ac.id_code /* calcule CODEARRET = premiers caractères du libellé avant "-" */ JOIN ( SELECT id_code, TRIM(SUBSTRING_INDEX(libelle, '-', 1)) AS code_arret FROM 154clm_admin.admin_codes ) AS x ON x.id_code = ac.id_code SET /* nouvelle URL normalisée */ u.url = CONCAT('https://evolity.holybus.fr/arret/', x.code_arret), /* mise à jour du JSON si valide : contenu.url := nouvelle URL */ ac.contenu = CASE WHEN JSON_VALID(ac.contenu) THEN JSON_SET(ac.contenu, '$.url', CONCAT('https://evolity.holybus.fr/arret/', x.code_arret)) ELSE ac.contenu END WHERE u.url LIKE '%evolity%' AND ac.libelle NOT LIKE 'Campagne Pack%' AND x.code_arret <> ''; ```