Dolibarr Developer Skill
When to Use
- Creating or extending a Dolibarr module (custom or external)
- Implementing hooks (
actions_mymodule.class.php) or triggers
- Writing DAO/business object classes, SQL table definitions
- Adding menus, tabs, permissions, boxes, exports, CSS/JS
- Building cron/command-line scripts
- Writing PDF/ODT document templates
- Following Dolibarr coding rules (PHP, SQL, HTML norms)
Key Concepts
Architecture
- MVC pattern: Controller (
/* Actions */) + View (/* View */) in same PHP file
- Active Record ORM: one class per table with CRUD methods
- Global objects:
$db, $user, $conf, $langs, $mysoc, $hookmanager, $extrafields
- Module location: external modules live in
htdocs/custom/mymodule/
- Table prefix: all tables prefixed
llx_
Module Entry Points
| Extension point |
When to use |
| Hooks |
Inject/replace code in existing pages without modifying core |
| Triggers |
React to business events (invoice created, order validated…) |
| Tabs |
Add tabs on thirdparty, order, product, invoice… sheets |
| Menus |
Add top-level or left-menu entries |
| Boxes |
Add widgets on home page |
| Extrafields |
Add fields to existing objects (no module needed for simple cases) |
| PDF templates |
Customize generated PDF documents |
Step-by-Step: Build a Module
1. Generate Skeleton
Use the built-in Module Builder (enable it in Setup → Modules, then click the bug icon top-right). It generates modMyModule.class.php, SQL files, DAO class, and page skeletons.
GitHub template: https://github.com/Dolibarr/dolibarr/tree/develop/htdocs/modulebuilder/template
2. Module Descriptor (required)
File: htdocs/custom/mymodule/core/modules/modMyModule.class.php
See → Module Structure reference
3. SQL Tables (optional)
- Files in
mymodule/sql/llx_mytable.sql + llx_mytable.key.sql
- Load via
$this->_load_tables('/mymodule/sql/') in init()
- Primary key always
rowid INTEGER AUTO_INCREMENT PRIMARY KEY
- Table prefix
llx_, InnoDB engine, no DB triggers, no DELETE CASCADE
See → Coding Rules reference
4. DAO Class (optional)
File: mymodule/class/myobject.class.php
- Copy from
htdocs/modulebuilder/templates/class/myobject.class.php
- Methods:
create(), fetch(), update(), delete(), fetchAll()
- DB access pattern:
$db->begin() / $db->query() / $db->commit() or $db->rollback()
5. Hooks (optional)
- Declare context in
modMyModule.class.php: $this->module_parts = array('hooks' => array('thirdpartycard', 'orderlist'))
- Create
mymodule/class/actions_mymodule.class.php with hook methods
- Disable + re-enable module after changing contexts (stored in DB)
- Find contexts: search
initHooks( in source. Find hook names: search executeHooks( in source.
See → Hooks & Triggers reference
6. Menus (optional)
Declare in $this->menu array in module descriptor.
fk_menu=0 + type='top' for top menu
fk_menu='fk_mainmenu=xxx' + type='left' for left sub-menu
perms field controls visibility by permission
user=0 internal, 1 external, 2 both
7. Tabs (optional)
Declare in $this->tabs array: 'objecttype:+tabcode:Title:langfile@mymodule:condition:/mymodule/page.php?id=__ID__'
Object types: thirdparty, order, invoice, product, contact, contract, propal, member, user…
8. Permissions (optional)
Declare in $this->rights array. Test with $user->rights->mymodule->action->subaction.
9. PHP Pages (optional)
- Bootstrap: include
main.inc.php (try multiple relative paths, see template)
- Use
dol_include_once('/mymodule/class/myclass.class.php', 'MyClass') for module classes
- Use
require_once DOL_DOCUMENT_ROOT.'/core/...' for Dolibarr core classes
- CSS classes:
liste_titre, pair/impair, flat, button
- JS: pass
$morejs array to llxHeader()
10. Setup Page (optional)
- Create
mymodule/admin/setup.php
- Set
$this->config_page_url = array("setup.php@mymodule") in descriptor
Packaging & Distribution
References
Official Docs
1---2name: dolibarr-development3description: Dolibarr ERP/CRM developer skill. Use for: building or extending Dolibarr modules (external/custom), implementing hooks, triggers, DAO classes, SQL tables, menus, permissions, tabs, boxes, PDF templates, cron scripts. Covers both core contributor and external module developer workflows. Applies coding rules (PSR-12, SQL norms, MVC pattern, Active Record).4---56# Dolibarr Developer Skill78## When to Use9- Creating or extending a Dolibarr module (custom or external)10- Implementing hooks (`actions_mymodule.class.php`) or triggers11- Writing DAO/business object classes, SQL table definitions12- Adding menus, tabs, permissions, boxes, exports, CSS/JS13- Building cron/command-line scripts14- Writing PDF/ODT document templates15- Following Dolibarr coding rules (PHP, SQL, HTML norms)1617## Key Concepts1819### Architecture20- **MVC pattern**: Controller (`/* Actions */`) + View (`/* View */`) in same PHP file21- **Active Record ORM**: one class per table with CRUD methods22- **Global objects**: `$db`, `$user`, `$conf`, `$langs`, `$mysoc`, `$hookmanager`, `$extrafields`23- **Module location**: external modules live in `htdocs/custom/mymodule/`24- **Table prefix**: all tables prefixed `llx_`2526### Module Entry Points27| Extension point | When to use |28|---|---|29| Hooks | Inject/replace code in existing pages without modifying core |30| Triggers | React to business events (invoice created, order validated…) |31| Tabs | Add tabs on thirdparty, order, product, invoice… sheets |32| Menus | Add top-level or left-menu entries |33| Boxes | Add widgets on home page |34| Extrafields | Add fields to existing objects (no module needed for simple cases) |35| PDF templates | Customize generated PDF documents |3637---3839## Step-by-Step: Build a Module4041### 1. Generate Skeleton42Use the built-in **Module Builder** (enable it in Setup → Modules, then click the bug icon top-right). It generates `modMyModule.class.php`, SQL files, DAO class, and page skeletons.4344GitHub template: https://github.com/Dolibarr/dolibarr/tree/develop/htdocs/modulebuilder/template4546### 2. Module Descriptor (required)47File: `htdocs/custom/mymodule/core/modules/modMyModule.class.php`48- Class name starts with `mod`, file matches class name49- Unique `$this->numero` (check https://wiki.dolibarr.org/index.php/List_of_modules_id)50- Declare hooks contexts, menus, permissions, tabs, boxes, CSS/JS in this file51- Enable/disable via Setup → Modules5253See → [Module Structure reference](./references/module-structure.md)5455### 3. SQL Tables (optional)56- Files in `mymodule/sql/llx_mytable.sql` + `llx_mytable.key.sql`57- Load via `$this->_load_tables('/mymodule/sql/')` in `init()`58- Primary key always `rowid INTEGER AUTO_INCREMENT PRIMARY KEY`59- Table prefix `llx_`, InnoDB engine, no DB triggers, no DELETE CASCADE6061See → [Coding Rules reference](./references/coding-rules.md)6263### 4. DAO Class (optional)64File: `mymodule/class/myobject.class.php`65- Copy from `htdocs/modulebuilder/templates/class/myobject.class.php`66- Methods: `create()`, `fetch()`, `update()`, `delete()`, `fetchAll()`67- DB access pattern: `$db->begin()` / `$db->query()` / `$db->commit()` or `$db->rollback()`6869### 5. Hooks (optional)70- Declare context in `modMyModule.class.php`: `$this->module_parts = array('hooks' => array('thirdpartycard', 'orderlist'))`71- Create `mymodule/class/actions_mymodule.class.php` with hook methods72- **Disable + re-enable** module after changing contexts (stored in DB)73- Find contexts: search `initHooks(` in source. Find hook names: search `executeHooks(` in source.7475See → [Hooks & Triggers reference](./references/hooks-triggers.md)7677### 6. Menus (optional)78Declare in `$this->menu` array in module descriptor.79- `fk_menu=0` + `type='top'` for top menu80- `fk_menu='fk_mainmenu=xxx'` + `type='left'` for left sub-menu81- `perms` field controls visibility by permission82- `user=0` internal, `1` external, `2` both8384### 7. Tabs (optional)85Declare in `$this->tabs` array: `'objecttype:+tabcode:Title:langfile@mymodule:condition:/mymodule/page.php?id=__ID__'`8687Object types: `thirdparty`, `order`, `invoice`, `product`, `contact`, `contract`, `propal`, `member`, `user`…8889### 8. Permissions (optional)90Declare in `$this->rights` array. Test with `$user->rights->mymodule->action->subaction`.9192### 9. PHP Pages (optional)93- Bootstrap: include `main.inc.php` (try multiple relative paths, see template)94- Use `dol_include_once('/mymodule/class/myclass.class.php', 'MyClass')` for module classes95- Use `require_once DOL_DOCUMENT_ROOT.'/core/...'` for Dolibarr core classes96- CSS classes: `liste_titre`, `pair`/`impair`, `flat`, `button`97- JS: pass `$morejs` array to `llxHeader()`9899### 10. Setup Page (optional)100- Create `mymodule/admin/setup.php`101- Set `$this->config_page_url = array("setup.php@mymodule")` in descriptor102103---104105## Packaging & Distribution106- Package via `build/makepack-dolibarrmodule.pl`107- Deploy: unzip in Dolibarr root108- Publish on https://www.dolistore.com109110---111112## References113- [Module structure, descriptor, file tree](./references/module-structure.md)114- [Hooks system & Triggers](./references/hooks-triggers.md)115- [Coding rules: PHP, SQL, HTML](./references/coding-rules.md)116- [Technical components: menus, tabs, permissions, DB, dates](./references/technical-components.md)117118## Official Docs119- Developer docs: https://wiki.dolibarr.org/index.php/Developer_documentation120- Module development: https://wiki.dolibarr.org/index.php/Module_development121- Hooks system: https://wiki.dolibarr.org/index.php/Hooks_system122- Coding rules: https://wiki.dolibarr.org/index.php/Language_and_development_rules123- Doxygen (class/file tree): https://doxygen.dolibarr.org/