vTiger研究记录

1         运行环境搭建

1.1   环境搭建

软件vTigerCRM是以Apache为Web服务器,MySQL为数据库,因此选择XAMPP作为其运行环境,在Linux上采用LAMPP,在Windows系统上采用WAMPP。本次研究环境选择WAMPP。

 

操作系统:Windows 7

Web环境:WAMPP 1.7.7

1)MySQL版本:5.5.16

2)PHP版本:5.3.8

3)Apache版本:2.2.21

4)phpMyAdmin: 3.4.5

5)FileZilla FTP Server: 0.9.39

6)Tomcat: 7.0.21 (with mod_proxy_ajp as connector)

研究对象:vTigerCRM 5.3.0

开发工具:NetBeans 7.0.1

 

本研究报告的运行环境包括WAMPP 1.7.7和vTigerCRM 5.3.0,下载地址如下:

WAMPP:http://www.apachefriends.org/en/xampp.html(下载WAMPP)

vTigerCRM:http://wiki.vtiger.com/index.php/Vtiger530:Downloads

NetBeans:http://netbeans.org/

 

在本次研究中,XAMPP的安装路径为F:\XAMPP1.7.7

 

说明:本次研究侧重软件本身,操作系统和软件自身可能存在的安全性不在研究范围内,考虑到研究的方便性,采用Windows 7操作系统。

 

1.2   WAMPP安装

WAMPP安装步骤如下:

1)        下载WAMPP 1.7.7,地址:http://www.apachefriends.org/download.php?xampp-win32-1.7.7-VC9-installer.exe

2)        下载完成后,执行该程序;

3)        设置安装路径,例如“F:\XAMPP1.7.7”。安装最后,提示选择“Put XAMPP to desktop”,即把XAMPP控制台放到桌面。

4)        运行XAMPP控制台,启动Apache和MySQL,可注册为系统服务自动启动。

5)        在浏览器访问:http://localhost/xampp,如果正常,则安装成功。

6)        使用root登录进入phpmyadmi,设置root密码;

7)        编辑安装路径F:\xampp1.7.7\phpMyAdmin\config.inc.php,将$cfg['Servers'][$i]['auth_type'] = 'config';修改为$cfg['Servers'][$i]['auth_type'] = 'cookie';

8)        编辑F:\xampp1.7.7\mysql\bin\my.ini,在[client]下添加“default_character_set = utf8”,在[mysqld]下添加“character_set_server=utf8”和“collation_server=utf8_unicode_ci”,重新启动mysql;

 

1.3   vTigerCRM安装

vTigerCRM5.3.0安装步骤如下:

下载vTigerCRM 5.3.0,地址:http://www.vtiger.com/vtiger-crm/downloads/,选择“SOURCE”下载项。

将下载包解压缩到F:\xampp1.7.7\htdocs\vtigercrm530,参考如下链接进行安装:http://service.syncomni.com:10080/twiki/bin/view/Syncomni/VTigerCRMSetup

安装需要5-10分钟。

安装完成后,下载中文语言包,下载地址为:http://service.syncomni.com:10080/twiki/pub/Syncomni/VTigerCRMSetup/vTiger_CRM_zh_cn_5.2_Release_20101001.zip,然后解压缩到f:\xampp1.7.7\htdocs\vtigercrm530目录下。

打开mysql命令行,执行:

INSERT INTO `vtiger_language` VALUES ('9', '简体中文', 'zh_cn', '简体中文', '2012-01-12', NULL , '1', '1');

并将第1条记录的is_default设置为0。

使用admin登录到http://localhost/vtigercrm530/index.php

在My Preferences(右上角)中设置Language为“简体中文”,刷新页面即可显示中文。

打开F:\XAMPP1.7.7\htdocs\vtigercrm530\config.inc.php,将$default_language = 'en_us'修改为$default_language = 'zh_cn',即把中文设置为默认语言。

 

安装到此完成。

2         研究报告

2.1   登录界面

从5.3.0版本之前,登录界面提供语言选择,在5.3.0版本中,默认语言的设置转到了config.inc.php中,用户登录后可以在“我的信息”->“更多信息”->“语言”中修改喜欢的语言。

 

