问:如何获取module参数?如果module参数不存在,如何处理?
答:首先检查$_REQUEST['module'],然后再检查$sugar_config['default_module']是否有设置,如果都没有则用SugarApplication类的实例变量$default_module(默认为Home)。这些在SugarApplication::execute()函数的开头进行处理:

  1. if (!empty($sugar_config['default_module']))
  2. $this->default_module = $sugar_config['default_module'];
  3. $module = $this->default_module;
  4. if (!empty($_REQUEST['module']))
  5. $module = $_REQUEST['module'];

问:获得module后,会去创建控制器类,在哪里找到该类?
答:ControllerFactory::getController($module)函数负责创建控制器类:

  1. function getController($module) {
  2. $class = ucfirst($module).'Controller';
  3. $customClass = 'Custom' . $class;
  4. if (file_exists('custom/modules/'.$module.'/controller.php')){
  5. $customClass = 'Custom' . $class;
  6. require_once('custom/modules/'.$module.'/controller.php');
  7. if (class_exists($customClass)) {
  8. $controller = new $customClass();
  9. } else if (class_exists($class)) {
  10. $controller = new $class();
  11. }
  12. } elseif (file_exists('modules/'.$module.'/controller.php')) {
  13. require_once('modules/'.$module.'/controller.php');
  14. if (class_exists($customClass)) {
  15. $controller = new $customClass();
  16. } else if (class_exists($class)) {
  17. $controller = new $class();
  18. }
  19. } else {
  20. if (file_exists('custom/include/MVC/Controller/SugarController.php')) {
  21. require_once('custom/include/MVC/Controller/SugarController.php');
  22. }
  23. if (class_exists('CustomSugarController')){
  24. $controller = new CustomSugarController();
  25. } else {
  26. $controller = new SugarController();
  27. }
  28. }
  29. //setup the controller
  30. $controller->setup($module);
  31. }

从代码分析,ControllerFactory按照下列顺序寻找控制器类:

  • custom/modules/{module}/controller.php,检查Custom{Module}Controller类是否存在,若不存在,再检查{Module}Controller类是否存在。
  • modules/{module}/controller.php,检查Custom{Module}Controller类是否存在,若不存在,再检查{Module}Controller类是否存在。
  • custom/include/MVC/Controller/SugarController.php,检查CustomSugarController类是否存在,若不存在,再检查SugarController类是否存在。
  • include/MVC/Controller/SugarController.php,检查CustomSugarController类是否存在,若不存在,再检查SugarController类是否存在。

问:如何获取action参数?如果action参数不存在,如何处理?
答:action参数对应到SugarController的$action实例变量,该实例变量默认值为index:

  1. class SugarController{
  2. /**
  3. * The name of the current action.
  4. */
  5. public $action = 'index';
  6. }

当控制器setup()时调用loadPropertiesFromRequest()获取$_REQUEST中的action参数:

  1. public function setup($module = ''){
  2. ......
  3. //set properties on the controller from the $_REQUEST
  4. $this->loadPropertiesFromRequest();
  5. //load the mapping files
  6. $this->loadMappings();
  7. }
  8.  
  9. private function loadPropertiesFromRequest(){
  10. if(!empty($_REQUEST['action']))
  11. $this->action = $_REQUEST['action'];
  12. if(!empty($_REQUEST['record']))
  13. $this->record = $_REQUEST['record'];
  14. if(!empty($_REQUEST['view']))
  15. $this->view = $_REQUEST['view'];
  16. if(!empty($_REQUEST['return_module']))
  17. $this->return_module = $_REQUEST['return_module'];
  18. if(!empty($_REQUEST['return_action']))
  19. $this->return_action = $_REQUEST['return_action'];
  20. if(!empty($_REQUEST['return_id']))
  21. $this->return_id = $_REQUEST['return_id'];
  22. }

也就是说,action参数首选会从$_REQUEST['action']获取,如果没有设置$_REQUEST['action']则使用SugarController的默认值index。

问:SugarController中如何装入Mapping文件?
答:控制器中有一个loadMapping()函数用来装入Mapping文件。该函数在控制器的setup()函数中被调用:

  1. public function setup($module = ''){
  2. ......
  3. //load the mapping files
  4. $this->loadMappings();
  5. }
  6.  
  7. private function loadMappings(){
  8. $this->loadMapping('action_view_map');
  9. $this->loadMapping('action_file_map');
  10. $this->loadMapping('action_remap', true);
  11. }

