Lenguaje y Normas de Desarrollo: Difference between revisions

From Dolibarr ERP CRM Wiki
Jump to navigation Jump to search
Tag: 2017 source edit
 
(85 intermediate revisions by 7 users not shown)
Line 1: Line 1:
<!-- BEGIN interlang links -->
<!-- Do NOT edit this section
    Links below are automatically managed by PolyglotBot
    You can edit links on the English source page : Language_and_development_rules -->
[[en:Language_and_development_rules]]
[[de:Sprachen_und_Programmierregeln]]
[[fr:Langages_et_normes]]
[[zh:语言和开发规则]]
<!-- END interlang links -->
{{TemplateDocDesarrollo}}
{{TemplateDocDesarrollo}}
{{ToTranslate}}


He aquí algunas normas sobre el lenguaje, la sintaxis y las norma de desarrollo en vigor para el proyecto Dolibarr:
He aquí algunas normas sobre el lenguaje, la sintaxis y las norma de desarrollo en vigor para el proyecto Dolibarr:


== Versiones ==
=Versiones=


* Dolibarr debe funcionar con:
*Dolibarr debe funcionar con:
# Todos los SO (Windows, Linux, MACOS...)
# PHP 4.3 ó + (Debe funcionar sin ningún módulo PHP complementario, exceptuando los módulos de acceso a la base de datos).
# Mysql 3.1 ó +


== Normas PHP ==
#Todos los SO (Windows, Linux, MACOS...)
#PHP {{PHPMinVersion}} (Debe funcionar sin ningún módulo PHP complementario, exceptuando los módulos de acceso a la base de datos).
#Mysql {{MySqlMinVersion}}


* Dolibarr está escrito en PHP y soporta todas las versiones de PHP superiores a la 4.1. Todos los archivos deben de contener la extensión .php
=Normas de Copyright=
 
*Todos los archivos PHP deben empezar con una cabezara como
 
<syntaxhighlight lang="PHP">
<?php
/* Copyright (C) YYYY John Doe  <email@email.com>
*
* Licence information
*/
...
</syntaxhighlight>
 
Si edita un archivo existente del proyecto, debe añadir una línea de Copyright debajo de las otras.
 
=Normas PHP=
 
*Dolibarr está escrito en PHP y soporta todas las versiones de PHP superiores a la {{PHPMinVersion}}. Todos los archivos deben de contener la extensión .php
 
*La llamada a las variables superglobales PHP deben pasar a través de los operadores dedicados $_COOKIE, $_SERVER, $_ENV y a través de la función dolibarr GETPOST() para obtener el contenido de$_GET o $_POST...


* La llamada a las variables superglobales PHP deben pasar a través de los operadores dedicados $_GET, $_POST, $_COOKIES, $_SERVER, $_ENV.
Los otros operadores ($HTTP_SERVER_GET, ...) están siendo depreciados en el seno de PHP, no deben de ser ya utilizados. Por lo tanto, el código debe funcionar incluso cuando la opción '''register_long_arrays''' esté en off.
Los otros operadores ($HTTP_SERVER_GET, ...) están siendo depreciados en el seno de PHP, no deben de ser ya utilizados. Por lo tanto, el código debe funcionar incluso cuando la opción '''register_long_arrays''' esté en off.
Además de que el código debe funcionar cuando la opción de PHP '''register_globals''' esté en off (recomendado por PHP), también lo deberá hacer cuando la opción '''register_globals''' esté en on (por defecto en muchas instalaciones).
Además de que el código debe funcionar cuando la opción de PHP '''register_globals''' esté en off (recomendado por PHP), también lo deberá hacer cuando la opción '''register_globals''' esté en on (por defecto en muchas instalaciones).


* Los smart tags PHP no són utilizados. Las secciones de código deben de empezar por '''<?php'''
*Los smart tags PHP no són utilizados. Las secciones de código deben de empezar por '''<?php'''
 
*No se permite el uso de la variable '''PHP_SELF'''. Utilice en su lugar $_SERVER["PHP_SELF"]


* No se permite el uso de la variable '''PHP_SELF'''. Utilice en su lugar $_SERVER["PHP_SELF"]
*Cuando varias variables deben ser inicializadas con el mismo valor, utilice múltiples líneas


* Cuando varias variables deben ser inicializadas con el mismo valor, utilize múltiples líneas
<syntaxhighlight lang="PHP">
<pre>
$var1 = 1; $var2 = 1; $var3 = 1;
$var1=1;$var2=1;$var3=1;
</syntaxhighlight>
</pre>
en lugar de
en lugar de
<pre>
<syntaxhighlight lang="PHP">
$var1=$var2=$var3=1;
$var1 = $var2 = $var3 = 1;
</pre>
</syntaxhighlight>
qui est moins performant.
que es menos eficiente.
 
*las cadenas deben de ser con las variables sacadas de la cadena.


* Les chaines doivent être encadrés de simple quote et les variables sorties de la chaine.
<syntaxhighlight lang="PHP">
<pre>
print "Mi texo muestra mi ".$variable." !\n";
print 'Mon texte affiche ma '.$variable.' !';
</syntaxhighlight>
</pre>


* 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
*Los comentarios deben seguir la sintaxis de C, es decir, una doble barra invertida para una línea de comentario y el uso de una barra con arterisco para abrir un bloque de varias líneas
<pre>


/* Bloc de commentaire
<syntaxhighlight lang="PHP">
/* Bloque de comentarios
  *
  *
  * Fin du bloc
  * Fin el bloque
  */
  */


Line 51: Line 79:
for ($i = 1 , $i < 2 ; $i++)
for ($i = 1 , $i < 2 ; $i++)
{
{
   // commentaire sur une ligne
   // comentario de una línea
   print $i;
   print $i;
}
}


</pre>
</syntaxhighlight>
 
*Los ficheros deben ser guardados en formato Unix (LF) y no en formato Windows (CR/LF). El formato Unix es compatible con los SO Unix, Windows, Mac, mientras que el formato de archivo de texto de Windows es problemático en algunos PHP en Unix.


* Les fichiers doivent etre sauvés en format Unix (LF) et non Windows (CR/LF). Le format Unix étant compatible sur les OS Unix like, Windows, Mac, alors que le format fichier texte Windows pose problème sous certains PHP sous Unix.
*Las funciones deben devolver >0 en caso de éxito, y un número <0 en caso de error.


Les fonctions doivent retourner 0 en cas de succès, et un nombre <0 en cas d'erreur.
*Sin código muerto (no usado) en el código principal de Dolibarr (El código usado únicamente por un módulo externo debe ser incluido en el módulo externo).
A ce jour, très peu de fonctions respectent ce standard mais c'est celui vers lequel il faut tendre.


== Normes SQL ==
*Usar "include_once" para la inclusión de todo archivo que contenga definiciones de funciones o de clases (archivos *.class.php y *.lib.php), usar "include" para la inclusión de archivos de tipo template o que contenga una mezcla de HTML y PHP (archivos *.inc.php et *.tpl.php).


* 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:
*Ejemplo de nombre de Campos php:
<pre>
{{TemplatePHPFields}}
 
=Normas SQL=
 
==Estructura de Tabla==
 
*Todas las tablas tienen prefijo para evitar conflictos de nombres. A día de hoy, el prefijo está determinado y no se puede cambiar. Su valor es <tt>llx_</tt>. Sin embargo, está pendiente de considerar, en una futura versión, el poder cambiarlo en el momento de la instalación.
 
*En la práctica, con la finalidad de set compatible con todas las precisiones de los paises, utilizaremos los siguientes tipos:
 
- integer para cualquier foreign key
- double(24,8) para cualquier importe
- double(6,3) para las tasas de IVA
- real para una cantidad
- varchar para una cadena (incluidos los de longitud 1, el tipo char se está depreciando)
- timestamp para fecha+hora que deba ser actualizado automáticamente
- datetime para fecha+hora
- date para fecha
 
==Clave primaria==
La clave primaria de una tbla se llama <tt>rowid</tt>.
 
Hay unas pocas tablas que incumplen la norma ahora (ej [[Table llx_c_actioncomm]]), por razones históricas. Podrá ser estudiada una evolución para una próxima versión.
 
==Clave secundaria==
El nombre de una clave secundaria empieza con el prefijo <tt>fk_</tt> seguido por el nombre de la tabla vinculada (necesario para evitar duplicaciones globales en la base de datos, problemáticas en algunos RDBMS como postgresql), seguido del campo vinculado (para permitir diferentes claves secundarias en la misma tabla).
 
Ejemplo:
fk_facture_fourn_fk_soc
 
==Clave alternativa==
A veces no sólamente la clave primaria debe ser única. Por lo tanto, podemos añadir un índice de clave única alternativa. Este índice es llamado por un nombre que comienza con el prefijo <tt>uk_</tt> seguido por el nombre de la tabla  (necesario para evitar la duplicación de índeces globales en la base de datos, problemáticos en algunos DBMS como postgresql) y de un sufijo que caracterice a la clave (para permitir múltiples índices en una sola tabla).
 
Ejemplo:
uk_societe_code_client
 
==Indices de rendimiento==
Algunos campos se utilizan a menudo como un criterio para la búsqueda, clasificación o afiliación. Conviene en este caso, poner un índice de rendimiento. Tales índices se llamarán con un prefijo <tt>idx_</tt> seguidos del nombre de la tabla y el nombre del campo en el que el índice trabaja.
 
Ejemplo:
idx_societe_user_creat
 
==Formato de fichero DDL==
Los ficheros que contienen la definición de la estructura de la base de datos (DDL) deben de estar repartidos en dos tablas:
 
*Cada tabla se define en su propio archivo cuyo nombre es <tt>llx_''mitabla''.sql</tt>
 
Donde habrá un comentario junto a cada campo para explicar su significado.
 
*Claves de relacionales y el índice de rendimiento o otras constraints de carácter único se definen en un archivo cuyo nombre es <tt>llx_''mitable''.key.sql</tt>
 
Estos ficheros se guardan el la carpeta '''install/mysql/tables''' para los ficheros standards ó '''mimodulo/tables''' para las tablas llevadas por un módulo.
 
Ejemplos '''Fichero tabla llx_matable.sql''':
 
<syntaxhighlight lang="sql">
-- ===========================================================================
-- Copyright (C) 2008 Author <email@author.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- ===========================================================================
 
create table llx_matable
(
  rowid      integer AUTO_INCREMENT PRIMARY KEY,
  field_one  integer,
  field_two  integer NOT NULL,
  fk_field    integer,
  field_date  datetime,
  tms        timestamp
)type=innodb;
</syntaxhighlight>
 
Ejemplos '''Fichero de claves/índices llx_matable.key.sql'''
 
<syntaxhighlight lang="sql">
-- ===========================================================================
-- Copyright (C) 2008 Author <email@author.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- ===========================================================================
 
ALTER TABLE llx_matable ADD UNIQUE uk_matable_field(field_one, field_two);
 
ALTER TABLE llx_matable ADD CONSTRAINT fk_matable_fk_field FOREIGN KEY (fk_field) REFERENCES llx_matablepere (rowid);
</syntaxhighlight>
 
==SQL Coding rules==
 
*Uso de alias / nombres de los campos
 
Dentro de los selects pueden utilizar alias para simplificar la redacción de las consultas:
<syntaxhighlight lang="sql">
select chp1, chpxxx2 as chp2 from table2 as t1, table2 as t2 where t1.chpx = t2.chpy
</syntaxhighlight>
Sin embargo, no debemos utilizar este alias en las consultas de actualización porque no es compatible con mysql 3.1.
 
*¡Los SELECT * están prohibidos! Cada Select deberá especificar la lista completa de los campos para recuperar. Esto permitirá evitar confusiones. Ejemplo:
 
<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'
</pre>
</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 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.
*En las consultas SQL, entrecomillaremos los campos, pero no los numéricos que contengan cantidades que se almacenen en los campos de tipo double o real. Los entrecomillados en los numéricos de tipo float se almacenan con un valor diferente. Por ejemplo 412.62 dentro del insert se guardara con el valor 412.61999512 en base si el campo es de tipo double(24,8). Y PHP sólo ve 412.61999512. Otras herramientas verán 412.62 dando la impresión de que no hay problemas. Y PHP tiene razón, hay un problema en base. Mediante la eliminación de las comillas en los numéricos, esto irá  mejor.


Exemple:
Ejemplo:
<pre>
<syntaxhighlight lang="sql">
Bon:     INSERT INTO table_1 (field_txt, field_num) VALUES ('txt', 412.62)
Bien: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')
Mal: INSERT INTO table_1 (field_txt, field_num) VALUES ('txt', '412.62')
</pre>
</syntaxhighlight>


Remarque, le pb 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é à:
Nota, el problema de los float es general y no sólamete en el acceso a la base de datos, está presente en todos los lenguajes cuando trabajamos sobre números reales, por lo que deberán ser limpiados por la función price2num con el segundo parámetro rellenado con:
'MU', 'MT' ou 'MS' selon le besoin. (voir doc fonction)
'MU', 'MT' ó 'MS' según sea necesario. Consulte el capítulo "Los números reales, importes y cálculos" más abajo.


* Dolibarr doit fonctionner même avec l'option '''strict''' de Mysql active.
*las funciones NOW, SYSDATE ó IFNULL están prohibidas en las órdenes de SQL. Si se necesita indicar la fecha del momento en un campo, el valor debe provenir de PHP y no del motor de la base de datos. Esto además de ofrecer una mejor portabilidad del código, también permite una gestión correcta de la zona horaria.


* Les fonctions NOW ou SYSDATE sont interdites au sein des ordres SQL. S'il faut saisir la date du moment dans un champ, la valeur doit venir du PHP 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.
==Reglas de migración de base de datos==


== Normes HTML ==
*Los scripts de migración de estructura se encuentran en el directorio '''install/mysql/migration/a.b.c-x.y.z.sql'''. En un archivo de migración de n a n+1, no destruiremos una tabla (DROP TABLE) que no sea utilizada en n+1, se realizará en la migración de la versión n+1 a n+2. Esto tiene el fin de conservar las tablas depreciadas durante una versión para poder reparar una situación de error de migración.


* Tous les attributs dans les balises HTML doivent être *en minuscule* et quotés avec des *doubles quote* (Norme xhtml)
==Particularidades de MySQL==


* Les liens href doivent être absolus et se baser pour les pages sur la constante DOL_URL_ROOT qui pointe sur htdocs et pour les images se base sur l'appel de la fonction img_picto.
*Las tablas deben de estar en formato InnoDB.
Par exemple:
<pre>
print '<a href="'.DOL_URL_ROOT.'/monrep/mapage.php">'.img_picto('Texte alt','nompictopng','').'</a>';
</pre>


* Le javascript 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"
En efecto, este formato soporta claves secundarias, las eventuales restricciones que se adjuntan y la noción de integridad de transacciones requeridas para obteter datos coherentes entre tablas en la base de datos.
<pre>
 
if ($conf->use_javascript)
*Dolibarr debe trabajar incluso con la opción '''strict''' de Mysql activa.
{
 
...  // Le code php qui génère du javascript est ici
Para activarla, añada la siguiente línea en su archivo config del servidor MySql (my.cnf o my.ini)
{{MySqlStrictMode}}
 
==Particularidades de PostgreSQL==
Sólo los archivos de MySQL deben mantenerse.
Los archivos para otras bases de datos se convierten "al vuelo" por el gestor de la base de datos.
 
=Normas HTML=
 
*Todos los atributos de las etiquetas HTML deben de estar *en minúscula* y entrecomillados con *doble comilla*.
 
*Los enlaces href deben de ser absolutos. para las páginas, basarse en la function dol_buildpath(). Para las imágenes basarse en la llamada de la función img_picto.
 
Por ejemplo:
<syntaxhighlight lang="PHP">
print '<a href="'.dol_buildpath('/monrep/mapage.php').'">'.img_picto('Texte alt','nompictopng','').'</a>';
</syntaxhighlight>
 
*Las tablas HTML deben tener las columnas sin valores forcados, a excepción de las columnas que contienen información cuya longitud no es variable. Por ejemplo, una columna con una imagen puede forzarse a un with="20px". En los otros casos, hay que evitar forzar la longitud de las columnas. Esto es porque en la mayoría de los casos el navegador realiza un buen trabajo al definir automáticamente la longitud de las columnas, independientemente de la resolución de la pantalla.
 
*Javascript/ajax y la llamada a scripts java en las páginas php está fuera de las normas. Si de todas maneras se incluye código javascript, debe estar condicionado mediante el test "$conf->use_javascript_ajax"
 
<syntaxhighlight lang="PHP">
if ($conf->use_javascript_ajax) {
...  // El código PHP que genera el javascript va aquí
}
}
</pre>
</syntaxhighlight>
 
*Las ventanas emergentes  no deben de ser utilizadas, exceptuando los tooltips (y quedan condicionados por el punto anterior).
 
*Los scripts externos son escritos en Perl si no pueden serlo en php, la utilización de otro lenguaje no está prohibido, pero debe de ser discutido priero en la lista de correo de desarrollo.


* Les popups windows ne doivent pas être utilisées, sauf pour des tooltips (et restent condtionnées par le point ci-dessus).
=Normas Dolibarr y plantillas de código=


* Les scripts externes sont écrits en Perl s'ils ne peuvent l'être en php, l'utilisation d'un autre langage n'est pas interdit mais doit être discuté au préalable dans la mailing list des développeurs. Le langage devra être maitrisé par au moins 2 développeurs pour en assurer la maintenance.
==Plantillas de código==
Para estandarizar el código y acelerar el desarrollo de nuevos componentes en Dolibarr, en la carpeta '''htdocs/modulebuilder/templates''' encontraremos plantillas de código preparadas.


== Normes Dolibarr et squelettes de code ==
*1 que sirve de ejemplo de descriptor de módulo: '''myModule.class.php'''
*1 que sirve de ejemplo de código para crear una nueva clase: '''skeleton_class.class.php'''
*1 que sirve de ejemplo de código para crear una nueva página: '''skeleton_page.php'''
*1 que sirve de ejemplo de código para crear una nuevo script a ejecutar en línea de comandos: '''skeleton_script.php'''


=== Squelettes de code ===
Úsenlas como ejemplo.
Afin d'uniformiser le code et d'accélérer le développement de nouveaux composants dans Dolibarr, se trouvent dans le répertoire '''dev/skeletons''', 4 squelettes de code tout préparés.
Tenga en cuenta que estas plantillas también son utilizadas por el generador de código PHP que se describe en el capítulo de Desarrollo de módulos Dolibarr módulo para acelerar su desarrollo.


* 1 qui sert d'exemple de descripteur de module: '''myModule.class.php'''
==Las fechas y la Zona Horaria==
* 1 qui sert d'exemple de code pour faire une nouvelle classe: '''skeleton_class.class.php'''
Dolibarr es una aplicación multi-usuario y multi-ubicación. Por lo tanto, es necesario almacenar las fechas en el formato correcto. Para evitar problemas de conversión, deben aplicarse las siguientes reglas:
* 1 qui sert d'exemple de code pour faire une nouvelle page: '''skeleton_page.php'''
* 1 qui sert d'exemple de code pour faire un script à exécuter en ligne de commande: '''skeleton_script.php'''


Servez-vous en comme exemple.
*Una fecha en memoria debe de estar en formato Timestamp GMT.
Notons que ces squelettes sont aussi utilisés par le générateur de code PHP qui est décrit dans la chapitre de développement de module Dolibarr pour accélérer vos développement.
*Una fecha guardada en la base de datos contiene el Timestamp GMT en relación con la fecha que figura en la consulta en hora local <b>del servidor PHP</b>. No se trata de las fechas de actualización de la base de datos (campo '''tms''' en la base de datos).


=== Les dates et TimeZone ===
Por lo tanto, el 1 de enero de 1970, a las 3 en París (TZ=+1) = las 2 en Greenwitch (TZ=0) será almacenado en memoria 7200 y será enviado a la base de datos con la cadena '19700101030000' (PHP convierte en hora de su TZ y la base de datos la de-convierte con su TZ que es la misma que la de PHP).
Dolibarr se veut une application mutli-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:
* Une date en mémoire doit être au format Timestamp GMT.
* Une date stockée en base de données contient le Timestamp GMT en rapport avec la date soumise dans la requête en heure locale <b>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, 2 heures à Paris (TZ=+1) sera stocké en mémoire sera soumis à la base de données avec la chaine '19700101020000' (PHP convertit en heure de son TZ et la base déconvertit avec son TZ qui est le même que celui de PHP).


Les méthodes select doivent donc traduire les champs dates lus qui sont au format chaine TZ de la base ('19700101020000') 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).
Los métodos select deben traducir los campos fecha al formato de cadena TZ de la base ('19700101030000') mediante la llamada del método db->jdate para recuperar la información en memoria en formato Timestamp GMT. Y los métodos insert deben deben generar la petición convirtiendo la fecha en memoria conocida en variable, mediante el método db->idate (Ver ejemplos generados por la plantilla).


* Les dates mises à jour automatiquement par la base (champ '''tms''' en base) contiennent le Timestamp GMT au moment où la modification est faite. Les méthodes select récupèrent directement cette donnée en mémoire au format Timestamp GMT.
*Las actualizaciones automáticas de la base de datos (campo '''tms''' en la base) contienen el Timestamp GMT del momento en que se ha realizado la modificación. Los métodos select recuperan directamente este dato en memoria en formato Timestamp GMT.


=== L'encodage UTF8/ISO ===
*La manipulación de fechas en PHP debe realizarse usando las funciones de fechas de Dolibarr: '''dol_now(), dol_mktime(), dol_stringtotime(), dol_getdate(), dol_time_plus_duree()'''. También se encuentran otras funciones listas para su uso en el archivo date.lib.php.
Dolibarr stocke les informations de manière suivante:
* En base de donnée, les données sont en UTF8 ou ISO. Cela dépend du pagecode de la base, donc des options à la création de cette base. Dans tous les cas le driver d'accès base Dolibarr (dans /lib/database) s'arrange à la lecture et insertion pour convertir vers et depuis de l'UTF8.
* Les données en mémoires sont donc stockées en UTF8 (instances d'objets PHP).
* Les pages web affichées à l'écran sont au format UTF8 (avec les versions < 2.5.1, c'est le vieux paramètre $character_set du fichier conf.php qui définissait le format de sortie).


=== Les nombres réels, montants et calculs ===
==Codificación UTF8/ISO==
En PHP comme dans d'autres langages (Java par exemple), les données non entières (float, real, double) ne sont pas fiables.
Dolibarr guarda la información de la manera siguiente:
Essayer de faire par exemple
 
<pre>
*En la base de datos, los datos en UTF8 ó ISO. Esto depende del pagecode de la base de datos, y por lo tanto, de las opciones en la creación de esta base de datos. En todos los casos, el controlador de base de datos Dolibarr (dentro de /lib/database) lee e inserta por conversión desde y hacia UTF8.
*Los datos en memoria se guardan en UTF8 (instancias de objetos PHP).
*las páginas web mostradas en pantalla se encuentran en formato UTF8 (con versiones < 2.5.1, es el antiguo parámetro $character_set del fichero conf.php quien define el formato de salida).
 
==Los números reales, importes y cálculos==
Tanto en PHP como en otros lenguajes (Java, por ejemplo), los datos no enteros (float, real, double) no son fialbes.
Pruebe a realizar por ejemplo
<syntaxhighlight lang="PHP">
print 239.2 - 229.3 - 9.9;
print 239.2 - 229.3 - 9.9;
</pre>
</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.
No obtendrá 0, sino un número muy pequeño en potencia 10 negativo . Si obtiene cero, puede encontrar otros ejemplos que no funcionan.
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).
El problema de los float es general, una variable resultante del cálculo de números reales debe SISTEMATICAMENTE ser limpiada mediante la función '''price2num()''' con el segundo parámetro rellenado con: 'MU', 'MT' ó 'MS' según el caso (ver doc de la función).
<pre>
<syntaxhighlight lang="PHP">
print price2num(239.2 - 229.3 - 9.9, 'MT');
print price2num(239.2 - 229.3 - 9.9, 'MT');
</pre>
</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()'''.
Si no es un precio que se ajuste a los parámetros de MU, MT, MS debe utilizar la función '''round()'''.
 