登录界面定义文件:Login.tpl

 

 

2.2   菜单

2.2.1   参考

http://wiki.vtiger.com/index.php/Creating_New_Module

http://forums.vtiger.com/viewtopic.php?t=26465

2.2.2   菜单相关的数据

菜单分为主菜单和子菜单,在vTiger中主菜单称为parent tab,子菜单称为child tab。

与主菜单相关的文件有parent_tabdata.php,该文件定义了主菜单全局变量$parent_tab_info_array,以及和其相关的子菜单(模块)编码数组$parent_child_tab_rel_array。

相关的数据库表有vtiger_parenttab和vtiger_parenttabrel。

和菜单相关的源代码文件:include/utils/CommonUtils.php

 

如果一个主菜单下的任何模块,不允许当前用户访问,则登录后该主菜单不会显示。

 

建议增加一个独立菜单编辑器工具,用于管理主菜单和子菜单。该工具只给特定的软件开发人员使用。

 

2.2.3   全局变量

 

文件名

变量

用途

tabdata.php

$tab_info_array

定义模块编码

$tab_seq_array

 

$tab_ownedby_array

 

$action_id_array

 

$action_name_array

 

parent_tabdata.php

$parent_tab_info_array

定义主菜单

$parent_child_tab_rel_array

定义主菜单中包含的子菜单(模块)编码,参见$tab_info_array

 

 

 

 

 

 

2.2.4   菜单相关代码的研究

文件:CommonUtils.php

 

函数:checkParentTabExists($parenttab)

要点:如果文件parent_tabdata.php存在,则使用全局变量$parent_tab_info_array,否则,使用数据库表vtiger_parenttab。

 

函数:getParentTabFromModule($module)

要点:如果文件tabdata.php和parent_tabdata.php存在,则根据文件中定义的全局变量计算;否则根据数据库表vtiger_parenttab、vtiger_tab和vtiger_parenttabrel计算。

 

函数:getHeaderArray()

要点:需要包含parent_tabdata.php,否则访问页面时会有warning,提示没有该文件,主菜单也无法显示。

 

总结:

通过对vTigerCRM 5.3.0的研究,菜单相关的数据既保存到文件,也保存到数据库,目前尚不清楚为什么分两处存放。在已有的函数或方法中,既有同时支持文件和数据库存储的方式,也有只支持文件,或者只支持数据库的方式。因此,如果对主菜单进行操作,既要修改文件,也要修改相关数据库。详细的研究过程参加章节“附录1:实验->2. 增加新主菜单”。

建议:

将主菜单数据统一存储到数据库。

 

 

2.2.5   支持中文

添加语言配置:简体中文

执行如下SQL添加中文币种,并在“设置>货币”中添加RMB。

INSERT INTO vtiger_currencies( `currency_name`, `currency_code`,`currency_symbol` ) VALUES ( '人民币元', 'RMB', '¥' );

另外,编辑表vtiger_currency_info,将人民币的defaultid设置为-11,作为基础币种,美元的defaultid设置为0,同时设置好汇率。在“我的设定>货币”中设置好当前用的币种即可。

 

 

2.3   字段Fields

参考:

http://wiki.vtiger.com/index.php/Creating_New_Fields_in_Existing_Modules

http://wiki.vtiger.com/index.php/Ui_types

http://forums.vtiger.com/viewtopic.php?t=25886

2.3.1   常用相关字段的匹配表

类型解释

1)        Generated Type

2)        Display Type

a)        值为1:在所有视图中显示

b)        值为2:在DetailView中显示(只读,不包括编辑视图EditView)

c)        值为3:不单独显示,与其他字段相关

d)       值为4:只在CreateView视图中显示

 

UI Type

(默认值1)

说明

Column Type (默认值:VARCHAR(100))

GeneratedType

(默认值1)

Type Of Data

(默认值V~O)

Display Type

(默认值1)

Quick Create

(默认值1)

6

日期时间datetime

DATETIME

 

DT~M

 

 

2

文本框textbox

VARCHAR(255)

 

V~M

 

 

4

Text box with Inheritance, mandatory entry

VARCHAR(100)

2

 

 

3

15

下拉框droplist

VARCHAR(255)

 

V~M

 

 

53

用户名下拉框

VARCHAR(100)

 

 

 

 

70

日期date

VARCHAR(100)

 

T~O

2

 

101

用户名弹出窗口

VARCHAR(36)

1

V~O

1

1

56

检查框checkbox

 

1

V~/C~

1,3

1,2,3

28

文件上传

 

 

 

 

 

19

占2个显示单元的描述

Varchar(255)

1

 

 

 

21

占1个显示单元的描述

Varchar(255)

1

 

 

 

10

通用弹出窗口

Varchar(255)

 

 

 

 

 

 

 

 

 

2.3.2   自定义编码

模块中如果定义了自定义编码字段(uitype=4,generatedtype=2,quickcreate=3),其编码值可以通过“设置 > Customize Record Numbering”进行设置,相关表是vtiger_modentity_num。

2.3.3   下拉框

用途:用在两个或者两个以上可选择数据的情况。在一个下拉框中可以根据不同的角色分配不同的值。当一个模块中,有2个或者更多的下拉框,且下拉框之间的数据有关联关系的时候,可以通过设置定义依赖关系。

 

下拉框相关的数据库表包括:

表名

说明

vtiger_picklist

定义下拉框的编码和名称

vtiger_picklist_seq

保存vtiger_picklist中最大的picklistid

vtiger_picklistvalues_seq

保存最新的下拉框的值,以后依次加1

vtiger_picklist_dependency

定义两个下拉框之间的数据逻辑关系,在“设置->编辑下拉框之间依赖关系”中设置

vtiger_picklist_dependency_seq

保存vtiger_picklist_dependency中最大id

vtiger_role2picklist

定义角色与下拉框的对应关系,在“设置->下拉框编辑”中设置

vtiger_<picklist_name>

下拉框名为“picklist_name”的值

vtiger_<picklist_name>_seq

保存vtiger_<picklist_name>中最大id

 

 

2.4   Uitype的研究

2.4.1   相关文件

视图模板:EditViewUI.tpl(查询uitype eq)

后台代码:CRMEntity.php,DetailView.php,EditView. php(可搜索包含文字“uitype == ”)

2.4.2   自定义UITYPE

新增uitype从1000开始编码,如果是对已有uitype的扩充,则新的uitype编码=1000+原uitype。例如,基于uitype 28新增一个uitype,则新的uitype值为1028.

新增uitype需要两方面工作:

1)                界面显示:编辑smarty/templates/EditViewUI.tpl,找到参考的uitype,复制并进行相应修改;

2)                后台逻辑:选择编辑如下文件:

a)        data/CRMEntity.php

b)        include/utils/DetailViewUtils.php

c)        include/utils/DetailViewUtils.php/EditViewUtils.php

 

2.5   调试

2.5.1   日志设置

参考:

http://wiki.vtiger.com/archives/index.php?title=Developer:Debug_techniques

http://wiki.vtiger.com/archives/index.php/Log4php

 

修改config.performance.php中的参数:

        'LOG4PHP_DEBUG' => true,

编辑log4php.properties,打开LOG4PHP的日志标志:

log4php.rootLogger=DEBUG,A1

 

 

 

 

2.6   Smarty模板

2.6.1   模板调用

当需要定制List View或者模块的配置页面时,需要创建一个Smart Template的模板文件。模板文件应该创建在Smarty/templates/modules/<NewModuleName>目录下。

调用模板的代码如下:

$smarty->display(vtlib_getModuleTemplate($currentModule, 'MyListview.tpl'));

2.6.2   Field的显示模板

文件:Smarty/templates/EditViewUI.tpl

功能:根据uitype进行显示

说明:当需要修改某种uitype的显示时,可在此文件中修改。

2.6.2.1         在模板中显示当前用户名

在“模块/EditView.php”中给模板$CURRENT_USERNAME赋值;

global $current_user; 
$smarty->assign("CURRENT_USER", $current_user->user_name);

