SugarCRM源码分析之ViewFactory

来源:互联网 发布:看门狗软件下载 编辑:程序博客网 时间:2024/05/01 22:39


        和ControllerFactory类似,ViewFactory则负责实例并初始各个模块的视图类,不过调用的视图工厂则是在各个具体控制器内。

class SugarController{    ```    private function processView(){        if(!isset($this->view_object_map['remap_action']) && isset($this->action_view_map[strtolower($this->action)]))        {          $this->view_object_map['remap_action'] = $this->action_view_map[strtolower($this->action)];        }        $view = ViewFactory::loadView($this->view, $this->module, $this->bean, $this->view_object_map, $this->target_module);        $GLOBALS['current_view'] = $view;        if(!empty($this->bean) && !$this->bean->ACLAccess($view->type) && $view->type != 'list'){            ACLController::displayNoAccess(true);            sugar_cleanup(true);        }        if(isset($this->errors)){          $view->errors = $this->errors;        }        $view->process();    }    ```}

        下面接主要ViewFactory的功能

class ViewFactory{    /**     * load the correct view     * @param string $type View Type     * @return valid view     */    function loadView($type = 'default', $module, $bean = null, $view_object_map = array(), $target_module=''){        $type = strtolower($type);        // first let's check if the module handles this view        $view = null;        // Check to see if we should load a custom parent view instance        /**          * 这一步加载具体的视图类【ViewSidecar】文件,并且进而引入试图类【SidecarView】,最后引入总的视图继承类          * class ViewSidecar extends SidecarView {```}          * class SidecarView extends SugarView {```}          * class SugarView {```}            function loadParentView($type)            {                SugarAutoLoader::requireWithCustom('include/MVC/View/views/view.'.$type.'.php');            }        */        loadParentView($type);        if(!empty($target_module)) {            $view_file = SugarAutoLoader::existingCustomOne('modules/'.$target_module.'/views/view.'.$type.'.php');            $view_module = $target_module;        } else {            $view_module = $module;        }        // 下面三步,逐次提高,现在所属模块查找view文件,没有再提升到总的视图查找        // 这里侧重的是如果用户定制了视图文件,那么就加载用户定制的视图文件        // 因为existingCustomOne最后加载的视图文件[如果有的话],返回时array_pop会把此文件给弹出来        if(empty($view_file)) {            $view_file = SugarAutoLoader::existingCustomOne('modules/'.$module.'/views/view.'.$type.'.php');        }        if(empty($view_file)) {            $view_file = SugarAutoLoader::existingCustomOne('include/MVC/View/views/view.'.$type.'.php');        }        if(!empty($view_file)) {            $view = ViewFactory::_buildFromFile($view_file, $bean, $view_object_map, $type, $view_module);        }        if(empty($view)) {            // Default to SugarView if still nothing found/built            $view = new SugarView();        }        ViewFactory::_loadConfig($view, $type);        return $view;    }    /**     * This is a private function which just helps the getView function generate the     * proper view object     *     * @return a valid SugarView     */    function _buildFromFile($file, &$bean, $view_object_map, $type, $module){        // 第一优先级,查找HomeViewSidecar类        require_once($file);        //try ModuleViewType first then try ViewType if that fails then use SugarView        $class = SugarAutoLoader::customClass(ucfirst($module).'View'.ucfirst($type));        if(class_exists($class)){            return ViewFactory::_buildClass($class, $bean, $view_object_map);        }        // 第二优先级,查找ViewSidecar类,bingo        //Now try the next set of possibilites if it was none of the above        //It can be expensive to load classes this way so it's not recommended        $class = SugarAutoLoader::customClass('View'.ucfirst($type));        if(class_exists($class)){            return ViewFactory::_buildClass($class, $bean, $view_object_map);        }         // 第三优先级,查找SugarView类        //Now check if there is a custom SugarView for generic handling        // autoloader will check filesystem        $class = SugarAutoLoader::customClass('SugarView', true);        //if all else fails return SugarView        return new $class($bean, $view_object_map);    }    /**     * instantiate the correct view and call init to pass on any obejcts we need to     * from the controller.     *     * @param string class - the name of the class to instantiate     * @param object bean = the bean to pass to the view     * @param array view_object_map - the array which holds obejcts to pass between the     *                                controller and the view.     *     * @return SugarView     */    function _buildClass($class, $bean, $view_object_map){        // 实例并初始化        $view = new $class();        $view->init($bean, $view_object_map);        if($view instanceof SugarView){            return $view;        }else            return new SugarView($bean, $view_object_map);    }    /**     * Load the view_<view>_config.php file which holds options used by the view.     */    function _loadConfig(&$view, $type){        $view_config_custom = array();        $view_config_module = array();        $view_config_root_cstm = array();        $view_config_root = array();        $view_config_app = array();        $config_file_name = 'view.'.$type.'.config.php';        $view_config = sugar_cache_retrieve("VIEW_CONFIG_FILE_".$view->module."_TYPE_".$type);        if(!$view_config){            $view_config_all = array('actions' => array(), 'req_params' => array(),);            // 加载include/MVC/View/views/view.config.php后,$view_config会有数据            foreach(SugarAutoLoader::existingCustom(                'include/MVC/View/views/view.config.php',                'include/MVC/View/views/'.$config_file_name,                'modules/'.$view->module.'/views/'.$config_file_name            ) as $file) {                $view_config = array();                require $file;                if(!empty($view_config['actions'])) {                    $view_config_all['actions'] = array_merge($view_config_all['actions'], $view_config['actions']);                }                if(!empty($view_config['req_params'])) {                    $view_config_all['req_params'] = array_merge($view_config_all['req_params'], $view_config['req_params']);                }            }            $view_config = $view_config_all;            sugar_cache_put("VIEW_CONFIG_FILE_".$view->module."_TYPE_".$type, $view_config);        }        $action = strtolower($view->action);        $config = null;        if(!empty($view_config['req_params'])){            // try the params first            foreach($view_config['req_params'] as $key => $value){                if(!empty($_REQUEST[$key]) && $_REQUEST[$key] == "false") {                    $_REQUEST[$key] = false;                }                if(!empty($_REQUEST[$key])){                    if(!is_array($value['param_value'])){                        if($value['param_value'] ==  $_REQUEST[$key]){                            $config = $value['config'];                            break;                        }                    }else{                        foreach($value['param_value'] as $v){                            if($v ==  $_REQUEST[$key]){                                $config = $value['config'];                                break;                            }                        }                    }                }            }        }        if($config == null && !empty($view_config['actions']) && !empty($view_config['actions'][$action])){                $config = $view_config['actions'][$action];        }        if($config != null)            $view->options = $config;    }}


