2018-3-9 14:42:14 星期五

本文分两部分:

第一部分是从index.php入口开始的代码执行的部分流程

第二部分是对官方文档的翻译

第一部分: 流程:

入口文件: index.php

->加载 include/entryPoint.php

entryPoin.php:

->加载配置文件 config.php ($sugar_config 数据库配置, 邮件配置, 语种, 日志配置, 默认module/action等等 )  config_override.php

->加载安全相关类, DB工厂类, autoloader, 本地化, 邮件, 日志

->加载权限认证类, 钩子, SugarApplaction类

->设置session_id, 实例化Localization, 获取管理员信息

->sugarApplication()->execute()

exectute():

-> 获取module名字

-> 加载controller.php 查找顺序:

  custom/modules/moduleNameController/controller.php

  modules/moduleNameController/controller.php

  custom/include/MVC/Controller/SugarController.php::CustomSugarController.php

  include/MVC/controller/SugarController.php

-> 检查权限认证信息, 设置主题, -> 设置数据库查询超时, 查询最大连接等资源

->controller->execute()

 注意:

action=index时, 默认是listView: SugarController->remap_action

加载模板:

以SugarController.php为例

SugarController->execute()->procesView()->ViewFactory::loadView()

loadview优先级(当action=index时):

1.当URL参数中有target_module时

custom/modules/{$target_module}/views/view.list.php > modules/{$target_module}/views/view.list.php

2.档URL参数中没有target_module时

  custom/modules/{$module}/views/view.list.php

  modules/{$module}/views/view.list.php

  custom/include/MVC/View/views/view.list.php

  include/MVC/View/views/view.list.php

loadView():

ViewFactory::_buildFormFile()-> new SugarView() (或者_buildClass()) -> ViewFactory::_loadConfig() -> process()

注意: view.list.php是一个公用的模板文件, 他最终的渲染内容是会根一些配置文件, 数据文件有关的

第二部分: 翻译:

Dashlets:

他就是首页页面上的一个功能模块(一个横条) 参考

自定义模块的相关文件:

custom/modules/xxx/Dashlets/xxx/xxx.meta.php : 定义一个数组变量, 里边有模块的名字,描述, 图标, 归属哪个模块

custom/modules/xxx/Dashlets/xxx/xxx.php : 定义一个类, 里边有显示模块内容的方法display()

custom/modules/xxx/Dashlets/xxx/xxx.en_us.lang.php : xxx.meta.php中的title, description使用(没有就直接使用xxx.meta.php数组中定义的值)

单个dashlets要继承自Dashlet.php,

list dashlets继承自DashletGeneric.php,

图表dashlets继承自DashletGenericChart.php

所有的dashlets信息存放在user_preferences表, 每个dashlets都有一个ID

dashlets种类:

1. 展示modules数据 2. 订阅其他网站的数据 3.图表展示 4. 工具(日历, 记事本, 时钟等) 5. 其他

javascript:

位置: ./include/JavaScript/Dashlets.js

功能: 提交表单(postForm), 请求数据(callMethod: 调用dashlet类的方法, 或者调用外部接口,如谷歌地图)

 Databases

支持MySQL和mssql, 高级版本还支持db2和oracle, 没有使用触发器和存储过程, 方便编码和抽象

索引: 放在系统模块或者自定义模块目录下的vardefs.php, 键名叫indices (注意vardef文件, 和metadata文件, 前者是描述数据库表的信息, 后者是描述html样式和布局的配置文件)

主键: sugar用create_guid()方法生成全局的唯一值(GUID)当做所有表的主键, 一共36位的字符串: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee, 没有使用自增值是为了防止在数据同步时产生主键冲突

Entry Point 入口文件

/cron.php  windows/linux 计划任务入口

/index.php  框架入口

/service/{v1版本号}/soap.php

/service/{v1版本号}/rest.php

./include/MVC/Controller/entry_point_registry.php

URL访问方式: http://{sugar url}/index.php?entryPoint={entry point name}

自定义入口: 分 6.3版本之前和之后

6.3之后: 入口文件写在/custom/Extension/application/Ext/EntryPointRegistry/中, 然后通过编译生成到: /custom/application/Ext/EntryPointRegistry/entry_point_registry.ext.php

6.3之前: 要创建/custom/include/MVC/Controller/entry_point_registry.php文件 定义入口(仍然兼容, 但不推荐)

入口信息是一个数组, 每一项是一个入口点, 每一项中包含两个值一个是入口文件的路径, 另一个是bool值,表示是否进行权限验证

