31,029
edits
Tag: 2017 source edit |
mNo edit summary Tag: 2017 source edit |
||
| Line 25: | Line 25: | ||
*Tout fichier PHP doit avoir un en-tête selon le masque suivant | *Tout fichier PHP doit avoir un en-tête selon le masque suivant | ||
< | <syntaxhighlight lang="PHP"> | ||
<?php | <?php | ||
/* Copyright (C) YYYY John Doe <email@email.com> | /* Copyright (C) YYYY John Doe <email@email.com> | ||
| Line 32: | Line 32: | ||
*/ | */ | ||
... | ... | ||
</ | </syntaxhighlight> | ||
Quand vous éditez un fichier existant du projet, ajouter une ligne Copyright sous celles existantes. | Quand vous éditez un fichier existant du projet, ajouter une ligne Copyright sous celles existantes. | ||
| Line 50: | Line 50: | ||
*Quand plusieurs variables doivent être initialisées avec la même valeur, il faut utiliser plusieurs instructions: | *Quand plusieurs variables doivent être initialisées avec la même valeur, il faut utiliser plusieurs instructions: | ||
< | <syntaxhighlight lang="PHP"> | ||
$var1=1;$var2=1;$var3=1; | $var1=1;$var2=1;$var3=1; | ||
</ | </syntaxhighlight> | ||
plutôt que | plutôt que | ||
< | <syntaxhighlight lang="PHP"> | ||
$var1=$var2=$var3=1; | $var1=$var2=$var3=1; | ||
</ | </syntaxhighlight> | ||
qui est moins performant. | qui est moins performant. | ||
*Les chaines doivent être encadrées de simple quote et les variables sorties de la chaine. | *Les chaines doivent être encadrées de simple quote et les variables sorties de la chaine. | ||
< | <syntaxhighlight lang="PHP"> | ||
print 'Mon texte affiche ma '.$variable.' !'; | print 'Mon texte affiche ma '.$variable.' !'; | ||
</ | </syntaxhighlight> | ||
*Les commentaires doivent suivre la syntaxe C, ie un double antislash pour un commentaire d'une ligne et utilisation slash-étoile pour ouvrir un bloc de plusieurs lignes | *Les commentaires doivent suivre la syntaxe C, ie un double antislash pour un commentaire d'une ligne et utilisation slash-étoile pour ouvrir un bloc de plusieurs lignes | ||
< | <syntaxhighlight lang="PHP"> | ||
/* Bloc de commentaire | /* Bloc de commentaire | ||
* | * | ||
| Line 82: | Line 82: | ||
} | } | ||
</ | </syntaxhighlight> | ||
*Les fonctions doivent retourner une valeur strictement > à 0 en cas de succès, et un nombre < à 0 en cas d'erreur. | *Les fonctions doivent retourner une valeur strictement > à 0 en cas de succès, et un nombre < à 0 en cas d'erreur. | ||
| Line 175: | Line 175: | ||
Exemple '''fichier table llx_matable.sql''': | Exemple '''fichier table llx_matable.sql''': | ||
< | <syntaxhighlight lang="sql"> | ||
-- =========================================================================== | -- =========================================================================== | ||
-- Copyright (C) 2008 Author <email@author.com> | -- Copyright (C) 2008 Author <email@author.com> | ||
| Line 202: | Line 202: | ||
tms timestamp | tms timestamp | ||
)ENGINE=innodb; | )ENGINE=innodb; | ||
</ | </syntaxhighlight> | ||
Exemple '''fichier clés/index llx_matable.key.sql''': | Exemple '''fichier clés/index llx_matable.key.sql''': | ||
< | <syntaxhighlight lang="sql"> | ||
-- =========================================================================== | -- =========================================================================== | ||
-- Copyright (C) 2008 Author <email@author.com> | -- Copyright (C) 2008 Author <email@author.com> | ||
| Line 227: | Line 227: | ||
ALTER TABLE llx_matable ADD CONSTRAINT fk_matable_fk_field FOREIGN KEY (fk_field) REFERENCES llx_matablepere (rowid); | ALTER TABLE llx_matable ADD CONSTRAINT fk_matable_fk_field FOREIGN KEY (fk_field) REFERENCES llx_matablepere (rowid); | ||
</ | </syntaxhighlight> | ||
==Règles de codage SQL== | ==Règles de codage SQL== | ||
| Line 234: | Line 234: | ||
Dans le cas des select on pourra utiliser les alias pour simplifier l'écriture des requêtes: | Dans le cas des select on pourra utiliser les alias pour simplifier l'écriture des requêtes: | ||
< | <syntaxhighlight lang="sql"> | ||
select chp1, chpxxx2 as chp2 from table2 as t1, table2 as t2 where t1.chpx = t2.chpy | select chp1, chpxxx2 as chp2 from table2 as t1, table2 as t2 where t1.chpx = t2.chpy | ||
</ | </syntaxhighlight> | ||
Toutefois, il ne faut pas utiliser ces alias sur des requêtes update car non compatible avec mysql 3.1. | Toutefois, il ne faut pas utiliser ces alias sur des requêtes update car non compatible avec mysql 3.1. | ||
*Les SELECT * sont interdits ! Chaque SELECT doit spécifier la liste complète des champs à récupérer. Cela permet d'éviter les confusions. Exemple: | *Les SELECT * sont interdits ! Chaque SELECT doit spécifier la liste complète des champs à récupérer. Cela permet d'éviter les confusions. Exemple: | ||
< | <syntaxhighlight lang="sql"> | ||
SELECT field_a, field_b, field_c FROM table_1 WHERE field_d = '$id' | SELECT field_a, field_b, field_c FROM table_1 WHERE field_d = '$id' | ||
</ | </syntaxhighlight> | ||
*Dans les requêtes SQL, on quote les champs mais pas les numériques qui contiennent des montants destinés à être stockés dans des champs de type double ou real. Les quotes sur les numériques de type float provoquent parfois un stockage d'une valeur différente. Par exemple 412.62 dans le insert sera en fait stocké avec la valeur 412.61999512 en base (suite à des conversions chaines-numériques implicites) si le champ est de type double(24,8). Et seul le PHP voit 412.61999512. Les autres outils verront 412.62 donnant l'impression qu'il n'y a pas de problème. Et c'est le PHP qui a raison, il y a problème en base. En supprimant les quotes sur les numériques, cela va mieux. | *Dans les requêtes SQL, on quote les champs mais pas les numériques qui contiennent des montants destinés à être stockés dans des champs de type double ou real. Les quotes sur les numériques de type float provoquent parfois un stockage d'une valeur différente. Par exemple 412.62 dans le insert sera en fait stocké avec la valeur 412.61999512 en base (suite à des conversions chaines-numériques implicites) si le champ est de type double(24,8). Et seul le PHP voit 412.61999512. Les autres outils verront 412.62 donnant l'impression qu'il n'y a pas de problème. Et c'est le PHP qui a raison, il y a problème en base. En supprimant les quotes sur les numériques, cela va mieux. | ||
Exemple: | Exemple: | ||
< | <syntaxhighlight lang="sql"> | ||
Bon: INSERT INTO table_1 (field_txt, field_num) VALUES ('txt', 412.62) | Bon: INSERT INTO table_1 (field_txt, field_num) VALUES ('txt', 412.62) | ||
Mauvais: INSERT INTO table_1 (field_txt, field_num) VALUES ('txt', '412.62') | Mauvais: INSERT INTO table_1 (field_txt, field_num) VALUES ('txt', '412.62') | ||
</ | </syntaxhighlight> | ||
Remarque, le problème des float est général et pas seulement sur les accès base, il est présent dans tous les languages quand on travaille sur des nombres réels, aussi ils doivent être, dès que affectés, nettoyés par la fonction price2num avec le 2eme paramètre renseigné à: | Remarque, le problème des float est général et pas seulement sur les accès base, il est présent dans tous les languages quand on travaille sur des nombres réels, aussi ils doivent être, dès que affectés, nettoyés par la fonction price2num avec le 2eme paramètre renseigné à: | ||
| Line 260: | Line 260: | ||
Par exemple, on ne fera pas: | Par exemple, on ne fera pas: | ||
< | <syntaxhighlight lang="PHP"> | ||
$sql="SELECT rowid FROM table where datefield = NOW()"; | $sql="SELECT rowid FROM table where datefield = NOW()"; | ||
</ | </syntaxhighlight> | ||
mais: | mais: | ||
< | <syntaxhighlight lang="PHP"> | ||
$sql="SELECT rowid FROM table where datefield = '".$this->db->idate(dol_now())."'"; | $sql="SELECT rowid FROM table where datefield = '".$this->db->idate(dol_now())."'"; | ||
</ | </syntaxhighlight> | ||
Par exemple, on ne fera pas: | Par exemple, on ne fera pas: | ||
< | <syntaxhighlight lang="PHP"> | ||
$sql="SELECT rowid FROM table where DATEDIFF(table.datefield, NOW()) > 7"; | $sql="SELECT rowid FROM table where DATEDIFF(table.datefield, NOW()) > 7"; | ||
</ | </syntaxhighlight> | ||
mais: | mais: | ||
< | <syntaxhighlight lang="PHP"> | ||
$sql="SELECT rowid FROM table where datefield < '".$this->db->idate(dol_now() - (7 * 24 * 3600))."'"; | $sql="SELECT rowid FROM table where datefield < '".$this->db->idate(dol_now() - (7 * 24 * 3600))."'"; | ||
</ | </syntaxhighlight> | ||
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. | ||
| Line 301: | Line 301: | ||
Les requêtes "UPDATE FROM" : | Les requêtes "UPDATE FROM" : | ||
Syntax MySQL : | Syntax MySQL : | ||
< | <syntaxhighlight lang="sql"> | ||
UPDATE table_taget as target, table_source as source SET fieldtarget=source.fieldsource | UPDATE table_taget as target, table_source as source SET fieldtarget=source.fieldsource | ||
WHERE source.rowid=target.rowid; | WHERE source.rowid=target.rowid; | ||
</ | </syntaxhighlight> | ||
Syntax PgSQL: | Syntax PgSQL: | ||
< | <syntaxhighlight lang="sql"> | ||
UPDATE table_taget as target SET fieldtarget=source.fieldsource | UPDATE table_taget as target SET fieldtarget=source.fieldsource | ||
FROM table_source as source WHERE source.rowid=target.rowid; | FROM table_source as source WHERE source.rowid=target.rowid; | ||
</ | </syntaxhighlight> | ||
Il n'en existe pas dans Dolibarr, mais pour vos modules Vous devriez faire tel que : | Il n'en existe pas dans Dolibarr, mais pour vos modules Vous devriez faire tel que : | ||
< | <syntaxhighlight lang="PHP"> | ||
if ($this->db->type=='pgsql') { | if ($this->db->type=='pgsql') { | ||
$sql="UPDATE table_taget as target SET fieldtarget=source.fieldsource | $sql="UPDATE table_taget as target SET fieldtarget=source.fieldsource | ||
| Line 321: | Line 321: | ||
WHERE source.rowid=target.rowid"; | WHERE source.rowid=target.rowid"; | ||
} | } | ||
</ | </syntaxhighlight> | ||
=Normes HTML= | =Normes HTML= | ||
| Line 330: | Line 330: | ||
Par example: | Par example: | ||
< | <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>'; | ||
</ | </syntaxhighlight> | ||
*Les tables HTML doivent avoir des colonnes sans valeurs forcées, excepté pour les colonnes qui contiennent une information dont la longueur est non variable. Par exemple, une colonne avec un picto peut être forcée à with="20px". Dans les autres cas, il faut éviter de forcer la largeur des colonnes. La raison est que, dans la plupart des cas, le navigateur fait un meilleur travail pour définir automatiquement la bonne largeur des colonnes qu'en forçant manuellement les largeurs. Et ceci marche quelque soit la résolution de l'écran. | *Les tables HTML doivent avoir des colonnes sans valeurs forcées, excepté pour les colonnes qui contiennent une information dont la longueur est non variable. Par exemple, une colonne avec un picto peut être forcée à with="20px". Dans les autres cas, il faut éviter de forcer la largeur des colonnes. La raison est que, dans la plupart des cas, le navigateur fait un meilleur travail pour définir automatiquement la bonne largeur des colonnes qu'en forçant manuellement les largeurs. Et ceci marche quelque soit la résolution de l'écran. | ||
| Line 338: | Line 338: | ||
*Le javascript/ajax et l'appel aux scripts java dans les pages php est à proscrire. Si toutefois du code javascript est inclus, il doit être conditionné par le test sur "$conf->use_javascript_ajax" | *Le javascript/ajax et l'appel aux scripts java dans les pages php est à proscrire. Si toutefois du code javascript est inclus, il doit être conditionné par le test sur "$conf->use_javascript_ajax" | ||
< | <syntaxhighlight lang="PHP"> | ||
if ($conf->use_javascript_ajax) { | if ($conf->use_javascript_ajax) { | ||
... // Le code php qui génère du javascript est ici | ... // Le code php qui génère du javascript est ici | ||
} | } | ||
</ | </syntaxhighlight> | ||
*Les popups windows ne doivent pas être utilisées, sauf pour des tooltips (et restent conditionnées par le point ci-dessus). | *Les popups windows ne doivent pas être utilisées, sauf pour des tooltips (et restent conditionnées par le point ci-dessus). | ||
| Line 387: | Line 387: | ||
En PHP comme dans d'autres langages (Java par exemple), les données non entières (float, real, double) ne sont pas fiables. | En PHP comme dans d'autres langages (Java par exemple), les données non entières (float, real, double) ne sont pas fiables. | ||
Essayer de faire par exemple | Essayer de faire par exemple | ||
< | <syntaxhighlight lang="PHP"> | ||
print 239.2 - 229.3 - 9.9; | print 239.2 - 229.3 - 9.9; | ||
</ | </syntaxhighlight> | ||
Vous n'obtiendrez pas zéro mais un nombre très petit en puissance de 10 négative. Si vous obtenez zéro, vous pourrez trouvez d'autres exemples qui ne fonctionnent pas. | Vous n'obtiendrez pas zéro mais un nombre très petit en puissance de 10 négative. Si vous obtenez zéro, vous pourrez trouvez d'autres exemples qui ne fonctionnent pas. | ||
Le problème des float est général, une variable résultante de calcul de nombre réels doit SYSTEMATIQUEMENT être nettoyée par la fonction '''price2num()''' avec le 2eme paramètre renseigné à: 'MU', 'MT' ou 'MS' selon le besoin (voir doc fonction). | Le problème des float est général, une variable résultante de calcul de nombre réels doit SYSTEMATIQUEMENT être nettoyée par la fonction '''price2num()''' avec le 2eme paramètre renseigné à: 'MU', 'MT' ou 'MS' selon le besoin (voir doc fonction). | ||
< | <syntaxhighlight lang="PHP"> | ||
print price2num(239.2 - 229.3 - 9.9, 'MT'); | print price2num(239.2 - 229.3 - 9.9, 'MT'); | ||
</ | </syntaxhighlight> | ||
S'il ne s'agit pas d'un prix sur lequel s'adapte les paramètres MU, MT ou MS, il faut utiliser la fonction '''round()'''. | S'il ne s'agit pas d'un prix sur lequel s'adapte les paramètres MU, MT ou MS, il faut utiliser la fonction '''round()'''. | ||
| Line 405: | Line 405: | ||
Si votre code a besoin de faire des choses différentes selon la version de Dolibarr, vous pouvez utiliser le truc suivant pour comparer les versions | Si votre code a besoin de faire des choses différentes selon la version de Dolibarr, vous pouvez utiliser le truc suivant pour comparer les versions | ||
< | <syntaxhighlight lang="PHP"> | ||
$version=preg_split('/[\.-]/',DOL_VERSION); | $version=preg_split('/[\.-]/',DOL_VERSION); | ||
if (versioncompare($version,array(5,0,-4)) >= 0) { //mycode for 5.0 only; } // For dolibarr 5.0.* (the -4 means we include also alpha, beta, rc and rcX) | if (versioncompare($version,array(5,0,-4)) >= 0) { //mycode for 5.0 only; } // For dolibarr 5.0.* (the -4 means we include also alpha, beta, rc and rcX) | ||
</ | </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"> | ||
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> | ||
==Logs== | ==Logs== | ||
Ajouter des traces dans votre code avec la fonction | Ajouter des traces dans votre code avec la fonction | ||
< | <syntaxhighlight lang="PHP"> | ||
dol_syslog($yourmessage, LOG_INFO|LOG_DEBUG|LOG_WARNING|LOG_ERR); | dol_syslog($yourmessage, LOG_INFO|LOG_DEBUG|LOG_WARNING|LOG_ERR); | ||
</ | </syntaxhighlight> | ||
==Répertoires de travail== | ==Répertoires de travail== | ||
| Line 426: | Line 426: | ||
Le répertoire peut être créé dans votre code à l'exécution par le code suivant: | Le répertoire peut être créé dans votre code à l'exécution par le code suivant: | ||
< | <syntaxhighlight lang="PHP"> | ||
$mymoduledir=DOL_DATA_ROOT.'/monmodule'; | $mymoduledir=DOL_DATA_ROOT.'/monmodule'; | ||
dol_mkdir($mymoduledir); | dol_mkdir($mymoduledir); | ||
</ | </syntaxhighlight> | ||
Si vous avez besoin d'un répertoire qui contiendra des données temporaires, ce répertoire doit être''' DOL_DATA_ROOT.'/monmodule/temp'''' | Si vous avez besoin d'un répertoire qui contiendra des données temporaires, ce répertoire doit être''' DOL_DATA_ROOT.'/monmodule/temp'''' | ||