您的位置:首页 > 其它

SugarCRM源码分析之ViewFactory

2016-01-27 14:05 204 查看
        和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']);
}

```

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: