Module development: Difference between revisions
| Line 219: | Line 219: | ||
== Définissez vos entrées == | == Définissez vos entrées == | ||
Pour cela, il vous faut définir dans le fichier descripteur de menu le | Pour cela, il vous faut définir dans le fichier descripteur de module, le tableau this->menu qui déclare les menus. | ||
Ce tableau contient toutes les entrées qui apparaitront dans les menus une fois le module activé. | |||
Le fichier de descripteur de module exemple '''modMyModule.class.php''' possède un exemple de déclaration de menu haut ainsi que de ses entrées menu gauche associées. | |||
Voici un exemple de déclaration d'entrées de menu dans le fichier descripteur: | |||
<pre> | <pre> | ||
$this->menu | // 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'=>'1', // Use 1 if you also want to add left menu entries using this descriptor. Use 0 if left menu entries are defined in a file pre.inc.php (old school). | |||
'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'=>'r=0', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry) | |||
'type'=>'left', // This is a Left menu entry | |||
'titre'=>'MyModule left menu 1', | |||
'mainmenu'=>'mymodule', | |||
'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++; | |||
</pre> | </pre> | ||
== Tester vos entrées menus == | == Tester vos entrées menus == | ||
Revision as of 00:28, 26 July 2009
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 :
- Add new tables in database
- Add your own menu entries
- Add new screens to edit new tables
- Add predefined exports for the internal export tool
- Add new information boxes in the home page
- Define new permissions
- Execute code automatically triggered by a particular Dolibarr action
etc... All those operations are possible with version 2.4 or more of Dolibarr.
Create a descriptor of Module (required)
When: Required as soon as an addon is developped, whatever is its goal.
Create your module descriptor
The first step is to create a file descriptor for the module. To do this go into the directory dev/skeletons and copy the file modMyModule.class.php in the directory htdocs/includes/modules. Then change the contents of this file to replace:
* all "modMyModule" with a value which corresponds to the vocation of your module. This value must always start with 'mod'. * $this->numero = 10000 by a number of free module (Go to Home page -> System Information -> Dolibarr to know id the list of modules used). * $this->const_name = 'MAIN_MODULE_MYMODULE' by $this-> const_name = 'MAIN_MODULE_XXX' where XXX must match the value chosen to replace MyModule and put in capitalized. * $dir = DOL_DOCUMENT_ROOT.'/mysql/tables/mymodule/'; by $dir = DOL_DOCUMENT_ROOT.'/mysql/tables where xxxxxxxx is the name of your module (without spaces). * 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.
Test your descriptor
Launch Dolibarr and go to page Setup->module? You must see a new line with your new module and the possibility to activate it or not (browse all the tabs of each category of modules to find it). It's value of $this->special that determines in which tab will be your module.
Create your SQL tables and the PHP accessor class (optionnal)
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.
Files for your own module must be placed in a directory.
Create a subdirectory called "sql" into directory of your module (eg htdocs/mymodule/sql) to put the sql scripts that you will create. Then in the "load_tables" function of your file descriptor module, modify the line
$dir = DOL_DOCUMENT_ROOT.'/mymodule/sql/';
by
$dir = DOL_DOCUMENT_ROOT.'/valuechooseformymodule/sql/';
Rules to follow:
- Add the files about creating tables commands on the principle of a file llx_matable.sql per table with a possibly file llx_matable.key.sql (see existing files in mysql/tables for examples).
- To manage data, you must create a file called data.sql inside directory /mymodule/sql/ that contains SQL command to add/edit/delete datas.
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. Rem: 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 Dolibarr to disable the module, dropper tables in database and reactivate the module. The tables should be recreated by the activation of the module. If this is not the case, check your scripts by passing them by hand, or check the Dolibarr logs.
Generate the accessors PHP class
Once you have created your tables into the database, move to the dev/skeletons directory and run the script
php build_class_from_table.php tablename
Note: If the command does not work, try to use php-cli php instead.
This will generate a file out.tablename.class.php that contains the class to manage table tablename. In this class, you can find the CRUD methods (Create / Read / Update / Delete) already working to do an insert, a fetch (select), an update, a delete of a row in table. Remove just the "out" from the file name and put the file in a subdirectory of htdocs specific to your module (in htdocs/mymodule for example).
A file out.tablename_script.php has been generated and contains a sample code to use the class for each of the 4 CRUD methods.
Add your own tabs on entities sheets (optionnal)
When: To add a tab on an entity (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
$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
The table should contain a list of strings, each string representing a new tab. The format of the string consisting of 4 parts separated by ":"
- Part 1: The entity code which should appear in the tab is a value from the following:
- 'thirdparty'
- 'intervention'
- 'supplier_order'
- 'supplier_invoice'
- 'invoice'
- 'order'
- 'product'
- 'propal'
- 'member'
- Part 2: The title of the tab. This can be a hard read or better code translation in a file lang.
- Part 3: The name of the file. Lang which contains correspondence between the code translation and language to display.
- Part 4: The url of the page to display when you click on the tab. The __ID__ string will be replaced automatically by the Id of the entity concerned.
To feed the contents of the tab with data from the database, see the next chapter.
Create your own PHP screens (optionnal)
When: If the purpose of your module is to add features that require new screens.
Create a 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 dev/skeletons (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/monmodule for example) to store the pages you will create.
Copy, into that directory, the file skeletons_page.php that will serve as a starting point for your page file and also file pre.inc.php. Edit the file pre.inc.php to have a correct relative path to the main.inc.php file.
include("../../main.inc.php)";
This depends on the depth of the directory in which the file is pre.inc.php (Add or remove "../"). 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 Objet that contains the characteristics of the user + his permissions.
- $conf Objet that contains Dolibarr configuration.
- $db Objet that contains an opened connection handler to the database.
- $langs Objet that contains the user's language.
Then enter your code to display the page.
Database access
If you need to edit some data in database inside you 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".
Utiliser le sélecteur de date de Dolibarr
Si vous le désirez, vous pouvez profiter du sélecteur de date dans des écrans Dolibarr. Pour cela, utilisez la ligne suivante:
$form=new Form($db); $form->select_date(,'mykey',0,0,0,"myform");
La chaine mykey identifie la zone date. Il faut y mettre une valeur différente s'il y a plusieurs zones. La chaine myform est le nom de la zone FORM (dans form name="myform" de la page HTML). L'affichage d'un sélecteur de date doit donc être intégrée dans une zone FORM Html.
Pour récupérer la valeur, à l'issu du POST, la commande est:
$datefacture = dolibarr_mktime(12, 0 , 0, $_POST['mykeymonth'], $_POST['mykeyday'], $_POST['mykeyyear']);
print strftime('%A %d %B %Y', $datefacture);
Définir votre page de configuration (optionnel)
Quand: Si votre module offre plusieurs options paramétrables.
Creer votre page d'édition de configuration
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). Créer une page PHP nommée monmodule_setupapage.php qui affiche les options possibles et les met à jour. 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. 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).
$this->config_page_url = array("monmodule_setupapage.php");
Tester votre page
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.
Quand: Si vous avez créé des pages PHP, il est nécessaire que ces écrans soient accessibles depuis le menu Dolibarr.
Définissez vos entrées
Pour cela, il vous faut définir dans le fichier descripteur de module, le tableau this->menu qui déclare les menus. Ce tableau contient toutes les entrées qui apparaitront dans les menus une fois le module activé. Le fichier de descripteur de module exemple modMyModule.class.php possède un exemple de déclaration de menu haut ainsi que de ses entrées menu gauche associées.
Voici un exemple de déclaration d'entrées de menu dans le fichier descripteur:
// 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'=>'1', // Use 1 if you also want to add left menu entries using this descriptor. Use 0 if left menu entries are defined in a file pre.inc.php (old school). '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'=>'r=0', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry) 'type'=>'left', // This is a Left menu entry 'titre'=>'MyModule left menu 1', 'mainmenu'=>'mymodule', '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++;
Désactiver et réactiver votre module sous Dolibarr, les entrées menus doivent alors apparaitre.
Définir vos propres permissions (optionnel)
Quand: Si vous voulez ajouter de nouvelles permissions.
La définition des permissions que gèrera votre module se fait dans le fichier descripteur créé dans la première étape. Modifier la ligne $this->rights_class = 'facture' par
$this->rights_class = 'monmodule'
Ensuite remplissez le tableau $this->rights avec autant d'entrée que de permissions différentes à gérer.
$this->rights[$r][0] = 10001; $this->rights[$r][1] = 'Libelle par défaut de ma permission'; $this->rights[$r][3] = 1; $this->rights[$r][4] = 'action'; $this->rights[$r][5] = 'sousaction'; $r++;
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. Dans $this->rights[$r][3], mettre 1 si cette permission est attribué d'office par défaut quand un utilisateur est créé. 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). 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:
if ($user->rights->monmodule->action->sousaction) ...
Définir vos propres box (optionnel)
Quand: Si votre module amène avec lui une ou plusieurs Boxes.
Définissez vos box
Pour cela, modifier les tableaux $this->boxes du fichier descripteur de module. Il suffit d'ajouter une ligne par fichier box qui se trouve dans le répertoire htdocs/includes/boxes
Exemple:
this->boxes[0][1]='mabox0.php' this->boxes[1][1]='mabox1.php' this->boxes[2][1]='mabox2.php' ... this->boxes[n][1]='maboxn.php'
Ensuite creer les fichiers mabox0.php, mabox1.php... en prenant exemple sur des box existantes (dans le répertoire htdocs/include/boxes
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)
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).
Définissez l'export
Pour cela, décommenter et modifier les tableaux $this->export_xxx du votre fichier descripteur de module.
Tester votre export
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é). 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)
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
Créer et déclarer votre feuille de style
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. 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
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)
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. 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.
Cette fonctionnalité n'est pas encore possible.
Déclencher du code sur un évènement Dolibarr (optionnel)
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.
Voir aussi Interfaces_Dolibarr_vers_exterieur et Interfaces_Exterieur_vers_Dolibarr
Create a package to distribute and install your module
- 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 CVS 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 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.tgz 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 monmodule.tgz
- If you want your module to be public, you can submit it (the tgz file) on Dolibarr web site on download area: http://www.dolibarr.org -> downloads -> contrib -> submit a file (you must create an account and be logged to have link appeared).
- If your module was build correctly, file will be validated later.
- If quality is enough and license permits it, code might be added inside main Dolibarr sources (except if you disagree for that).
Some coding rules
The coding rules to be followed are defined in the Developer documentation, under section "General Information - Language and standards development".
Using MDA
A method to generate a functional module from a UML model has been developed. More information on the page UML2Dolibarr - Build a module using MDA.