然后,可以在模板中使用,例如在EditFieldUI.tpl中,将uitype101的默认值设置为当前用户名。

{elseif $uitype eq 101}<!-- for reportsto field USERS POPUP -->

                            <td width="20%" class="dvtCellLabel" align=right>

                           <font color="red">{$mandatory_field}</font>{$usefldlabel} {if $MASS_EDIT eq '1'}<input type="checkbox" name="{$fldname}_mass_edit_check" id="{$fldname}_mass_edit_check" class="small" >{/if}

                   </td>

                            <td width="30%" align=left class="dvtCellInfo">

                                   <input id="{$fldname}_display" name="{$fldname}_display" readonly type="text" style="border:1px solid #bababa;" {if isset($fldname)} value="{$fldvalue}" {else} value="{$CURRENT_USER}" value="{$fldvalue}" class="small" />&nbsp;

                                   <input id="{$fldname}" name="{$fldname}" type="hidden" value="{$secondvalue}" id="{$fldname}" />

                                   &nbsp;<input title="{$APP.LBL_CHANGE_TITLE}" accessKey="C" type="button" class="small" value='{$APP.LBL_CHANGE}' name="btn1" onclick='return window.open("index.php?module=Users&action=Popup&html=Popup_picker&form=vtlibPopupView&form_submit=false&fromlink={$fromlink}&recordid={$ID}&forfield={$fldname}","test","width=640,height=603,resizable=0,scrollbars=0");'>

                       &nbsp;<input type="image" src="{'clear_field.gif'|@vtiger_imageurl:$THEME}" alt="{$APP.LBL_CLEAR}" title="{$APP.LBL_CLEAR}" onClick="this.form.{$fldname}.value=''; this.form.{$fldname}_display.value=''; return false;" align="absmiddle" style='cursor:hand;cursor:pointer'>

                            </td>

 

 

 

2.7   文件上传

2.7.1   附件相关表

表名

说明

vtiger_seattachmentsrel

定义crmid(表vtiger_crmentity)与附件的关系。

Vtiger_attachments

附件信息

vtiger_attachmentsfolder

 

vtiger_attachmentsfolder_seq

 

 

2.7.2   界面

上传文件UI设置如下:

 

 

 

 

 

 

 

 

2.8   vtlib

参见:http://service.syncomni.com:10080/twiki/bin/view/Syncomni/VTigerCRMVtlibManual

 

2.9   全局数据

数据

变量

当前用户

$current_user

 

 

 

 

2.10     数据库表研究

2.10.1 Vtiger_entityname

功能:记录模块实体的名字信息

字段

描述

 

 

 

 

2.10.2 Vtiger_field

字段含义及其赋值:http://service.syncomni.com:10080/twiki/bin/view/Syncomni/VTigerCRMFieldSetting

 

 

2.10.3 Vtiger_time_zone

将Asia/Taipei改为Asia/Beijing

 

2.10.4 vtiger_fieldmodulerel

记录与某一个field相关的模块。

 

 

 

 

 

 

 

2.11     权限控制

2.11.1 总述

 

 

 

 

 

2.11.2 字段数据的权限控制

不同的角色可以看到不同的picklist类型的数据,这些数据在Settings>Picklist Editor中配置。

 

 

 

 

2.12     工作流

参考:http://wiki.vtiger.com/index.php/vtiger510:Module_Workflow

 

 

2.13     报表

 

 

 

2.14     文件上传

部分配置在config.inc.php中的配置可以通过“设置>Configuration Editor”编辑。

 

 

2.15     模块Documents

这个模块比较特殊,与其对应的表是vtiger_notes。

 

2.16     关于删除

2.16.1 批量删除

如果一个模块不允许批量删除,编辑模块下的ListView.php,注释掉如下内容,将不会在界面上显示批量删除的按钮:

if(isPermitted($currentModule,'Delete','') == 'yes') $list_buttons['del'] = $app_strings[LBL_MASS_DELETE];

 

2.16.2 单条删除

如果一个模块不允许批量删除,编辑模块下的Delete.php,注释掉如下内容,将不会执行删除操作:

DeleteEntity($currentModule, $return_module, $focus, $record, $return_id);

 

 

 