File cache  文件缓存

主要缓存模板文件和语言字符串

默认放在/cache目录下边, 如果需要更改位置, 则需要需改 config.php 或者 config_override.php

打开文件缓存: 系统管理 > 系统 > 系统设置 > 高级 > 开发模式

Quick Search

Sugar QuickSearch (SQS)

Suagr Bean

数据库操作:

增:

$bean = BeanFactory::newBean($module);
$bean->name = 'Example Record';
$bean->save();
$record_id = $bean->id;

改:

$bean = BeanFactory::getBean($module, $id);
$bean->name = 'Updated Name';
$bean->save();

通过bean的fetched_rows 属性可以确认一条记录是新建的还是已经存在的 原文

 

Module Framework (module/下的代码结构, 与之对应的是 Application Framework 指application/下的代码结构)

一个module通常包含的文件:

1. Vardefs文件, 定义了数据库的表, 字段, 数据类型和关联关系的信息

2. SugarBean文件, 实现了增删改查的功能, 每个模块都继承自SugarBean, 并添加了适用本模块的方法和变量

3. MetaData文件, 定义页面布局和内容信息: (ListView, DetialView, EditeView, SubPanels(跟其他module的关系), Popups(跟其他记录关联的数据列表))

MVC

主要流程: SugarApplication -> ControllerFactory::getController() -> SugarController() -> SugarController::execute()::process()::processView() -> ViewFactory() -> view -> view::process -> SugarView -> SugarView::display()

Model:

SugarBean 以及其子类, 用来操作数据库, 许多普通的module也会继承自SugarObject

内置的六种SugarObject: Basic, Person, issue, Company, File, Sale

View:

Views, otherwise known as actions are typically used to render views or to process logic

或者叫Action, 他不仅可以输出HTML数据, 也可以输出json数据或其他结构的数据, 有一个内置的/默认的SugarView类, 他实现了很多view所需要的基础功能, 例如处理HTML头部和底部信息,

自定义的view文件, 应该放在 /your_module/views/view.<view_name>.php 而其类名应该是驼峰式命名: <Modulename>View<Viewname>, 首字母大写, 其余字母小写, 自定义视图文件可以继承自SugarView或其他View

view分类:

1. DatilView, 通常从ListView页面进入, 他显示了自身的一些数据以及关联的条目(子面板), 子面板是在详情页显示的与之有关的列表性质的信息

./<module>/metadata/detailviewdefs.php定义了详情页的布局  ./<module>/metadata/subpaneldefs.php定义了详情页显示的子面板

2, EditView, 新添加或者编辑都属于他, ./<module>/metadata/editviewdefs.php 中存放编辑页面的布局

3, ListView, 他包含了搜索表单, 搜索结果, 可以 删除, 导出, 批量更新数据, 也可以点击去查看详情

4, Save,

5, Delete

view 方法:

1, preDidplay() 当一个视图继承了其他视图的时候就可以使用这个函数了,

2, display()  展示数据, 将逻辑都写在这里边

加载视图:

ViewFactory 按照以下顺序去加载vew文件:

./custom/modules/<module>/views/view.<view>.php
./modules/<module>/views/view.<view>.php
./custom/include/MVC/View/view.<view>.php
./include/MVC/Views/view.<view>.php

视图的配置文件:

ViewFactory在渲染页面的时候, 会从下边文件中找到一些配置信息, 去控制视图的显示

./customs/modules/<module>/views/view.<view>.config.php
./modules/<module>/views/view.<view>.config.php
./custom/include/MVC/View/views/view.<view>.config.php
./include/MVC/View/views/view.<view>.config.php

Controller

Sugar主要的控制器是 SugarController, 如果想继承他, 就要在自己的模块中创建一个controller.php, 并把类名定义为<ModuleName>Controller, 而类的action的命名方式是 action_functionName

有许多细粒度的控制机制可以被开发者利用, 去重写controller的处理流程, 例如:

如果你想重写Save功能, 你可能要重写三个地方:

1, action_save: 处理保存的逻辑

2, pre_save: 处理来自表单的数据

3, post_save: 这里可以设置跳转链接, 或者保存后的一些处理逻辑, 或者展示一个新的view

自定义controller

自定义的controller要么继承自已经存在于/<module>/controller.php的类, 要么继承自SagurController, 但都要放在 ./custom/modules/<module>/controller.php 为了升级的时候不会被覆盖

