模块开发
要创建新模块,需要执行以下几个步骤。本教程旨在向您介绍每一个步骤,以便添加一个模块来扩展Dolibarr的功能,例如添加以下一个或多个功能:
- 在数据库中添加新表
- 在菜单中添加您自己的菜单项
- 添加对象和屏幕以输入/查看新表
- 在视图页上添加或删除选项卡/编辑对象(发票、产品、订单、事件等)
- 为内部导出工具添加预定义的导出
- 向主页添加新信息框/widget小组件
- 添加新的替换变量
- 定义新权限
- 自动触发指定 Dolibarr 操作的代码
- 将自定义代码插入 Dolibarr 的钩子位置
- 为所创建的对象的引用添加编号模块(为数据自动编码的模块)
- 添加PDF文档模板
- 添加一个新主题/皮肤
等等...
以下章节介绍了如何以简单的方式手动完成所有这些操作。对于有经验的开发人员来说,使用MDA生成的方法也不错,详见最后一章。
使用模块生成器构建模块
从Dolibarr 9.0开始,您可以使用"模块生成器"(Module Builder)创建模块的主要文件。要激活它 :
- 设置参数 MAIN_FEATURES_LEVEL 的值为 2 ( 设置 / 其他 )(或者修改llx_const表中该项的记录的value值为2)
- 在 主页 - 设置 - 设置-模块/应用 多模块工具 中激活“模块生成器”(ModuleBuilder)
- 点击屏幕右上角菜单栏中出现的'Bug'图标
- 运行的ModuleBuilder界面如下:
外部模块模板示例
一个Dolibarr外部模块的模板/框架:Github Dolibarr模块
创建模块
以下章节描述了创建Dolibarr模块所需的操作。无论模块的用途如何,第一章描述的操作都是必须要完成的,后续章节描述的操作是否要做将取决于模块的需求。
创建模块描述符(必做)
何时:无论其用途如何,开发扩展模块时都是强制性的。从Dolibarr 9.0开始,您可以使用“模块生成器”创建模块的描述符。该工具仍处于开发和完善阶段,但其已经可以使用。
使用模块生成器创建描述符
- 通过单击"Bug"图标启动模块生成器
- 在下图“模块名称”处输入不含空格的模块名称(模块名称不得包含下划线 :_),然后单击"创建"按钮。
- 已初始化具有第一个文件的模块。然后,您可以更改模块描述符的参数:
备选方案:手动创建描述符(不使用模块生成器)
第一步是创建模块描述文件(描述符)。为此:
- 创建目录 htdocs/custom/mymodule/core/modules 。
- 进入目录 htdocs/modulebuilder/template/core/modules 将文件 modMyModule.class.php 复制到目录 htdocs/custom/mymodule/core/modules 中。
- 重命名modMyModule.class.php文件,只需修改MyModule部分即可(文件必须以mod开头)
然后,编辑此文件的内容:
- 将所有modMyModule替换为与模块用途相对应的值。此值必须始终以“mod”开头,并且仅包含字母字符。
- 通过 $this->numero = 100000 设置模块ID。为避免冲突,您可以参考以下页面查找已分配的ID:模块ID清单 。
- 可能还需要修改构造函数中定义的其他变量(有关其含义,请参阅类文件代码中的注释)。
模块的描述文件(描述符)已准备就绪。请参阅下一步“测试描述符”以激活您的新模块。
测试描述符
启动Dolibarr并进入 主页->设置->模块/应用 页面,您应该会看到一个新行,其中包含新模块以及是否激活它的选项(浏览每个模块类别的所有选项卡,直到找到它)。
$this->special 的值决定了模块位于哪个类别选项卡中。
注意:如果在模块描述符中设置了属性 version ,则应在 模块/应用 页面看到包含新模块的新行以及是否激活它的选项。如果将属性 version 设置为“develop”或“experiental”,若要查看模块,必须先进入页面 “主页->设置->其他设置”,并将参数 MAIN_FEATURES_LEVEL 设置为 1 以查看“实验性”(experimental)模块,或设置为 2 以查看“开发”(development)模块。
模块的名称
模块名称不得包含下划线或下划线:_
新模块的树视图(必需)
以下是组织模块文件时要遵循的树结构(如果使用ModuleBuilder生成文件,则自动采用此树结构)。
注:zip 文件也必须符合此规则,只有第二行是强制性的。
- mymodule/* ---------------- 包含php页面(请注意,您也可以添加您选择的任何其他子目录)。注意:如果您的模块是一个metapackage(一个以zip的形式嵌入其他模块的模块),则必须在此处放置一个文件 metapackage.conf。
- mymodule/build/ ----------- 可以包含用于编译或构建模块安装包而开发的任何文件
- mymodule/core/modules/ ---- 包含模块描述符文件 modMyModule.class.php
- mymodule/core/triggers ---- 包含模块提供的触发器
- mymodule/admin/ ----------- 包含设置模块的页面
- mymodule/class/ ----------- 包含模块提供的PHP类文件
- mymodule/css -------------- 包含模块提供的CSS文件
- mymodule/js --------------- 包含模块提供的javascript文件
- mymodule/docs ------------- 提供doc和licence文件
- mymodule/img -------------- 包含模块提供的图片文件
- mymodule/langs/xx_XX ------ 包含xx_XX语言的语言文件(至少要放一个 en_US 语言文件)
- mymodule/lib -------------- 包含模块提供和使用的库文件
- mymodule/scripts ---------- 提供命令行工具或脚本。注意:命令行脚本的第一行必须是:#!/usr/bin/env php
- mymodule/sql -------------- 包含模块提供的用于添加新表或索引的SQL文件
- mymodule/themes/mytheme --- 如果模块提供了自己的主题/皮肤
一个好的Dolibarr扩展模块的模板/框架:GitHub Dolibarr Module Modèle
创建数据表和 PHP DAO 类 (可选)
何时:如果您的模块需要管理自己的数据
创建 .sql 文件
如果您的模块要处理在Dolibarr标准版中不存在的数据,则需要自定义数据库表来存储这些数据。
在模块的目录中创建sql子目录(mymodule/sql),用于放置要创建的sql脚本(使用ModuleBuilder,在"对象"选项卡中创建新对象后,将自动执行此步骤)。
接下来,检查模块描述符文件,在 init 函数中是否包括行:
$this->_load_tables('/mymodule/sql/');
并且未被注释掉。
应遵循的规则:
- 根据每个表1个文件的原则添加表的创建命令文件,命名为 llx_mytable.sql(用于表),可能还附带 llx_mytable.key.sql 文件(用于索引或外键)。示例请参阅 install/mysql/tables 中的现有文件。
- SQL字段的推荐类型和名称在 [[1]] 页中定义。
- 管理数据:对于添加/操作数据的命令,它们都必须位于同一目录 /mymodule/sql/ 中名为 data.sql 的文件中。
- 不要使用双引号(如 "string"),因为双引号(")在 PostGreSQL 中有特殊的含义
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__');
文件中的SQL语句必须对 mysql 数据库有效。请注意:不需要维护其他数据库类型的文件。它们由数据库驱动程序动态读取和转换。
测试 .sql 文件
文件准备就绪后,您可以返回Dolibarr的模块管理页面,禁用模块,删除数据库表(如果它们已经存在),然后重新激活模块。正常情况下,应该可以通过激活模块来重新创建表。否则,请手动检查脚本,或查看Dolibarr日志。
生成 PHP DAO 表访问类
创建对象时,ModuleBuilder会自动生成对象的PHP DAO类文件。
如果不使用模块生成器,您将在模块框架文件htdocs/modulebuilder/templates/class/myobject.class.php 中找到示例。
在这个类中,已经有可调用的 CRUD(Create/Read/Update/Delete)方法来执行表行数据的插入、获取(select)、更新和删除。修改此文件以使用正确的模块名和表名,并将该文件放在模块的 class 子目录中。若使用 ModuleBuilder 只需点击几下鼠标即可完成此操作。
使用ModuleBuilder生成PHP DAO类文件
- 使用ModuleBuilder生成PHP DAO类文件,简单至在下图中选择'对象'选项卡,输入'对象名',然后点击创建,即可生成相关一切文档。
选项卡显示(可选)
添加或删除对象表单上的选项卡
何时:在标准对象(发票、订单、报价单、会员…)的表单中添加您自己的选项卡
要执行此操作,请打开之前创建的模块描述符文件并编辑 $this->tabs 数组:
// 用于在新tabs中添加新页面或删除现有页面的数组
$this->tabs = array('objecttype:+tabname1:Title1:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mypagetab1.php?id=__ID__' // 增加一个由code tabname1标识的新tab
'objecttype:+tabname2:Title2:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mypagetab2.php?id=__ID__', // 增加一个由code tabname2标识的新tab
'objecttype:-tabname'); // 删除一个由code tabname标识的现有选项卡
该表应包含字符串列表,每个字符串表示一个新选项卡。字符串格式由6个部分组成,由“:”分隔
- 第1部分:选项卡的元素类型(objecttype),只能是下列值之一:
- 'categories_x'-------在类别视图中添加选项卡(将 'x' 替换为类别类型:0=产品;1=供应商;2=客户/准客户;3=会员)
- 'contact'------------在联系人/地址视图中添加选项卡
- 'contract'-----------在合同视图中添加选项卡
- 'group'--------------在用户组视图中添加选项卡
- 'intervention'-------在现场服务视图中添加选项卡
- 'invoice'------------在客户发票视图中添加选项卡
- 'invoice_supplier'---在供应商发票视图中添加选项卡
- 'member'-------------在会员视图中添加选项卡
- 'opensurveypoll'-----在调查视图中添加选项卡
- 'order'--------------在客户订单视图中添加选项卡
- 'order_supplier'-----在供应商订单视图中添加选项卡
- 'payment'------------在客户付款视图中添加选项卡
- 'payment_supplier'---在供应商付款视图中添加选项卡
- 'product'------------在产品视图中添加选项卡
- 'propal'-------------在报价单视图中添加选项卡
- 'project'------------在项目视图中添加选项卡
- 'stock'--------------在库存视图中添加选项卡
- 'thirdparty'---------在合作方视图中添加选项卡
- 'user'---------------在用户视图中添加选项卡
- 第2部分:用于标识要添加(以+开头)或删除(以-开头)的选项卡的codeName
- 第3部分:选项卡的标题。这可以是硬编码的字符串,或者是更好的,lang文件中的翻译代码。
- 第4部分:文件“*.lang”的名称(不带.lang扩展名),此文件内有翻译代码和要显示的语言字符串之间的对应关系。如果这个文件名后面跟@mymodule,则Dolibarr将在模块自己的 lang 目录中查找翻译文件,即htdocs/mymodule/langs/code_CODE/mymodule.lang,否则Dolibarr将查找翻译文件htdocs/langs/code_CODE/mylangfile.lang。
- 第5部分:判断选项卡是否可见的条件。设置为“1”,会使其始终可见。
- 第6部分:单击选项卡时要显示的页面的URL。字符串“__ID__”将自动替换为相关元素的ID。
要使声明生效,必须禁用并重新激活该模块。
要使用来自数据库的数据填充选项卡的内容,请参阅下一章。
为了获取现有选项卡的名称“tabname”,您必须检查文件“core/lib/module.lib.php”的函数“product_prepare_head”中使用的名称,该文件对应于“$head[$h][2]”部分。
将对象的标准选项卡添加到其自己的表单页面
何时:在您自己的表单中添加标准对象(产品、合作方…)的选项卡
必须遵循以下步骤:
1. 在代码中包含定义相关函数的文件
对于每种对象选项卡,都有两个文件需要使用下列语句:
require_once($url_fichier) ;
以下是要包含的文件示例(DOL_DOCUMENT_ROOT 对应于 dolibarr/htdocs/ 文件夹):
- 合作方(thirdparty) :
- DOL_DOCUMENT_ROOT/societe/class/societe.class.php
- DOL_DOCUMENT_ROOT/core/lib/company.lib.php
- 产品(product) :
- DOL_DOCUMENT_ROOT/product/class/product.class.php
- DOL_DOCUMENT_ROOT/core/lib/product.lib.php
- 发票 (invoice) :
- DOL_DOCUMENT_ROOT/compta/facture/class/facture.class.php
- DOL_DOCUMENT_ROOT/core/lib/invoice.lib.php
...
2. 创建并加载要在自己的表单中显示的标准对象
创建所需类的对象,并从数据库中获取对象数据。为此,您必须使用相应类的fetch()函数,并将从URL(/mytab.php?id=1)获取的对象id作为参数传递。
例如:
$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. 检索与所选实体对应的选项卡列表
使用函数XXX_prepare_head($obj)(其中XXX是实体名称)创建一个包含要显示的选项卡定义的数组。要传递的参数是要显示选项卡的对象。
返回的数组由以下内容组成:
$head // 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
示例:
$head = product_prepare_head($product, $user) ; // 参数 $user 是要显示选项卡的对象,这就是"产品"对象为"user"对象准备的所有可用的选项卡的数组。
某些函数上不存在$user参数
4. 在您的页面上显示选项卡
使用dol_fiche_head()函数,该函数显示由 XX_prepare_head() 返回的 $head 数组中包含的选项卡。
dol_fiche_head($links, $active='0', $title='', $notab=0, $picto='')
//$links // tabs的数组,上面称为$head
//$active // 活动选项卡(输入模块文件中定义的选项卡名称,或$head[$h][2]中包含的名称)。此选项卡将突出显示
//$title // 要显示的标题(显示在无法单击的特殊选项卡中)
//$notab
//$picto // 要显示到标题中的图片的名称。可能的值为:
// product
// service
// company
此函数将显示所需的选项卡,并打开一个html元素< div class="" >,该元素对应于选项卡下方的显示区域(如果参数 $notab=0)。要关闭显示区域,只需在PHP代码中使用关闭元素</div>。
注:相关的更多细节,请参阅 Doxygen文档 或直接参考 Dolibarr 代码。
创建PHP屏幕页面(可选)
何时:如果新模块的目的是添加一个需要新屏幕页面的功能。
创建原始PHP屏幕页面
随后,您可以使用 modulebuilder 目录中提供的示例模板(myobject_page.php)创建基于表数据的PHP页面(有关命令行脚本的开发,请参阅 脚本开发 )。同样,如果您使用的是 ModuleBuilder,则在初始化对象时会自动创建页面实例(清单、创建页面、Notes选项卡等)。
要创建新的用户屏幕页面,请创建特定于模块的 htdocs 子目录(如果尚未创建)(如 htdocs/mymodule ),以便在其中放置要创建的页面。
从复制文件 myobject_page.php 作为开始。编辑该文件,以便能正确找到并加载 main.inc.php 文件:
// 加载Dolibarr环境
$res=0;
// 尝试include在CONTEXT_DOCUMENT_ROOT(不总是定义的)中定义的已知web根目录中的main.inc.php
if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
// 尝试include由SCRIPT_FILENAME计算的web根检测到web根的main.inc.php
$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");
// 尝试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 && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
if (! $res) die("Include of main fails");
如您所见,其多次尝试加载 main.inc.php(或 master.inc.php)文件。目标是在尽可能多的场景下取得成功。最少为2行:一行用于尝试将 master/main.inc.php 文件加载到 dolibarr 的根目录中,另一行用于尝试加载该文件,以支持模块部署在“custom”目录中的场景。但你可能不得不处理更多的场景。上面提供的示例应该能够在几乎所有场景/配置下加载 main/master.inc.php 文件。
在3.2之后,为所有版本的Dolibarr开发的扩展模块可以放置在不同的文件夹中,而不仅仅是“htdocs”,如“htdocs/custom”,为了不必修改模块的源代码,我们要做几个包含,所以这个规则必须被所有模块使用。
请注意,您可以根据文件相对于模块目录树的深度添加更多的“../”。
main.inc.php文件加载了技术环境变量和权限。然后设置以下对象变量:
- $user 包含用户属性 + 权限的对象
- $conf 包含 Dolibarr 设置的对象
- $db 包含数据库连接句柄的对象
- $langs 包含用户语言的对象
然后输入代码以显示页面。
- 在不知道从何处调用文件的情况下,使用Dolibarr函数dol_include_once()(而不是直接使用include_once)包含专用于模块的类或库
例如:
dol_include_once('/mymodule/class/myclass.class.php', 'MyClass');
- 另一方面,Dolibarr提供的标准类将使用 require-once 直接调用,语法如下:
例如:
require_once DOL_DOCUMENT_ROOT.'/core/class/doli.class.php';
原因是,尽管dol_include_once很方便,却因它会扫描每个备用路径目录以找到文件,所以它的性能也很差,因为它会在每次调用时生成访问和磁盘搜索(实际上,PHP集成了已读文件的缓存,但未集成“未找到”文件的缓存)。由于给定的文件只可能存在于一个树中,所以总会有一个无此文件的备用树,这会产生对硬盘的不必要访问,从而影响性能。与Dolibarr的内部文件一样,我们总是知道确切的路径,应该首选带有该直接路径的 require_once)。
在已存在的表单上增加新字段
您可能希望提供一个模块,将更多字段添加到某些元素的表单(录入和展示)中。
一个繁琐(但不太糟糕)的解决方案可能是替换用于创建元素的所有页面(这意味着禁用“新建元素”菜单项并添加您的菜单项,并禁用显示元素的选项卡,以替换选项卡,该选项卡是您自己的完整页面(从原始页面复制/粘贴),使其与原始页面相同,但被修改为添加字段并将添加的数据存储到您自己的表中)。如果此解决方案适合您,请前往菜单 #Define your entries in menu (optional) 和 #The tab management (optional)(本解决方案更强大,因为您可以在页面中改变你想要改变的一切)。
我们将在这里描述另一种解决方案,该解决方案仅适用于在现有字段的末尾“添加字段”,下面以元素“category”作为示例,但您可以将本教程转换为发票、报价单...
- 首先,添加一个由您的模块拥有的表,以存储新字段的值。此表将有一个名为“rowid”的列(将包含与元素表的字段rowid相同的值+每一个要添加的新字段。然后为这个新表创建一个具有CRUD(Create/Read/Update/Delete)方法的类。对于这两项任务,请返回前一章#创建数据表和表的PHP类文件 (可选)。
- 其次,在模块中添加一个钩子,以将新字段添加到表单中。有关使用钩子的通用文档,请参阅Hooks_system#Implement_the_Hook章节。
如果遵循本教程,则必须执行以下操作才能将字段添加到 category 表单中:
用钩子添加/替换部分字段
请参阅 钩子系统#实现钩子 章节,了解如何使用Dolibarr现有的钩子在Dolibarr钩子位置添加/替换代码。
访问数据库
如果您需要对自己添加的表进行基本变更,请使用之前生成的类,其中包含用于此目的的方法。
但是,如果您希望在没有专用PHP对象的情况下访问表,这仍然是可能的(例如,检索记录列表)。在这种情况下,请考虑以下示例:
对于插入、更新或删除:
$db->begin(); // Start transaction
$db->query("My SQL request insert, update or delete");
$db->commit(); // Validate transaction
or $db->rollback() // Cancel transaction
对于读取:
$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++;
}
}
}
定义页面样式
为了使页面的外观与 Dolibarr 主题保持一致,必须使用 Dolibarr CSS 样式。
例如:
- 在表格标题行的tr和td标签上使用 class="liste_titre"
- 在表格数据行的tr和td标签上使用 class="pair" 或 class="impair"
- 在所有输入域(input, select, textarea...)上使用 class="flat"
- 在所有 type="submit" 的 input 对象上使用 class="button"
使用 Dolibarr 日期选择器
如果您愿意,您可以使用 Dolibarr 屏幕页面中的日期选择器(带日历弹出窗口)。为此,请使用以下行:
$form=new Form($db);
$form->select_date('','mykey',0,0,0,"myform");
字符串
$form=new Form($db);
$form->select_date('','mykey',0,0,0,"myform");
标识表单中的日期选择器。如果在同一页面中使用多个日期选择器,则必须设置不同的值。
字符串myform是FORM区域的名称(在HTML页面的form name=“myform”中)。因此,日期选择器的显示必须集成到FORM Html区域中。
要在POST结束时检索值,命令为:
$mydate = dol_mktime(12, 0 , 0, $_POST['mykeymonth'], $_POST['mykeyday'], $_POST['mykeyyear']);
print strftime('%A %d %B %Y', $mydate);
覆盖模板文件 (tpl)
如果您想覆盖模块上的tpl文件,则需要在 module_parts 上声明它:
'tpl' => 1,
然后您可以在 mymodule/core/tpl 上放置任何tpl文件。
一旦模块被激活,tpl就会被覆盖。
设置配置页面 (可选)
何时:如果您的模块提供多个可配置选项。
创建配置编辑页面
如果您的模块提供了多个可配置选项,则需要创建一个PHP页面来编辑这些选项(存储在 表 llx_const 中)。
创建一个名为 mymodule_setuppage.php 的PHP页面,显示可能的选项并更新它们。
有必要以 /admin 中的一个页面为例,展示读取或保存选项的方法。将此配置页面也放在/admin目录中。
修改模块的描述符文件
然后,在模块描述符文件中,修改变量 config_page_url 以指定该PHP页面的名称。
如果页面在目录 admin/ 中),则:
$this->config_page_url = array("mymodule_setuppage.php");
如果页面在目录 mymodule/admin/ 中,则:
$this->config_page_url = array("mymodule_setuppage.php@mymodule");
测试您的页面
前往“主页->设置->模块/应用”页面,您应该会看到一个齿轮图标,允许您访问配置页面,并且您应该能够修改这些选项并将其保存到数据库中。
设置菜单项 (可选)
何时 :如果您创建了PHP页面,则必须从Dolibarr菜单访问这些屏幕页面。
设置菜单项
为此,您需要在模块描述符文件中定义数组 this->menu,该数组用于声明菜单。
此数组包含模块激活后将显示在菜单中的所有条目。
模块描述符文件的示例文件 modMyModule.class.php 中有一个声明顶部菜单及其相关的左侧菜单项的示例。
以下是描述符文件中菜单项声明的示例:
// 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++;
若要根据权限限制对菜单的访问,请更改数组的 perms 属性。有关如何添加权限的更多信息,请参阅后面有关权限的章节。
测试您的菜单项
在Dolibarr中禁用并重新激活您的模块,然后应该会出现菜单项(如果 “enabled”为真)。
设置您自己的权限 (可选)
何时: 如果要添加新权限。
模块将其管理的权限定义,放在第一步中创建的模块描述符文件中完成。更改行:
$this->rights_class = 'mymodule'
录入正确的 myModule 值。
然后在 $this->rights 数组中填充与要管理的不同权限一样多的条目。
$this->rights[$r][0] = 10001;
$this->rights[$r][1] = 'Label by default of permission';
$this->rights[$r][3] = 1;
$this->rights[$r][4] = 'action';
$this->rights[$r][5] = 'subaction';
$r++;
在$this->rights[$r][0]中,输入尚未使用的权限ID(请参阅系统信息菜单,在运行Dolibarr的设备上查看已在使用的ID)。
在$this->rights[$r][1]中,输入默认标签(如果在 admin.lang 文件中找不到您权限标签的翻译字符串,则显示该标签。翻译键值为 “Permission10001=我的超级权限的描述”)。
在$this>rights[$r][2]中,输入权限类型。有三种类型的权限,“r”表示读取、列出清单或导出权限,“w”表示写入或更新权限,“d”表示删除权限。
在$this->rights[$r][3]中,如果任何一个新创建的用户都会被默认自动分配此权限,则输入1。
在$this->rights[$r][4]和$this->rights[$r][5]中,输入不带空格的操作和子操作字符串。然后,您可以通过以下命令在PHP代码中测试用户是否具有正确的权限:
if ($user->rights->mymodule->action->subaction) ...
设置您自己的消息框/widget小组件 (可选)
何时:如果您的模块附带提供在主页上展示的一个或多个消息框。
设置您的消息框
为此,请修改模块描述符文件中的数组 $this->boxes。
首先为即将在 htdocs/mymodule/core/boxes 目录中创建的每个box文件添加2行。
例如:
$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'
其次,创建文件htdocs/mymodule/core/boxes/mybox0.php、htdocs/mymodule/core/boxes/mybox1.php…,以现有的消息框(在 htdocs/core/boxes 目录中)为示例。
测试您的消息框是否被 Dolibarr 检测到
停用并重新激活模块。
前往菜单 主页 - 设置 - widget小组件 。
您的消息框必须显示在可激活消息框的清单中。激活它们,然后前往主页并检查它们是否正确显示。
定义您自己的导出 (可选)
何时:如果您的模块附带提供预定义的数据导出(针对自己的表或来自另一个Dolibarr模块的现有表)。
定义导出
为此,请取消注释并修改模块描述符文件中的 $this->export_xxx 数组。
测试您的导出
前往菜单 工具->导出助手 。您的导出应显示在可用的预定义导出清单中(如果您的模块已激活)。选择它,您将看到在上一步时在表中定义的可能字段。选择几个字段并尝试生成导出文件。
设置CSS样式 (可选)
何时:在PHP屏幕页面中,您使用的样式类不是Dolibarr主题的样式类(不推荐)。
创建并声明您的样式表
创建一个名为 mymodule.css 或 mymodule.css.php 的CSS样式文件,并将其放在 htdocs/mymodule 目录中。每个模块只能有一个CSS文件。
请记住,最好使用已有的Dolibarr样式(Dolibarr使用的CSS文件是themes/mytheme/themename.css.php)。仅当您必须处理不存在的样式时,才创建特定于模块的CSS文件。
样式表准备就绪后,通过更改 $this->modules_parts 属性在模块描述符文件中声明样式表。
此处要输入的值必须是 CSS 文件 URL 的相对路径。
例如:
$this->module_parts = array('css' => array('/mymodule/css/mymodule.css.php'));
测试您的样式表
停用并重新激活模块。
前往Dolibarr的主页。查看页面的HTML源代码。
您应该在HTML标头中看到有一行是声明您的样式表。
定义Javascript函数 (可选)
何时:当您在PHP屏幕页面中使用的 javascript 函数不是Dolibarr的标准js函数(在lib_head.js中)。
如果在PHP屏幕页面上使用 javascript 函数,则必须将在 javascript 文件 htdocs/mymodule/js/mymodule.js 中声明的函数加载到HTML头中。
若要求Dolibarr(负责生成 header 部分)包含一个 javascript 文件,必须在页面开头调用的llxHeader()函数的参数中提供包含要包含的JS URL的参数。
页面 /htdocs/mymodule/mypage.php 的示例:
$morejs=array("/mymodule/js/mymodule.js");
llxHeader('','Titre','','','','',$morejs,'',0,0);
在Dolibarr事件上触发代码 (可选)
何时:希望在Dolibarr标准操作后触发执行特定操作时(例如:当在Dolibarr中创建发票时,我想更新模块中的表),您需要创建一个 triggers 文件。
另请参阅 Dolibarr到外部系统的接口 和 外部系统到Dolibarr的接口
在Dolibarr的hooks处插入代码 (可选)
何时:当您想更改或添加业务事件以外的代码时(请参阅上一章)。
请参阅页面 Hooks系统.
添加编号模块(可选)
何时:当您想添加默认模块未涵盖的编号规则时。
请参阅页面 创建编号模块 。
添加新文档模板 (可选)
何时:需要添加新文档模板时。如想要个性化自己生成的 PDF 或 ODT 文档。
注意:要添加此功能,您无需创建模块描述符文件。
有关如何从模板生成文档的详情,请参阅页面 创建PDF文档模板 或 创建ODT文档模板 。
添加主题 (可选)
何时:当您想要根据您的情况定制界面(颜色/字体/图形)时。
注意:要添加此功能,您无需创建模块描述符。
请参阅页面 主题 。
修改开发模块作者名
在myModule.class.php中查找editor_name
修改以下变量的值以修改作者名称
$this->editor_name = 'Roger@QQ:12464313';
$this->editor_url = 'https://www.ivnun.cn';
面向开发人员的一些编码规则和函数
要遵循的编码规则请参阅 开发语言和编码规范(PHP, SQL, HTML) 。
要调用 Dolibarr 供开发人员使用的预定义函数,请参阅 开发文档 的“内部函数”一节。
创建一个安装包来分发和安装您的模块
必须使用此步骤来制作安装包,以便将其提交到市场 http://www.dolistore.com。
但您也可以使用它通过自己的分发网络轻松分发模块。
- 进入 /build 目录并将文件 makepack-dolibarrmodules.conf 复制到 makepack-mymodule.conf。请注意,稳定版本包中可能不提供此目录。如果是这种情况,可以在 Dolibarr 网站的“开发版本”部分供下载的快照中检索(在这种情况下,请获取整个 build 目录,这是一个独立于版本的目录)。
在此文件中输入为模块创建的新文件的名称清单(模块描述符、新表的SQL文件、PHP页面、图像等)。
- 通过 Perl 运行脚本(需要Perl 5.0或更高版本):
perl makepack-dolibarrmodule.pl
该脚本将询问模块的名称、主要版本和次要版本。然后将生成一个 mymodule.zip 文件,其中包含准备部署的模块。
- 接收您的模块的人员必须将该文件放在其 Dolibarr 的安装根目录中,并执行以下命令:
tar -xvf mymodule.zip
- 如果您希望您的模块惠及所有人,您可以在插件市场 DoliStore.com 上提交它(zip文件)(您必须先创建一个帐户并登录,以使用“提交模块/产品”链接)。
- 如果您的模块制作正确,文件将很快通过验证。
- 如果质量足够好、许可证允许、并且模块的功能被证明是普遍感兴趣的,则可以将代码添加到 Dolibarr 的源代码中(除非您不希望这样做)。
Dolistore上外部模块的归档和验证
请参阅 验证规则