控制器允许会从多个地方寻找Mapping文件:

  1. private function loadMapping($var, $merge = false){
  2. if ($merge && !empty($this->$var)){
  3. $$var = $this->$var;
  4. } else {
  5. $$var = array();
  6. }
  7. if(file_exists('include/MVC/Controller/'. $var . '.php')){
  8. require('include/MVC/Controller/'. $var . '.php');
  9. }
  10. if(file_exists('modules/'.$this->module.'/'. $var . '.php')){
  11. require('modules/'.$this->module.'/'. $var . '.php');
  12. }
  13. if(file_exists('custom/modules/'.$this->module.'/'. $var . '.php')){
  14. require('custom/modules/'.$this->module.'/'. $var . '.php');
  15. }
  16. if(file_exists('custom/include/MVC/Controller/'. $var . '.php')){
  17. require('custom/include/MVC/Controller/'. $var . '.php');
  18. }
  19.  
  20. // entry_point_registry -> EntryPointRegistry
  21. $varname = str_replace(" ","",ucwords(str_replace("_"," ", $var)));
  22. if(file_exists("custom/application/Ext/$varname/$var.ext.php")){
  23. require("custom/application/Ext/$varname/$var.ext.php");
  24. }
  25. if(file_exists("custom/modules/{$this->module}/Ext/$varname/$var.ext.php")){
  26. require("custom/modules/{$this->module}/Ext/$varname/$var.ext.php");
  27. }
  28.  
  29. $this->$var = $$var;
  30. }

loadMapping()函数在最后会将装入的Mapping映射为控制器的实例变量。

问:控制器中如何实现URL重定向?
答:SugarController中定义了一个实例变量redirect_url:

  1. class SugarController {
  2. /**
  3. * url to redirect to
  4. */
  5. public $redirect_url = '';
  6. }

在Action方法中设置$redirect_url就可以实现URL重定向。例如:

  1. function action_redirect() {
  2. $this->redirect_url = 'http://www.baidu.com/';
  3. |

这是因为SugarController使用execute()函数处理请求,在该函数末尾有检查$redirect_url是否有设值。若有设值,则调用SugarApplication::redirect()跳转:

  1. final public function execute() {
  2. try
  3. {
  4. $this->process();
  5. if(!empty($this->view))
  6. {
  7. $this->processView();
  8. }
  9. elseif(!empty($this->redirect_url))
  10. {
  11. $this->redirect();
  12. }
  13. }
  14. catch (Exception $e)
  15. {
  16. $this->handleException($e);
  17. }
  18. }
  19.  
  20. protected function redirect(){
  21. if (!empty($this->redirect_url))
  22. SugarApplication::redirect($this->redirect_url);
  23. }

如果不在控制器中要实现URL重定向,就应该用SugarApplication::redirect()函数。

问:控制器如何自动读取Bean?

答:如果请求参数中有record存在,则SugarController会自动读取后台数据到实例变量$bean中。首先控制器要从$_REQUEST获取record参数到$this->record:

  1. public function setup($module = ''){
  2. ......
  3. //set properties on the controller from the $_REQUEST
  4. $this->loadPropertiesFromRequest();
  5. }
  6.  
  7. private function loadPropertiesFromRequest(){
  8. ......
  9. if(!empty($_REQUEST['record']))
  10. $this->record = $_REQUEST['record'];
  11. }

然后,控制器在处理请求时通过在process()函数中调用loadBean()实现读取Bean:

  1. public function process(){
  2. ......
  3. $this->loadBean();
  4. }
  5.  
  6. public function loadBean()
  7. {
  8. if(!empty($GLOBALS['beanList'][$this->module])){
  9. $class = $GLOBALS['beanList'][$this->module];
  10. if(!empty($GLOBALS['beanFiles'][$class])){
  11. require_once($GLOBALS['beanFiles'][$class]);
  12. $this->bean = new $class();
  13. if(!empty($this->record)){
  14. $this->bean->retrieve($this->record);
  15. if($this->bean)
  16. $GLOBALS['FOCUS'] = $this->bean;
  17. }
  18. }
  19. }
  20. }

从loadBean()代码可以发现,要自动装入Bean需要定义$GLOBALS['beanList']和$GLOBALS['beanFiles']。默认的定义在include/modules.php:

  1. // index.php
  2. // require_once('include/entryPoint.php')
  3. // require_once('include/modules.php');
  4.  
  5. $beanList['Leads'] = 'Lead';
  6. $beanFiles['Lead'] = 'modules/Leads/Lead.php';

问:控制器如何处理action_remap?
问:控制器如何处理action_file_map和action_view_map?
问:控制器如何检查用户请求的权限?例如谁人可以执行数据库的备份和恢复处理?

SugarCE问题点记录的更多相关文章

  1. 记一次debug记录:Uncaught SyntaxError: Unexpected token ILLEGAL

    在使用FIS3搭建项目的时候,遇到了一些问题,这里记录下. 这里是发布搭建代码: // 代码发布时 fis.media('qa') .match('*.{js,css,png}', { useHash ...

  2. nginx配置反向代理或跳转出现400问题处理记录

    午休完上班后,同事说测试站点访问接口出现400 Bad Request  Request Header Or Cookie Too Large提示,心想还好是测试服务器出现问题,影响不大,不过也赶紧上 ...

  3. Kali对wifi的破解记录

    好记性不如烂笔头,记录一下. 我是在淘宝买的拓实N87,Kali可以识别,还行. 操作系统:Kali 开始吧. 查看一下网卡的接口.命令如下 airmon-ng 可以看出接口名称是wlan0mon. ...

  4. 2015 西雅图微软总部MVP峰会记录

    2015 西雅图微软总部MVP峰会记录 今年决定参加微软MVP全球峰会,在出发之前本人就已经写这篇博客,希望将本次会议原汁原味奉献给大家 因为这次是本人第一次写会议记录,写得不好的地方希望各位园友见谅 ...

  5. 分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)

    分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...

  6. 我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  7. 前端学HTTP之日志记录

    前面的话 几乎所有的服务器和代理都会记录下它们所处理的HTTP事务摘要.这么做出于一系列的原因:跟踪使用情况.安全性.计费.错误检测等等.本文将谥介绍日志记录 记录内容 大多数情况下,日志的记录出于两 ...

  8. ASP.NET Core应用中如何记录和查看日志

    日志记录不仅对于我们开发的应用,还是对于ASP.NET Core框架功能都是一项非常重要的功能特性.我们知道ASP.NET Core使用的是一个极具扩展性的日志系统,该系统由Logger.Logger ...

  9. python+uwsgi导致redis无法长链接引起性能下降问题记录

    今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...