包含控制器的文件:

./include/MVC/Controller/SugarController.php
./include/MVC/Controller/ControllerFactory.php
./modules/<MyModule>/Controller.php
./custom/modules/<MyModule>/controller.php

action

控制器中的方法可以直接写在控制器类中, 也可以通过 $action_file_map 去找到对应的代码文件去执行, $action_file_map的加载顺序如下, 后边的变量会覆盖前边的同名变量

./include/MVC/Controller
./modules/<module>
./custom/modules/<module>
./custom/include/MVC/Controller

自定义的 $action_file_map 文件需要放在 ./custom/modules/<module>/action_file_map.php 路径中, 确保安全升级

Controller执行流程:

1, 从index.php开始, 加载SugarApplication实例

2, SugarApplication实例化 SugarControllerFactory

3, SugarControllerFactory加载对应的Controller

4, 检查 ./custom/modules/<module>/Controller.php 是否存在

  1, 如果不存在, 检查./modules/<module>/Controller.php是否存在

  2, 如果还不存在, 就加载SugarController.php

5, 调用对应的action

  1, 检查./custom/modules/<module>/<action>.php是否存在, 如果找到了, 并且./custom/modules/<module>/views/view.<action>.php不存在, 那就用这个view ???wtf

  2, 如果不存在 ./custom/modules/<module>/<action> 就去查找 modules/<module>/<action>.php, 如果找到了, 并且./modules/<module>/views/view.<action>.php不存在, 就使用modules/<module>/<action>.php

  3, 如果不存在 modules/<module>/<action>.php 就在控制器里查找 action_<action> 方法

  4, 如果控制器中不存在这个方法, 就去加载 action_file_mapping, 并查找

  5, 还是没有找到, 就报错"Action is not defined"

Metadata (用于页面布局的配置信息)

背景: Metadata定义为数据的信息 , 框架会利用这些文件去表达/抽象系统中页面怎么显示或者业务是怎样的逻辑, Metadata存在于定义性质的php文件中, 并由php进行处理, 这些处理通常包括, 1. Smarty 模板渲染页面, 2. JavaScript库处理(调用)一些影响显示的逻辑,或者对输入进行验证等

概念: Metadata是一个定义了嵌套数组的php文件, 他描述了视图中的按钮, hidden input标签, 字段布局等等的信息,

Application级别的Metadata

所有可用的应用模块都定义在 /include/moudules.php 其中:

$moduleList 定义了用于在界面顶部显示的tabs的名字, 他是个索引数组, 每一项的值都用复数形式 (so??)

$beanList 定义了可用的beans(modules), 他是一个关联数组, 键是复数形式, 值是单数形式, 值还跟$beanFiles关联

$beanFiles 定义了modules文件位置

$modInvisList 定义了可以在界面上显示的modues

$adminOnlyList 定义了在admin页面可以被admin看到的modules

Module级别的Metadata

路径: modules/[module]/metadata

additionalDetails.php 定义了当用户鼠标滑过listView的一行时的显示效果
editviewdefs.php 编辑页面如何渲染
detailviewdefs.php 详情页面如何渲染
listviewdefs.php 列表页面如何渲染
metafiles.php 重新定义详情, 编辑, 列表需要的metadata文件的路径
popupdefs.php 渲染搜索表单和列表页面时使用
searchdefs.php 显示modules的基础和高级搜索时使用
sidecreateviewdefs.php 在快捷面板上创建表单时使用
subpaneldefs.php 在详情页面的字面板展示

这些metadata文件的路径也可以在metafiles.php中被重新定义

搜索表单(Search Form)的Metadata

文件名是searchdefs.php, 里边是一个多维数组, 定义了某个模块的表单怎么显示

比如Accounts模块的表单( $searchDefs['Accounts']), 这个表单有多少列, 每一个表单项的文字宽度是多少百分比, input框多少百分比, input的name属性的值等等

其中$searchDefs['Accounts'] 中的Accounts是在 include/modules.php::$moduleList 变量中定义的键名

当一个模块的list视图被渲染的时候, 就会引入searchdefs.php文件, 在view.list.php中会检查modules中是否存在SearchForm.html

如果存在, 就会以Classic模式, 用include/SearchForm/SearchForm.php去处理搜索表单, (Classic Mode是指5.x版本之前, 目前是MVC/Metadata模式)

如果不存在, 就会用include/SearchForm/SearchForm2.php去处理搜索表单, 此时 就会在 custom/modules/[module]/metadata/ 和 modules/[module]/metadata 中依次寻找searchdefs.php文件

