YComponent.class.php 4.97 KB
<?php
/**
 * 控件处理基类
 * 
 * @example 
 * <pre>
 *     视图View调用:
 *     $this->_component('test::component', array(
 *         参数名1 => 参数值1,
 *         参数名2 => 参数值2,
 *         ...
 *     ));
 *     
 *     控制器Controller或模块Module中调用:
 *     Component_Scripts_Test::component($params);
 * </pre>
 * 
 * @name Framework_YComponent
 * @package framework
 * @version 0.2 (2012-12-19 14:37:41) <fei.hong@yoho.cn>
 * @since 0.1 (2012-6-25) <xiaoma>
 */
class Framework_YComponent 
{
	/**
	 * 组件ID
	 */
	private $_id = 0;
	
	/**
	 * HTTP请求对象
	 *
	 * @var Framework_YHttpRequest
	 */
	protected $_request;
	
	/**
	 * 组件参数列表
	 *
	 * @var array
	 */
	protected static $_params = array();
	
	
	/**
	 * 组件的视图存放目录
	 *
	 * @var string
	 * @since 0.2
	 */
	private $_viewPath = 'component/views';
	
	/**
	 * 组件的脚本存放目录
	 *
	 * @var string
	 * @since 0.2
	 */
	private $_componentPath = 'component/scripts';
	
	
	/**
	 * 构造函数
	 */
	public function __construct($id = '' )
	{
		$this->_id = ($id) ? $id : uniqid('component_id_rand');
		$this->_request = Framework_YHttpRequest::instance();
	}
	
	/**
	 * 执行组件
	 *
	 * @param string $alias (组件路径)
	 * @param array $params (组件参数)
	 * @return mixed
	 * @since 0.2
	 */
	public function execute($alias, $params = array())
	{
		// 获取组件的类及方法, 返回array(类名, 方法); 若组件不存在, 返回null.
		$component = $this->_getComponent($alias);
	
		// 判断组件是否存在
		if (null !== $component)
		{
		    //设置变量
		    self::$_params = array() ;//重置参数
		    $this->set($params) ;
		    
			// 判断组件的方法是否存在
			if (null !== $component[1])
			{
				// 实例化反射类
				$rc = new ReflectionClass($component[0]);
				// 判断组件类对应的方法是否存在
				if ($rc->hasMethod($component[1]))
				{
					// 判断此是否是静态方法, 返回boolean
					if ($rc->getMethod($component[1])->isStatic())
					{
						// 静态化调用
						call_user_func($component, $params);
					}
					else
					{
						// 实例化调用
						$object = new $component[0]();
						$object->$component[1]($params);
					}
				}
				$rc = null; unset($rc);
			}
		}
	}
	
	/**
	 * 渲染组件的视图
	 *
	 * @param string $viewname (视图名称, 默认为null)
	 * @param array $params (向视图传递的参数, 默认为null)
	 * @return mixed
	 * @since 0.2
	 */
	public function display($viewname, $params = null)
	{
		if (null !== $viewname)
		{
			$response = new Framework_YView();
			$response->setBasePath(C('APP.Root_Dir'))
			         ->setScriptPath(DS . $this->_viewPath)
					 ->renderPartial($viewname, $params, true);
		}
	}
	
	/**
	 * 获取组件的ID
	 * 
	 * @return string
	 */
	protected function id()
	{
		return $this->_id;
	}
	
	/**
	 * 设置控件变量(用于引用控件时调用)
	 *
	 * @param array $params
	 * @return this
	 */
	protected function set( $params = array() )
	{
	    if (is_array($params) && $params)
	    {
	        self::$_params = array_merge(self::$_params, $params);
	    }
		return $this;
	}
	
	/**
	 * 获取参数
	 *
	 * @param string $key (参数名)
	 * @param mixed $default (默认返回值)
	 * @return mixed
	 */
	protected function get($key = null, $default = null)
	{
		if (null === $key)
		{
			return self::$_params;
		}
		elseif (array_key_exists($key, self::$_params))
		{
			return self::$_params[$key];
		}
		else 
		{
			return $default;
		}
	}
	
	/**
	 * 设置组件的视图根目录
	 * 
	 * @param string $path
	 * @return this
	 * @since 0.2
	 */
	protected function setViewPath($path)
	{
		$this->_viewPath = $path;
		
		return $this;
	}
	
	/**
	 * 获取组件的视图根目录
	 * 
	 * @return string
	 * @since 0.2
	 */
	protected function getViewPath()
	{
		return $this->_viewPath;
	}
	
	/**
	 * 设置组件的脚本所在目录
	 * 
	 * @param string $path
	 * @return this
	 * @since 0.2
	 */
	protected function setComponentPath($path)
	{
		$this->_componentPath = $path;
		
		return $this;
	}
	
	/**
	 * 获取组件的脚本所在目录
	 * 
	 * @return string
	 * @since 0.2
	 */
	protected function getComponentPath()
	{
		return $this->_componentPath;
	}
	
	/**
	 * 获取组件的类及方法
	 *
	 * @param string $class (匿名类及方法名称)
	 * @return array (类和方法名 | null: 组件不存在)
	 * @since 0.2
	 */
	private function _getComponent($class)
	{
		$method = null;
		if (strpos($class, '.') !== false)
		{
			$class = strtr(ltrim($class, '.'), array('.' => '_'));
		}
		elseif (strpos($class, '\\') !== false)
		{
			$class = str_replace('\\', '_', ltrim($class, '\\'));
		}
		if (($pos = strrpos($class, '::')) !== false)
		{
			$method = substr($class, $pos + 2);
			$class = substr($class, 0, $pos);
		}
		else
		{
			// 默认的组件方法名 
			$method = 'render';
		}
		$class = strtr($this->_componentPath, array('/' => '_')) . '_' . $class;
		
		return class_exists($class, true) ? array($class, $method) : null;
	}
	
}