==Creación de tablas==
No crear una tabla a utilizar, es decir, al '''primer uso''' del módulo.
Si crea un módulo que usa tablas que no se incluyen como estándar en el código de Dolibarr, asegúrese de seguir el tutorial Creación de un módulo que explica cómo incluir las tablas que se crean en la activación del módulo y no en su uso (ver más arriba).
 
==Logs==
Añada traces dentro de su código mediante la función
<syntaxhighlight lang="PHP">
dol_syslog($yourmessage, LOG_INFO|LOG_DEBUG|LOG_WARNING|LOG_ERR);
</syntaxhighlight>
 
==Carpetas de trabajo==
Si tiene que crear una carpeta de trabajo, en el código, haga referencia a esta carpeta de la siguiente forma
'''DOL_DATA_ROOT.'/mimodulo''''
 
La carpeta puede crearse en desde su código mediante el código siguiente:
<syntaxhighlight lang="PHP">
$mymoduledir=DOL_DATA_ROOT.'/mimodulo';
dol_mkdir($mymoduledir);
</syntaxhighlight>
 
Si necesita una carpeta de datos temporales, esta carpeta deberá ser '''DOL_DATA_ROOT.'/minmodulo/temp''''
 
=Patrones de Diseño y programación con objetos=
==Patrones de Diseño Creacionales (GoF)==
Design patterns definidos por el le Gang Of Four (ver la wikipedia sobre los [http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o Design patterns]).
No hay design patterns creacionales particulares.
Hay objetos cercanos a los Singleton y creados conforme al 100% en el espíritu, pero no en la sintaxis, a fin de ser compatible con PHP 4 que no es un lenguaje orientado a objetos completo.
 