随机推荐

  1. Java多线程-run方法与start方法的区别

    package com.interview; /** * java多线程的两种实现方式以及run.start方法的区别 * @author MEI.LIU * */ public class Thre ...

  2. 【拓扑排序】【DFS】Painting A Board

    [poj1691]Painting A Board Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3902   Accept ...

  3. 【预处理】【分类讨论】Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains

    分几种情况讨论: (1)仅用C或D买两个 ①买两个代价相同的(实际不同)(排个序) ②买两个代价不同的(因为买两个代价相同的情况已经考虑过了,所以此时对于同一个代价,只需要保存美丽度最高的喷泉即可)( ...

  4. POJ 3437 Tree Grafting

    题意:给出一个深度优先遍历树的up down顺序,求这棵树以及这棵树变为”左子右兄”树的高度 思路:直接dfs,x代表树1的高度,y代表树2的高度 #include<cstdio> #in ...

  5. MySQL v5.7.18 版本解压安装

    下载MySQL https://dev.mysql.com/downloads/mysql/5.1.html#downloads 个人机子是64位的,所以选择下载:Windows (x86, 64-b ...

  6. js 根据开始日期和结束日期显示倒计时

    <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con ...

  7. leetcode 576. Out of Boundary Paths

    leetcode 576 题意大概就是在一个m*n的网格中,在坐标为[i,j]的网格上放一个物体,在规定时间N(t<=N)中,有多少种方法把物体移动出去.物体只能上下左右移动,一次移动一格,移动 ...

  8. FORM-加载前指定日期时间格式

    PRE-FORM -- Standard date format --BEGIN  set_application_property(DATE_FORMAT_COMPATIBILITY_MODE, ' ...

  9. 事件click,bind,click

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  10. Openshift部署Zookeeper和Kafka

    部署Zookeeper github网址 https://github.com/ericnie2015/zookeeper-k8s-openshift 1.在openshift目录中,首先构建imag ...