模块开发

要创建新模块,需要执行以下几个步骤。本教程旨在向您介绍每一个步骤,以便添加一个模块来扩展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类文件,简单至在下图中选择'对象'选项卡,输入'对象名',然后点击创建,即可生成相关一切文档。

 

参见ModuleBuilder用户手册

选项卡显示(可选)

添加或删除对象表单上的选项卡

何时:在标准对象(发票、订单、报价单、会员…)的表单中添加您自己的选项卡

要执行此操作,请打开之前创建的模块描述符文件并编辑 $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 表单中:

  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".
  待完成,欲帮助完成,注册帐号,点击“编辑"
  ページは未完成の状態です。完成させるにはアカウントを作成し、ページに戻って「編集」をクリックして下さい。

用钩子添加/替换部分字段

请参阅 钩子系统#实现钩子 章节,了解如何使用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 样式。

例如:

  • 在表格标题行的trtd标签上使用 class="liste_titre"
  • 在表格数据行的trtd标签上使用 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.phphtdocs/mymodule/core/boxes/mybox1.php…,以现有的消息框(在 htdocs/core/boxes 目录中)为示例。

测试您的消息框是否被 Dolibarr 检测到

停用并重新激活模块。

前往菜单 主页 - 设置 - widget小组件

您的消息框必须显示在可激活消息框的清单中。激活它们,然后前往主页并检查它们是否正确显示。

定义您自己的导出 (可选)

何时:如果您的模块附带提供预定义的数据导出(针对自己的表或来自另一个Dolibarr模块的现有表)。

定义导出

为此,请取消注释并修改模块描述符文件中的 $this->export_xxx 数组。

测试您的导出

前往菜单 工具->导出助手 。您的导出应显示在可用的预定义导出清单中(如果您的模块已激活)。选择它,您将看到在上一步时在表中定义的可能字段。选择几个字段并尝试生成导出文件。

设置CSS样式 (可选)

何时:在PHP屏幕页面中,您使用的样式类不是Dolibarr主题的样式类(不推荐)。

创建并声明您的样式表

创建一个名为 mymodule.cssmymodule.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上外部模块的归档和验证

请参阅 验证规则