# CHAPITRE 23 — Le catalogue produit dynamique en profondeur
Le catalogue produit dynamique transforme votre table `llx_product` en pages web générées automatiquement. Ce chapitre détaille l'ensemble du fonctionnement côté développeur : architecture, classes, configuration et points d'extension.
### Architecture en couches
| Couche
| Rôle
|
|---|
| **StudioProductCatalog**
| Lit les produits Dolibarr (filtres, tris, multilingue) et expose un format normalisé.
|
| **StudioSolutionWrapper**
| Génère et supprime les wrappers Apache
`solution-[.php]`
en fonction des produits publiés.
|
| **Le gabarit solution-detail (page<X>.tpl.php)**
| Le gabarit unique qui affiche un produit. Une seule page Dolibarr Website pour N produits.
|
| **Trigger PRODUCT et CATEGORY**
| Régénère automatiquement les wrappers à chaque modification de produit ou de catégorie.
|
| **Tâche planifiée horaire**
| Filet de sécurité : relance la génération si un trigger a été manqué.
|
### Le modèle de données produit
Chaque produit Dolibarr utilisé dans le catalogue exploite plusieurs tables :
| Table
| Données
|
|---|
| `llx_product`
| Champs natifs : ref, label, description, prix, tosell.
|
| `llx_product_lang`
| Traductions natives (label, description par langue).
|
| `llx_product_extrafields`
| Champs personnalisés canoniques : tagline, hero\_image, badge, cta\_label, cta\_url, deployment, compatibility, support, languages, features (JSON), pricing\_tiers (JSON), infrasstudio\_published.
|
| `llx_infrasstudio_product_translation`
| Surcharges par langue des champs personnalisés traduisibles.
|
| `llx_categorie_product`
| Liens entre produits et catégories (utilisés pour la cartographie d'univers).
|
### Provisionner les champs personnalisés
Les onze champs personnalisés nécessaires ne sont pas livrés en standard avec Dolibarr. Pour les créer en une commande, utilisez le script de provisionnement générique :
```
php htdocs/custom/infrasstudio/scripts/preset_default.php \
htdocs/custom/infrasstudio/presets/keaticweb.json
```
Le fichier JSON livre les définitions par défaut (voir Chapitre 28 pour le format). Vous pouvez créer votre propre preset si vous avez besoin d'autres champs personnalisés.
### Utiliser StudioProductCatalog
La classe expose plusieurs méthodes pour interroger les produits :
```
dol_include_once('/infrasstudio/class/studioproductcatalog.class.php');
$catalog = new StudioProductCatalog($db);
// Tous les produits publiés, dans la langue courante
$products = $catalog->fetchPublishedProducts(array(), $iso2);
// Filtres
$products = $catalog->fetchPublishedProducts(array(
'univers' => 'supply-chain',
'type' => 'saas',
), $iso2);
// Un produit par référence
$product = $catalog->fetchProductBySlug('supplyflow-pro', $iso2);
// Univers utilisés (pour le filtre du catalogue)
$univers = $catalog->fetchUsedUnivers();
```
##### Format normalisé d'un produit
```
array(
'id' => 5,
'ref' => 'supplyflow-pro',
'label' => 'SupplyFlow Pro', // résolu selon la langue
'description' => 'Description...
',
'price' => 290.00,
'badge' => 'Nouveau',
'hero_image' => '/medias/...',
'cta_label' => 'Demander une démo',
'cta_url' => '/contact',
'tagline' => 'Optimisez votre supply chain...',
'deployment' => 'Cloud SaaS',
'compatibility'=> 'SAP, Oracle, Sage',
'support' => '24/7',
'languages' => 'fr,en,de',
'features' => array('Prévision IA', 'Multi-entrepôts'),
'pricing_tiers'=> array(...),
'univers' => 'supply-chain',
'type' => 'saas',
)
```
### Cartographie catégorie vers univers
Les produits sont rattachés à des catégories Dolibarr. Le module associe chaque catégorie à un univers (concept éditorial : Supply Chain, Health, Legal, etc.).
##### **Cartographie par défaut**
```
// Les six univers livrés par défaut
'supply-chain' => array(...catégories supply chain),
'health' => array(...catégories santé),
'legal' => array(...catégories juridique),
'digital-humanities' => array(...catégories sciences humaines),
'transversal' => array(...catégories outils transversaux),
'fsm' => array(...catégories field service)
```
##### **Surcharge par JSON**
Pour personnaliser, définissez la constante :
```
// Via dolibarr_set_const ou via la page de configuration admin
$conf->global->INFRASSTUDIO_PRODUCT_UNIVERS_MAP = json_encode(array(
'mon-univers' => array(12, 13, 14), // identifiants de catégories
'autre' => array(15, 16),
));
```
### StudioSolutionWrapper
Cette classe gère la génération des wrappers Apache à partir des produits publiés.
##### **Génération manuelle**
```
dol_include_once('/infrasstudio/class/studiosolutionwrapper.class.php');
require_once DOL_DOCUMENT_ROOT . '/website/class/website.class.php';
$website = new Website($db);
$website->fetch(0, 'monsite');
$wrapper = new StudioSolutionWrapper($db);
$stats = $wrapper->rebuildAll($website, '/var/www/monsite');
print_r($stats);
// array('created' => 3, 'updated' => 2, 'deleted' => 1, 'skipped' => 5)
```
##### **Anatomie d'un wrapper généré**
```
entity > 1 ? '/' . $conf->entity : '')
. '/website/monsite/page42.tpl.php';
}
if ($res === false) { http_response_code(500); print 'Failed to make include'; }
```
**Sécurité anti-collision —** Le module ne touche qu'aux wrappers qu'il a lui-même créés (présence du marqueur « StudioSolutionWrapper » dans l'en-tête du fichier). Les pages Dolibarr standards portant un slug commençant par `solution-` sont préservées.
### Configuration du générateur de wrappers
| Constante
| Rôle
|
|---|
| `INFRASSTUDIO_WEBSITE_KEY`
| Référence du site cible.
|
| `INFRASSTUDIO_PUBLIC_DOCROOT`
| Docroot Apache absolu (par exemple
`/var/www/monsite`
).
|
| `INFRASSTUDIO_SITE__WRAPPER_PREFIX`
| Préfixe des wrappers (par défaut
`solution-`
). Exemples :
`produit-`
,
`service-`
.
|
| `INFRASSTUDIO_SITE__WRAPPER_TEMPLATE_PAGEURL`
| Slug du gabarit solution-detail (par défaut
`solution-detail`
).
|
### Le gabarit solution-detail
Il s'agit d'une page Dolibarr Website classique (avec son slug et son tpl.php), mais utilisée par tous les wrappers. Elle reçoit la variable globale `$solution_ref` qui identifie le produit à afficher.
##### **Squelette type**
```
fetchProductBySlug($solution_ref, $iso2);
if (!$product) {
http_response_code(404);
print 'Produit introuvable
';
exit;
}
ob_start();
try {
?>
getMessage(); }
include dol_buildpath('/infrasstudio/core/tpl/website_output.tpl.php', 0);
```
**Mélanger slots et données produit —** Vous pouvez combiner les deux : les zones éditoriales (par exemple un titre marketing au-dessus de la grille) en slots, et les zones produit (label, prix, fonctionnalités) lues via `StudioProductCatalog`. Les deux cohabitent sans conflit.
### Le trigger PRODUCT et CATEGORY
Le module installe un trigger qui écoute :
- `PRODUCT_CREATE`
- `PRODUCT_MODIFY`
- `PRODUCT_DELETE`
- `PRODUCT_PRICE_MODIFY`
- `CATEGORY_LINK` (uniquement si l'objet lié est un produit)
- `CATEGORY_UNLINK`
À chaque événement, le trigger appelle `StudioSolutionWrapper::rebuildAll()` sur le site configuré.
**Note —** Si `INFRASSTUDIO_WEBSITE_KEY` ou `INFRASSTUDIO_PUBLIC_DOCROOT` ne sont pas configurées, le trigger se termine silencieusement. Ni bruit, ni erreur. Cette discrétion convient aux instances Dolibarr qui n'utilisent pas le catalogue dynamique.
### La tâche planifiée horaire (filet de sécurité)
Une tâche planifiée s'exécute toutes les heures et appelle `StudioSolutionWrapper::rebuildAllConfigured()`. Elle lit les constantes et relance la régénération.
Cette tâche apporte les bénéfices suivants :
- Rattrapage si un trigger a été manqué (import en masse, modification SQL directe, etc.).
- Synchronisation après une migration de serveur.
- Garantie de cohérence sans intervention manuelle.
### Reconstruction manuelle en ligne de commande
```
php htdocs/custom/infrasstudio/scripts/rebuild_solution_wrappers.php \
[entity]
# Exemple
php htdocs/custom/infrasstudio/scripts/rebuild_solution_wrappers.php \
monsite /var/www/monsite 2
```
### Aides visuelles dans le Studio
Deux indicateurs visuels accompagnent l'administrateur dans la prise en main et la maintenance d'une instance qui utilise le catalogue. Ils sont là pour signaler immédiatement les problèmes de configuration et les actions ponctuelles qui n'ont de sens qu'à un moment précis du cycle de vie d'un site.
##### **Bandeau « Produits de démonstration » dans l'éditeur Produits**
Quand un site a été créé depuis un template préfabriqué (Vibrant ou Editorial), le seed pose six produits factices catégorisés pour que le catalogue soit immédiatement peuplé et visualisable. Ces produits ont vocation à être remplacés par les vrais produits du client. L'éditeur Produits du Studio détecte automatiquement leur présence — via le préfixe de référence `demo-*` posé par le seed — et affiche un bandeau jaune en haut de la grille avec deux actions en un clic :
- **Dépublier en masse** — bascule `infrasstudio_published=0` sur les six produits démo. Ils restent dans Dolibarr (cohérents avec une éventuelle migration ultérieure) mais disparaissent du catalogue public et de l'index du site. Réversible en un clic.
- **Supprimer en masse** — efface complètement les six produits, leurs traductions `llx_product_lang`, leurs extrafields `llx_product_extrafields` et leurs liaisons à la catégorie démo. Irréversible. Une modale de confirmation Studio garde le doigt sur le bouton.
Le bandeau disparaît automatiquement dès qu'aucun produit démo n'est détecté dans l'entité courante. Aucun risque d'effacer des produits réels : la détection se base strictement sur le préfixe `demo-` et sur la liaison à la catégorie démo créée par le seed.
##### **Badge d'alerte dans la barre du Studio**
La barre supérieure du Studio (visible sur toutes les pages de l'éditeur) intègre un badge d'alerte qui clignote en rouge lorsque la configuration du catalogue présente un problème bloquant. Le badge agrège plusieurs vérifications croisées et synthétise leur état en un seul point d'attention :
- **Module InfraSStudio désactivé** sur l'entité courante (cas typique d'une migration multi-entité partiellement appliquée).
- **Tables InfraSStudio manquantes** — la classe `StudioProductCatalog` a besoin de `llx_infrasstudio_slot`, `llx_infrasstudio_media` et `llx_infrasstudio_product_translation` ; le badge s'allume si l'une d'elles est absente (échec de migration, restauration partielle).
- **Docroot Apache introuvable** — la constante `INFRASSTUDIO_PUBLIC_DOCROOT` pointe vers un chemin qui n'existe pas physiquement, ce qui empêche les wrappers `solution-*.php` d'être écrits.
- **Référence de site cassée** — la constante `INFRASSTUDIO_WEBSITE_KEY` renvoie vers un site supprimé ou inexistant.
- **Champs personnalisés produit manquants** — un ou plusieurs des onze extrafields utilisés par `StudioProductCatalog` n'existent pas dans `llx_extrafields`, ce qui dégraderait le rendu des fiches produit.
Au survol, le badge déplie une mini liste détaillée des incidents avec un lien direct vers la page Diagnostic complète, qui les résout un par un. Cette approche évite que l'administrateur découvre un dysfonctionnement par un client qui voit une page blanche, en remontant le problème **avant** que les visiteurs ne soient impactés.
### Récapitulatif
**Vous savez désormais :**
- Comprendre l'architecture du catalogue (StudioProductCatalog, StudioSolutionWrapper, gabarit, trigger, tâche planifiée).
- Provisionner les champs personnalisés produit avec le preset générique.
- Interroger les produits via `StudioProductCatalog`.
- Cartographier les catégories Dolibarr vers vos univers via `INFRASSTUDIO_PRODUCT_UNIVERS_MAP`.
- Personnaliser la cartographie des types de produit et le préfixe d'URL des fiches via les constantes catalogue.
- Activer ou désactiver le filtre `infrasstudio_published` selon que votre site utilise ou non la notion de brouillon catalogue.
- Comprendre comment `StudioSolutionWrapper::rebuildAll()` génère les wrappers Apache.
- Configurer le préfixe et le slug du gabarit par site.
- Écrire le gabarit `solution-detail` qui sert tous les produits.
- Comprendre le rôle du trigger automatique et de la tâche planifiée de sécurité.
- Lancer une reconstruction manuelle en ligne de commande.
- Utiliser le bandeau de gestion des produits de démonstration livrés avec les templates Vibrant et Editorial.
- Identifier les incidents de configuration du catalogue grâce au badge d'alerte de la barre du Studio.
**Fin de la Partie IV —** Vous maîtrisez désormais l'intégration côté développeur : préparer un site, annoter avec des slots, comprendre la grammaire, brancher des données Dolibarr, gérer le multilingue, créer vos gabarits et exploiter le catalogue dynamique. Vous êtes en mesure de livrer un site clé en main.
La Partie V aborde l'administration et la maintenance. Si vous êtes administrateur Dolibarr, c'est votre prochaine destination.
**Fin de la Partie IV —** Vous maîtrisez désormais l'intégration côté développeur : préparer un site, annoter avec des slots, comprendre la grammaire, brancher des données Dolibarr, gérer le multilingue, créer vos gabarits et exploiter le catalogue dynamique. Vous êtes en mesure de livrer un site clé en main.
La Partie V aborde l'administration et la maintenance. Si vous êtes administrateur Dolibarr, c'est votre prochaine destination.