YController.class.php 6.9 KB
<?php/**
 * 控制器基类
 * 
 * @name Framework_YController
 * @package framework
 * @version 0.2 (2012-12-14 17:14:29) <fei.hong@yoho.cn>
 * @since 0.1 (2012-6-25) xiaoma
 */class Framework_YController {
	/**
	 * HTTP请求对象
	 *
	 * @var Framework_YHttpRequest
	 */
	protected $_request;
	
	/**
	 * 存放视图变量
	 *
	 * @var array
	 */
	protected $_view = array();
	
	/**
	 * 使用的视图名称
	 *
	 * @var 视图名称
	 */
	protected $_viewname = '';

	/**
	 * 视图脚本存放目录
	 *
	 * @var string
	 */
	protected $_viewScriptFolder = 'script';
	
	/**
	 * 构造函数
	 */
	public function __construct()
	{
		$this->_request = Framework_YHttpRequest::instance();
	}
	
	/**
	 * 执行
	 * 
	 * @param string action 操作名称
	 * @param array $args 额外参数
	 * @return mixed
	 */
	public function execute($action, array $args = array())
	{
		// 执行Action之前的操作
		$this->beforeExecute();
		
		// 初始化并执行Action操作
		$response = $this->init();
		if (null === $response)
		{
			$action = $this->formatAction($action);
			$response = call_user_func_array(array($this , $action), $args);
		}
        
		// 执行Action之后的操作
		$this->afterExecute($response);
		
		// 如果无返回值,则渲染视图页面.
        if (null === $response && is_array($this->_view))
        {
        	// 渲染视图之前的操作
            $this->beforeRender($response);
            
            // 渲染视图操作
            $response = $this->render($this->_viewname, $this->_view);
        }
        
        return $response;
	}
	
	/**
	 * 渲染视图 
	 *
	 * @param string $viewname (视图名称) 
	 * @param array $params (传递到视图的参数)
	 * @return string (视图页面内容)
	 * @since 0.2
	 */
	public function render($viewname = '', $params = array())
	{
		$viewname = $this->formatView($viewname);

		$response = new Framework_YView();
        $output = $response->setBasePath($this->getViewBasePath())
        		           ->setScriptPath($this->getViewScriptPath())
        		           ->setViewname($viewname)
        		           ->assign($params)
                           ->render();
        
        return $output;
	}
	
    /**
     * 部分渲染视图 
     *  
     * (直接包含方式, 不解析页面)
     * 
     * @param string $viewname (视图名称)
     * @param mixed $params (向视图传递的参数)
     * @param boolean $display  (控制是直接显示,还是返回结果) @since 0.3
     * @return string | void
     * @since 0.2
     * @version 0.3
     */
    public function renderPartial($viewname = '', $params = null, $display = true)
    {
    	$viewname = $this->formatView($viewname);
    		
    	$response = new Framework_YView();
        $response->setBasePath($this->getViewBasePath())
	        	 ->setScriptPath($this->getViewScriptPath());
    		
        if ($display)
        {
            $response->renderPartial($viewname, $params, true);
        }
        else
        {
            $output = $response->renderPartial($viewname, $params, false);
            
            return $output;
        }
    }
    
	/**
	 * 返回一个 Framework_Response_YForward 对象
	 *
	 * @param string $url (URL地址)
	 * @param integer $delay (时间单位秒)
	 * @param string $script (JS脚本)
	 * @return Framework_Response_YForward
	 */
	public function _redirect($url, $delay = 0, $script = '')
	{
		return new Framework_Response_YRedirect($url, $delay, $script);
	}
	
	/**
	 * 返回一个 Framework_Response_YForward 对象
	 *
	 * @param string $udi (请求对应的UDI)
	 * @param array $args (附加参数)
	 * @return Framework_Response_YForward
	 */
	public function _forward($udi, $args = array())
	{
		return new Framework_Response_YForward($udi, $args);
	}
	
	/**
	 * 检查指定方法是否存在
	 *
	 * @param string $action (方法名)
	 * @return boolean
	 */
    public function existsAction($action)
    {
        $action = $this->formatAction($action);
        
        return method_exists($this, $action);
    }
    
    /**
     * 格式化action名称
     *
     * @param string $action (方法名)
     * @return string
     */
    protected function formatAction($action)
    {
        $action .= 'Action';
        
    	return $action;
    }
    
    /**
     * 格式化view名称
     * 
     * @param string $view (视图名)
     * @return string
     * @since 0.2
     */
    protected function formatView($view)
    {
        // 如果没有传递视图, 则获取当前控制器Controller对应的操作Action
    	if ($view === '' || $view == null)
    	{
    		$view = strtolower($this->_request->controller_name . DS . $this->_request->action_name);
    	}
    	// 已指定的视图
    	elseif ('\\' == $view[0])
    	{
    		$view = substr($view, 1);
    	}
    	// 默认
    	else
    	{
    		$view = strtolower($this->_request->controller_name . DS . $view);
    	}
    	
    	return $view;
    }
    
    /**
     * 设置使用的视图
     *
     * @return string
     */
    protected function setViewName($name)
    {
    	$this->_viewname = $name;
    }
    
    /**
     * 获取使用的视图
     *
     * @return string
     * @since 0.2
     */
    protected function getViewName()
    {
        $viewname = '';
                
    	if (empty($this->_viewname))
    	{
    		// 返回默认的当前执行的Action对应的视图名称
    		$viewname = $this->_request->action_name;
    	}
    	else
    	{
    		// 返回指定的视图名称
    		$viewname = $this->_viewname;
    	}
    	
    	return $viewname;
    }
    
    /**
     * 获取视图文件所在的根目录
     * 
     * @return string
     * @since 0.2
     */
    protected function getViewBasePath()
    {
        $path = '';
        
    	if ($this->_request->module_name)
    	{
    		$path = C('APP.Module_Dir') . DS . $this->_request->module_name . DS . 'view';
    	}
    	else
    	{
    		$path = C('APP.Root_Dir') . DS . 'view';
    	}
    	
    	return $path;
    }
    
    /**
     * 获取视图脚本所在的目录
     * 
     * @return string
     * @since 0.2
     */
    protected function getViewScriptPath()
    {
    	$path = '';
    	
    	if ($this->_viewScriptFolder)
    	{
    		$path .= DS . $this->_viewScriptFolder;
    	}
    	if ($this->_request->namespace)
    	{
    		$path .= DS . $this->_request->namespace;
    	}
    	
    	return $path;
    }

    /**
     * 执行控制器动作之前初始化
     * 
     * @param $response 
     */
    protected function init() {}
    
    /**
     * 执行控制器动作之后调用
     * 
     * @param $response 
     */
    protected function beforeExecute() {}
    
    /**
     * 执行控制器动作之后调用
     * 
     * @param $response 
     */
    protected function afterExecute(&$response) {}
    
    /**
     * 渲染之前调用
     *
     * @param $response
     */
    protected function beforeRender($response) {}
    }