==Design patterns Estructurales (GoF)==
(ver la wikipedia sobre los [http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o Design patterns]).
No hay design patterns estructurales particulares.
 
==Design patterns de Comportamiento (GoF)==
(ver la wikipedia sobre los [http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o Design patterns]).
No hay design patterns de Comportamiento particulares.
 
==Design patterns enterprise (Martin Fowler)==
 
===Motivos de organización del código===
 
[[wikipedia:Martin Fowler|Martin Fowler]] ha identificado 3 métodos de organización de código llamados '''principios''':
 
*El '''Transaction Script''' (El código es lineal en función de una acción del usuario).
 
Es el antiguo principio utilizado en los lenguajes de procedimiento.
Inconveniente: Redundancia de código. Necesidad de conocer el modelo físico a desarrollar.
 
*El '''Domain Model'''


=== Création de tables ===
Es un modelo posible desde los lenguajes orientados a objeto. Son procedimentos funcionales (que deben de ser indentificados antes) que sirven de base para las clases objeto.
Ne pas créer de table à l'utilisation, c'est-à-dire à la '''première utilisation''' du module.
Inconveniente: Motivo de mantenimiento complejo.
Si vous créez un module qui utilise des tables qui ne sont pas intégrées en standard dans le code de Dolibarr, veillez à suivre le didacticiel Créer un module qui explique comment joindre des tables qui se créent à l'activation du module et non à son utilisation (voir plus haut).


=== Logs ===
*El '''Table Module'''
Ajouter des traces dans votre code avec la fonction
dolibarr_syslog($yourmessage, LOG_INFO|LOG_DEBUG|LOG_WARNING|LOG_ERR);


=== Répertoires de travail ===
Un intermedio entre los 2 anteriores donde se tiene una sola clase por tabla de la base de datos.
Si vous avez besoin de créer un répertoire de travail, dans votre code, faites référence à ce répertoire par
DOL_DATA_ROOT.'/monmodule'.
Le répertoire peut être créé dans votre code à l'exécution par le code suivant:
<pre>
$mymoduledir=DOL_DATA_ROOT.'/monmodule';
if (! is_dir($mymoduledir)) create_exdir($mymoduledir);
</pre>


Si vous avez besoin d'un répertoire qui contiendra des données temporaires, ce répertoire doit être DOL_DATA_ROOT.'/monmodule/temp'
-> Como se muestra en el código de la plantilla (ver sección anterior) Dolibarr se basa en el principio de '''Table Module'''.


== Programmation Objet ==
===Comunicación lógica de negociado - datos (ORM)===


=== Motifs d'organisation du code: ===
Existen 3 tipos de conexiones:


'''Martin Fowler''' a identifié 3 méthodes d'organisation du code appelées '''motifs''':
*'''Data Gateway a tablas y filas'''
* Le '''Transaction Script''' (Le code est linéraire en fonction d'une action utilisateur).
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.
* 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.
Inconvénient: Motif complexe à maintenir.
* Le '''Table Module'''
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'''.
Es el más simple. Creamos una tabla por clase y cada clase es un puente con la tabla correspondiente, ver una clase por línea tabla. Una instancia de la clase será pues un registro de la tabla. La clase contiene sólo el código de acceso a líneas o columnas de tablas.


=== Communication Logique métier - Données (ORM): ===
Ejemplo: Es el método utilizado al utilizar ciertos Frameworks de ORM como '''iBatis''' (http://ibatis.apache.org/).


Il existe 3 modes de liaisons:
*El '''Active Record'''
* Le Table And Row Data Gateway
C'est le plus simple. On crée une table par classe et chaque classe est un pont avec la table correspondante, voir une classe par ligne de table. Une instance de classe étant alors un enregistrement de la table. La classe ne contient que du code d'accès aux lignes ou colonnes de tables.


Exemple: C'est le mode mis en oeuvre quand on utilise certains Frameworks d'ORM comme '''iBatis''' (http://ibatis.apache.org/).
Idéntico al anterior, pero podemos añadir algunas funciones de negociado en la clase, siempre que estas funciones sean exclusivas de la tabla o la grabación.


* Le Active Record
Ejemplo: Es el método utilizado por los desarrollos de Dolibarr y por otras muchas aplicaciones en PHP que disponen de su propio propio framework y prácticas de desarrollo.
Identique au précédent, mais on se permet d'ajouter quelques fonctions métiers sur la classe, à conditions que ces fonctions soient propres à la table ou à l'enregistrement.


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éveloppements.
*El '''Data Mapper'''


* Le Data Mapper
Las clases representan las entidades del problema y no los datos. Por lo tanto hay que doblar, triplicar... estas clases con clases de mapeo para acceder a los datos.
Les classes représentent les entités du problème et non les données. Il faut donc doubler, tripler... ces classes avec des classes Mapper pour accéder aux données.
Más "purista" en el papel ya que el negociado está más cercano, este método también tiene la desventaja de ser más complejo en la práctica.
Plus "puriste" sur le papier car plus proche du métier, ce mode a aussi l'inconvénient d'être plus complexe sur le plan pratique.
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.


Ejemplo: Es el utilizadao si utilizamos el Framework de ORM '''Propel''' (https://propelorm.org/). Lo encontraremos pues en aplicacciones más pesadas basadas en este ORM.


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).
-> Para los desarrollos de Dolibarr, es recomendado utilizar el modo '''Active Record ''' que ofrece las ventajas de un modelo cercano de negociado sin la complejidad y sin dificultar mucho la técnica. Es en este modo mediante el cual el desarrollo, la comprensión del código y el mantenimiento técnico y/o funcional parece ser la más productivo (Sin embargo, se trata de un eterno debate entre los puristas y los pragmáticos, el debate en el que nadie puede realmente estar en lo cierto, porque todo depende de los objetivos a atender).

Latest revision as of 10:25, 8 March 2024


He aquí algunas normas sobre el lenguaje, la sintaxis y las norma de desarrollo en vigor para el proyecto Dolibarr:

Versiones

  • Dolibarr debe funcionar con:
  1. Todos los SO (Windows, Linux, MACOS...)
  2. PHP 7.1.0+ (Debe funcionar sin ningún módulo PHP complementario, exceptuando los módulos de acceso a la base de datos).
  3. Mysql 5.7.7+

Normas de Copyright

  • Todos los archivos PHP deben empezar con una cabezara como
<?php
/* Copyright (C) YYYY John Doe  <email@email.com>
*
* Licence information
*/
...

Si edita un archivo existente del proyecto, debe añadir una línea de Copyright debajo de las otras.

Normas PHP

  • Dolibarr está escrito en PHP y soporta todas las versiones de PHP superiores a la 7.1.0+. Todos los archivos deben de contener la extensión .php
  • La llamada a las variables superglobales PHP deben pasar a través de los operadores dedicados $_COOKIE, $_SERVER, $_ENV y a través de la función dolibarr GETPOST() para obtener el contenido de$_GET o $_POST...

Los otros operadores ($HTTP_SERVER_GET, ...) están siendo depreciados en el seno de PHP, no deben de ser ya utilizados. Por lo tanto, el código debe funcionar incluso cuando la opción register_long_arrays esté en off. Además de que el código debe funcionar cuando la opción de PHP register_globals esté en off (recomendado por PHP), también lo deberá hacer cuando la opción register_globals esté en on (por defecto en muchas instalaciones).

  • Los smart tags PHP no són utilizados. Las secciones de código deben de empezar por <?php
  • No se permite el uso de la variable PHP_SELF. Utilice en su lugar $_SERVER["PHP_SELF"]
  • Cuando varias variables deben ser inicializadas con el mismo valor, utilice múltiples líneas
$var1 = 1; $var2 = 1; $var3 = 1;

en lugar de

$var1 = $var2 = $var3 = 1;

que es menos eficiente.

  • las cadenas deben de ser con las variables sacadas de la cadena.
print "Mi texo muestra mi ".$variable." !\n";
  • Los comentarios deben seguir la sintaxis de C, es decir, una doble barra invertida para una línea de comentario y el uso de una barra con arterisco para abrir un bloque de varias líneas
/* Bloque de comentarios
 *
 * Fin el bloque
 */

$monobjet = new MonObjet($db);
$result=$monobjet->fetch($idobject);

for ($i = 1 , $i < 2 ; $i++)
{
  // comentario de una línea
  print $i;
}
  • Los ficheros deben ser guardados en formato Unix (LF) y no en formato Windows (CR/LF). El formato Unix es compatible con los SO Unix, Windows, Mac, mientras que el formato de archivo de texto de Windows es problemático en algunos PHP en Unix.
  • Las funciones deben devolver >0 en caso de éxito, y un número <0 en caso de error.
  • Sin código muerto (no usado) en el código principal de Dolibarr (El código usado únicamente por un módulo externo debe ser incluido en el módulo externo).
  • Usar "include_once" para la inclusión de todo archivo que contenga definiciones de funciones o de clases (archivos *.class.php y *.lib.php), usar "include" para la inclusión de archivos de tipo template o que contenga una mezcla de HTML y PHP (archivos *.inc.php et *.tpl.php).
  • Ejemplo de nombre de Campos php:
- entity                         that is id for the multicompany feature
- date_creation:                 date of creation
- date_modification:             date of last modification (often field tms in database)
- date_validation:               date validation
- fk_user_creation:              id of User of creation
- fk_user_modification:          id of User of last modification
- fk_user_validation:            id of User of validation
- import_key                     contains the import code YYYYMMDDHHMMSS, if record was loaded with a mass import.

Normas SQL

Estructura de Tabla

  • Todas las tablas tienen prefijo para evitar conflictos de nombres. A día de hoy, el prefijo está determinado y no se puede cambiar. Su valor es llx_. Sin embargo, está pendiente de considerar, en una futura versión, el poder cambiarlo en el momento de la instalación.
  • En la práctica, con la finalidad de set compatible con todas las precisiones de los paises, utilizaremos los siguientes tipos:
- integer para cualquier foreign key
- double(24,8) para cualquier importe
- double(6,3) para las tasas de IVA
- real para una cantidad
- varchar para una cadena (incluidos los de longitud 1, el tipo char se está depreciando)
- timestamp para fecha+hora que deba ser actualizado automáticamente
- datetime para fecha+hora
- date para fecha

Clave primaria

La clave primaria de una tbla se llama rowid.

Hay unas pocas tablas que incumplen la norma ahora (ej Table llx_c_actioncomm), por razones históricas. Podrá ser estudiada una evolución para una próxima versión.

Clave secundaria

El nombre de una clave secundaria empieza con el prefijo fk_ seguido por el nombre de la tabla vinculada (necesario para evitar duplicaciones globales en la base de datos, problemáticas en algunos RDBMS como postgresql), seguido del campo vinculado (para permitir diferentes claves secundarias en la misma tabla).

Ejemplo: fk_facture_fourn_fk_soc

Clave alternativa

A veces no sólamente la clave primaria debe ser única. Por lo tanto, podemos añadir un índice de clave única alternativa. Este índice es llamado por un nombre que comienza con el prefijo uk_ seguido por el nombre de la tabla (necesario para evitar la duplicación de índeces globales en la base de datos, problemáticos en algunos DBMS como postgresql) y de un sufijo que caracterice a la clave (para permitir múltiples índices en una sola tabla).

Ejemplo: uk_societe_code_client

Indices de rendimiento

Algunos campos se utilizan a menudo como un criterio para la búsqueda, clasificación o afiliación. Conviene en este caso, poner un índice de rendimiento. Tales índices se llamarán con un prefijo idx_ seguidos del nombre de la tabla y el nombre del campo en el que el índice trabaja.

Ejemplo: idx_societe_user_creat

Formato de fichero DDL

Los ficheros que contienen la definición de la estructura de la base de datos (DDL) deben de estar repartidos en dos tablas:

  • Cada tabla se define en su propio archivo cuyo nombre es llx_mitabla.sql

Donde habrá un comentario junto a cada campo para explicar su significado.

  • Claves de relacionales y el índice de rendimiento o otras constraints de carácter único se definen en un archivo cuyo nombre es llx_mitable.key.sql

Estos ficheros se guardan el la carpeta install/mysql/tables para los ficheros standards ó mimodulo/tables para las tablas llevadas por un módulo.

Ejemplos Fichero tabla llx_matable.sql:

-- ===========================================================================
-- Copyright (C) 2008 Author <email@author.com>
-- 
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- ===========================================================================

create table llx_matable
(
  rowid       integer AUTO_INCREMENT PRIMARY KEY,
  field_one   integer,
  field_two   integer NOT NULL,
  fk_field    integer,
  field_date  datetime,
  tms         timestamp
)type=innodb;

Ejemplos Fichero de claves/índices llx_matable.key.sql

-- ===========================================================================
-- Copyright (C) 2008 Author <email@author.com>
-- 
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- ===========================================================================

ALTER TABLE llx_matable ADD UNIQUE uk_matable_field(field_one, field_two);

ALTER TABLE llx_matable ADD CONSTRAINT fk_matable_fk_field FOREIGN KEY (fk_field) REFERENCES llx_matablepere (rowid);

SQL Coding rules

  • Uso de alias / nombres de los campos

Dentro de los selects pueden utilizar alias para simplificar la redacción de las consultas:

select chp1, chpxxx2 as chp2 from table2 as t1, table2 as t2 where t1.chpx = t2.chpy

Sin embargo, no debemos utilizar este alias en las consultas de actualización porque no es compatible con mysql 3.1.

  • ¡Los SELECT * están prohibidos! Cada Select deberá especificar la lista completa de los campos para recuperar. Esto permitirá evitar confusiones. Ejemplo:
SELECT field_a, field_b, field_c FROM table_1 WHERE field_d = '$id'
  • En las consultas SQL, entrecomillaremos los campos, pero no los numéricos que contengan cantidades que se almacenen en los campos de tipo double o real. Los entrecomillados en los numéricos de tipo float se almacenan con un valor diferente. Por ejemplo 412.62 dentro del insert se guardara con el valor 412.61999512 en base si el campo es de tipo double(24,8). Y PHP sólo ve 412.61999512. Otras herramientas verán 412.62 dando la impresión de que no hay problemas. Y PHP tiene razón, hay un problema en base. Mediante la eliminación de las comillas en los numéricos, esto irá mejor.

Ejemplo:

Bien:INSERT INTO table_1 (field_txt, field_num) VALUES ('txt', 412.62)
Mal: INSERT INTO table_1 (field_txt, field_num) VALUES ('txt', '412.62')

Nota, el problema de los float es general y no sólamete en el acceso a la base de datos, está presente en todos los lenguajes cuando trabajamos sobre números reales, por lo que deberán ser limpiados por la función price2num con el segundo parámetro rellenado con: 'MU', 'MT' ó 'MS' según sea necesario. Consulte el capítulo "Los números reales, importes y cálculos" más abajo.

  • las funciones NOW, SYSDATE ó IFNULL están prohibidas en las órdenes de SQL. Si se necesita indicar la fecha del momento en un campo, el valor debe provenir de PHP y no del motor de la base de datos. Esto además de ofrecer una mejor portabilidad del código, también permite una gestión correcta de la zona horaria.

Reglas de migración de base de datos

  • Los scripts de migración de estructura se encuentran en el directorio install/mysql/migration/a.b.c-x.y.z.sql. En un archivo de migración de n a n+1, no destruiremos una tabla (DROP TABLE) que no sea utilizada en n+1, se realizará en la migración de la versión n+1 a n+2. Esto tiene el fin de conservar las tablas depreciadas durante una versión para poder reparar una situación de error de migración.

Particularidades de MySQL

  • Las tablas deben de estar en formato InnoDB.

En efecto, este formato soporta claves secundarias, las eventuales restricciones que se adjuntan y la noción de integridad de transacciones requeridas para obteter datos coherentes entre tablas en la base de datos.

  • Dolibarr debe trabajar incluso con la opción strict de Mysql activa.

Para activarla, añada la siguiente línea en su archivo config del servidor MySql (my.cnf o my.ini)

sql-mode="STRICT_ALL_TABLES,ONLY_FULL_GROUP_BY,NO_ZERO_DATE,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

Particularidades de PostgreSQL

Sólo los archivos de MySQL deben mantenerse. Los archivos para otras bases de datos se convierten "al vuelo" por el gestor de la base de datos.

Normas HTML

  • Todos los atributos de las etiquetas HTML deben de estar *en minúscula* y entrecomillados con *doble comilla*.
  • Los enlaces href deben de ser absolutos. para las páginas, basarse en la function dol_buildpath(). Para las imágenes basarse en la llamada de la función img_picto.

Por ejemplo:

print '<a href="'.dol_buildpath('/monrep/mapage.php').'">'.img_picto('Texte alt','nompictopng','').'</a>';
  • Las tablas HTML deben tener las columnas sin valores forcados, a excepción de las columnas que contienen información cuya longitud no es variable. Por ejemplo, una columna con una imagen puede forzarse a un with="20px". En los otros casos, hay que evitar forzar la longitud de las columnas. Esto es porque en la mayoría de los casos el navegador realiza un buen trabajo al definir automáticamente la longitud de las columnas, independientemente de la resolución de la pantalla.
  • Javascript/ajax y la llamada a scripts java en las páginas php está fuera de las normas. Si de todas maneras se incluye código javascript, debe estar condicionado mediante el test "$conf->use_javascript_ajax"
if ($conf->use_javascript_ajax) {
...  // El código PHP que genera el javascript va aquí
}
  • Las ventanas emergentes no deben de ser utilizadas, exceptuando los tooltips (y quedan condicionados por el punto anterior).
  • Los scripts externos son escritos en Perl si no pueden serlo en php, la utilización de otro lenguaje no está prohibido, pero debe de ser discutido priero en la lista de correo de desarrollo.

Normas Dolibarr y plantillas de código

Plantillas de código

Para estandarizar el código y acelerar el desarrollo de nuevos componentes en Dolibarr, en la carpeta htdocs/modulebuilder/templates encontraremos plantillas de código preparadas.

  • 1 que sirve de ejemplo de descriptor de módulo: myModule.class.php
  • 1 que sirve de ejemplo de código para crear una nueva clase: skeleton_class.class.php
  • 1 que sirve de ejemplo de código para crear una nueva página: skeleton_page.php
  • 1 que sirve de ejemplo de código para crear una nuevo script a ejecutar en línea de comandos: skeleton_script.php

Úsenlas como ejemplo. Tenga en cuenta que estas plantillas también son utilizadas por el generador de código PHP que se describe en el capítulo de Desarrollo de módulos Dolibarr módulo para acelerar su desarrollo.

Las fechas y la Zona Horaria

Dolibarr es una aplicación multi-usuario y multi-ubicación. Por lo tanto, es necesario almacenar las fechas en el formato correcto. Para evitar problemas de conversión, deben aplicarse las siguientes reglas:

  • Una fecha en memoria debe de estar en formato Timestamp GMT.
  • Una fecha guardada en la base de datos contiene el Timestamp GMT en relación con la fecha que figura en la consulta en hora local del servidor PHP. No se trata de las fechas de actualización de la base de datos (campo tms en la base de datos).

Por lo tanto, el 1 de enero de 1970, a las 3 en París (TZ=+1) = las 2 en Greenwitch (TZ=0) será almacenado en memoria 7200 y será enviado a la base de datos con la cadena '19700101030000' (PHP convierte en hora de su TZ y la base de datos la de-convierte con su TZ que es la misma que la de PHP).

Los métodos select deben traducir los campos fecha al formato de cadena TZ de la base ('19700101030000') mediante la llamada del método db->jdate para recuperar la información en memoria en formato Timestamp GMT. Y los métodos insert deben deben generar la petición convirtiendo la fecha en memoria conocida en variable, mediante el método db->idate (Ver ejemplos generados por la plantilla).

  • Las actualizaciones automáticas de la base de datos (campo tms en la base) contienen el Timestamp GMT del momento en que se ha realizado la modificación. Los métodos select recuperan directamente este dato en memoria en formato Timestamp GMT.
  • La manipulación de fechas en PHP debe realizarse usando las funciones de fechas de Dolibarr: dol_now(), dol_mktime(), dol_stringtotime(), dol_getdate(), dol_time_plus_duree(). También se encuentran otras funciones listas para su uso en el archivo date.lib.php.

Codificación UTF8/ISO

Dolibarr guarda la información de la manera siguiente:

  • En la base de datos, los datos en UTF8 ó ISO. Esto depende del pagecode de la base de datos, y por lo tanto, de las opciones en la creación de esta base de datos. En todos los casos, el controlador de base de datos Dolibarr (dentro de /lib/database) lee e inserta por conversión desde y hacia UTF8.
  • Los datos en memoria se guardan en UTF8 (instancias de objetos PHP).
  • las páginas web mostradas en pantalla se encuentran en formato UTF8 (con versiones < 2.5.1, es el antiguo parámetro $character_set del fichero conf.php quien define el formato de salida).

Los números reales, importes y cálculos

Tanto en PHP como en otros lenguajes (Java, por ejemplo), los datos no enteros (float, real, double) no son fialbes. Pruebe a realizar por ejemplo

print 239.2 - 229.3 - 9.9;

No obtendrá 0, sino un número muy pequeño en potencia 10 negativo . Si obtiene cero, puede encontrar otros ejemplos que no funcionan. El problema de los float es general, una variable resultante del cálculo de números reales debe SISTEMATICAMENTE ser limpiada mediante la función price2num() con el segundo parámetro rellenado con: 'MU', 'MT' ó 'MS' según el caso (ver doc de la función).

print price2num(239.2 - 229.3 - 9.9, 'MT');

Si no es un precio que se ajuste a los parámetros de MU, MT, MS debe utilizar la función round().

Creación de tablas

No crear una tabla a utilizar, es decir, al primer uso del módulo. Si crea un módulo que usa tablas que no se incluyen como estándar en el código de Dolibarr, asegúrese de seguir el tutorial Creación de un módulo que explica cómo incluir las tablas que se crean en la activación del módulo y no en su uso (ver más arriba).

Logs

Añada traces dentro de su código mediante la función

dol_syslog($yourmessage, LOG_INFO|LOG_DEBUG|LOG_WARNING|LOG_ERR);

Carpetas de trabajo

Si tiene que crear una carpeta de trabajo, en el código, haga referencia a esta carpeta de la siguiente forma DOL_DATA_ROOT.'/mimodulo'

La carpeta puede crearse en desde su código mediante el código siguiente:

$mymoduledir=DOL_DATA_ROOT.'/mimodulo';
dol_mkdir($mymoduledir);

Si necesita una carpeta de datos temporales, esta carpeta deberá ser DOL_DATA_ROOT.'/minmodulo/temp'

Patrones de Diseño y programación con objetos

Patrones de Diseño Creacionales (GoF)

Design patterns definidos por el le Gang Of Four (ver la wikipedia sobre los Design patterns). No hay design patterns creacionales particulares. Hay objetos cercanos a los Singleton y creados conforme al 100% en el espíritu, pero no en la sintaxis, a fin de ser compatible con PHP 4 que no es un lenguaje orientado a objetos completo.

Design patterns Estructurales (GoF)

(ver la wikipedia sobre los Design patterns). No hay design patterns estructurales particulares.

Design patterns de Comportamiento (GoF)

(ver la wikipedia sobre los Design patterns). No hay design patterns de Comportamiento particulares.

Design patterns enterprise (Martin Fowler)

Motivos de organización del código

Martin Fowler ha identificado 3 métodos de organización de código llamados principios:

  • El Transaction Script (El código es lineal en función de una acción del usuario).

Es el antiguo principio utilizado en los lenguajes de procedimiento. Inconveniente: Redundancia de código. Necesidad de conocer el modelo físico a desarrollar.

  • El Domain Model

Es un modelo posible desde los lenguajes orientados a objeto. Son procedimentos funcionales (que deben de ser indentificados antes) que sirven de base para las clases objeto. Inconveniente: Motivo de mantenimiento complejo.

  • El Table Module

Un intermedio entre los 2 anteriores donde se tiene una sola clase por tabla de la base de datos.

-> Como se muestra en el código de la plantilla (ver sección anterior) Dolibarr se basa en el principio de Table Module.

Comunicación lógica de negociado - datos (ORM)

Existen 3 tipos de conexiones:

  • Data Gateway a tablas y filas

Es el más simple. Creamos una tabla por clase y cada clase es un puente con la tabla correspondiente, ver una clase por línea tabla. Una instancia de la clase será pues un registro de la tabla. La clase contiene sólo el código de acceso a líneas o columnas de tablas.

Ejemplo: Es el método utilizado al utilizar ciertos Frameworks de ORM como iBatis (http://ibatis.apache.org/).

  • El Active Record

Idéntico al anterior, pero podemos añadir algunas funciones de negociado en la clase, siempre que estas funciones sean exclusivas de la tabla o la grabación.

Ejemplo: Es el método utilizado por los desarrollos de Dolibarr y por otras muchas aplicaciones en PHP que disponen de su propio propio framework y prácticas de desarrollo.

  • El Data Mapper

Las clases representan las entidades del problema y no los datos. Por lo tanto hay que doblar, triplicar... estas clases con clases de mapeo para acceder a los datos. Más "purista" en el papel ya que el negociado está más cercano, este método también tiene la desventaja de ser más complejo en la práctica.

Ejemplo: Es el utilizadao si utilizamos el Framework de ORM Propel (https://propelorm.org/). Lo encontraremos pues en aplicacciones más pesadas basadas en este ORM.

-> Para los desarrollos de Dolibarr, es recomendado utilizar el modo Active Record que ofrece las ventajas de un modelo cercano de negociado sin la complejidad y sin dificultar mucho la técnica. Es en este modo mediante el cual el desarrollo, la comprensión del código y el mantenimiento técnico y/o funcional parece ser la más productivo (Sin embargo, se trata de un eterno debate entre los puristas y los pragmáticos, el debate en el que nadie puede realmente estar en lo cierto, porque todo depende de los objetivos a atender).