2.17     一条记录包含多条明细

实例:例如销售订单(SalesOrder)模块中,当添加一个销售订单时,可以添加多个产品。

本章节重点研究如何实现上述功能。

第一步,将产品信息移植到模块实例Systeo中。

在Smarty/templates下建立目录TrainingPlan,将Smarty/templates/ProductDetails.tpl复制到该目录中。

 

 

 

 

 

 

 

2.18     Theme开发

 

2.19     系统配置

2.19.1 时区

文件:config.inc.php

修改:$default_timezone = 'Asia/Shanghai';

 

2.20     软件体系结构

 

3         vTiger开发工具

3.1   总述

使用jquery作为javascript开发包,所有javascript的调用都写在新增的文件jquery_vtiger_tools.js中。

版本:jquery1.7.1

3.2   增加主菜单

功能:增加一个主菜单

 

算法:在vtiger_parenttab表中增加主菜单,并同步到文件parent_tabdata.php

vTiger代码修改:在vtlib/Vtiger/Menu.php中增加静态方法:

        /**

        * Add one main tab, if the tab name exists, then do nothing.

        * @param main tab name

         * By Kevin Wang, 2012/2/1

        */

       static function addMainMenu($tab_id, $tab_label, $seq) {

           

                self::log("Enter addMainMenu ...");

                global $adb;

              $query = false;

              $instance = false;

               

                $query = "SELECT * FROM vtiger_parenttab WHERE parenttabid=?";

              $result = $adb->pquery($query, Array($tab_id));

              if($adb->num_rows($result)) {

                     self::log("Main tab [label=$tab_id] exists! Cannot add again!");

                        return 1;

              }

               

                $query = "SELECT * FROM vtiger_parenttab WHERE parenttab_label=?";

              $result = $adb->pquery($query, Array($tab_label));

              if($adb->num_rows($result)) {

                     self::log("Main tab [label=$tab_label] exists! Cannot add again!");

                        return 1;

              }

               

              $adb->pquery("INSERT INTO vtiger_parenttab (parenttabid,parenttab_label,sequence,visible) VALUES(?,?,?)",

                                   Array($tab_id, $tab_label, $seq, 0));

               

              self::log("Main tab [id=$tab_id, label=$tab_label,seq=$seq] is added to menu ... DONE");

              self::syncfile();

               

                return 0;

       }

工具实现:增加文件add_main_menu.html和add_main_menu.php,在jquery_vtiger_tools添加AJAX调用实现。

依赖:jquery/jquery1.7.1.js

 

 

 

 

4         vTiger开发流程

4.1   理解需求

充分理解客户需求,明确:

1)        每个功能需求涉及到的业务数据及其格式

2)        和功能相关的配置数据以及修改频率的高低

3)        需求对功能和数据的权限要求

4)        业务流程

在理解需求的基础上,由测试人员负责编写测试计划。

 

4.2   设计

在充分理解需求的前提下,划分功能模块,主要工作如下:

1)        定义出模块数目及其功能

2)        对每个模块设计页面布局,考虑相关数据

3)        设计数据信息,包括只读性、UI类型、数据类型、变量名称及其显示信息

4)        设计权限规划

5)        编写配置信息说明

 

4.3   编码

编码主要包括三部分内容:

1)        根据设计,开发添加和删除模块的脚本

2)        开发多语言支持的代码

3)        根据业务需求,开发特定功能代码

 

 

 

4.4   测试

 

使用开发工具添加/删除模块,按照测试计划测试。

 

4.5   部署

测试通过后,将模块导出到.zip文件,在生产环境中导入该.zip文件。

 

 

5         项目实施需要做的工作

在基于vTigerCRM开发完成后,如果需要进行客户化项目实施,需要注意如下内容:

 

 

 

 

5.1   记录编码规则

在“Settings>Customize Record Numbering”设置好编码规则。

 

 

 

 

 

 

 

6         附录1:实验

6.1   增加一个模块Systeo

参考:http://service.syncomni.com:10080/twiki/bin/view/Syncomni/VTigerCRMDevelopment

 