EditView 和 DetailView  的 Metadata

metadata文件也以通过studio interface(手工拖动?)去自动创建, 这种情况下, metadata会放在 custom/modules/[module]/metadata/目录下

当第一次访问一个view的时候, preDisplay()方法会去尝试加载正确的metadata文件, 通常情况下metadata文件会在/modules/[module]/metadata/目录下

metadata也可能放在其他路径下边, 他们的路径可以在metafiles.php中找到

生成html文件/渲染视图

当按照上边的约定加载完metadata后,  preDisplay()方法还会创建一个EditView object(以EditView为例), 检查是否需要根据metadata区构建一个smarty模板, EditView object会做大量的工作:

创建模板, 赋值, 权限等级判断等等,

在view代码中调用完preDisplay()方法后就会去调用display()->EditView object()::process()->EditView object()::display()->将生成的html数据放到buffer中输出

举例

加入有一个详情页的请求:  index.php?action=DetailView&module=Opportunities&record=46af9843-ccdf-f489-8833

1. 程序先去是否有一个 modules/Opportunity/DetailView.php 如果有就会去触发 Classic 模式的渲染方式

如果没有这个文件, 程序就会去找modules/Opportunity/views/view.detail.php

如果两个都没有, 程序就会加载include/DetailView/DetailView.php,  此时是 MVC模式,  include/MVC/View/views/views.detail.php 会创建一个DetailView的实例 -> 加载smarty -> setup() -> process() -> display();

2. 其中setup()会创建一个 TemplateHandler 实例, 他在创建最终的详情视图时会去检查加载哪个detailviewdefs.php, 如果setup()中传入了metadata参数就用这个参数, 没有的话, 就去做其他检查

TemplateHandler 实例 也会去做一些 ajax, javascript验证有关的事情

3. process()方法会根据metadata去计算页面展示时HTML元素之间的距离, 字段个数, 以及每列所占的百分比等等

4. display()方法会把变量赋值到Smarty模板上去, 并返回最终要输出的内容

5. 在输出前, TemplateHandler 实例会去检查缓存目录中有没有对应的文件(cache/modules/Opportunity/DetailView.tpl), 如果没有, 就会调用Sugar_Smarty::fetch()去生成缓存文件, 这一步很耗费资源, 另外, 通过 studio interface 方法生成的模板肯定会刷新缓存

Sugar Fields

sugar 根据metadata文件(例如listviewdefs.php)vardefs.php中定义的字段信息, 可以在include/SugarFields/Fields中找到sugar Fields文件

在 include/SugarFields/Fields/Base 中你会找到渲染  DetailView, EditView, ListView, 和 Search Forms 这些基础视图的模板(例如, DetailView.tpl)

目录结构:

./include/SugarFields/Fields/
./include/SugarFields/Fields/<Type>/DetailView.tpl  //Type: 比如Bool, Enum, Text, URL, Readonly... 
./modules/MyModule/vardefs.php
./modules/MyModule/metadata/defs.php

字段类型以及关联信息(比如是枚举类型, 他就会有多个值) 去自动生成HTML标签

Type: 也有group类型的比如 Address, Datetime, Parent, Relate

大多数的Sugar Field包含了一堆Smarty tpl文件

一些 Sugar Fields 还包含了 SugarFieldBase  的子类, 用来覆盖原有的方法去做一些额外的处理, 子类的名字要这样写: SugarField[Sugar Field Type] 其中后边的英文单词首字母要大写

例如:

enum类型的SugarField(会被渲染成 select 标签)的代码, 放在 ./include/SugarFields/Fields/Enum/SugarFieldEnum.php中,

这个代码中你可以看到, 枚举类型是是怎么使用6个Smarty模板中的一个取决于

1. view是什么(edit, detail or search)

2. enum vardef 的定义中是否有一个 'function' 属性去调用php函数去渲染字段的内容

例子, 添加一个视频input

Vardefs

他(Variable Definitions) 给Application提供了SugarBean的信息, 如果一个moudles包含了SugarBean, 那么就会有一个vardefs文件,

该文件用来描述表中的每个字段的信息, beans之间的关系, bean的索引信息, 关联表/字段信息等等

 

还有一页

