Langages et normes: Difference between revisions

Jump to navigation Jump to search
m
m (suppression correction car il duplique plusieurs fois...)
Tag: 2017 source edit
 
(45 intermediate revisions by 2 users not shown)
Line 9: Line 9:
<!-- END interlang links -->
<!-- END interlang links -->


{{TemplateDocDev}}
{{TemplateDocDevFr}}


Voici les quelques règles sur le langage, la syntaxe et normes de développement en vigueur pour le projet Dolibarr :
Voici les quelques règles sur le langage, la syntaxe et normes de développement en vigueur pour le projet Dolibarr :
Line 18: Line 18:


#Tous OS (Windows, Linux, MACOS...)
#Tous OS (Windows, Linux, MACOS...)
#PHP {{PHPMinVersion}} (Doit fonctionner sans aucun module PHP complémentaire hors les modules d'accès base de donnée).
#PHP {{PHPMinVersion}} (Doit fonctionner sans aucun module PHP complémentaire hors les modules d'accès base de donnée). Voir la page [[Versions|Liste des versions, journal des modifications et compatibilités]] pour les prérequis des versions plus anciennes.
#Mysql {{MySqlMinVersion}}
#Mysql {{MySqlMinVersion}}


Line 41: Line 41:
*Dolibarr est écrit en PHP et supporte toutes versions PHP supérieures à la {{PHPMinVersion}}. Les fichiers doivent tous comporter l'extension .php
*Dolibarr est écrit en PHP et supporte toutes versions PHP supérieures à la {{PHPMinVersion}}. Les fichiers doivent tous comporter l'extension .php


*L'appel aux variables superglobales PHP doit passer par les opérateurs dédiés $_COOKIES, $_SERVER, $_ENV. Mais pour récupérer les contenus de $_GET ou $_POST, il faut passer par la fonction dolibarr [[Fonctions utiles Dolibarr|GETPOST()]] .
*L'appel aux variables superglobales PHP doit passer par les opérateurs dédiés $_COOKIE, $_SERVER, $_ENV. Mais pour récupérer les contenus de $_GET ou $_POST, il faut passer par les fonctions dolibarr [[Fonctions utiles Dolibarr|GETPOST...()]] .