6.1.1   问题总结

问题1:添加数据时下拉框Systeo Type不显示数据,编辑时可以显示。

分析:

增加一个模块Systeo的脚本代码中,增加了picklist类型(类型编码是15)的字段(field),生成代码如下:

$field2 = new Vtiger_Field();

$field2->name = 'SysteoType';

$field2->label = 'Systeo Type';

$field2->columntype = 'VARCHAR(100)';

$field2->uitype = 15;

$field2->typeofdata = 'V~O';// Varchar~Optional

$block1->addField($field2); /** table and column are automatically set */

 

$field2->setPicklistValues( Array ('Employee', 'Trainee') );

红字部分将会导致在数据库表“vtiger_picklist”中增加一条记录“SysteoType”,在页面显示时,系统将会查找表“vtiger_SysteoType”,实际的表名字是“vtiger_systeotype”。而数据库中,表名字是大小写敏感的,因此页面不能显示期待显示的下拉框数据。

解决:修改表“vtiger_picklist”中name全部为小写即可。

 

问题2:Setting>PickList Editor中,编辑Systeo的Picklist,显示有2条记录,但是值都是空白。

分析:

在AssignPicklistValues.tpl编译生成的.php文件中,显示list的代码如下:

                            <select multiple id="availList" name="availList" class="small crmFormList" style="overflow:auto; height: 150px;width:200px;border:1px solid #666666;font-family:Arial, Helvetica, sans-serif;font-size:11px;">

                                   <?php $_from = $this->_tpl_vars['PICKVAL']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array'); }if (count($_from)):

    foreach ($_from as $this->_tpl_vars['pick_val']):

?>

                                          <option value="<?php echo $this->_tpl_vars['pick_val']; ?>

"><?php echo $this->_tpl_vars['pick_val']; ?>

</option>

                                   <?php endforeach; endif; unset($_from); ?>

                            </select>

 

经过研究代码,未发现任何问题。因此,打开日志调试,计划通过打印更多的信息进行跟踪。打开日志后,发现数据显示正常。猜测是某些代码未及时更新到缓冲程序中。

 

 

 

 

 

 

 

6.2   增加新主菜单

功能:增加一个主菜单Finance,包含2个系统自带的子菜单(模块)Contact和Webmail。

实现:

1)        编辑文件parent_tabdata.php,在$parent_tab_info_array增加:9=>'Finance',在$parent_child_tab_rel_array增加9=>array(4,28)

2)        编辑include/language/en_us.lang.php,在$app_strings中增加’Finance’=>’Finance’

3)        编辑include/language/zh_cn.lang.php,在$app_strings中增加’Finance’=>’财务’

4)        刷新登录页面,出现Finance菜单,但是鼠标划过时没有子菜单出现。

5)        往vtiger_parenttabrel和vtiger_parenttabrel增加对应数据

 

问题:到第4步,不能显示子菜单,分析如下:

原因:在生成页面时,没有生成菜单层,例如对于Settings菜单,会生成菜单层Settings_sub,内容如下:

<div class="drop_mnu" id="Settings_sub" onmouseout="fnHideDrop('Settings_sub')" onmouseover="fnShowDrop('Settings_sub')">

       <table width="100%" border="0" cellpadding="0" cellspacing="0">

                                         

                                                    

              <tr><td><a href="index.php?module=Settings&action=index&parenttab=Settings" class="drop_down">Settings</a></td></tr>

                                         

                                                                                 

              <tr><td><a href="index.php?module=Settings&action=ModuleManager&parenttab=Settings" class="drop_down">Module Manager</a></td></tr>

                     </table>

</div>

如上内容通过调用Header.tpl实现,内容如下:

<!-- Drop Down Menu in the Main Tab -->

{foreach name=parenttablist key=parenttab item=details from=$QUICKACCESS}

