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. Silverlight设计器——Path

    如下图,在设计一个InfoWindow的时候,顶栏的关闭按钮没有出现.观察了半天,也没有弄明白.无意中,拖动一个几乎透明的信息框,突然就出现了关闭的按钮.原来,那个信息框只是一个Path,它遮住了关闭 ...

  2. Java面试题系列(五)

    序言 基本数据类型数组和引用数据类型数组的区别 基本数据类型数组: 其中存储的元素为基本类型数据. 引用类型数组: 元素是对象,其中存储的是对象的地址值. 引用数据类型的数组使用规定长度的方式进行初始 ...

  3. JS创建对象之组合使用构造函数模式和原型模式

    function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.friends = { ...

  4. cpp 标准库

    源:http://bbs.csdn.net/topics/300040713 C++标准库的所有头文件都没有扩展名.C++标准库的内容总共在50个标准头文件中定义,其中18个提供了C库的功能.< ...

  5. Hbase思维导图之数据存储

  6. Java中使用到的锁

    同一进程 重入锁 使用ReentrantLock获取锁的时候回判断当前线程是否为获取锁的线程,如果是则将同步的状态+1,释放锁的时候则将状态-1,只有将同步状态的次数置为0的时候才会是最终释放锁. 读 ...

  7. 简单的复用accep

    s = socket.socket() adress = ("192.168.15.102", 9999) s.bind(adress) s.listen() s.setblock ...

  8. Maven项目配置logback

    首先,在pom.xml中加入maven依赖 <!-- log start --> <dependency> <groupId>org.slf4j</group ...

  9. 51NOD 数字1的数量

    题目描述: 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. Input ...

  10. linux中管理包的apt和dpkg命令用法

    1,apt-get命令 apt-get是debian,ubuntu发行版的包管理工具,与红帽中的yum工具非常类似,适用于deb包管理式的操作系统,主要用于自动从互联网的软件仓库中搜索.安装.升级.卸 ...