Les autres opérateurs ($HTTP_SERVER_GET, ...) ayant été passés en deprecated au sein de PHP, ne doivent plus être utilisés. Ainsi le code doit fonctionner y compris quand l'option '''register_long_arrays''' est à off.
Les autres opérateurs ($HTTP_SERVER_GET, ...) ayant été passés en deprecated au sein de PHP, ne doivent plus être utilisés. Ainsi le code doit fonctionner y compris quand l'option '''register_long_arrays''' est à off.
Line 88: Line 88:
*Pas de code mort (non utilisé) dans le code principal de Dolibarr (le code utilisé uniquement par un module externe doit être inclus dans le module externe).
*Pas de code mort (non utilisé) dans le code principal de Dolibarr (le code utilisé uniquement par un module externe doit être inclus dans le module externe).


*Utiliser "include_once" pour l'inclusion de tout fichier contenant des définitions de fonction ou de classes (donc fichiers *.class.php et *.lib.php), utiliser "include" pour tout inclusion de fichier de type template ou contenant un mixte de HTML et PHP (donc fichiers *.inc.php et *.tpl.php).
*Utiliser "include_once" ou "require_once" pour l'inclusion de tout fichier contenant des définitions de fonction ou de classes (donc fichiers *.class.php et *.lib.php), utiliser "include" pour tout inclusion de fichier de type template ou contenant un mixte de HTML et PHP (donc fichiers *.inc.php et *.tpl.php).


*Le style de code a utiliser est le PSR-12 (https://www.php-fig.org/psr/psr-12/). Seules les règles "MUST" sont imposées. Notez aussi les points/exceptions suivants:
*Le style de code a utiliser est le PSR-12 (https://www.php-fig.org/psr/psr-12/). Seules les règles "MUST" sont imposées. Notez aussi les points/exceptions suivants:
Line 107: Line 107:
=Normes SQL=
=Normes SQL=


==Structure des tables et champs==
==Structure et nom des tables et champs==


*Toutes les tables sont préfixées pour éviter les conflits de nommage. Aujourd'hui, le préfixe est modifiable au moment de l'installation. Sa valeur par défaut est <tt>llx_</tt>.
*Toutes les tables sont préfixées pour éviter les conflits de nommage. Aujourd'hui, le préfixe est modifiable au moment de l'installation. Sa valeur par défaut est <tt>llx_</tt>.
Line 151: Line 151:
fk_facture_fourn_fk_soc
fk_facture_fourn_fk_soc


Note: Si vous développez votre propre module externe, il ne doit pas y avoir de clé étrangère depuis vos tables qui pointent sur les tables standards de Dolibarr. Ceci casserait les fonctionnalités de mise à jour, de réparation, de sauvegardes et de restauration.
Note: Si vous développez votre propre module externe, il ne doit pas y avoir de clé étrangère depuis vos tables qui pointent sur les tables standards de Dolibarr. Ceci casserait les fonctionnalités de mise à jour, de réparation, de sauvegardes et de restauration et ces processus ne doivent pas dépendre de la présence d'un module externe. Il vous faut donc assurer l'intégrité de manière applicative si nécessaire.


==Clés alternatives==
==Clés alternatives==
Line 257: Line 257:
Voir aussi le chapitre "Les nombres réels, montants et calculs" plus bas.
Voir aussi le chapitre "Les nombres réels, montants et calculs" plus bas.


*Les fonctions NOW, SYSDATE ou DATEDIFF sont interdites au sein des ordres SQL. S'il faut saisir la date du moment dans un champ, la valeur doit venir du PHP, par exemple par la fonction dol_now(), et non du moteur de base de données. Ceci afin d'avoir une meilleure portabilité du code mais surtout d'avoir une gestion correcte des TimeZone et ne pas dépendre du TimeZone de la base de donnée.
*Les fonctions SQL de date NOW, SYSDATE, DATEDIFF, DATE sont interdites au sein des ordres SQL. S'il faut saisir la date du moment dans un champ, la valeur doit venir du PHP, par exemple par la fonction dol_now(), et non du moteur de base de données. Ceci pour les raisons suivantes:
**afin d'avoir une meilleure portabilité du code
**avoir une gestion correcte des TimeZone et ne pas dépendre du TimeZone de la base de donnée (le timezone de réference est le timezone de PHP et le timezone de la base de données peut être différent de celui-ci, aussi les conversions de date doivent se faire toute côté PHP).
**meilleurs performances (voir exemples et commentaire plus loin)


Par exemple, on ne fera pas:
Par exemple, on ne fera pas:
Line 278: Line 281:


Un autre avantage de cette règle est que la requête peut bénéficier de l'utilisation de l'index puisqu'on compare datefield à une valeur fixe. Dans le cas du datediff, on applique un traitement sur le champ avant comparaison, rendant impossible l'utilisation de l'index de ce champ. Les conséquences sont des performances très dégradées par rapport à la version sans datediff.
Un autre avantage de cette règle est que la requête peut bénéficier de l'utilisation de l'index puisqu'on compare datefield à une valeur fixe. Dans le cas du datediff, on applique un traitement sur le champ avant comparaison, rendant impossible l'utilisation de l'index de ce champ. Les conséquences sont des performances très dégradées par rapport à la version sans datediff.
*L'instruction WITH ROLLUP est interdite :
Cette instruction ne doit pas être utilisée : Elle n'est pas gérée de la même manière par des bases de données différentes.
De plus, l'utilisation de WITH ROLLUP brise la pureté des données retournées. L'agrégation intermédiaire de génération de sous-totaux réalisée par cette instruction peut facilement être effectuée à l'aide de PHP et permet de conserver le tableau de données retourné propre (non corrompu par des données insérées artificiellement).
Outres son côté pas bien standardisé, en insérant des résultats de calculs au sein des données, donnant un résultat qui est un mixe donnée et calculs métiers d'aggrégation, la compréhension du code se trouve compliqué et même les évolutions du code sur ces agrégations plus possibles lorsque se complexifient.
*Utilisez $db->ifsql pour le IF SQL
N'incluez pas le IF dans votre requête SQL générée. Mais utilisez plutôt la méthode $db->ifsql() pour créer un SQL IF compatible avec toutes les bases de données SQL.
*Pas de DELETE CASCADE et ON UPDATE CASCADE
De telles instructions SQL sont interdites car elles contournent les règles métiers de l'application. Par exemple, s'il existe une cascade de suppression entre la table A et B, lorsque l'application exécutera le code pour supprimer un enregistrement dans A, les enfants de la table B seront également supprimés. S'il y a eu un trigger Dolibarr PHP (par exemple apporté par un module externe) sur la suppression de l'enregistrement de B (par exemple pour valider la suppression ou pour exécuter une action complémentaire), la DELETE CASCADE sera exécutée sans avoir le trigger Dolibarr PHP exécuté, manquant la validation ou les actions du déclencheur PHP du module. Donc toutes les règles métiers doivent être implémentées du même côté (côté serveur PHP), c'est la raison pour laquelle les règles métier implémentées sur Database ne sont pas autorisées (même situation que le point suivant sur les triggers Database)
==Utilisation des triggers de base de données / procédures stockées==
L'utilisation des triggers de base de données n'est pas autorisée dans le code de Dolibarr. Vous ne devriez donc rencontrer aucun problème avec ces déclencheurs.
*Les triggers de base de données ne sont pas portables. La compatibilité peut être compromise lors de la mise à jour de votre base de données.
*Les triggers de base de données sont souvent oubliés dans les outils de sauvegarde.
*Les triggers de base de données nécessitent des autorisations spéciales que vous ne possédez peut-être pas (et que vous ne devriez pas posséder) sur une base de données sécurisée classique.
*L'utilisation de triggers de base de données implique également l'inclusion de certaines « règles métier » de votre application dans la base de données, alors que la plupart des autres règles sont gérées par le code lui-même (ce qui peut créer des conflits ou rendre le code impossible à déboguer pas à pas).
*Les triggers de base de données exécutent le code en utilisant le fuseau horaire et la langue par défaut de la base de données, au lieu du fuseau horaire de référence de l'application (qui peut être différent), ce qui génère un décalage dans la base de données. De plus, la langue par défaut de l'application est également déconseillée.
*Il existe de nombreuses autres raisons pour lesquelles nous déconseillons l'utilisation des triggers de base de données dans vos développements.
L'utilisation de triggers de base de données peut certes vous faire gagner du temps lors du développement, mais constitue une très mauvaise pratique lorsque la qualité, la portabilité, la sécurité et la pérennité sont primordiales. C'est pourquoi elle est interdite, car elle est incompatible avec le haut niveau de qualité de code exigé par l'équipe Dolibarr. Les modules externes utilisant des déclencheurs de base de données peuvent également être refusés sur la plateforme, car ils ne fonctionneront pas pour plus de 50 % des utilisateurs.


==Règles de migration de base==
==Règles de migration de base==
Line 327: Line 362:
*Tous les attributs dans les balises HTML doivent être *en minuscule* et quotés avec des *doubles quote*.
*Tous les attributs dans les balises HTML doivent être *en minuscule* et quotés avec des *doubles quote*.


*Les liens href doivent être absolus en se basant sur la fonction dol_buildpath() pour obtenir un chemin absolu depuis un chemin relatif au répertoire htdocs. Pour les tags img, il faut faire appel à la fonction img_picto().
*Les liens href doivent être absolus en se basant sur la fonction dol_buildpath() obtenir un chemin absolu depuis un chemin relatif au répertoire htdocs (pour les modules externes) ou en utilisant DOL_URL_ROOT pour le code core. Pour les tags img, il faut faire appel à la fonction img_picto().


Par example:
Par example:
<syntaxhighlight lang="PHP">
<syntaxhighlight lang="PHP">
print '<a href="'.dol_buildpath('/monrep/mapage.php').'">'.img_picto('Texte alt','nompictopng','').'</a>';
print '<a href="'.dol_buildpath('/monrep/mapage.php').'">'.img_picto('Texte alt','nompictopng','').'</a>';
print '<a href="'.DOL_URL_ROOT.'/repducore/pageducore.php">'.img_picto('Texte alt','nompictopng','').'</a>';
</syntaxhighlight>
</syntaxhighlight>


Line 355: Line 391:
Par exemple:
Par exemple:


*1 fichier qui sert d'exemple de descripteur de module: '''myModule.class.php'''
*1 fichier qui sert d'exemple de descripteur de module: '''core/modules/myModule.class.php'''
*1 fichier qui sert d'exemple de code pour faire une nouvelle classe: '''skeleton_class.class.php'''
*1 fichier qui sert d'exemple de code pour faire une nouvelle classe: '''class/skeleton_class.class.php'''
*1 fichier qui sert d'exemple de code pour faire une nouvelle page: '''skeleton_page.php'''
*1 fichier qui sert d'exemple de code pour faire une nouvelle page: '''skeleton_page.php'''
*1 fichier qui sert d'exemple de code pour faire un script à exécuter en ligne de commande: '''skeleton_script.php'''
*1 fichier qui sert d'exemple de code pour faire un script à exécuter en ligne de commande: '''scripts/skeleton_script.php'''


...
...
Line 364: Line 400:
Servez-vous en comme exemple.
Servez-vous en comme exemple.
Notons que ces squelettes sont aussi utilisés par le générateur de code PHP ([[Module ModuleBuilder]]) qui est décrit dans la chapitre de développement de module Dolibarr pour accélérer vos développements.
Notons que ces squelettes sont aussi utilisés par le générateur de code PHP ([[Module ModuleBuilder]]) qui est décrit dans la chapitre de développement de module Dolibarr pour accélérer vos développements.
==Variables globales==
Certaines informations ou objets sont communs et fixes pour toute l'exécution d'une page PHP et doivent être utilisés presque partout dans le code. Pour éviter de propager partout ces
informations ou objets, ils sont stockés dans des variables globales auxquelles vous pouvez accéder partout. Ces variables globales sont initialisées au début de chaque appel PHP (dans le master.inc.php ou master.inc.php ou en haut de la page). Ces objets ne sont normalement instanciés qu’une seule fois. La liste des variables globales disponibles est définie ici :
{{Template:TemplateGlobalVariables}}
*$conf est l'objet qui contient la configuration (enregistrée dans la base de données)
*$user est l'objet de l'utilisateur actuel
*$mysoc est l'objet contenant toutes les informations sur l'entreprise actuelle
*$langs est l'objet avec la langue actuelle
*$db est le gestionnaire de base de données de la connexion actuelle à la base de données
*$hookmanager est une classe d'usine pour gérer les hooks
*$extrafields est une classe d'usine pour gérer les extrafields


==Les dates et TimeZone==
==Les dates et TimeZone==
Dolibarr se veut une application multi-utilisateur et multi-localisation. Il convient donc de stocker les dates dans le bon format. Pour éviter les problèmes de conversion, les règles suivantes doivent être appliquées:
Dolibarr est une application multi-utilisateur et multi-site. Il est donc nécessaire de stocker les dates dans le format approprié. Pour éviter les problèmes de conversion, les règles suivantes doivent être appliquées :
 
*  En mémoire, une date doit toujours être stockée au format Timestamp GMT.
*  Une date stockée en base de données correspond au Timestamp GMT de la date soumise dans la requête, en utilisant le fuseau horaire du serveur PHP. Cela ne s'applique pas aux dates mises à jour automatiquement par le moteur de base de données (champs `tms` en base de données).
 
Par exemple, le 1er janvier 1970 à 3 heures à Paris (fuseau horaire +1) équivaut à 2 heures à Greenwich (fuseau horaire 0) ; la date sera stockée en mémoire sous la forme de l'entier 7200 (2 * 3600 s) et transmise à la base de données via une requête SQL sous la chaîne '19700101030000' (PHP convertit l'entier selon son fuseau horaire, et la base de données effectue la conversion inverse en utilisant également son propre fuseau horaire, identique à celui de PHP).
 
'''Gestion des dates incluant les heures'''
 
Ainsi, toutes les méthodes d'insertion ou de mise à jour doivent convertir, lors de la génération de la requête SQL, la date stockée en mémoire (sous forme d'entier) en une chaîne de caractères compatible avec la base de données, en utilisant `db->idate` (des exemples sont disponibles dans le squelette de code).
 
De même, toutes les méthodes de sélection doivent convertir les champs de date provenant de la base de données (chaînes au format du fuseau horaire du serveur, par exemple '19700101030000') en un champ timestamp (entier) en appelant la méthode `db->jdate()`. Cela permet de stocker la date en mémoire sous forme d'entier (Timestamp GMT).
 
'''Gestion des dates sans heures (jour uniquement)'''


*Une date en mémoire doit être au format Timestamp GMT.
Pour les insertions et mises à jour, vous devez effectuer la conversion avec `db->idate(valeur, 'gmt')` ; ainsi, pour la valeur 0, vous obtiendrez '19700101000000'.
*Une date stockée en base de données contient le Timestamp issue de la date soumise dans la requête en heure <b>locale du serveur PHP</b>. Cela ne concerne pas les dates mises à jour automatiquement par la base (champ '''tms''' en base).


Ainsi le 1er janvier 1970, 3 heures à Paris (TZ=+1) = 1er janvier 1970, 2 heures à Greenwich (TZ=0) sera stocké en mémoire par 7200 et sera soumis à la base de données avec la chaine '19700101030000' (PHP convertit en heure de son TZ et la base déconvertit avec son TZ qui est le même que celui de PHP).
Toutes les méthodes de sélection doivent convertir les champs de date provenant de la base de données (chaînes au format du fuseau horaire du serveur, par exemple '19700101000000') en utilisant `$db->jdate(..., 'gmt')`.  


Les méthodes select doivent donc traduire les champs dates lus qui sont au format chaine TZ de la base ('19700101030000') par appel de la méthode db->jdate afin de récupérer une information en mémoire au format Timestamp GMT. Et les méthodes insert doivent lors de la génération de la requête convertir la date mémoire connue en variable, par la méthode db->idate (Voir exemples générés par le squelette).
'''Autres cas'''


*Les dates mises à jour automatiquement par la base (champ '''tms''' en base) contiennent le Timestamp où la modification est faite selon le timezone de la base de donnée. Les méthodes select récupèrent cette donnée en mémoire au format Timestamp GMT en appliquant également le db->jdate. Si le timezone de la base de donnée diffère de celui du PHP (un des 2 est mal réglé), il peut donc y avoir des écarts entre date de création et modification.
*Les dates mises à jour automatiquement (champ '''tms''' en base de données) contiennent un horodatage GMT correspondant au moment où la modification a été effectuée. La requête de sélection utilise également `db->jdate` (qui s'appuie sur le fuseau horaire du serveur PHP) pour convertir les données lues en un horodatage GMT en mémoire. Ainsi, si le fuseau horaire de la base de données diffère de celui du serveur PHP (par exemple, si l'un d'eux est mal configuré), vous pourriez constater des écarts entre la date de création et la date de mise à jour. Il est conseillé de ne pas se baser sur ce champ dans Dolibarr (ce champ à mise à jour automatique est principalement destiné au débogage).


*La manipulation de dates en PHP doit être faite en utilisant les fonctions dates de Dolibarr: '''dol_now(), dol_mktime(), dol_stringtotime(), dol_getdate(), dol_time_plus_duree()'''. Vous trouverez également d'autres fonctions prêtes à l'emploi dans le fichier '''date.lib.php'''.
*La manipulation des dates en PHP doit s'effectuer à l'aide des fonctions de date de Dolibarr : '''dol_now(), dol_mktime(), dol_stringtotime(), dol_getdate(), dol_time_plus_duree()'''. Vous trouverez également d'autres fonctions disponibles dans le fichier '''date.lib.php'''.


==L'encodage UTF8/ISO==
==L'encodage UTF8/ISO==
Line 412: Line 473:
</syntaxhighlight>
</syntaxhighlight>


Mais cette solution requiert de faire un include avoir la fonction versioncompare. Une alternative est d'utiliser le test suivant :
Mais cette solution requiert de faire un include avoir la fonction versioncompare. Une alternative est d'utiliser le test suivant:
<syntaxhighlight lang="PHP">
<syntaxhighlight lang="PHP">
if ((float) DOL_VERSION >= 5.0) { //mycode for 5.0 only; } // For dolibarr 5.0.*
if ((float) DOL_VERSION >= 5.0) { //mycode for 5.0 only; } // For dolibarr 5.0.*
</syntaxhighlight>
</syntaxhighlight>
<br />


==Logs==
==Logs==
Line 452: Line 511:


C'est le motif à l'ancienne utilisé dans les langages procéduraux.
C'est le motif à l'ancienne utilisé dans les langages procéduraux.
Inconvénient: Redondance du code. Nécessité de connaitre le modèle physique pour développer les parties métiers.
Inconvénient: Redondance du code. Nécessité de connaitre le modèle physique pour développer les parties métiers.


*Le '''Domain Model'''
*Le '''Domain Model'''


C'est un concept possible depuis les langages objets. Ce sont les procédures métiers (qui doivent être identifiés avant) qui servent de bases pour les classes objets.
C'est un concept possible depuis les langages objets. Ce sont les procédures métiers (qui doivent être identifiés avant) qui servent de bases pour les classes objets. C'est le modèle dit le plus "puriste".
Inconvénient : Motif complexe à maintenir.
 
Inconvénient : Motif plus complexe à maintenir.


*Le '''Table Module'''
*Le '''Table Module'''
Line 463: Line 524:
Un intermédiaire entre les 2 précédents où l'on a une instance unique de classe par table de la base de données.
Un intermédiaire entre les 2 précédents où l'on a une instance unique de classe par table de la base de données.


-> Comme le montre les squelettes de code (voir point précédent), Dolibarr se base sur le principe du '''Table Module'''.
-> Comme le montre les squelettes de code (voir chapitre précédent Normes Dolibarr et squelettes de code), Dolibarr se base sur le principe du '''Table Module''', car le plus pragmatique des 3.


===Communication Logique métier - Données (ORM)===
===Communication Logique métier - Données (ORM)===
Line 476: Line 537:
*Le '''Active Record'''
*Le '''Active Record'''


Identique au précédent, mais on se permet d'ajouter quelques fonctions métiers sur la classe, à condition que ces fonctions soient bien  propres à la table ou à la notion métier portée par l'enregistrement. C'est le pattern qui offre le meilleur rapport fonctionnalité/complexité.
Identique au précédent, mais on se permet d'ajouter quelques fonctions métiers sur la classe, à condition que ces fonctions soient bien  propres à la table ou à la notion métier portée par l'enregistrement. Jugé plus éloigné des standards scolaires de la programmation objet, c'est toutefois le pattern qui offre le meilleur rapport fonctionnalité/complexité.


Exemple: C'est le mode choisi pour les développements Dolibarr et de nombreuses autres applications PHP qui ont leur propre framework et pratiques de développement.
Exemple: C'est le mode choisi pour les développements Dolibarr et de nombreuses autres applications PHP qui ont leur propre framework et pratiques de développement.
La couche ORM de Dolibarr se limite à une couche d abstraction de la base (on développe une fois et le driver de base converti le code pour l'accès base dans la syntaxe de la base de donnée: mysql vs postgresql vs ...)


*Le '''Data Mapper'''
*Le '''Data Mapper'''
Line 485: Line 548:
Plus "puriste" sur le papier car plus proche du métier, ce mode a aussi l'inconvénient d'être très complexe et difficile à maintenir dans la réalité (l'expérience pratique constatée ne rejoignant pas les promesses de la théorie).
Plus "puriste" sur le papier car plus proche du métier, ce mode a aussi l'inconvénient d'être très complexe et difficile à maintenir dans la réalité (l'expérience pratique constatée ne rejoignant pas les promesses de la théorie).


Exemple: C'est le choix si on utilise le Framework d'ORM '''Propel''' (http://propel.phpdb.org/trac/). On le trouve donc sur des applications plus lourdes basées sur cet ORM entre autres.
Exemple: C'est le choix si on utilise des Framework d'ORM comme '''Propel''' (https://propelorm.org/). On le trouve donc sur des applications plus lourdes basées sur cet ORM entre autres.


-> Pour les développements Dolibarr, il est recommandé d'utiliser le mode de liaison '''Active Record''' qui offre les avantages d'un modèle proche du métier sans en avoir la complexité et sans trop masquer non plus la technique. C'est dans ce mode que le développement, la compréhension du code et la maintenance technique et/ou fonctionnelle semble la plus productive (ceci est toutefois un éternel débat entre les puristes et les pragmatiques, débat dans lequel personne ne peut vraiment avoir raison, car tout dépend des objectifs à atteindre).
-> Pour les développements Dolibarr, il est recommandé d'utiliser le mode de liaison '''Active Record''' qui offre les avantages d'un modèle proche du métier sans en avoir la complexité et sans trop masquer non plus la technique. C'est dans ce mode que le développement, la compréhension du code et la maintenance technique et/ou fonctionnelle semble la plus productive (ceci est toutefois un éternel débat entre les puristes et les pragmatiques, débat dans lequel personne ne peut vraiment avoir raison, car tout dépend des objectifs à atteindre).
Line 491: Line 554:
==Design Pattern d'Interface Graphique (MVC)==
==Design Pattern d'Interface Graphique (MVC)==
Il existe plusieurs design pattern pour les interfaces utilisateurs (MVC, MVP, MVVM).
Il existe plusieurs design pattern pour les interfaces utilisateurs (MVC, MVP, MVVM).
Beaucoup confonde ce design pattern avec celui consistant à utiliser un framework de templates. C'est sans rapport. Un framework de template (voir point précédent) n'est en lien qu'avec la partie "V" de ces modèles.
Beaucoup confonde ce design pattern avec celui consistant à utiliser un framework de templates. C'est sans rapport. Un framework de templates (voir point précédent) n'est en lien qu'avec la partie "V" de ces modèles.


-> Dolibarr utilise le Design Pattern '''MVC'''. La partie M est matérialisée par une classe DAO contenant les méthode CRUD (Create-Read-Update-Delete) d'accès à la table.
-> Dolibarr utilise le Design Pattern '''MVC''' (Model - Vue - Contrôleur). La partie M est matérialisée par une classe DAO contenant les méthode CRUD (Create-Read-Update-Delete) d'accès à la table.
Beaucoup de frameworks ont fait le choix de mettre la partie de code C (Controller) et la partie de code du V (vue) dans des fichiers, voir même répertoires séparés. La maintenance semble plus aisé sur la papier, en pratique, il faut sans arrêt jonglé entre n fichiers, le C étant fortement lié au V. Aussi dans Dolibarr, la séparation est faite par une simple section de commentaire. La partie de code C (Controller) est donc le code qui se trouve sont la balise
Beaucoup de frameworks ont fait le choix de mettre la partie de code C (Contrôleur) et la partie de code du V (vue) dans des fichiers, voir même répertoires séparés. La maintenance semble plus aisé sur la papier, en pratique, il faut sans arrêt jongler entre n fichiers, le C étant fortement lié au V. Aussi dans Dolibarr, la séparation est faite par une simple section de commentaire. La partie de code C (Contrôleur) est donc le code qui se trouve sont la balise
<pre>
<pre>
/*
/*
Line 507: Line 570:
</pre>
</pre>


Ce mode de séparation a eu un effet neutre sur les nouveaux développement mais a permis de réduire de manière si importante le temps requis pour la maintenance et correction de bugs qu'il n'est pas envisagé de basculer vers un autre type de séparation (oui les constats fait dans la vraie vie ne sont pas toujours ceux attendus par la théorie scolaire). L'important reste qu'il y ait toujours séparation entre le C et le V, peut importe comment est matérialisé cette séparation, du moment qu'elle l'est (Rappel: Ne pas confondre la notion de séparation du C et du V avec la notion de séparation du code pour alimenter la données d'une Vue et du code pour formater la Vue, ceci un principe de séparation relevant du Design Pattern de Vue, voir point suivant).
Ce mode de séparation a eu un effet neutre sur les nouveaux développement mais a permis de réduire de manière si importante le temps requis pour la maintenance et correction de bugs qu'il n'est pas envisagé de basculer vers un autre type de séparation (les constats faits dans la vraie vie ne sont pas toujours ceux attendus par la théorie scolaire). L'important reste qu'il y ait toujours séparation entre le C et le V pour être MVC, peu importe comment est matérialisée cette séparation, du moment qu'elle l'est (Rappel: Ne pas confondre la notion de séparation du C et du V qui relève du design pattern MVC avec la notion de séparation du code pour alimenter les données d'une Vue et du code pour formater la Vue, cette deuxième notion étant un principe de séparation relevant du Design Pattern de Vue, autrement appelé notion de templates, sans lien avec le MVC donc, voir point suivant).


==Design Pattern de Vue - Présentation==
==Design Pattern de Vue - Présentation==
Il existe des frameworks spécialisés dans le Design Pattern de Vue, la partie qui consiste à formater l'écran vue par l'utilisateur.
Il existe des frameworks spécialisés dans le Design Pattern de Vue, la partie qui consiste à formater l'écran vue par l'utilisateur.
Les vieilles versions de Dolibarr utilisaient Smarty. Ce framework est une surcouche à un Framework, déjà très puissant, de formatage d'écran nommé... PHP. Les bénéfices étant très inférieurs aux inconvénients, il a été abandonné au profit de templates PHP (fichier .tpl.php) qui restent le plus simple, le plus universel, le plus évolutif et le plus performant, des frameworks de présentation.  
Les vieilles versions de Dolibarr utilisaient Smarty. Ce framework est une surcouche à un Framework, déjà très puissant, de formatage d'écran nommé... PHP. Les bénéfices étant très inférieurs aux inconvénients, il a été abandonné au profit de templates PHP (fichiers .php ou .tpl.php) qui restent, de tous les frameworks de présentation, le plus simple, plus universel, plus évolutif, plus performant et surtout plus résilient au temps.
 
Son seul défaut est qu'il ne peut garantir à 100% les écarts d'un développeur qui irait intégrer dans la Vue, une logique sans rapport avec la présentation (donc autre que du code à vocation de génération, de formatage, de sortie HTML, de logique de test ou de boucle pour le rendering écran). Ce point est toutefois contrôlé par le mécanisme de validation du code des chefs de projets.


Son seul défaut est qu'il ne peut garantir à 100% les écarts d'un développeur qui irait intégrer dans la Vue, une logique sans rapport avec la présentation (donc autre que du code à vocation de génération, de formatage, de sortie HTML, de logique de test ou de boucle). Ce point est toutefois contrôlé par le mécanisme de validation du code des chefs de projets.
La encore, c'est l'expérience et le constat "sur le terrain" d'un meilleur rendement de productivité, d'évolution applicative et de performance qui a motivé l'abandon des frameworks de Présentation externes au profit du framework PHP.


La encore, c'est l'expérience et le constat "sur le terrain" d'un meilleur rendement de productivité qui a motivé l'abandon des frameworks de Présentation externes au profit du framework PHP.
= Règles pour définir la branche cible d'une contribution =
Les règles pour décider si une contribution (Pull Request) doit être poussée dans une ancienne branche de maintenance ou dans une branche de développement ne sont pas strictes et sont souvent définies par le bon sens (pragmatisme avant tout).
Nous pouvons nous aider du diagramme de décision disponible sur cette page [[:Category:RoadMap#Merging_PR_process_.28develop_or_maintenance_.3F.29]]

Navigation menu