Module development: Difference between revisions

mNo edit summary
mNo edit summary
Tag: 2017 source edit
 
(290 intermediate revisions by 24 users not shown)
Line 1: Line 1:
<!-- BEGIN origin interlang links -->
<!-- You can edit this section but do NOT remove these comments
    Links below will be automatically replicated on translated pages by PolyglotBot -->
[[fr:Développement_module]]
[[es:Desarrollo_de_un_módulo]]
[[de:Modul_Entwicklung]]
[[zh:模块开发]]
[[ja:モジュール_開発]]
<!-- END interlang links -->
[[Category:Core]]
{{TemplateDocDevEn}}
{{TemplateDocDevEn}}


To create a new module/addon ofr Dolibarr, there is several steps. This tutotial will describe you each of them to build a module to extend Dolibarr features, like one or several of the following :
To create a new module/addon for Dolibarr, there are several steps. This tutorial will describe each of them to let you build a module that extends Dolibarr features, such as:
* Add new tables in database
 
* Add your own menu entries
*Add new tables in database.
* Add new screens to edit new tables
*Add your own menu entries.
* Add predefined exports for the internal export tool
*Add new screens to edit new tables.
* Add new information boxes in the home page
*Add or remove tabs on object view (invoice, product, order, event, ...).
* Define new permissions
*Add predefined exports for the internal export tool.
* Execute code automatically triggered by a particular Dolibarr action
*Add more CSS or JS code on all or some pages
*Add new information widget in the home page.
*Add new substitutions variables.
*Define new permissions.
*Execute code automatically triggered by a particular Dolibarr action.
*Insert your code inside Dolibarr hooks positions.
*Add your numbering rule to generate the reference of objects
*Add a new document template.
*Add a new skin.
 
etc...
etc...
All those operations are possible with version 2.4 or more of Dolibarr.


The following chapters explain how to do all of this manually in an easy way.
=Module creation with the module builder=
From Dolibarr v. 12.0 it is possible to create the main pages of your module with the Module Builder. To activate it:
Go into the list of modules and enable the "Module Builder" module:
[[File:Module Builder.png|alt=Module Builder|thumb|none]]
Then click on the "bug" image in the top right of screen.[[File:Module Builder icon.png|alt=Module Builder icon|left|thumb]]
<br />
=Template of an External Module=
A good model to start development of external module can be found here : [https://github.com/Dolibarr/dolibarr/tree/develop/htdocs/modulebuilder/template GitHub Dolibarr Module Template]
=Create your module=
==Create a Module descriptor for your Module (required)==
'''When it is required''': Required as soon as an addon is developed, whatever its goal is (only adding a skin does not require a module descriptor file).
'''Since Dolibarr 9.0, you should use the ModuleBuilder module provided as a standard module to generate the module descriptor'''
===Create your module descriptor===
The first step is to create a file descriptor for the module.
*Create directory '''/htdocs/custom/''mymodule''/core/modules''' (for an external module) or '''/htdocs/''mymodule''/core/modules''' if you plan to have this module an official core module of Dolibarr. Then copy the file <code>modMyModule.class.php</code> from the directory '''htdocs/modulebuilder/template''' into this directory. Change the name of the file <code>modMyModule.class.php</code> to the name corresponding to the purpose of your module. Name of the file must start with <code>mod</code> and end with <code>.class.php</code> (for example if you want to give the name 'NewName' to this file, then the name should be <code>modNewName.class.php</code>).
Then, modify the contents of this file as follows:
*Replace all occurrences of "modMyModule" with a value which corresponds to the purpose of your module. This value must always start with 'mod' and contain only alpha characters (again, if the name given to the file was 'NewName', then replace all "modMyModule" with "modNewName").
*Change the number in: $this->numero = 100000 by a number that designates your module id. To avoid conflicts with other modules, you can consult the page that lists already reserved id numbers: [[List of modules id|List of module IDs]].
*Modify any other variables defined in the constructor (see comment in the code skeleton for their meaning).
Your file descriptor for your module is ready. See the next step to activate it.
===Test your descriptor===
Launch Dolibarr and go to page '''Setup->module'''?
If you set the property version in the module description you should see a new line with your new module and the possibility to activate it or not. If you set the property version to "develop" or "experiental", to see your module, you must first go into '''Setup-Others''' and set MAIN_FEATURES_LEVEL to 1 to see "experimental" modules or 2 to see "development" modules.


= Create a descriptor of Module (required) =
==Tree of path for new module files (required)==
'''When''': Required as soon as an addon is developped, whatever is its goal.
This is how your files must be organized when building a new module (the zip file must also match this rule).
Note: Only the second line is mandatory.


== Create your module descriptor ==
{{TemplateModuleTreeSimple}}
{{ToTranslate}}


La première étape est donc de créer un fichier descripteur du module.
==Create your SQL tables and the PHP DAO class (optional)==
Pour cela, aller dans le répertoire '''dev/skeletons''' et recopier le fichier modMyModule.class.php dans le répertoire
'''When''': If your module needs to manage data of its own
'''htdocs/includes/modules'''.
Ensuite, modifier le contenu de ce fichier afin de remplacer:
* les ''modMyModule'' en une valeur qui corresponde a la vocation de votre module. Cette valeur doit toujours commencer par 'mod'.
* $this->numero = ''10000'' par un numero de module libre (Aller dans la page Accueil -> Infos système -> Dolibarr pour connaitre la liste des id module deja utilises).
* $this->const_name = 'MAIN_MODULE_MYMODULE' par $this->const_name = 'MAIN_MODULE_XXX' où XXX doit correspondre à la valeur choisie pour remplacer MYMODULE et mis en majuscule.
* $dir = DOL_DOCUMENT_ROOT.'/mysql/tables/mymodule/'; par $dir = DOL_DOCUMENT_ROOT.'/mysql/tables/xxxxxxxx/'; ou xxxxxxxx représente le nom de votre module (sans espaces).
* Modifier éventuellement les autres variables définies dans le constructeurs (Voir le commentaire dans le code du squelette pour leur signification).


Votre fichier descripteur de votre module est alors en place.
===Create your .sql file===
If your module is designed to manage data of its own, which are not available in the standard version of Dolibarr, it is necessary to define SQL tables to store the data.


== Tester votre descripteur ==
Scripts for creating tables and loading data by your own module are saved into a subdirectory sql ('''"mymodule/sql"''') of your module. (With ModuleBuilder, the directory and all sql files will be created automatically when you will create a new Object from tab Object).


Lancer Dolibarr et aller sur la page '''Configuration->module''', vous devez voir apparaitre une nouvelle ligne avec votre nouveau module et la possibilité de l'activer ou non (parcourez tous les onglets de chaque catégories de modules jusqu'à le retrouver).
Then check into your descriptor file, into function '''init''' that the line
C'est la valeur de $this->special qui détermine dans quel onglet se trouve votre module.


= Créer vos tables SQL et la classe PHP des accesseurs (optionnel) =
<syntaxhighlight lang="PHP">$this->_load_tables('/mymodule/sql/');</syntaxhighlight>
'''Quand''': Si votre module a besoin de gérer des données qui lui sont propres


== Créer vos fichiers .sql ==
is not commented.
Si votre module a vocation à gérer des données bien a lui, qui n'existent pas en base dans la version standard de Dolibarr, il est nécessaire de définir des tables SQL pour stocker ces données.


Les fichiers propre a votre module doivent être placé dans un répertoire situé.
''Rules to follow:''


Créer un sous-répertoire '''sql''' dans le repertoire de votre module (par exemple '''htdocs/monmodule/sql''') afin d'y placer les scripts sql que vous aller créer.
*Add the files about creating tables commands on the principle of an '''llx_mytable.sql''' file per table, with an optional '''llx_mytable.key.sql''' file (see existing files in '''install/mysql/tables''' for examples).
Ensuite, dans la fonction load_tables de votre fichier descripteur de module, modifier la ligne
*The recommended type and name for SQL fields are defined into page [[Language_and_development_rules#Table_and_fields_structures]].
<pre>$dir = DOL_DOCUMENT_ROOT.'/mymodule/sql/';</pre>
*To manage data, you must create a file called '''data.sql''' inside directory '''/mymodule/sql/''' that contains SQL command to add/edit/delete data.
par
*Don't use the double quote for strings (eg 'chaine' not "chaine") because the double quote have a specific meaning in PostGreSQL
<pre>$dir = DOL_DOCUMENT_ROOT.'/monmodule/sql/';</pre>


''Règle à respecter:''
Example of content of a file data.sql
* Ajouter les fichiers d'ordre de création de vos tables sur le principe d'un fichier '''llx_matable.sql''' par table accompagné éventuellement du fichier '''llx_matable.key.sql''' (voir les fichiers existants dans '''mysql/tables''' pour exemple).
<syntaxhighlight lang="sql">
* Pour ce qui est des ordres de gestion des données, ils doivent tous se trouver dans un fichier nommé '''data.sql''' situé dans le même répertoire '''/monmodule/sql/'''.
Exemple de contenu de ficheir data.sql
  delete from llx_const where name='MYMODULE_IT_WORKS' and entity='__ENTITY__';
  delete from llx_const where name='MYMODULE_IT_WORKS' and entity='__ENTITY__';
  insert into llx_const (name, value, type, note, visible, entity) values ('MYMODULE_IT_WORKS','1','chaine','A constant vor my module',1,'__ENTITY__');
  insert into llx_const (name, value, type, note, visible, entity) values ('MYMODULE_IT_WORKS','1','chaine','A constant vor my module',1,'__ENTITY__');
</syntaxhighlight>
Files must be operational for the database mysql. Note: The files of other databases are not maintained. They will be read and converted on the fly by the driver of the other database.
===Test your .sql files===
Once the files ready, you can return to the page to enable Dolibarr modules and disable the module, drop those tables in the database (if they already exist) and reactivate the module. The tables should be recreated by the activation of the module. If this is not the case, check the Dolibarr logs, or as a first step try running your scripts manually on your database (because SQL errors from your scripts may not show up in the Dolibarr logs).
===Generate the PHP DAO class===
The DAO PHP files should have been generated by ModuleBuilder after creating an object.
You can however create them manually by copying existing object however using ModuleBuilder is highly recommended. You should find examples into '''htdocs/modulebuilder/templates/class/myobject.class.php'''
In this class, there are already operational CRUD (Create/Read/Update/Delete) methods to perform an insert, a fetch (select), an update, a delete of a table row. Edit the file to use the correct module name, tables and place this file in the class subdirectory of the module. The Module Builder allows you to do this with just a few mouse clicks.
==The tab management (optional)==
===Add or remove your own tabs on object sheets===
'''When''': To add a tab on an object (invoices, orders, proposals, member ...)
To do this go into the file descriptor of module previously created and edit the $this->tabs array:
<syntaxhighlight lang="PHP">
// Array to add new pages in new tabs or remove existing one
$this->tabs = array('objecttype:+tabname1:Title1:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mypagetab1.php?id=__ID__'    // To add a new tab identified by code tabname1
                            'objecttype:+tabname2:Title2:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mypagetab2.php?id=__ID__',  // To add a new tab identified by code tabname2
                            'objecttype:-tabname');                                                    // To remove an existing tab identified by code tabname
</syntaxhighlight>
The table should contain a list of strings, each string representing a new tab.
The format of the string consisting of 5 parts separated by ":"
*Part 1: The element type (object type) where the tab should appear is a value from the following:
{{TemplateModuleTabs}}
*Part 2: A code to identify tab to add (start with +tabname1) or to remove (start with -tabname1)
*Part 3: The title of the tab(Title1). This can be a hardcoded read or better a code translation in module lang file .
*Part 4: The name of the file "*.lang" (mylangfile@mymodule) which contains correspondence between the code translation and language to display. If this name is followed with @mymodule, Dolibarr will search translation file "*.lang" within the module in htdocs/custom/mymodule/langs/code_CODE/mylangfile.lang, otherwise Dolibarr will look for file in htdocs/langs/code_CODE/mylangfile.lang
*Part 5: A condition to test if tab must be visible($user->rights->mymodule->read) '''or''' put 1 to be always visible.
*Part 6: The URL of the page to display when you click on the tab (/mymodule/mypagetab1.php). The __ID__ string will be replaced automatically by the Id of the element concerned.
To feed the contents of the tab with data from the database, see the next chapter.
In order to get the names  'tabname' of existing tabs, you have to check the names used in the function 'product_prepare_head' of the file  'core/lib/module.lib.php' corresponding to section '$head[$h][2]'.
===Show tabs navigation into your own pages===
'''When''': To show all standard tabs of an object (product, tiers, etc.) on your page.
You must follow these steps :
'''1. Include files you need into your file'''
For each object type, there are two files to include with line
<syntaxhighlight lang="PHP">require_once($url_fichier) ;</syntaxhighlight>
This is example of files to include (DOL_DOCUMENT_ROOT is often dolibarr/htdocs/) :
*Object thirdparty (thirdparty) :
**DOL_DOCUMENT_ROOT/societe/class/societe.class.php
**DOL_DOCUMENT_ROOT/core/lib/company.lib.php
*Object product (product) :
**DOL_DOCUMENT_ROOT/product/class/product.class.php
**DOL_DOCUMENT_ROOT/core/lib/product.lib.php
*Object invoice (invoice) :
**DOL_DOCUMENT_ROOT/compta/facture/class/facture.class.php
**DOL_DOCUMENT_ROOT/core/lib/invoice.lib.php
...
'''2. Create and load the object to show into your tab'''
Create an instance of an object of the correct class and load object from the database by using the fetch method of an object in providing to this method the id you get from URL (ie : /mytab.php?id=1).
''Example :''
<syntaxhighlight lang="PHP">
$id=GETPOST('id','int');
$ref=GETPOST('ref','alpha');
$product = new Product($db) ;
$result = $product->fetch($id,$ref) ; // Test $result to check the database read is ok
</syntaxhighlight>
'''3. Get a list of all tabs to show for your object type'''
Use function XXX_prepare_head($obj), where XXX is name of object. This will return an array with all definition of tab entries to show. The parameter to put into this method is the instance of an object you want tabs.
The resulting array has the following structure
<syntaxhighlight lang="PHP">
$head        // Array of tabs
$head[$h]    // Element to describe one tab.
$head[$h][0] // Url of page to show when you click on tab
$head[$h][1] // Title of tab
$head[$h][2] // Code name to identify the tab
</syntaxhighlight>
''Example :''
<syntaxhighlight lang="PHP">
$head = product_prepare_head($product, $user) ; // parameter $user is present for some function anly
</syntaxhighlight>
'''4. show tabs on your page'''
Use the <code>dol_fiche_head()</code> function to show all tabs defined in the <code>$head</code> array returned by <code>XX_prepare_head()</code>.
<syntaxhighlight lang="PHP">
dol_fiche_head($links, $active='0', $title='', $notab=0, $picto='')
//$links  // Tableau des onglets, appelé $head plus haut.
//$active // Onglet actif (mettre le nom de l'onglet défini dans votre fichier de module, ou un nom contenu dans $head[$h][2]). Cet onglet sera mis en surbrillance
//$title  // Title to show (shown into a special tab that you can't click)
//$notab
//$picto  // Name of image to show into title. Possible values are:
//            product
//            service
//            company
</syntaxhighlight>
This function will show required tabs and open an html element ''< div class="" >'' that correspond to the area under the tabs. To close area of a tab, just use ''< /div >'' into your PHP page.


Les fichiers doivent être opérationnels pour la base de données '''mysql'''.
==Create or modify PHP screens (optional)==
Rem: Les fichiers des autres bases ne sont pas à maintenir. Ils sont lus et convertit à la volée par le driver de la base de données.
'''When''': If the purpose of your module is to add features that require new or modified screens.


== Tester vos fichier .sql ==
===Create a new PHP screen===
You must then create your PHP pages that will show/edit data from tables using the skeleton templates provided as an example in the directory '''modulebuilder/myobject_page.php''' (For the development of a script from the command line, see [[Script development]]).


Une fois les fichiers prêts, vous pouvez retourner sous Dolibarr puis désactiver le module, dropper les tables en base et réactiver le module.
To create a new user screen, create a subdirectory of '''htdocs''' (if not already done) for your module (in '''htdocs/mymodule''' for example) to store the pages you will create.
Les tables doivent alors être recréées par l'activation du module.
Si tel n'est pas le cas, vérifiez vos scripts en les passant à la main, ou consultez les logs Dolibarr.


== Générer la classe PHP d'accès ==
Copy, into that directory, the file '''myobject_page.php''' that will serve as a starting point for your page file.
Edit the file to have a correct relative path to the main.inc.php file.
<syntaxhighlight lang="PHP">
// Load Dolibarr environment
$res=0;
// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
// Try main.inc.php using relative path
if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
if (! $res) die("Include of main fails");
</syntaxhighlight>
As you can see, there are several tries to load the main.inc.php (or master.inc.php). The goal is to succeed in the most cases as possible. The minimum is 2 lines: one to try to load the master/main.inc.php into the dolibarr root directory and another one to try to load the file to support the case when the module is deployed into the "custom" directory. But you can have more to deal more situation. The provided example should be able to load the file main/master.inc.php in nearly all situation/setups.


Une fois votre ou vos tables créées en base, aller dans le répertoire '''dev/skeletons''' et lancez le script
Note that you may add more "../" depending on the depth of the file relative to your module directory tree.
<pre>php build_class_from_table.php nomtable</pre>
Remarque: Si la commande ne fonctionne pas, essayer d'utiliser php-cli plutot que php.


Ceci génèrera un fichier '''out.nomtable.class.php''' qui contient la classe de gestion de la table nomtable.
It's in the main.inc.php file that is loaded technical environment variables and permissions. The following variables are objects positioned in this file:
Dans cette classe, se trouve des méthodes CRUD (Create/Read/Update/Delete) déjà opérationnelles pour faire un insert, un fetch (select), un update, un delete d'une ligne de la table.
Supprimer juste le "out" du nom de fichier et placer votre fichier dans un sous-répertoire de '''htdocs''' propre à votre module (Dans '''htdocs/monmodule''' par exemple).


Un fichier '''out.nomtable_script.php''' a également été généré et contient un exemple de code pour utiliser la classe pour chacune des 4 méthodes CRUD.
*$user    Object that contains the characteristics of the user + his permissions.
*$conf    Object that contains Dolibarr configuration.
*$db      Object that contains an opened connection handler to the database.
*$langs  Object that contains the user's language.


= Ajouter vos onglets sur les fiches entités (optionnel) =
Then enter your code to display the page.
'''Quand''': Pour ajouter un onglet sur une fiche entité (facture, commande, proposition commercial, adhérent...)


Pour cela, aller dans le fichier descripteur de module précédemment créé et modifier le tableau $this->tabs:
*To include a class or library dedicated to the module is done using a Dolibarr function (and not using directly include_once):
<pre>
// Array to add new pages in new tabs
$this->tabs = array('product:ComposedProducts:@composition:/composition/show_composition.php?id=__ID__');
// where entity can be
// 'thirdparty'      to add a tab in third party view
// 'intervention'    to add a tab in intervention view
// 'supplier_order'  to add a tab in supplier order view
// 'supplier_invoice' to add a tab in supplier invoice view
// 'invoice'          to add a tab in customer invoice view
// 'order'            to add a tab in customer order view
// 'product'          to add a tab in product view
// 'propal'          to add a tab in propal view
// 'member'          to add a tab in fundation member view
</pre>


Le tableau doit contenir une liste de chaine, chaque chaine représentant un nouvel onglet.
''Example :''
Le format de la chaine étant composée de 4 parties séparées par ":"
<syntaxhighlight lang="PHP">
* Partie 1: Le code entité dans lequel doit apparaitre l'onglet qui est une valeur parmi celle-ci:
dol_include_once('/mymodule/class/myclass.class.php', 'MyClass');
** 'thirdparty'
</syntaxhighlight>
** 'intervention'
** 'supplier_order'
** 'supplier_invoice'
** 'invoice'
** 'order'
** 'product'
** 'propal'
** 'member'
* Partie 2: Le titre de l'onglet. Cela peut être un libellé en dur ou mieux un code traduction présent dans un fichier lang.
* Partie 3: Le nom du fichier .lang qui contient la correspondance entre le code traduction et le libellé à afficher.
* Partie 4: L'url de la page à afficher quand on clique sur l'onglet. La chaine __ID__ sera remplacée automatiquement par l'Id de l'entité concernée.


Pour alimenter le contenu de l'onglet avec des données issues de la base, voir le chapitre suivant.
*To include classes provided with Dolibarr, use the following syntax:


= Créer vos pages écran PHP (optionnel) =
''Example :''
'''Quand''': Si l'objet de votre module est d'ajouter des fonctionnalités qui nécessitent de nouveaux écrans.
<syntaxhighlight lang="PHP">
require_once DOL_DOCUMENT_ROOT.'/core/class/doli.class.php';
</syntaxhighlight>


== Créer une page écran PHP ==
===Add some fields into existing forms===
Vous devez ensuite créer vos pages PHP qui se basent sur les données de vos tables en utilisant les squelettes fournis comme exemple dans le répertoire '''dev/skeletons''' (Pour le développement d'un script en ligne de commande, voir [[Developpement_script]]).
You may want to provide a module that adds more fields into forms (input and view) of some elements.  


Pour créer une nouvelle page écran utilisateur, créer un sous-répertoire de '''htdocs''' (si non déjà fait) propre à votre module (Dans '''htdocs/monmodule''' par exemple) afin d'y placer les pages que vous aller créer.
A heavy solution (but not so bad) may be to replace all pages used to create element (this means disabling the "New element" menu entry and adding yours, and disabling the tab that shows the element to replace with a tab that is your own full page (copied/pasted from original) to do same than original page but modified to add your fields and stored added data into your own table). Go to menu [[#Define your entries in the menu (optional)]] and [[#The tab management (optional)]] if this solution suits you (this solution is more powerful since you can change everything you want into the page).  


Y recopier le fichier '''skeletons_page.php''' qui va servir de point de départ à votre page ainsi que le fichier '''pre.inc.php'''.
We will describe here another solution, that works only to "add fields" at end of existing fields, using the element "category" as an example but you can convert this tutorial for invoice, proposal ...
Modifier le fichier '''pre.inc.php''' afin que le chemin relatif du
<pre>
include("../../main.inc.php)";
</pre>
soit correct, en fonction de la profondeur de répertoire dans laquelle se trouve le fichier '''pre.inc.php''' (Enlever ou supprimer des "../").
C'est dans le main qu'est chargé l'environnement technique ainsi que les habilitations. Les variables objets suivantes sont alors positionnées:


* $user    L'objet qui contient les caractéristiques de l'utilisateur + ses droits.
*First thing is to add a table, owned by your module, to store the value of new fields. This table will only have one column called <code>rowid</code> (will contain the same value as the <code>rowid</code> column in the element table) + one column for each new field you want to add. Then, create a class with CRUD (Create/Read/Update/Delete) methods for this new table. For those two tasks, go back to the previous chapter [[#Create your SQL tables and the PHP DAO class (optional)]].
* $conf    L'objet qui contient la configuration de Dolibarr.
*Next step is to add a hook into your module to add the new fields into the form. See chapter [[Hooks_system#Implement_the_Hook]] for generic documentation to use hooks.
* $db      L'objet qui contient le handler de connexion ouvert à la base de donnée.
* $langs  L'objet qui contient la langue de l'utilisateur.


Saisissez ensuite votre code pour afficher la page.
If you follow this tutorial, to be able to add fields into category forms, you must do:
{{ToComplete}}


== Accès à la base ==
===Add/replace part of fields supported by hooks===
Si vous avez besoin de réaliser des modifications en base dans votre propre table ajouté, utilisez la classe générée plus haut.
See chapter [[Hooks_system#Implement_the_Hook]] to know how to use Dolibarr existing hooks to add/replace code at Dolibarr hooks place.


Si toutefois vous voulez faire des accès dans des tables sans objet PHP dédié, ceci reste possible (par exemple pour récupérer une liste d'enregistrement). Dans ce cas, pensez à suivre ces exemples:
===Database access===
If you need to edit some data in the database inside your own table, use the PHP class generated before.


Pour un insert, update ou delete:
If you to make access to tables with no dedicated PHP class available, this is always possible (for example if you want to get a list of records with a particular join or filter). In this case, this is a code samples to follow:


<pre>
To make an insert, update or delete:
$db->begin();  // Debut transaction
$db->query("Ma requete insert, update ou delete");
$db->commit();      // Valide
ou $db->rollback()  // Annule
</pre>


Pour une lecture:
<syntaxhighlight lang="PHP">
$db->begin();  // Start transaction
$db->query("My SQL request insert, update or delete");
$db->commit();      // Validate transaction
or $db->rollback()  // Cancel transaction
</syntaxhighlight>


<pre>
To read:
$resql=$db->query("Ma requete select");
 
<syntaxhighlight lang="PHP">
$resql=$db->query("My select request");
if ($resql)
if ($resql)
{
{
Line 175: Line 323:
}
}
}
}
</pre>
</syntaxhighlight>
 
===Define style of your pages===
To have the look of your own pages to match the Dolibarr theme, it is necessary to use the Dolibarr CSS styles.
 
You can use for example:
 
*class="'''liste_titre'''" on tags ''tr'' and ''td'' for the head row of a table.
*class="'''pair'''" or class="'''impair'''" on tags ''tr'' and ''td'' of other rows of a table.
*class="'''flat'''" on all input fields (''input, select, textarea''...).
*class="'''button'''" on HTML fields with type ''input type="submit"''.


== Définition du style ==
===Use the Dolibarr date picker===
Pour que le look de la page soit aligné avec le thème Dolibarr, il est nécessaire d'utiliser les styles des CSS de Dolibarr.
If you want to use the Dolibarr date selector (with its calendar popup) into your pages, use the following line:
<syntaxhighlight lang="PHP">
$form=new Form($db);
$form->select_date('','mykey',0,0,0,"myform");
</syntaxhighlight>
The string mykey will identify the date selector in the form. You must use different values if you use several date selectors in same page.
The string myform is the name of the FORM in which the selector is included (value found in the form name="myform" in HTML page).
This means a date selector must be included necessarily into an html FORM.


Par exemple:
To get value after the POST of your form, the command is:
<syntaxhighlight lang="PHP">
$mydate = dol_mktime(12, 0 , 0, $GETPOST('mykeymonth', 'int'), GETPOST('mykeyday', 'int'), GETPOST('mykeyyear', 'int'));
print strftime('%A %d %B %Y', $mydate);
</syntaxhighlight>


* class="'''liste_titre'''" sur les balises ''tr'' et ''td'' pour une ligne de titre de tableau.
===Overwrite template file (tpl)===
* class="'''pair'''" ou class="'''impair'''" sur les balises ''tr'' et ''td'' des lignes de donnees de tableau.
If you want to overwrite tpl file on your module, you need to declare it on the module_parts :
* class="'''flat'''" sur tous les champs de saisie (''input, select, textarea''...).
<syntaxhighlight lang="PHP">
* class="'''button'''" sur les objets de type ''input type="submit"''.
'tpl' => 1,
</syntaxhighlight>
Then you can put any tpl file on '''mymodule/core/tpl'''
as soon as the module is activate, the tpl will be overwrited


==Add your own setup page (optional)==
'''When''': If your module needs parameters, which are to be provided by the user, for proper setting up of the module.


== Utiliser le sélecteur de date de Dolibarr ==
===Create your page to edit parameters===
If your module needs several parameters to be setup, you must create a page to edit options (these options will be saved in the [[Table llx_const|table '''llx_const''']]).
Create a page named '''mymodule_setuppage.php''' that shows a form for possible options to update them into the above-mentioned table.
It is necessary to take an example from a page of the directory '''/admin''' that will show you the way to read/save your parameters.
Put this PHP page into the directory '''/admin''' of your module (e.g. mymodule/admin/mymodule_setuppage.php).


Si vous le désirez, vous pouvez profiter du sélecteur de date dans des écrans Dolibarr. Pour cela, utilisez la ligne suivante:
===Modify the descriptor file of your module===
<pre>
Then, within the descriptor file of your module, modify the variable '''config_page_url''' to set the name of this PHP page.
$form=new Form($db);
If the page is in the directory '''admin/''', then the path is not required, e.g. like this:
print $form->select_date('','mykey',0,0,0,"myform");
<syntaxhighlight lang="PHP">
</pre>
$this->config_page_url = array("mymodule_setuppage.php");
La chaine mykey identifie la zone date. Il faut y mettre une valeur différente s'il y a plusieurs zones.
</syntaxhighlight>
La chaine myform est le nom de la zone FORM (dans form name="myform" de la page HTML).
If the page is in the directory '''mymodule/admin/''', then like this:
L'affichage d'un sélecteur de date doit donc être intégrée dans une zone FORM Html.
<syntaxhighlight lang="PHP">
$this->config_page_url = array("mymodule_setuppage.php@mymodule");
</syntaxhighlight>


Pour récupérer la valeur, à l'issu du POST, la commande est:
===Test your page===
<pre>
Go into page '''Home->Setup->Modules''', you should see a picture at the end of the line of your module to reach your setup page. Click on it, you should be able to view/edit parameters from your page.
$datefacture = dolibarr_mktime(12, 0 , 0, $_POST['mykeymonth'], $_POST['mykeyday'], $_POST['mykeyyear']);
print strftime('%A %d %B %Y', $datefacture);
</pre>


= Définir votre page de configuration (optionnel) =
==Define your entries in the menu (optional)==
'''Quand''': Si votre module offre plusieurs options paramétrables.
'''When''': If you have created PHP pages, it is necessary that those pages can be reached from menu entries in Dolibarr menu.


== Creer votre page d'édition de configuration ==
===Define your menu entries===
Si votre module offre plusieurs options paramétrables, il est nécessaire de créer une page PHP pour éditer les options (qui sont stockées dans la table '''llx_const''').
For this, you must define into the module descriptor, the array this->menu that declares all menus added by your module.
Créer une page PHP nommée '''monmodule_setupapage.php''' qui affiche les options possibles et les met à jour.
This array contains entries that will appear once your module is activated.
Il est nécessaire de prendre exemple sur une page dans '''/admin''' qui vous montre la méthode pour lire ou sauvegarder en base votre option.
The example module descriptor file '''modMyModule.class.php''' contains an example to declare a top menu and also its left menu entries.
Placer cette page de configuration dans le répertoire '''/admin''' également.
Ensuite dans le descripteur de module, modifier la variable pour indiquer le nom de cette page PHP (sans le chemin qui n'est pas nécessaire, la page étant forcément dans le rep admin).
<pre>
$this->config_page_url = array("monmodule_setupapage.php");
</pre>


== Tester votre page ==
This is the example of code to declare your own menu entries in a module descriptor file:
Aller sur la page '''Configuration->module''', vous devez voir apparaitre un icone qui permet d'accéder à la page de configuratione tvous devez etre capable de modifier ces options et les voir conservé en base.
<syntaxhighlight lang="PHP">
// Main menu entries
$this->menu = array(); // List of menus to add
$r=0;


= Définir vos entrées de menu (optionnel) =
// Add here entries to declare new menus
'''Quand''': Si vous avez créé des pages PHP, il est nécessaire que ces écrans soient accessibles depuis le menu Dolibarr.
// Example to declare the Top Menu entry:
$this->menu[$r]=array( 'fk_menu'=>0, // Put 0 if this is a top menu
'type'=>'top', // This is a Top menu entry
'titre'=>'MyModule top menu',
'mainmenu'=>'mymodule',
'leftmenu'=>'mymodule',
'url'=>'/mymodule/pagetop.php',
'langs'=>'mylangfile', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'position'=>100,
'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled.
'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
'target'=>'',
'user'=>2); // 0=Menu for internal users, 1=external users, 2=both
$r++;


== Définissez vos entrées ==
// Example to declare a Left Menu entry:
Pour cela, il vous faut définir dans le fichier descripteur de menu le tableau
$this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=xxx',     // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode of parent menu
<pre>
'type'=>'left',         // This is a Left menu entry
$this->menu
'titre'=>'MyModule left menu 1',
</pre>
'mainmenu'=>'xxx',
Ce tableau contient toutes les entrées qui apparaitront dans les menus une fois le module activé.
'leftmenu'=>'yyy',
Les fichiers de descripteur de module exemple possède un exemple de déclaration de menu haut ainsi que de ces entrées menu gauche correspondantes.
'url'=>'/mymodule/pagelevel1.php',
'langs'=>'mylangfile', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'position'=>100,
'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled.
'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
'target'=>'',
'user'=>2); // 0=Menu for internal users,1=external users, 2=both
$r++;
</syntaxhighlight>


== Tester vos entrées menus ==
To show the menu or not depending on a permission, modify property '''perms''' in the array. See chapter on permissions later to see how to add permissions.
Désactiver et réactiver votre module sous Dolibarr, les entrées menus doivent alors apparaitre.


= Définir vos propres permissions (optionnel) =
===Test your menu entries===
'''Quand''': Si vous voulez ajouter de nouvelles permissions.
Disable and re-enable your module under the Dolibarr module setup page, menus entries must appear (if property 'enabled' is declaration array is ok).


La définition des permissions que gèrera votre module se fait dans le fichier descripteur créé dans la première étape.
==Add your own permissions (optional)==
Modifier la ligne $this->rights_class = 'facture' par
'''When''': If you want to add new permissions.
<pre>
$this->rights_class = 'monmodule'
</pre>


Ensuite remplissez le tableau $this->rights avec autant d'entrée que de permissions différentes à gérer.
The way to define permissions that will manage your module is done inside the module descriptor created previously.
Modify line
<syntaxhighlight lang="PHP">
$this->rights_class = 'mymodule'
</syntaxhighlight>
with correct value for mymodule.


<pre>
Then you must fill the array $this->rights with as many entries than different permissions you need to manage.
 
<syntaxhighlight lang="PHP">
$this->rights[$r][0] = 10001;
$this->rights[$r][0] = 10001;
$this->rights[$r][1] = 'Libelle par défaut de ma permission';
$this->rights[$r][1] = 'Label by default of permission';
$this->rights[$r][2] = 'r';
$this->rights[$r][3] = 1;
$this->rights[$r][3] = 1;
$this->rights[$r][4] = 'action';
$this->rights[$r][4] = 'action';
$this->rights[$r][5] = 'sousaction';
$this->rights[$r][5] = 'subaction';
$r++;
$r++;
</pre>
</syntaxhighlight>


Dans $this->rights[$r][0], mettre un id de permission non déjà pris (Voir dans le menu '''Infos Système''' sur une installation de Dolibarr opérationnelle pour connaitre les id déjà utilisés.
Into $this->rights[$r][0], put a permission id not already used (See into menu '''System info''' on a working installation of Dolibarr to know list of id already used by standard modules.
Dans $this->rights[$r][3], mettre 1 si cette permission est attribué d'office par défaut quand un utilisateur est créé.
Into $this->rights[$r][1], put a label by default for permission (This label will be used if no translation can be found into the file '''admin.lang''' Translation key should be "Permission10001=My permission Label").
Dans $this->rights[$r][1], mettre un libellé par défaut (il sera affiché si aucune traduction n'est trouvé pour votre permission dans le fichier '''admin.lang''').
Into $this->rights[$r][2], types of the permission. There are three type of permission, 'r' for read, list or expert permission, 'w' for write or update permission and 'd' for delete permission.
Dans $this->rights[$r][4] et $this->rights[$r][5], mettre une chaine action et sousaction sans espaces. Vous pourrez alors tester dans le code PHP si un utilisateurs a bien les droits par la séquence suivante:
Into $this->rights[$r][3], put 1 if this permission must be granted automatically by default to any newly created user.
Into $this->rights[$r][4] and $this->rights[$r][5], put an action and subaction string without spaces. You will be able to test if a user has the permission in your PHP source code with the sequence:


<pre>
<syntaxhighlight lang="PHP">
if ($user->rights->monmodule->action->sousaction) ...
if ($user->rights->mymodule->action->subaction) ...
</pre>
</syntaxhighlight>


= Définir vos propres box (optionnel) =
==Define your own box (optional)==
'''Quand''': Si votre module amène avec lui une ou plusieurs Boxes.
'''When''': If your module needs to provide one or several new boxes to show on home page.


== Définissez vos box ==
===Define your box===
Pour cela, modifier les tableaux $this->boxes du fichier descripteur de module.
For this, modify the array $this->boxes into the module descriptor file.
Il suffit d'ajouter une ligne par fichier box qui se trouve dans le répertoire '''htdocs/includes/boxes'''
All you have to do is to add 2 lines for each box file you will create into directory '''htdocs/mymodule/core/boxes'''


''Exemple:''
''Example:''
<pre>
<syntaxhighlight lang="PHP">
this->boxes[0][1]='mabox0.php'
$this->boxes[0]['file']='mybox0.php@mymodule'
this->boxes[1][1]='mabox1.php'
$this->boxes[0]['note']='My box 0'
this->boxes[2][1]='mabox2.php'
...
...
$this->boxes[n]['file']='myboxn.php@mymodule'
this->boxes[n][1]='maboxn.php'
$this->boxes[n]['note']='My box n'
</pre>
</syntaxhighlight>
 
Then create files '''htdocs/mymodule/core/boxes/mybox0.php''', '''htdocs/mymodule/core/boxes/mybox1.php'''... by copying an example from an existing box file (found into directory '''htdocs/core/boxes''').
 
===Test if your box is detected by Dolibarr===
Disable and enabled module.
 
Go into menu '''Home - Setup - Boxes'''.
 
Your boxes must appear in the list of boxes you can activate. Activate the box and go on the home page to see if the box is showing correctly.
 
==Define your own export (optional)==
'''When''': If your module provides new predefined database export profiles (for its own tables or for already existing tables of another module).
 
===Define export===
For this uncomment and modify arrays $this->export_xxx in your module descriptor file.
 
===Test your export===
Go into menu Tools -> Export. Your export will appear in the list of available predefined exports (if your module is enabled).
Choose it, you must see a list of all possible fields defined in the export arrays.
Choose on field and try to build an export file. If ok, try again with all fields.
 
==Define your CSS styles (optional)==
'''When''': If in your PHP pages, you use class styles that are not defined inside Dolibarr themes CSS (not recommended).
 
===Create and declare your style sheet===
Create a style sheet CSS named '''mymodule.css''' or '''mymodule.css.php''' and put it into directory '''htdocs/mymodule'''. You can have several CSS files per module.
Remember it's better to use existing styles already available by default into Dolibarr (The CSS file used by Dolibarr is file '''themes/mytheme/''themename''.css.php'''. Create your own CSS files only if you need absolutely to add not already existing styles.
 
Once your style sheets are ready, declare them into your module descriptor file by modifying the property '''$this->modules_parts'''.
Value to put here must be an array of relative URLs of your CSS files.
For example
<syntaxhighlight lang="PHP">
$this->module_parts = array('css' => array('/mymodule/css/mymodule.css.php','/mymodule/css/myother.css'));
</syntaxhighlight>
 
===Test your style sheet===
Disable and enable your module.
 
Go on the home page (index.php). Show the HTML source of the page.
 
In the HTML header, you should see a line that declares your style sheet.
 
==Add your JavaScript functions (optional)==
'''When''': If in your PHP pages, you use javascript functions not available in Dolibarr (in file lib_head.js)
 
If you need to use your own JavaScript functions inside your PHP pages, it is necessary to define your functions in your JavaScript file '''htdocs/mymodule/js/mymodule.js''', included in the HTML <code>&lt;head/&gt;</code> section.
Dolibarr is responsible for building that HTML section. In order to ask it to include your JavaScript file, you just need to provide it to the llxHeader() function called by your page.
 
Example for page /htdocs/mymodule/mypage.php :
<syntaxhighlight lang="PHP">
$morejs=array("/mymodule/js/mymodule.js");
llxHeader('','Titre','','','','',$morejs,'',0,0);
</syntaxhighlight>
 
==Run your own code on any Dolibarr event (optional)==
'''When''': If you want to execute your own code once a common Dolibarr event has occurred (example: I want to update a table in my module when an invoice is created into Dolibarr), you must create a '''trigger'''.
 
See also [[Interfaces_Dolibarr_toward_foreign_systems]]
and [[Interfaces_from_foreign_systems_toward_Dolibarr]]
 
==Insert your code inside Dolibarr hooks positions (optional)==
'''When''': When you want to add code or replace Dolibarr code into another situation than a business event (See the previous chapter for adding code during a business event).


Ensuite creer les fichiers mabox0.php, mabox1.php... en prenant exemple sur des box existantes (dans le répertoire htdocs/include/boxes
See page [[Hooks_system]].


== Tester la présence de vos box dans Dolibarr ==
Aller dans le menu '''Accueil - Configuration - Boite'''.
Vos boxs doivent apparaitre dans la liste des box activables. Avticer les, aller sur la page d'accueil et vérifier qu'elles s'affichent correctement.


= Définir vos propres exports (optionnel) =
==Add your own numbering rules==
'''Quand''': Si votre module amène avec lui des exports prédéfini de données (pour ces propres tables ou des tables déjà existante d'un autre module de Dolibarr).
'''When''': When you need a new rule for generated ref of elements that are not covered by existing rules.


== Définissez l'export ==
See page [[Create numbering module]].
Pour cela, décommenter et modifier les tableaux $this->export_xxx du votre fichier descripteur de module.


== Tester votre export ==
==Add your document template (optional)==
Aller dans le menu outils -> export de Dolibarr. Votre export doit apparaitre dans la liste des exports prédéfinis disponible (si votre module est bien activé).
'''When''': When you want to personalize your own generated PDF or ODT documents.
Le choisir, vous devez alors voir les champs possible définis dans le tableau à l'étape précédente.
Choisir quelques champs et tenter une génération du fichier export.


= Définir vos styles CSS (optionnel) =
Note: To add this feature, you don't need to create a module descriptor.
'''Quand''': Si dans vos écrans PHP, vous utiliser des classes de styles qui ne sont pas celle des thèmes de Dolibarr (non recommandé).


Cette fonctionnalité est décrite mais pas encore opérationnel en 2.4
Documentation to add your own template is available on page [[Create_a_PDF_document_template]] or [[Create_an_ODT_document_template]].


== Créer et déclarer votre feuille de style ==
==Add your skin (optional)==
Créer un fichier de style css nommé '''monmodule.css''' et le placer dans le répertoire '''''monmodule''''' dans '''htdocs'''. Il ne peut y avoir qu'un fichier css propre à chaque module.
'''When''': When you want to personalized your colors/fonts/images.
Rappelons qu'il vaut mieux utiliser les styles déjà existant de Dolibarr (le fichier css utilisé par Dolibarr étant le fichier '''themes/nomtheme/''nomtheme''.php.css'''. Ne créer un fichier css propre à votre module que si vous devez absolument gérer des styles non déjà existants.
Une fois votre feuille de style prête, déclarer la dans votre fichier descripteur de module en modifiant la propriété '''$this->style_sheet'''.
La valeur à renseigner ici doit être le chemin relatif de l'URL de votre fichier css.
Par exemple '/monmodule/monfichier.css'.


== Tester votre feuille de style ==
Note: To add this feature, you don't need to create a module descriptor.
Assurez vous que votre module est actif.
Appelez la page d'accueil de Dolibarr. Afficher la source de la page HTML.
Vous devriez voir dans l'entête HTML, une ligne déclarant votre feuille de style.


= Définir vos fonctions Javascript (optionnel) =
To add your own skin, read page [[Skins]].
'''Quand''': Si dans vos écrans PHP, vous utiliser des fonctions javascript non dispo en standard (fichier lib_head.js)


Si dans vos écrans PHP, vous utilisez des fonctions javascript, il est nécessaire de faire en sorte que vos fonctions déclarées dans un fichiers javascript '''monmodule.js''' soit chargées dans l'entête head html.
=Some coding rules and predefined functions=
Pour demander à Dolibarr qui gère la génération de la section header d'inclure un de vos fichiers javascript, il est nécessaire de déclarer votre fichier javascript dans le descripteur de module.
The coding rules to be followed are defined in the [[Developer documentation]], under section "General Information - Language and standards development".


Cette fonctionnalité n'est pas encore possible.
A lot of predefined features for developers are also available and described into page [[Developer documentation]] under section "Technical components of Dolibarr".


= Déclencher du code sur un évènement Dolibarr (optionnel) =
=Create a package to distribute and install your module=
'''Quand''': Si vous voulez que des actions particulières s'exécutent suite au déclenchement d'action s standards de Dolibarr (exemple: je veux mettre à jour une table de mon module quand une facture se crée dans Dolibarr), il vous faut créer un fichier de '''triggers'''.
This process must be used to generate a package to submit it on the http://www.dolistore.com marketplace.
But you can use it to have a package easy to distribute on your own network.


Voir aussi [http://www.dolibarr.com/wikidev/index.php/Interfaces_Dolibarr_vers_exterieur Interfaces_Dolibarr_vers_exterieur]
*Go into the directory '''/build''' and copy the file '''makepack-dolibarrmodules.conf''' into '''makepack-mymodule.conf'''. Warning, this directory may not be provided in some packages of stable versions. If so, it can be retrieved from the snapshot available for download on the Dolibarr website in area "Development version" (taken in this case the whole build directory which is autonomous and independent directory).
et [http://www.dolibarr.com/wikidev/index.php/Interfaces_Exterieur_vers_Dolibarr Interfaces_Exterieur_vers_Dolibarr]


= Créer un package pour livrer et installer votre module =
Edit this file to add a list of file names for all new files you created for your module (module descriptor, new sql tables files, php page, images, etc...)


* Aller dans le répertoire '''/build''' et recopier le fichier '''makepack-dolibarrmodules.conf''' en '''makepack-monmodule.conf'''. Attention, ce répertoire peut ne pas être fourni dans les packages de versions stables. Si c'est le cas, il peut être récupéré dans le snapshot CVS disponible en téléchargement sur le site web Dolibarr dans la rubrique Version de développement (prendre dans ce cas tout le répertoire build qui est un répertoire autonome et indépendant de la version).
*Run the script via Perl (need the Perl version 5.0 or later):
Saisissez dans ce fichier la liste des noms des nouveaux fichiers que vous avez créé pour votre module (descripteur de module, nouveaux fichiers sql de tables, page php, images, etc...)


* Lancer le script via Perl (besoin de la version Perl 5.0 ou +):
<syntaxhighlight lang="bash">
<pre>
perl makepack-dolibarrmodule.pl
perl makepack-dolibarrmodule.pl
</pre>
</syntaxhighlight>
Le script vous demande le nom de votre module, sa version majeure et mineure.
The script asks you the name of your module, its major and minor version. A file '''mymodule.zip ''' will then be manufactured containing your module ready to be deployed.
Un fichier '''monmodule.tgz''' va alors être fabriqué contenant votre module prêt pour être déployé.
 
*The person who receives your module must then place the file in the root directory of a Dolibarr installation and perform the command:


* La personne qui reçoit votre module doit alors placer le fichier dans son répertoire racine d'installation de Dolibarr et réaliser la commande:
<syntaxhighlight lang="bash">
<pre>
tar -xvf mymodule.zip
tar -xvf monmodule.tgz
</syntaxhighlight>
</pre>


= Quelques règles de codage =
*If you want your module to be public, you can submit it (the zip file) on the Dolibarr marketplace website: {{LinkToPluginDownload}} (you must first create an account and be logged in to use the "Submit a module/product" link).
Les règles de codage à suivre sont définis dans la [[Documentation développeur]], rubrique "Informations Générales - Langage et normes de développement".
**If your module was built correctly, the file will be validated later.
**If quality is sufficient and license permits it, the code might be added inside main Dolibarr sources (except if you disagree for that).


= Utilisation du MDA =
=Enabling/activation condition of external module on DoliStore=


Une méthode pour générer un module fonctionnel depuis l'UML est en cours de mise au point. Plus d'informations sur la page [[Générer un module par MDA]].
See [[Module_Dolistore_Validation_Rules|Validation Rules]]
[[Category:Development]]

Latest revision as of 17:14, 5 April 2026

To create a new module/addon for Dolibarr, there are several steps. This tutorial will describe each of them to let you build a module that extends Dolibarr features, such as:

  • Add new tables in database.
  • Add your own menu entries.
  • Add new screens to edit new tables.
  • Add or remove tabs on object view (invoice, product, order, event, ...).
  • Add predefined exports for the internal export tool.
  • Add more CSS or JS code on all or some pages
  • Add new information widget in the home page.
  • Add new substitutions variables.
  • Define new permissions.
  • Execute code automatically triggered by a particular Dolibarr action.
  • Insert your code inside Dolibarr hooks positions.
  • Add your numbering rule to generate the reference of objects
  • Add a new document template.
  • Add a new skin.

etc...

The following chapters explain how to do all of this manually in an easy way.

Module creation with the module builder

From Dolibarr v. 12.0 it is possible to create the main pages of your module with the Module Builder. To activate it:

Go into the list of modules and enable the "Module Builder" module:


Then click on the "bug" image in the top right of screen.


Template of an External Module

A good model to start development of external module can be found here : GitHub Dolibarr Module Template

Create your module

Create a Module descriptor for your Module (required)

When it is required: Required as soon as an addon is developed, whatever its goal is (only adding a skin does not require a module descriptor file).

Since Dolibarr 9.0, you should use the ModuleBuilder module provided as a standard module to generate the module descriptor

Create your module descriptor

The first step is to create a file descriptor for the module.

  • Create directory /htdocs/custom/mymodule/core/modules (for an external module) or /htdocs/mymodule/core/modules if you plan to have this module an official core module of Dolibarr. Then copy the file modMyModule.class.php from the directory htdocs/modulebuilder/template into this directory. Change the name of the file modMyModule.class.php to the name corresponding to the purpose of your module. Name of the file must start with mod and end with .class.php (for example if you want to give the name 'NewName' to this file, then the name should be modNewName.class.php).

Then, modify the contents of this file as follows:

  • Replace all occurrences of "modMyModule" with a value which corresponds to the purpose of your module. This value must always start with 'mod' and contain only alpha characters (again, if the name given to the file was 'NewName', then replace all "modMyModule" with "modNewName").
  • Change the number in: $this->numero = 100000 by a number that designates your module id. To avoid conflicts with other modules, you can consult the page that lists already reserved id numbers: List of module IDs.
  • Modify any other variables defined in the constructor (see comment in the code skeleton for their meaning).

Your file descriptor for your module is ready. See the next step to activate it.

Test your descriptor

Launch Dolibarr and go to page Setup->module? If you set the property version in the module description you should see a new line with your new module and the possibility to activate it or not. If you set the property version to "develop" or "experiental", to see your module, you must first go into Setup-Others and set MAIN_FEATURES_LEVEL to 1 to see "experimental" modules or 2 to see "development" modules.

Tree of path for new module files (required)

This is how your files must be organized when building a new module (the zip file must also match this rule). Note: Only the second line is mandatory.

  • mymodule/* contains php pages (note that you can also add any other subdir of your choice). Note: If your module is a metapackage (a module that will embed other modules in same zip, you must put here a file metapackage.conf)
  • mymodule/build/ can contains any file you develop for compiling or building package
  • mymodule/core/modules/ contains module descriptor file modMyModule.class.php
  • mymodule/core/triggers contains triggers provided by module
  • mymodule/admin/ contains pages to setup module
  • mymodule/class/ contains PHP class files provided by module
  • mymodule/css contains CSS files provided by module
  • mymodule/js contains javascript files provided by module to add new functions
  • mymodule/docs to provide doc and licence files
  • mymodule/img contains images files provided by module
  • mymodule/langs/xx_XX contains language files for language xx_XX (try to put at least en_US)
  • mymodule/lib contains libraries provided and used by module
  • mymodule/scripts to provide command line tools or scripts. Note: Command lines script must start with line #!/usr/bin/env php
  • mymodule/sql contains SQL file provided by module to add new tables or indexes
  • mymodule/theme/mytheme if module provide its own theme/skin

Create your SQL tables and the PHP DAO class (optional)

When: If your module needs to manage data of its own

Create your .sql file

If your module is designed to manage data of its own, which are not available in the standard version of Dolibarr, it is necessary to define SQL tables to store the data.

Scripts for creating tables and loading data by your own module are saved into a subdirectory sql ("mymodule/sql") of your module. (With ModuleBuilder, the directory and all sql files will be created automatically when you will create a new Object from tab Object).

Then check into your descriptor file, into function init that the line

$this->_load_tables('/mymodule/sql/');

is not commented.

Rules to follow:

  • Add the files about creating tables commands on the principle of an llx_mytable.sql file per table, with an optional llx_mytable.key.sql file (see existing files in install/mysql/tables for examples).
  • The recommended type and name for SQL fields are defined into page Language_and_development_rules#Table_and_fields_structures.
  • To manage data, you must create a file called data.sql inside directory /mymodule/sql/ that contains SQL command to add/edit/delete data.
  • Don't use the double quote for strings (eg 'chaine' not "chaine") because the double quote have a specific meaning in PostGreSQL

Example of content of a file data.sql

 delete from llx_const where name='MYMODULE_IT_WORKS' and entity='__ENTITY__';
 insert into llx_const (name, value, type, note, visible, entity) values ('MYMODULE_IT_WORKS','1','chaine','A constant vor my module',1,'__ENTITY__');

Files must be operational for the database mysql. Note: The files of other databases are not maintained. They will be read and converted on the fly by the driver of the other database.

Test your .sql files

Once the files ready, you can return to the page to enable Dolibarr modules and disable the module, drop those tables in the database (if they already exist) and reactivate the module. The tables should be recreated by the activation of the module. If this is not the case, check the Dolibarr logs, or as a first step try running your scripts manually on your database (because SQL errors from your scripts may not show up in the Dolibarr logs).

Generate the PHP DAO class

The DAO PHP files should have been generated by ModuleBuilder after creating an object.

You can however create them manually by copying existing object however using ModuleBuilder is highly recommended. You should find examples into htdocs/modulebuilder/templates/class/myobject.class.php

In this class, there are already operational CRUD (Create/Read/Update/Delete) methods to perform an insert, a fetch (select), an update, a delete of a table row. Edit the file to use the correct module name, tables and place this file in the class subdirectory of the module. The Module Builder allows you to do this with just a few mouse clicks.

The tab management (optional)

Add or remove your own tabs on object sheets

When: To add a tab on an object (invoices, orders, proposals, member ...)

To do this go into the file descriptor of module previously created and edit the $this->tabs array:

	// Array to add new pages in new tabs or remove existing one
	$this->tabs = array('objecttype:+tabname1:Title1:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mypagetab1.php?id=__ID__'    // To add a new tab identified by code tabname1
                            'objecttype:+tabname2:Title2:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mypagetab2.php?id=__ID__',   // To add a new tab identified by code tabname2
                            'objecttype:-tabname');                                                     // To remove an existing tab identified by code tabname

The table should contain a list of strings, each string representing a new tab. The format of the string consisting of 5 parts separated by ":"

  • Part 1: The element type (object type) where the tab should appear is a value from the following:
    • 'thirdparty' to add a tab in third party view
    • 'intervention' to add a tab in intervention view
    • 'supplier_order' to add a tab in supplier order view
    • 'supplier_invoice' to add a tab in supplier invoice view
    • 'invoice' to add a tab in customer invoice view
    • 'order' to add a tab in customer order view
    • 'product' to add a tab in product view
    • 'stock' to add a tab in stock view
    • 'propal' to add a tab in propal view
    • 'member' to add a tab in fundation member view
    • 'contract' to add a tab in contract view
    • 'user' to add a tab in user view
    • 'group' to add a tab in group view
    • 'contact' to add a tab in contact view
    • 'payment' to add a tab in payments view (since 3.6.0)
    • 'payment_supplier' to add a tab in supplier payments view (since 3.6.0)
    • 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
  • Part 2: A code to identify tab to add (start with +tabname1) or to remove (start with -tabname1)
  • Part 3: The title of the tab(Title1). This can be a hardcoded read or better a code translation in module lang file .
  • Part 4: The name of the file "*.lang" (mylangfile@mymodule) which contains correspondence between the code translation and language to display. If this name is followed with @mymodule, Dolibarr will search translation file "*.lang" within the module in htdocs/custom/mymodule/langs/code_CODE/mylangfile.lang, otherwise Dolibarr will look for file in htdocs/langs/code_CODE/mylangfile.lang
  • Part 5: A condition to test if tab must be visible($user->rights->mymodule->read) or put 1 to be always visible.
  • Part 6: The URL of the page to display when you click on the tab (/mymodule/mypagetab1.php). The __ID__ string will be replaced automatically by the Id of the element concerned.

To feed the contents of the tab with data from the database, see the next chapter.

In order to get the names 'tabname' of existing tabs, you have to check the names used in the function 'product_prepare_head' of the file 'core/lib/module.lib.php' corresponding to section '$head[$h][2]'.

Show tabs navigation into your own pages

When: To show all standard tabs of an object (product, tiers, etc.) on your page.

You must follow these steps :

1. Include files you need into your file

For each object type, there are two files to include with line

require_once($url_fichier) ;

This is example of files to include (DOL_DOCUMENT_ROOT is often dolibarr/htdocs/) :

  • Object thirdparty (thirdparty) :
    • DOL_DOCUMENT_ROOT/societe/class/societe.class.php
    • DOL_DOCUMENT_ROOT/core/lib/company.lib.php
  • Object product (product) :
    • DOL_DOCUMENT_ROOT/product/class/product.class.php
    • DOL_DOCUMENT_ROOT/core/lib/product.lib.php
  • Object invoice (invoice) :
    • DOL_DOCUMENT_ROOT/compta/facture/class/facture.class.php
    • DOL_DOCUMENT_ROOT/core/lib/invoice.lib.php

...

2. Create and load the object to show into your tab

Create an instance of an object of the correct class and load object from the database by using the fetch method of an object in providing to this method the id you get from URL (ie : /mytab.php?id=1).

Example :

$id=GETPOST('id','int');
$ref=GETPOST('ref','alpha');
$product = new Product($db) ;
$result = $product->fetch($id,$ref) ; // Test $result to check the database read is ok

3. Get a list of all tabs to show for your object type

Use function XXX_prepare_head($obj), where XXX is name of object. This will return an array with all definition of tab entries to show. The parameter to put into this method is the instance of an object you want tabs.

The resulting array has the following structure

$head        // Array of tabs
$head[$h]    // Element to describe one tab.
$head[$h][0] // Url of page to show when you click on tab
$head[$h][1] // Title of tab
$head[$h][2] // Code name to identify the tab

Example :

$head = product_prepare_head($product, $user) ; // parameter $user is present for some function anly

4. show tabs on your page

Use the dol_fiche_head() function to show all tabs defined in the $head array returned by XX_prepare_head().

dol_fiche_head($links, $active='0', $title='', $notab=0, $picto='')
//$links  // Tableau des onglets, appelé $head plus haut.
//$active // Onglet actif (mettre le nom de l'onglet défini dans votre fichier de module, ou un nom contenu dans $head[$h][2]). Cet onglet sera mis en surbrillance
//$title  // Title to show (shown into a special tab that you can't click)
//$notab
//$picto  // Name of image to show into title. Possible values are:
//            product
//            service
//            company

This function will show required tabs and open an html element < div class="" > that correspond to the area under the tabs. To close area of a tab, just use < /div > into your PHP page.

Create or modify PHP screens (optional)

When: If the purpose of your module is to add features that require new or modified screens.

Create a new PHP screen

You must then create your PHP pages that will show/edit data from tables using the skeleton templates provided as an example in the directory modulebuilder/myobject_page.php (For the development of a script from the command line, see Script development).

To create a new user screen, create a subdirectory of htdocs (if not already done) for your module (in htdocs/mymodule for example) to store the pages you will create.

Copy, into that directory, the file myobject_page.php that will serve as a starting point for your page file. Edit the file to have a correct relative path to the main.inc.php file.

// Load Dolibarr environment
$res=0;
// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
// Try main.inc.php using relative path
if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
if (! $res) die("Include of main fails");

As you can see, there are several tries to load the main.inc.php (or master.inc.php). The goal is to succeed in the most cases as possible. The minimum is 2 lines: one to try to load the master/main.inc.php into the dolibarr root directory and another one to try to load the file to support the case when the module is deployed into the "custom" directory. But you can have more to deal more situation. The provided example should be able to load the file main/master.inc.php in nearly all situation/setups.

Note that you may add more "../" depending on the depth of the file relative to your module directory tree.

It's in the main.inc.php file that is loaded technical environment variables and permissions. The following variables are objects positioned in this file:

  • $user Object that contains the characteristics of the user + his permissions.
  • $conf Object that contains Dolibarr configuration.
  • $db Object that contains an opened connection handler to the database.
  • $langs Object that contains the user's language.

Then enter your code to display the page.

  • To include a class or library dedicated to the module is done using a Dolibarr function (and not using directly include_once):

Example :

dol_include_once('/mymodule/class/myclass.class.php', 'MyClass');
  • To include classes provided with Dolibarr, use the following syntax:

Example :

require_once DOL_DOCUMENT_ROOT.'/core/class/doli.class.php';

Add some fields into existing forms

You may want to provide a module that adds more fields into forms (input and view) of some elements.

A heavy solution (but not so bad) may be to replace all pages used to create element (this means disabling the "New element" menu entry and adding yours, and disabling the tab that shows the element to replace with a tab that is your own full page (copied/pasted from original) to do same than original page but modified to add your fields and stored added data into your own table). Go to menu #Define your entries in the menu (optional) and #The tab management (optional) if this solution suits you (this solution is more powerful since you can change everything you want into the page).

We will describe here another solution, that works only to "add fields" at end of existing fields, using the element "category" as an example but you can convert this tutorial for invoice, proposal ...

  • First thing is to add a table, owned by your module, to store the value of new fields. This table will only have one column called rowid (will contain the same value as the rowid column in the element table) + one column for each new field you want to add. Then, create a class with CRUD (Create/Read/Update/Delete) methods for this new table. For those two tasks, go back to the previous chapter #Create your SQL tables and the PHP DAO class (optional).
  • Next step is to add a hook into your module to add the new fields into the form. See chapter Hooks_system#Implement_the_Hook for generic documentation to use hooks.

If you follow this tutorial, to be able to add fields into category forms, you must do:

  Page waiting to complete. To complete, create an account, go back and clic on "Modify".
  Page en attente d'être complété. Pour compléter, créez un compte, revenez et cliquez sur "Modifier".
  Página a completar. Para completarla, cree una cuenta, vuelva a la página y haga clic en "editar"
  Seite wartet auf Vervollständigung. Um zu helfen, erstelle ein Konto, gehe zurück und klicke auf "Bearbeiten".
  待完成,欲帮助完成,注册帐号,点击“编辑"
  ページは未完成の状態です。完成させるにはアカウントを作成し、ページに戻って「編集」をクリックして下さい。

Add/replace part of fields supported by hooks

See chapter Hooks_system#Implement_the_Hook to know how to use Dolibarr existing hooks to add/replace code at Dolibarr hooks place.

Database access

If you need to edit some data in the database inside your own table, use the PHP class generated before.

If you to make access to tables with no dedicated PHP class available, this is always possible (for example if you want to get a list of records with a particular join or filter). In this case, this is a code samples to follow:

To make an insert, update or delete:

$db->begin();   // Start transaction
$db->query("My SQL request insert, update or delete");
$db->commit();       // Validate transaction
or $db->rollback()  // Cancel transaction

To read:

$resql=$db->query("My select request");
if ($resql)
{
	$num = $db->num_rows($resql);
	$i = 0;
	if ($num)
	{
		while ($i < $num)
		{
			$obj = $db->fetch_object($resql);
			if ($obj)
			{
				// You can use here results
				print $obj->field1;
				print $obj->field2;
			}
			$i++;
		}
	}
}

Define style of your pages

To have the look of your own pages to match the Dolibarr theme, it is necessary to use the Dolibarr CSS styles.

You can use for example:

  • class="liste_titre" on tags tr and td for the head row of a table.
  • class="pair" or class="impair" on tags tr and td of other rows of a table.
  • class="flat" on all input fields (input, select, textarea...).
  • class="button" on HTML fields with type input type="submit".

Use the Dolibarr date picker

If you want to use the Dolibarr date selector (with its calendar popup) into your pages, use the following line:

 $form=new Form($db);
 $form->select_date('','mykey',0,0,0,"myform");

The string mykey will identify the date selector in the form. You must use different values if you use several date selectors in same page. The string myform is the name of the FORM in which the selector is included (value found in the form name="myform" in HTML page). This means a date selector must be included necessarily into an html FORM.

To get value after the POST of your form, the command is:

$mydate = dol_mktime(12, 0 , 0, $GETPOST('mykeymonth', 'int'), GETPOST('mykeyday', 'int'), GETPOST('mykeyyear', 'int'));
print strftime('%A %d %B %Y', $mydate);

Overwrite template file (tpl)

If you want to overwrite tpl file on your module, you need to declare it on the module_parts :

'tpl' => 1,

Then you can put any tpl file on mymodule/core/tpl as soon as the module is activate, the tpl will be overwrited

Add your own setup page (optional)

When: If your module needs parameters, which are to be provided by the user, for proper setting up of the module.

Create your page to edit parameters

If your module needs several parameters to be setup, you must create a page to edit options (these options will be saved in the table llx_const). Create a page named mymodule_setuppage.php that shows a form for possible options to update them into the above-mentioned table. It is necessary to take an example from a page of the directory /admin that will show you the way to read/save your parameters. Put this PHP page into the directory /admin of your module (e.g. mymodule/admin/mymodule_setuppage.php).

Modify the descriptor file of your module

Then, within the descriptor file of your module, modify the variable config_page_url to set the name of this PHP page. If the page is in the directory admin/, then the path is not required, e.g. like this:

$this->config_page_url = array("mymodule_setuppage.php");

If the page is in the directory mymodule/admin/, then like this:

$this->config_page_url = array("mymodule_setuppage.php@mymodule");

Test your page

Go into page Home->Setup->Modules, you should see a picture at the end of the line of your module to reach your setup page. Click on it, you should be able to view/edit parameters from your page.

Define your entries in the menu (optional)

When: If you have created PHP pages, it is necessary that those pages can be reached from menu entries in Dolibarr menu.

Define your menu entries

For this, you must define into the module descriptor, the array this->menu that declares all menus added by your module. This array contains entries that will appear once your module is activated. The example module descriptor file modMyModule.class.php contains an example to declare a top menu and also its left menu entries.

This is the example of code to declare your own menu entries in a module descriptor file:

// Main menu entries
$this->menu = array();			// List of menus to add
$r=0;

// Add here entries to declare new menus
// Example to declare the Top Menu entry:
$this->menu[$r]=array(	'fk_menu'=>0,			// Put 0 if this is a top menu
			'type'=>'top',			// This is a Top menu entry
			'titre'=>'MyModule top menu',
			'mainmenu'=>'mymodule',
			'leftmenu'=>'mymodule',
			'url'=>'/mymodule/pagetop.php',
			'langs'=>'mylangfile',	// Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
			'position'=>100,
			'enabled'=>'1',			// Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled.
			'perms'=>'1',			// Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
			'target'=>'',
			'user'=>2);				// 0=Menu for internal users, 1=external users, 2=both
$r++;

// Example to declare a Left Menu entry:
$this->menu[$r]=array(	'fk_menu'=>'fk_mainmenu=xxx',		    // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode of parent menu
			'type'=>'left',			        // This is a Left menu entry
			'titre'=>'MyModule left menu 1',
			'mainmenu'=>'xxx',
			'leftmenu'=>'yyy',
			'url'=>'/mymodule/pagelevel1.php',
			'langs'=>'mylangfile',	// Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
			'position'=>100,
			'enabled'=>'1',			// Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled.
			'perms'=>'1',			// Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
			'target'=>'',
			'user'=>2);				// 0=Menu for internal users,1=external users, 2=both
$r++;

To show the menu or not depending on a permission, modify property perms in the array. See chapter on permissions later to see how to add permissions.

Test your menu entries

Disable and re-enable your module under the Dolibarr module setup page, menus entries must appear (if property 'enabled' is declaration array is ok).

Add your own permissions (optional)

When: If you want to add new permissions.

The way to define permissions that will manage your module is done inside the module descriptor created previously. Modify line

$this->rights_class = 'mymodule'

with correct value for mymodule.

Then you must fill the array $this->rights with as many entries than different permissions you need to manage.

$this->rights[$r][0] = 10001;
$this->rights[$r][1] = 'Label by default of permission';
$this->rights[$r][2] = 'r';
$this->rights[$r][3] = 1;
$this->rights[$r][4] = 'action';
$this->rights[$r][5] = 'subaction';
$r++;

Into $this->rights[$r][0], put a permission id not already used (See into menu System info on a working installation of Dolibarr to know list of id already used by standard modules. Into $this->rights[$r][1], put a label by default for permission (This label will be used if no translation can be found into the file admin.lang Translation key should be "Permission10001=My permission Label"). Into $this->rights[$r][2], types of the permission. There are three type of permission, 'r' for read, list or expert permission, 'w' for write or update permission and 'd' for delete permission. Into $this->rights[$r][3], put 1 if this permission must be granted automatically by default to any newly created user. Into $this->rights[$r][4] and $this->rights[$r][5], put an action and subaction string without spaces. You will be able to test if a user has the permission in your PHP source code with the sequence:

if ($user->rights->mymodule->action->subaction) ...

Define your own box (optional)

When: If your module needs to provide one or several new boxes to show on home page.

Define your box

For this, modify the array $this->boxes into the module descriptor file. All you have to do is to add 2 lines for each box file you will create into directory htdocs/mymodule/core/boxes

Example:

$this->boxes[0]['file']='mybox0.php@mymodule'
$this->boxes[0]['note']='My box 0'
 ...
$this->boxes[n]['file']='myboxn.php@mymodule'
$this->boxes[n]['note']='My box n'

Then create files htdocs/mymodule/core/boxes/mybox0.php, htdocs/mymodule/core/boxes/mybox1.php... by copying an example from an existing box file (found into directory htdocs/core/boxes).

Test if your box is detected by Dolibarr

Disable and enabled module.

Go into menu Home - Setup - Boxes.

Your boxes must appear in the list of boxes you can activate. Activate the box and go on the home page to see if the box is showing correctly.

Define your own export (optional)

When: If your module provides new predefined database export profiles (for its own tables or for already existing tables of another module).

Define export

For this uncomment and modify arrays $this->export_xxx in your module descriptor file.

Test your export

Go into menu Tools -> Export. Your export will appear in the list of available predefined exports (if your module is enabled). Choose it, you must see a list of all possible fields defined in the export arrays. Choose on field and try to build an export file. If ok, try again with all fields.

Define your CSS styles (optional)

When: If in your PHP pages, you use class styles that are not defined inside Dolibarr themes CSS (not recommended).

Create and declare your style sheet

Create a style sheet CSS named mymodule.css or mymodule.css.php and put it into directory htdocs/mymodule. You can have several CSS files per module. Remember it's better to use existing styles already available by default into Dolibarr (The CSS file used by Dolibarr is file themes/mytheme/themename.css.php. Create your own CSS files only if you need absolutely to add not already existing styles.

Once your style sheets are ready, declare them into your module descriptor file by modifying the property $this->modules_parts. Value to put here must be an array of relative URLs of your CSS files. For example

$this->module_parts = array('css' => array('/mymodule/css/mymodule.css.php','/mymodule/css/myother.css'));

Test your style sheet

Disable and enable your module.

Go on the home page (index.php). Show the HTML source of the page.

In the HTML header, you should see a line that declares your style sheet.

Add your JavaScript functions (optional)

When: If in your PHP pages, you use javascript functions not available in Dolibarr (in file lib_head.js)

If you need to use your own JavaScript functions inside your PHP pages, it is necessary to define your functions in your JavaScript file htdocs/mymodule/js/mymodule.js, included in the HTML <head/> section. Dolibarr is responsible for building that HTML section. In order to ask it to include your JavaScript file, you just need to provide it to the llxHeader() function called by your page.

Example for page /htdocs/mymodule/mypage.php :

$morejs=array("/mymodule/js/mymodule.js");
llxHeader('','Titre','','','','',$morejs,'',0,0);

Run your own code on any Dolibarr event (optional)

When: If you want to execute your own code once a common Dolibarr event has occurred (example: I want to update a table in my module when an invoice is created into Dolibarr), you must create a trigger.

See also Interfaces_Dolibarr_toward_foreign_systems and Interfaces_from_foreign_systems_toward_Dolibarr

Insert your code inside Dolibarr hooks positions (optional)

When: When you want to add code or replace Dolibarr code into another situation than a business event (See the previous chapter for adding code during a business event).

See page Hooks_system.


Add your own numbering rules

When: When you need a new rule for generated ref of elements that are not covered by existing rules.

See page Create numbering module.

Add your document template (optional)

When: When you want to personalize your own generated PDF or ODT documents.

Note: To add this feature, you don't need to create a module descriptor.

Documentation to add your own template is available on page Create_a_PDF_document_template or Create_an_ODT_document_template.

Add your skin (optional)

When: When you want to personalized your colors/fonts/images.

Note: To add this feature, you don't need to create a module descriptor.

To add your own skin, read page Skins.

Some coding rules and predefined functions

The coding rules to be followed are defined in the Developer documentation, under section "General Information - Language and standards development".

A lot of predefined features for developers are also available and described into page Developer documentation under section "Technical components of Dolibarr".

Create a package to distribute and install your module

This process must be used to generate a package to submit it on the http://www.dolistore.com marketplace. But you can use it to have a package easy to distribute on your own network.

  • Go into the directory /build and copy the file makepack-dolibarrmodules.conf into makepack-mymodule.conf. Warning, this directory may not be provided in some packages of stable versions. If so, it can be retrieved from the snapshot available for download on the Dolibarr website in area "Development version" (taken in this case the whole build directory which is autonomous and independent directory).

Edit this file to add a list of file names for all new files you created for your module (module descriptor, new sql tables files, php page, images, etc...)

  • Run the script via Perl (need the Perl version 5.0 or later):
perl makepack-dolibarrmodule.pl

The script asks you the name of your module, its major and minor version. A file mymodule.zip will then be manufactured containing your module ready to be deployed.

  • The person who receives your module must then place the file in the root directory of a Dolibarr installation and perform the command:
tar -xvf mymodule.zip
  • If you want your module to be public, you can submit it (the zip file) on the Dolibarr marketplace website: DoliStore.com (you must first create an account and be logged in to use the "Submit a module/product" link).
    • If your module was built correctly, the file will be validated later.
    • If quality is sufficient and license permits it, the code might be added inside main Dolibarr sources (except if you disagree for that).

Enabling/activation condition of external module on DoliStore

See Validation Rules