        拿实例化ViewSidecar类来说(这个是按默认的模块来的,也就是直接输入本地SugarCRM域名,会加载配置文件中的默认模块和默认方法)

require_once('include/MVC/View/SidecarView.php');class ViewSidecar extends SidecarView{    /**     * Constructor     *     * @see SidecarView::SidecarView()     */ public function __construct($bean = null, $view_object_map = array()) {        $this->options['show_title'] = false;        $this->options['show_header'] = false;        $this->options['show_footer'] = false;        $this->options['show_javascript'] = false;        $this->options['show_subpanels'] = false;        $this->options['show_search'] = false; parent::__construct($bean = null, $view_object_map = array()); }}

        继承了SideView类,初始化时设置了页面属性并加载父类SidecarView初始化方法

class SidecarView extends SugarView{    ```    protected $configFileName = "config.js";    protected $configFile;        public function __construct()    {        $this->configFile = sugar_cached($this->configFileName);        parent::SugarView();    }    ```}

      SidecarView又继承了SugarView类,同时也在初始化时执行了父类SugarView类的__construct方法

class SugarView{    ```    /**     * Constructor which will peform the setup.     */    public function SugarView($bean = null, $view_object_map = array())    {        $this->base_menu = SugarAutoLoader::loadExtension("menus", "application");    }    public function init($bean = null, $view_object_map = array())    {        $this->bean = $bean;        $this->view_object_map = $view_object_map;        $this->action = $GLOBALS['action'];        $this->module = $GLOBALS['module'];        $this->_initSmarty();    }    // 加载smarty模板类    protected function _initSmarty()    {        $this->ss = new Sugar_Smarty();        $this->ss->assign('MOD', $GLOBALS['mod_strings']);        $this->ss->assign('APP', $GLOBALS['app_strings']);    }    ```}



0 0