<div class="drop_mnu" id="{$parenttab}_sub" onmouseout="fnHideDrop('{$parenttab}_sub')" onmouseover="fnShowDrop('{$parenttab}_sub')">

       <table width="100%" border="0" cellpadding="0" cellspacing="0">

              {foreach name=modulelist item=modules from=$details}

              {assign var="modulelabel" value=$modules[1]|@getTranslatedString:$modules[0]}

             

              {* Use Custom module action if specified *}

              {assign var="moduleaction" value="index"}

          {if isset($modules[2])}

                  {assign var="moduleaction" value=$modules[2]}

          {/if}

             

              <tr><td><a href="index.php?module={$modules.0}&action={$moduleaction}&parenttab={$parenttab}" class="drop_down">{$modulelabel}</a></td></tr>

              {/foreach}

       </table>

</div>

{/foreach}

上述代码翻译后的结果如下:

<!-- Drop Down Menu in the Main Tab -->

<?php $_from = $this->_tpl_vars['QUICKACCESS']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array'); }$this->_foreach['parenttablist'] = array('total' => count($_from), 'iteration' => 0);

if ($this->_foreach['parenttablist']['total'] > 0):

    foreach ($_from as $this->_tpl_vars['parenttab'] => $this->_tpl_vars['details']):

        $this->_foreach['parenttablist']['iteration']++;

?>

<div class="drop_mnu" id="<?php echo $this->_tpl_vars['parenttab']; ?>

_sub" onmouseout="fnHideDrop('<?php echo $this->_tpl_vars['parenttab']; ?>

_sub')" onmouseover="fnShowDrop('<?php echo $this->_tpl_vars['parenttab']; ?>

_sub')">

       <table width="100%" border="0" cellpadding="0" cellspacing="0">

              <?php $_from = $this->_tpl_vars['details']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array'); }$this->_foreach['modulelist'] = array('total' => count($_from), 'iteration' => 0);

if ($this->_foreach['modulelist']['total'] > 0):

    foreach ($_from as $this->_tpl_vars['modules']):

        $this->_foreach['modulelist']['iteration']++;

?>

count($_from)的值是8,并没有将新增加的菜单Finance计算在内,因此需要研究为什么$_from只有8个元素。

$_from = $this->_tpl_vars['QUICKACCESS']是从函数getAllParenttabmoduleslist()获取的值,如下:

$smarty->assign("QUICKACCESS",getAllParenttabmoduleslist());

 

该函数查询了数据库表vtiger_parenttabrel、vtiger_tab和vtiger_parenttabrel进行计算,SQL语句如下:

select name,tablabel,parenttab_label,vtiger_tab.tabid from vtiger_parenttabrel inner join vtiger_tab on vtiger_parenttabrel.tabid = vtiger_tab.tabid inner join vtiger_parenttab on vtiger_parenttabrel.parenttabid = vtiger_parenttab.parenttabid and vtiger_tab.presence in (0,2) order by vtiger_parenttab.sequence, vtiger_parenttabrel.sequence

因此,除了在数据文件增加以外还需要往vtiger_parenttabrel和vtiger_parenttabrel增加对应数据,才能在鼠标划过主菜单时显示子菜单。

6.3   为Project模块增加字段

打开Project模块,初始状态下没有数据,首次添加一个Project,将会提示如下信息:

Duplicate Project No - Click here to Configure the Project No

原因:没有配置项目编码的规则,点击“here”配置即可。

建议:在“Settings>Customize Record Numbering”设置好编码规则。

 

 

7         附录2:中文包完善

文件

文件操作

modules/SMSNotifier/language/zh_cn.lang.php

添加

modules/Project/language/zh_cn.lang.php

添加

Modules/Settings/language/zh_cn.lang.php

修改

 

 

Settings

添加如下内容:

'LBL_PICKLIST_DEPENDENCY_SETUP' => '编辑下拉框依赖关系',

'LBL_PICKLIST_DEPENDENCY_DESCRIPTION' => '定制两个下拉框之间的数据逻辑关系',

 

8         附录:Userful SQL

8.1   Picklist相关

select * from vtiger_picklist where name in (select fieldname from vtiger_field where tablename like '%cashj%' and uitype=15)

 

9         附录:新增uitype列表

uitype

功能

修改文件

1028

DocLib文件上传按钮

Smarty\templates\EditViewUI.tpl:944~964

 

 

 

你可能感兴趣的:(记录)