禅道的定制开发
5.禅道定制开发
5.1.二次开发机制
禅道项目管理软件是使用我们自主开发的zentaoPHP框架开发的。zentaoPHP框架实现了功能强大的扩展机制、API调用机制和命令行机制。您可以使用不同的机制来实现对禅道功能的修改、扩展。也可以和其他的系统进行集成,也可以部署各种自动化脚本对禅道进行各种操作。
因此请您仔细阅读下面的文档,以充分了解zentaoPHP框架的二次开发机制:
1. zentaoPHP框架基本使用手册:http://devel.cnezsoft.com/book/zentaophphelp.html
2. zentaoPHP框架二次开发机制:http://devel.cnezsoft.com/book/extension.html
5.2.禅道的目录结构
了解了zentaoPHP框架的基本原理和二次开发机制之后,您对禅道项目管理软件的目录结构应该也比较熟悉了。
- 顶级目录结构
- www目录
- module目录
module目录下面总共有30多个模块,分别对应了禅道里面的某一个功能模块。整个禅道的功能,就是由这些模块组合而成。让我们来看一个具体的模块。
5.3.找到要修改的文件
要想对禅道进行修改,就必须知道对应的代码在什么地方。在了解了禅道的目录结构之后,我们来看下禅道的请求是如何对应到代码的。
1. control方法的定位
control方法是每一个页面的入口,顺藤摸瓜,让我们先来看个例子:bug-browse-1.html 或者是/?m=bug&f=browse&productID=1&t=html。这里面有什么玄机呢?让我们来揭晓。
bug-browse-1.html,表示是访问bug这个模块的browse方法,传递的第一个参数为1,访问的页面类型是html。
同样,/?m=bug&f=browse&productID=1&t=html,m代表了模块名称,f代表了方法名称,后面的则是参数列表。
那么我们就可以对应到禅道的源代码,module/bug/control.php中的browse方法:
2. control方法里面的调用
ok,我们现在已经知道了入口的函数在什么地方,我们来跟到里面看看吧。
$this->bug,表示的是调用bug模块的model对象,那么它对应的文件在什么地方呢?聪明的你,应该已经猜到了吧。在module/bug/model.php
this->loadmoel('tree')->xxx,表示加载tree模块的model对象,它对应的文件在module/tree/model.php
$this->app->loadClass('pager'),表示加载一个lib类,它对应的文件则在lib/pager/pager.class.php
$this->lang->bug->xxx,它的定义在module/bug/lang/zh-cn.php。后面的zh-cn根据当前用户的语言而定。
后来看模块文件。$this->display()之后,调用的是view目录下面和当前方法同名的模板文件。比如bug的browse方法,它对应的模板文件是module/bug/view/browse.html.php
5.4.禅道的数据库结构
禅道的数据库命名都比较简明扼要,从字面意思应该都可以猜出来表的用途。如果还不是很清楚的话,可以到每个表对应的模块下面的语言文件里面查找。
1. 产品相关的表
- zt_product,则记录了产品相关的信息。
- zt_productPlan,则记录了产品的计划信息。
- zt_story,是非常重要的一张表,记录了系统中所有的需求记录。zt_storySpec表是记录了story的历史信息。
- zt_release,记录了产品的发布信息。这张表同时也和zt_build互相关联。
2. 项目相关的表
- zt_project,项目表。
- zt_projectProduct,记录了项目和产品之间的关联关系。
- zt_proejctStory,记录了项目中需要做的需求列表。
- zt_task,任务表。
- zt_burn,燃尽图数据表。燃尽图就是根据这张表的数据画出来的。
- zt_team,记录了项目中的团队成员。
- zt_build,记录了项目中产品的build列表。
3. 测试相关的表
- zt_bug,bug表,也是大家非常熟悉的一张表了。
- zt_case,用例表。记录了所有的测试用例。zt_caseStep,则是记录了用例相关的步骤,包括历史。
- zt_testTask,测试任务表,记录了历次的测试任务。
- zt_testRun,则记录了每个测试任务所对应的用例执行情况。
- zt_testResult,记录了每个用例历次执行的结果。
4. 文档库相关的表
- zt_docLib,记录了自定义文档库列表。
- zt_doc,则记录了所有的文档。
5. 组织管理相关的表
- zt_user,用户表。
- zt_group,分组表。
- zt_userGroup,用户和分组之间的对应关系。
- zt_groupPriv,分组的权限。
- zt_dept,部门结构表。
- zt_userQuery,用户自定义查询表。
- zt_userTPL,用户的自定义模板表。
- zt_todo,代办事宜表。
6. 公共表
- zt_company,这张表记录了当前公司的信息,也是顶级的一张表。
- zt_module,也是非常重要的一张表,它维护了禅道系统中的模块划分数据,比如需求的模块划分。
- zt_action,操作历史表,记录对任何一个对象的所有修改记录。
- zt_history,记录了操作过程中,前后值的变化。
- zt_file,附件表。记录了所有的附件。
5.5.公共模块common
common模块在禅道中是比较特殊的一个模块,禅道里面的众多公用功能都是由common来实现的。
- common/control.php里面,提供了其他模块都有可能用到的一些方法。比如权限检查,菜单打印等功能。
- common/view目录下面,则是提供了公用的模板。比如公用的header.html.php,footer.html.php等。还包含了各种jquery插件的初始化代码模板。比如colorbox.html.php。
- common/lang下面,则是设置了公用的语言项。
所以,后面如果大家需要修改一些语言项,或者修改公用的模板文件,可以到common模块下面寻找相应的代码。
5.6.如何登记菜单
扩展禅道遇到的一个问题就是如何将自己增加的功能登记到菜单中,本篇文章来讲述如何来实现这个功能。
1. 菜单的组成
禅道的导航菜单分为三个部分,顶部菜单、模块菜单、功能菜单。
2. 菜单的定义
菜单的代码定义是在zentao/module/common/lang/zh-cn语言文件中。我们来看下主菜单的定义。
a) 主导航菜单的定义
80 $lang->menu->my = ' 我的地盘|my|index';
81 $lang->menu->product = '产品视图|product|index';
82 $lang->menu->project = '项目视图|project|index';
83 $lang->menu->qa = '测试视图|qa|index';
我们来看下代码的含义:83 $lang->menu->qa = '测试视图|qa|index';
这行代码定义了测试视图的代码,其中的menu->qa定义的是菜单的键值,可以根据实际的模块定义。后面是使用竖线分开的三个参数,分别是菜单的文本,对应到模块和方法。这句话就表示要定义一个顶级菜单,文本是“测试视图”,链接到qa模块的index方法。
b) 模块菜单的定义
我们以产品视图的模块菜单为例:
144 $lang->product->menu->list = '%s';
145 $lang->product->menu->story = array('link' => '需求|product|browse|productID=%s', 'subModule' => 'story');
155 $lang->product->menu->create = array('link' => ' 新增产品|product|create', 'float' => 'right');
158 $lang->productplan->menu = $lang->product->menu;
159 $lang->release->menu = $lang->product->menu;
这几行代码定义了产品视图模块的模块菜单,这里面出现了一些新的定义方法:
i. 使用数组来定义链接
145 $lang->product->menu->story = array('link' => '需求|product|browse|productID=%s', 'subModule' => 'story');
这行代码对链接进行定义的时候,使用了数组,分别定义了两个元素,link和subModule。其中link多增加了一个参数字段:productID=%s,代表产品视图的“需求”菜单会链接到product模块的browse方法,传递的参数是productID=%s,其中的%s会被替换成当前的产品id。
ii. 使用subModuel来定义子模块
145 $lang->product->menu->story = array('link' => '需求|product|browse|productID=%s','subModule' => 'story');
subModule定义的是它的子模块,这个需要是用来保持菜单高亮使用。这样当访问到story模块的时候,还会保持“产品视图”这个定义菜单高亮。
iii. 使用alias来定义方法别名
151 $lang->product->menu->view = array('link' => '概况|product|view|productID=%s', 'alias' => 'edit');
这个地方的alias代表product的edit页面和product的view页面是相同的,这样当编辑产品的时候,“概况”菜单还是会保持高亮的。
iv. 定义菜单的位置
所有的菜单默认都是显示在左侧的,如果需要将菜单显示在右侧,则需要定义它的float参数。
155 $lang->product->menu->create = array('link' => ' 新增产品|product|create', 'float' => 'right');
通过设置float参数,可以定义这个新增产品的链接显示在页面的右侧。
c) 功能菜单的定义
功能菜单是在每一个模块的视图文件里面打印的,其扩展方法和视图的扩展相同,后面会讲到这一点。
3. 菜单顺序的定义
前面讲述的是禅道菜单的定义,下面来讲下禅道菜单顺序的定义。在common/lang/下面有一个menuOrder.php的文件,在这个文件中定义了每个菜单的显示顺序。
/* Sort of main menu. */
$lang->menuOrder[5] = 'my';
$lang->menuOrder[10] = 'product';
$lang->menuOrder[15] = 'project';
$lang->menuOrder[20] = 'qa';
$lang->menuOrder[25] = 'doc';
$lang->menuOrder[30] = 'report';
$lang->menuOrder[35] = 'company';
$lang->menuOrder[40] = 'admin';
/* index menu order. */
$lang->index->menuOrder[5] = 'product';
$lang->index->menuOrder[10] = 'project';
4. 如何将自己的页面登记到菜单中
了解了禅道的菜单机制之后,做扩展就非常容易了。我们来说下步骤:
- 在module/common/ext/lang/zh-cn/下面创建一个文件,比如叫做abc.php(文件名可以任意定义)
- 在这个文件中加上自己的菜单就好了,比如禅道专业版本中的版本库菜单:
$lang->menu->repo = '版本库|repo|browse';
$lang->menuOrder[21] = 'repo';
$lang->repo->menu->list = '%s' . $lang->arrow;
$lang->repo->menu->browse = array('link' =>'浏览|repo|browse|repoID=%s', 'alias' => 'diff, log, view, revision, showsynccomment');
$lang->repo->menu->settings = '设置|repo|settings|repoID=%s';
$lang->repo->menu->delete = array('link' => '删除|repo|delete|repoID=%s', 'target' => 'hiddenwin');
$lang->repo->menu->create = array('link' => '新增版本库|repo|create|', 'float' => 'right');
5.7.如何修改禅道的语言提示
下面来看具体的例子吧,以修改bug的优先级列表提示为例:
1. 在module/bug/下面创建ext/lang/zh-cn/目录,这里面的zh-cn,可以根据实际情况换成相应的语言,比如en, zh-tw。
2. 在这个目录下面创建一个abc.php,注意,abc的名字是可以随便定义的。
3. 打开这个文件,重新定义优先级的提示:
unset($lang->bug->priList);
$lang->bug->priList[0] = '';
$lang->bug->priList[3] = '3';
$lang->bug->priList[1] = '1';
$lang->bug->priList[2] = '2';
$lang->bug->priList[4] = '4';
注意:
1. 如果你定义的是一个列表格式的数据,需要加上unset这一句。这样可以保证列表是完全按照你的定义。
2. 请一定按照我们的扩展机制来存放文件,这样可以保证我们后面升级,不会覆盖你自己的修改的代码。
3. windows下面编辑,建议使用ultraedit,保存的时候,保存成utf-8编码,nobom格式。否则会造成系统不正常。
5.8.创建bug时可以设置优先级字段
这个例子用来向大家展示如何使用禅道的扩展机制来对禅道进行各种定制,而不用担心后续升级之后被覆盖。
目标:在创建bug的时候,可以直接设置优先级字段。
- 创建目录
1. 在module/bug/目录下面建立ext/view目录。
2. 将module/bug/view/create.html.php拷贝到ext/view/目录下面,仍然是create.html.php
3. 修改ext/view/create.html.php
- 修改程序
把模板复制过去之后,需要修改头文件和footer文件的包含路径。然后再修改模板文件,在相应的地方加入bug优先级字段即可。
然后访问bug创建页面,就会出现优先级字段了。
- 下载插件
我们为大家提供了插件,可以下载:http://www.zentao.net/extension-viewExt-10.html
5.9.使用在线扩展编辑器
禅道还提供了web方式的代码扩展编辑器,可以使用超级管理员登录禅道,对禅道进行二次扩展:
访问入口
禅道扩展编辑就是后台模块下的扩展里。位置如图:
点击进入编辑器&API,首先看到的是可扩展的模块列表。
点击想要扩展的模块链接,右侧就会出现该模块所有可扩展的文件,包括control.php和model.php的方法。
这些文件是有排列顺序的,自上而下依次是:
model.php和该文件的方法、
control.php和该文件的方法、
view文件夹下的模板文件、
语言文件、
配置文件config.php
JS
CSS
扩展文件。
扩展文件中的排列顺序与上述的排列顺序是一致的,这样可以方便快速的找到要扩展的文件。在每个文件后面,有相应的操作链接,点击这些链接,就可以在线编辑扩展了。
在线编辑
1. model.php的扩展
可以对model.php的现有方法进行扩展,编辑器可以自动生成简单代码。当然也可以对model.php新增方法。
2. control.php的扩展
对control.php的现有方法进行扩展时,会有是否重用代码的提示
如果选择“确定”的话则会生成一个继承了该模块control.php的类,扩展后的方法可以继承该模块的control.php的方法。否则的话,则对该方法进行重新定义。
同样的也可以对control.php新增方法。
3. 模板文件的扩展
对模板文件的扩展也有两种方式,可以重写一个模板文件覆盖原来的。也可以写一个钩子脚本,对原来页面做一下局部修改。
4. 其他文件的扩展
对其他文件扩展时,将会显示源文件的内容,可以当做扩展的参考。
5. 对扩展文件的编辑
可以对ext目录下的扩展文件进行编辑和删除。
保存扩展文件
1. 不必输入文件名
对control.php的方法进行扩展和覆盖模板文件时,文件名是一定的不必输入文件名。
2. 可以输入文件名
像对model.php的方法扩展、对语言文件、配置文件等的扩展,如果不输入文件名,则会以默认文件名保存,如果输入文件名,则会以输入文件名保存。
3. 必须输入文件名
像新增方法、新增页面、新增钩子、新增扩展等,则必须输入文件名才能保存。
备注:
1、保存文件时,要保证程序有读写的权限。
2、如果文件名冲突,则不能保存,你可以更改保存的文件名或者勾选覆盖重复文件选项。
3. 该编辑器还很简陋,只是为方便扩展而建。可能还有很多问题,希望大家提出。
5.10.禅道项目管理软件打包规范1.1版本
大家在二次开发过程中,好的功能也可以打包成插件和大家进行分享。我们整理了禅道项目管理软件打包规范。
1. 可以扩展的元素
2. doc目录应当包含的文档
doc目录下面包含了插件的配置信息,按照语言进行存储,比如英文版本的,存为en.yaml,中文zh-cn.yaml
插件的配置文件采用yaml格式,里面包含了插件的基本信息以及历次版本的发布信息。共分为下面的信息:
可以参考:http://www.zentao.net/extension-viewExt-1-info-front.html
3. db目录下面包含的文件
db目录下面可以包含install.sql和uninstall.sql。顾名思义,install.sql是当安装插件的时候执行的sql语句,而uninstall.sql则是当卸载插件的时候需要执行的sql语句。这样如果你的插件涉及到数据库的改动,可以将相应的sql语句放在这两个文件中,禅道的插件管理程序会自动来执行。
4. module下面的文件:
module目录下面的文件,就按照我们的插件扩展机制 部署相应的目录结构就可以了。
5. 主配置文件的扩展
在实际过程中,可能会需要对全局的配置文件进行扩展,这种情况将扩展的配置文件放在zentao/config/ext/下面就可以了。
6. 安装和删除的钩子脚本
如果在安装之前,安装之后,卸载之前,卸载之后需要执行一些操作,可以建立一个hook目录,然后分别在里面创建preinstall.php, postinstall.php, preuninstall.php, postuninstall.php,里面放上你所需要的代码即可。
7. 小结:创建自己的插件
8. 查看示例
- 确定插件的英文名,比如叫做hello。
- 创建hello目录。
- 在hello目录下面创建doc目录。
- 在doc目录下面创建配置文件yaml文件:
- 如果有涉及到数据库的改动,在hello目录下面创建db目录,分别写好install.sql和uninstall.sql
- 如果需要钩子脚本,创建hook目录,创建 preinstall.php, postinstall.php, preuninstall.php, postuninstall.php。
- 然后部署相应的扩展代码。在hello目录下面创建一个module目录,然后将相应的模块扩展代码放在module下面。
- 打包,使用zip格式将整个hello目录打包成hello.zip,就可以了。