Lenguaje y Normas de Desarrollo: Difference between revisions

m (Import interlang links (links to translated versions of this page in other languages) from origin English page "Language_and_development_rules".)
Line 12: Line 12:
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 {{PHPMinVersion}} (Debe funcionar sin ningún módulo PHP complementario, exceptuando los módulos de acceso a la base de datos).
#Todos los SO (Windows, Linux, MACOS...)
# Mysql {{MySqlMinVersion}}
#PHP {{PHPMinVersion}} (Debe funcionar sin ningún módulo PHP complementario, exceptuando los módulos de acceso a la base de datos).
#Mysql {{MySqlMinVersion}}
 
=Normas de Copyright=
 
*Todos los archivos PHP deben empezar con una cabezara como


= Normas de Copyright =
* Todos los archivos PHP deben empezar con una cabezara como
<source lang="php">
<source lang="php">
<?php
<?php
Line 32: Line 35:
Si edita un archivo existente del proyecto, debe añadir una línea de Copyright debajo de las otras.
Si edita un archivo existente del proyecto, debe añadir una línea de Copyright debajo de las otras.


= Normas PHP =
=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


* 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 $_COOKIES, $_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 $_COOKIES, $_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.
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, utilice múltiples líneas
<source lang="php">
<source lang="php">
$var1=1;$var2=1;$var3=1;
$var1=1;$var2=1;$var3=1;
Line 54: Line 59:
que es menos eficiente.
que es menos eficiente.


* las cadenas deben de ser encuadradas con comillas simples y las variables sacadas de la cadena.
*las cadenas deben de ser encuadradas con comillas simples y las variables sacadas de la cadena.
 
<source lang="php">
<source lang="php">
print 'Mi texo muestra mi '.$variable.' !';
print 'Mi texo muestra mi '.$variable.' !';
</source>
</source>


* 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
*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
 