sugarCRM文档翻译1的更多相关文章

  1. 我是如何进行Spring MVC文档翻译项目的环境搭建、项目管理及自动化构建工作的

    感兴趣的同学可以关注这个翻译项目 . 我的博客原文 和 我的Github 前段时间翻译的Spring MVC官方文档完成了第一稿,相关的文章和仓库可以点击以下链接.这篇文章,主要是总结一下这个翻译项目 ...

  2. Hibernate 3.3.2 文档翻译 Day01

    Hibernate 3.3.2 文档翻译 翻译人:微冷的雨 第一次书写:2015年11月29日 本人呕心沥血之作,请细心阅读领悟! Day01-1.1 项目描述 微冷的雨翻译:例如,我们将要建立一个可 ...

  3. Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)中一些知识点

    Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Flume官方文档翻译--Flume 1.7.0 User Guide (unr ...

  4. Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)(二)

    Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Logging raw data(记录原始数据) Logging the raw ...

  5. SQLAlchemy 中文文档翻译计划

    SQLAlchemy 中文文档翻译计划已启动. Python 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质.交流群:467338606. 希望大家能够勇敢地去翻译和改进翻译.虽然我 ...

  6. Laravel 5.3 中文文档翻译完成

    经过一个多月的紧张翻译和校对,翻译完成.以下是参与人员: Laravel 5.3 中文文档翻译完成 稿源:七星互联www . qixoo.com 文档地址在此:https://laravel-chin ...

  7. 蓝牙4.0——Android BLE开发官方文档翻译

    ble4.0开发整理资料_百度文库 http://wenku.baidu.com/link?url=ZYix8_obOT37JUQyFv-t9Y0Sv7SPCIfmc5QwjW-aifxA8WJ4iW ...

  8. Linux内核文档翻译之Squashfs文件系统

    转载:http://blog.csdn.net/gqb_driver/article/details/12946629 对于使用openwrt的嵌入式系统来说,因为硬件绝大多数采用Flash,因此一般 ...

  9. GreenDao官方文档翻译(上)

    笔记摘要: 上一篇博客简单介绍了SQLite和GreenDao的比较,后来说要详细介绍下GreenDao的使用,这里就贴出本人自己根据官网的文档进行翻译的文章,这里将所有的文档分成上下两部分翻译,只为 ...

随机推荐

  1. 记一次解决非法参数DDoS攻击的实践

    起因 线上项目突然遭到大量的非法参数攻击,由于历史问题,之前的代码从未对请求参数进行校验. 导致大量请求落到了数据访问层,给应用服务器和数据库都带来了很大压力. 针对这个问题,只能对请求真正到Cont ...

  2. [Android] [putty连接Android设备] [Android设备网络调试]

    file: system/core/adb/adb.c line: 921 /* for the device, start the usb transport if the ** android u ...

  3. php与java通用AES加密解密算法

    AES指高级加密标准(Advanced Encryption Standard),是当前最流行的一种密码算法,在web应用开发,特别是对外提供接口时经常会用到,下面是我整理的一套php与java通用的 ...

  4. REST POST PUT差别

    rest api http://www.cnblogs.com/zhangpengshou/archive/2012/07/09/2583096.html Rest模式get,put,post,del ...

  5. Javaweb学习笔记——(十七)——————JDBC的原理、四大核心类、四大参数、预编译、Dao模式、批处理、大数据、时间类型的转换

    JDBC入门 *导入jar包:驱动 *加载驱动类:Class.forName("类名"); *给出url.username.password,其中url背下来 *使用DriverM ...

  6. ****** 四十 ******、软设笔记【网络基础】-Internet和Intranet基础

    Internet和Intranet基础 一.网络地址及子网掩码 1.IP地址结构及类别 IP地址是由32位二进制数,即4个字节组成的,由网络号和主机号两个字段组成. 网络号的位数决定了可以分配的网络数 ...

  7. poj2559/hdu1506 单调栈经典题

    我实在是太菜了啊啊啊啊啊 到现在连个单调栈都不会啊啊啊 写个经典题 #include<cstdio> #include<algorithm> #include<cstri ...

  8. PHP文件系统管理

    文件概念: 第一个是windows的文件,另一个php根据LINUX的文件,两者是有所不同的,我们说的页面基于windows的文件可以是是文件夹(也就是目录)或是文件,而php两者都必须有,它包含目录 ...

  9. DNN网络(二)反向传播算法

    本文摘自: https://www.cnblogs.com/pinard/p/6422831.html http://www.cnblogs.com/charlotte77/p/5629865.htm ...

  10. spring cloud心跳检测自我保护(EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.)

    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER ...