Table des matières

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

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

Bibliothèques et frameworks

Infrastructure

3. Framework NOOP - Architecture personnalisée

Caractéristiques principales

Structure de fonctionnement

// 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 ()

Service Admin ()

Services Mobiles ()

Chaque partenaire possède sa propre instance :

Conventions de nommage

5. Configuration et environnements

Configuration base de données (Production)

[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

define('DEV', (in_array($_SERVER['HTTP_HOST'], array('serveurweb', '192.168.2.200'))));

Configuration par environnement

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 :

- Base de gestion

- Base de redirection

Authentification MySQL

Flux de données inter-bases

Synchronisation automatique (mobile/cron.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

Patterns d'utilisation

Service Client

// Accès base admin pour données clients
'pdo' => array('db' => '154clm_admin')

Service URL

// Double accès pour redirection et logging
'pdo' => array(
    'db' => '154clm_url',      // URLs courtes
    'dbadmin' => '154clm_admin' // Référentiel clients
)

Services Mobile

// 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

6. Gestion des erreurs et logging

System d'exception personnalisé

Email de notification d'erreurs

mail(
    'webmaster@domain.com',
    'Error '.$code.': '.$message,
    $stackTrace,
    'Content-type: text/html; charset=utf-8'
);

7. Sécurité

Authentification

Protection des données

Accès aux fichiers

8. Déploiement et maintenance

Structure de déploiement

Chaque service est déployé sur son sous-domaine :

Maintenance

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

// 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
{
    "url": "https://evolity.holybus.fr/",
    "miniurl": "https://url.holybus.fr/12345"
}

Script d'import (import.php)

Utilisation avec CSV

# 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

# Accès navigateur pour générer codes + QR Codes + liste associations
https://admin.holytag.org/batchCampagne

Sorties générées :

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 :
    curl -k -F "csv=@./holybus-campagne-269-idSiri.csv" \
      https://admin.holytag.org/import

Phase 4 : Résultat final

Intégration système QR

Service de génération QR

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é

Maintenance

Performance

10. API et intégrations

Service URL

Configuration API

'api' => array(
    'url' => 'https://url.holybus.fr/',
    'url-auth' => 'webmaster:ChrAle09lca'
)

10. Ressources et contacts

Fichiers de configuration clés

Patterns de développement

Points d'attention


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) via le SQL suivant (à adapter bien-sûr) :

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 <> '';