<source lang="php">
<source lang="php">
/* Bloque de comentarios
/* Bloque de comentarios
Line 77: Line 84:
</source>
</source>


* 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.
*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.
*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).
*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).
*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:
*Ejemplo de nombre de Campos php:
{{TemplatePHPFields}}
{{TemplatePHPFields}}


= Normas SQL =
=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.


== Estructura de Tabla ==
*En la práctica, con la finalidad de set compatible con todas las precisiones de los paises, utilizaremos los siguientes tipos:
* 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
  - integer para cualquier foreign key
  - double(24,8) para cualquier importe
  - double(24,8) para cualquier importe
Line 103: Line 112:
  - date para fecha
  - date para fecha


== Clave primaria ==
==Clave primaria==
La clave primaria de una tbla se llama <tt>rowid</tt>.
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.
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 ==
==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).
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).


Line 114: Line 123:
fk_facture_fourn_fk_soc
fk_facture_fourn_fk_soc


== Clave alternativa ==
==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).
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).
Line 121: Line 130:
uk_societe_code_client
uk_societe_code_client


== Indices de rendimiento ==
==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.
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.


Line 127: Line 136:
idx_societe_user_creat
idx_societe_user_creat


== Formato de fichero DDL ==
==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:
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>
 
*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.
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>
 
*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.
Estos ficheros se guardan el la carpeta '''install/mysql/tables''' para los ficheros standards ó '''mimodulo/tables''' para las tablas llevadas por un módulo.
Line 191: Line 203:
</source>
</source>


== SQL Coding rules ==
==SQL Coding rules==
* Uso de alias / nombres de los campos
 
*Uso de alias / nombres de los campos
 
Dentro de los selects pueden utilizar alias para simplificar la redacción de las consultas:
Dentro de los selects pueden utilizar alias para simplificar la redacción de las consultas:
<source lang="sql">
<source lang="sql">
Line 199: Line 213:
Sin embargo, no debemos utilizar este alias en las consultas de actualización porque no es compatible con mysql 3.1.
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:
*¡Los SELECT * están prohibidos! Cada Select deberá especificar la lista completa de los campos para recuperar. Esto permitirá evitar confusiones. Ejemplo:
 
<source lang="sql">
<source 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'
</source>
</source>


* 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.
*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:
Ejemplo:
Line 215: Line 230:
'MU', 'MT' ó 'MS' según sea necesario. Consulte el capítulo "Los números reales, importes y cálculos" más abajo.
'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.
*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.


== Reglas de migración de base de datos ==
==Particularidades de MySQL==
* 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.


* 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.
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.
*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)
Para activarla, añada la siguiente línea en su archivo config del servidor MySql (my.cnf o my.ini)
<source lang="ini">
<source lang="ini">
Line 231: Line 249:
</source>
</source>


== Particularidades de PostgreSQL ==
==Particularidades de PostgreSQL==
Sólo los archivos de MySQL deben mantenerse.
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.
Los archivos para otras bases de datos se convierten "al vuelo" por el gestor de la base de datos.


= Normas HTML =
=Normas HTML=
 
*Todos los atributos de las etiquetas HTML deben de estar *en minúscula* y entrecomillados con *doble comilla*.


* 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.


* 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:
Por ejemplo:
<source lang="php">
<source lang="php">
Line 245: Line 264:
</source>
</source>


* 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.
*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"


* 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"
<source lang="php">
<source lang="php">
if ($conf->use_javascript_ajax) {
if ($conf->use_javascript_ajax) {
Line 254: Line 274:
</source>
</source>


* Las ventanas emergentes  no deben de ser utilizadas, exceptuando los tooltips (y quedan condicionados por el punto anterior).
*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.
*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 =
=Normas Dolibarr y plantillas de código=


== 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 '''dev/skeletons''' encontraremos 4 plantillas de código preparadas.
Para estandarizar el código y acelerar el desarrollo de nuevos componentes en Dolibarr, en la carpeta '''dev/skeletons''' encontraremos 4 plantillas de código preparadas.


* 1 que sirve de ejemplo de descriptor de módulo: '''myModule.class.php'''
*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 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 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'''
*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.
Ú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.
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 ==
==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:
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 <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).
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 memora 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 deconvierte con su TZ que es la misma que la de PHP).


Los métodos select deben traducir los campos fecha al formato de cadenta 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).
*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 <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).
 
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.
*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.
*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 ==
==Codificación UTF8/ISO==
Dolibarr guarda la información de la manera siguiente:
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.
*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).
*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).
*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 ==
==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.
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
Pruebe a realizar por ejemplo
Line 303: Line 325:
Si no es un precio que se ajuste a los parámetros de MU, MT, MS debe utilizar la función '''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 ==
==Creación de tablas==
No crear una tabla a utilizar, es decir, al '''primer uso''' del módulo.
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).
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 ==
==Logs==
Añada traces dentro de su código mediante la función  
Añada traces dentro de su código mediante la función  
<source lang="php">
<source lang="php">
Line 313: Line 335:
</source>
</source>


== Carpetas de trabajo ==
==Carpetas de trabajo==
Si tiene que crear una carpeta de trabajo, en el código, haga referencia a esta carpeta de la siguiente forma
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''''
'''DOL_DATA_ROOT.'/mimodulo''''
Line 325: Line 347:
Si necesita una carpeta de datos temporales, esta carpeta deberá ser '''DOL_DATA_ROOT.'/minmodulo/temp''''
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 y programación con objetos=
== Patrones de Diseño Creacionales (GoF) ==
==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]).
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.
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.
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) ==
==Design patterns Estructurales (GoF)==
(ver la wikipedia sobre los [http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o Design patterns]).
(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.
No hay design patterns estructurales particulares.


== Design patterns de Comportamiento (GoF) ==
==Design patterns de Comportamiento (GoF)==
(ver la wikipedia sobre los [http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o Design patterns]).
(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.
No hay design patterns de Comportamiento particulares.


== Design patterns enterprise (Martin Fowler) ==
==Design patterns enterprise (Martin Fowler)==


=== Motivos de organización del código ===
===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''':
[[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).
 
*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.
Es el antiguo principio utilizado en los lenguajes de procedimiento.
Inconveniente: Redundancia de código. Necesidad de conocer el modelo físico a desarrollar.
Inconveniente: Redundancia de código. Necesidad de conocer el modelo físico a desarrollar.
* El '''Domain Model'''
 
*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.
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.
Inconveniente: Motivo de mantenimiento complejo.
* El '''Table Module'''
 
*El '''Table Module'''
 
Un intermedio entre los 2 anteriores donde se tiene una sola clase por tabla de la base de datos.
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'''.
-> 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) ===
===Comunicación lógica de negociado - datos (ORM)===


Existen 3 tipos de conexiones:
Existen 3 tipos de conexiones:
* '''Data Gateway a tablas y filas'''  
 
*'''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.
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/).
Ejemplo: Es el método utilizado al utilizar ciertos Frameworks de ORM como '''iBatis''' (http://ibatis.apache.org/).


* El '''Active Record'''  
*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.
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.
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'''
*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.
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.
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.