zoukankan      html  css  js  c++  java
  • SugarCE问题点记录

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

    if (!empty($sugar_config['default_module']))
        $this->default_module = $sugar_config['default_module'];
    $module = $this->default_module;
    if (!empty($_REQUEST['module']))
        $module = $_REQUEST['module'];

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

    function getController($module) {
        $class = ucfirst($module).'Controller';
        $customClass = 'Custom' . $class;
        if (file_exists('custom/modules/'.$module.'/controller.php')){
            $customClass = 'Custom' . $class;
            require_once('custom/modules/'.$module.'/controller.php');
            if (class_exists($customClass)) {
                $controller = new $customClass();
            } else if (class_exists($class)) {
                $controller = new $class();
            }
        } elseif (file_exists('modules/'.$module.'/controller.php')) {
            require_once('modules/'.$module.'/controller.php');
            if (class_exists($customClass)) {
                $controller = new $customClass();
            } else if (class_exists($class)) {
                $controller = new $class();
            }
        } else {
            if (file_exists('custom/include/MVC/Controller/SugarController.php')) {
                require_once('custom/include/MVC/Controller/SugarController.php');
            }
            if (class_exists('CustomSugarController')){
                $controller = new CustomSugarController();
            } else {
                $controller = new SugarController();
            }
        }
        //setup the controller
        $controller->setup($module);
    }

    从代码分析,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:

    class SugarController{
        /**
         * The name of the current action.
         */
        public $action = 'index';
    }

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

    public function setup($module = ''){
        ......
        //set properties on the controller from the $_REQUEST
        $this->loadPropertiesFromRequest();
        //load the mapping files
        $this->loadMappings();
    }
    
    private function loadPropertiesFromRequest(){
        if(!empty($_REQUEST['action']))
          $this->action = $_REQUEST['action'];
        if(!empty($_REQUEST['record']))
          $this->record = $_REQUEST['record'];
        if(!empty($_REQUEST['view']))
          $this->view = $_REQUEST['view'];
        if(!empty($_REQUEST['return_module']))
          $this->return_module = $_REQUEST['return_module'];
        if(!empty($_REQUEST['return_action']))
          $this->return_action = $_REQUEST['return_action'];
        if(!empty($_REQUEST['return_id']))
          $this->return_id = $_REQUEST['return_id'];
    }

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

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

    public function setup($module = ''){
        ......
        //load the mapping files
        $this->loadMappings();
    }
    
    private function loadMappings(){
        $this->loadMapping('action_view_map');
        $this->loadMapping('action_file_map');
        $this->loadMapping('action_remap', true);
    }

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

    private function loadMapping($var, $merge = false){
        if ($merge && !empty($this->$var)){
          $$var = $this->$var;
        } else {
          $$var = array();
        }
        if(file_exists('include/MVC/Controller/'. $var . '.php')){
          require('include/MVC/Controller/'. $var . '.php');
        }
        if(file_exists('modules/'.$this->module.'/'. $var . '.php')){
          require('modules/'.$this->module.'/'. $var . '.php');
        }
        if(file_exists('custom/modules/'.$this->module.'/'. $var . '.php')){
          require('custom/modules/'.$this->module.'/'. $var . '.php');
        }
        if(file_exists('custom/include/MVC/Controller/'. $var . '.php')){
          require('custom/include/MVC/Controller/'. $var . '.php');
        }
    
        // entry_point_registry -> EntryPointRegistry
        $varname = str_replace(" ","",ucwords(str_replace("_"," ", $var)));
        if(file_exists("custom/application/Ext/$varname/$var.ext.php")){
          require("custom/application/Ext/$varname/$var.ext.php");
        }
        if(file_exists("custom/modules/{$this->module}/Ext/$varname/$var.ext.php")){
          require("custom/modules/{$this->module}/Ext/$varname/$var.ext.php");
        }
    
        $this->$var = $$var;
    }

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

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

    class SugarController {
        /**
         * url to redirect to
         */
        public $redirect_url = '';
    }

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

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

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

    final public function execute() {
        try
        {
            $this->process();
            if(!empty($this->view))
            {
                $this->processView();
            }
            elseif(!empty($this->redirect_url))
            {
                  $this->redirect();
            }
        }
        catch (Exception $e)
        {
            $this->handleException($e);
        }
    }
    
    protected function redirect(){
        if (!empty($this->redirect_url))
            SugarApplication::redirect($this->redirect_url);
    }

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

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

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

    public function setup($module = ''){
        ......
        //set properties on the controller from the $_REQUEST
        $this->loadPropertiesFromRequest();
    }
    
    private function loadPropertiesFromRequest(){
        ......
        if(!empty($_REQUEST['record']))
          $this->record = $_REQUEST['record'];
    }

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

    public function process(){
        ......
        $this->loadBean();
    }
    
    public function loadBean()
    {
        if(!empty($GLOBALS['beanList'][$this->module])){
            $class = $GLOBALS['beanList'][$this->module];
            if(!empty($GLOBALS['beanFiles'][$class])){
                require_once($GLOBALS['beanFiles'][$class]);
                $this->bean = new $class();
                if(!empty($this->record)){
                    $this->bean->retrieve($this->record);
                    if($this->bean)
                        $GLOBALS['FOCUS'] = $this->bean;
                }
            }
        }
    }

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

    // index.php
    //    require_once('include/entryPoint.php')
    //        require_once('include/modules.php');
    
    $beanList['Leads'] = 'Lead';
    $beanFiles['Lead'] = 'modules/Leads/Lead.php';

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

  • 相关阅读:
    python的三元运算符
    百度站长社区有价值SEO问题提炼(一)
    Python文件夹与文件的操作
    python核心编程课后题第二版第十章264页
    python核心编程课后题第二版第九章230页
    python核心编程课后题第二版第八章209页
    《python核心编程》课后题第二版第十一章308页
    PhoneGap源码分析1——说明
    EF db first 获取表名称
    SQL Server使用证书最小粒度授权
  • 原文地址:https://www.cnblogs.com/eastson/p/3483584.html
Copyright © 2011-2022 走看看