<?php
/***
 * 名称：插件模块类
 * Alan 2013.5
 * www.fcontex.com
*/

final class plugin 
{
	//路由HOOK列表
	public $hooksRouter;
	//锚点HOOK列表
	public $hooksAnchor;
	
	public function __construct()
	{
		$hooks = FCApplication::loadConfig('plugin.hooks', '', '', TRUE);
		if (!is_array($hooks)) $hooks = array();
		$this->hooksRouter = isset($hooks['router']) ? $hooks['router'] : array();
		$this->hooksAnchor = isset($hooks['anchor']) ? $hooks['anchor'] : array();
	}
	
	//加载插件对象
	public function loadPlugin($name)
	{
		static $plugins = array();
		$path = PATH_PLUGINS.$name.'/plugin.php';
		$key = md5($path);
		if (isset($plugins[$key]))
		{
			return empty($plugins[$key]) ? FALSE : $plugins[$key];
		}
		if (file_exists($path))
		{
			include $path;
			$class = 'FCPlugin'.ucfirst($name);
			$plugins[$key] = class_exists($class) ? new $class : FALSE;
			return $plugins[$key];
		}
		return FALSE;
	}
	
	//路由HOOK函数
	public function hookRouter(&$output)
	{
		global $R;
		
		foreach ($this->hooksRouter as $path=>$rules)
		{
			//匹配路由地址
			if (stripos($R->query, $path) === FALSE)
			{
				continue;
			}
			//执行插件函数
			foreach ($rules as $rule)
			{
				$plugin = $this->loadPlugin($rule['plugin']);
				if (method_exists($plugin, $rule['hook']))
				{
					$plugin->$rule['hook']($R->query, $output);
				}
			}
		}
	}
	
	//锚点HOOK函数
	public function hookAnchor($anchor, $args=NULL)
	{	
		//匹配锚点名称
		if (!isset($this->hooksAnchor[$anchor]))
		{
			return;
		}
		
		//执行插件函数
		foreach ($this->hooksAnchor[$anchor] as $rule)
		{
			$plugin = $this->loadPlugin($rule['plugin']);
			if (method_exists($plugin, $rule['hook']))
			{
				$plugin->$rule['hook']($args);
			}
		}
	}
	
	//在HOOK列表中移除指定插件
	public function hooksDelete($plugin, $save=TRUE)
	{
		//移除路由HOOK
		foreach ($this->hooksRouter as $path=>$rules)
		{
			foreach ($rules as $index=>$rule)
			{
				if ($rule['plugin'] != $plugin) continue;
				unset($this->hooksRouter[$path][$index]);
			}
			if (!empty($this->hooksRouter[$path])) continue;
			unset($this->hooksRouter[$path]);
		}
		//移除锚点HOOK
		foreach ($this->hooksAnchor as $path=>$rules)
		{
			foreach ($rules as $index=>$rule)
			{
				if ($rule['plugin'] != $plugin) continue;
				unset($this->hooksAnchor[$path][$index]);
			}
			if (!empty($this->hooksAnchor[$path])) continue;
			unset($this->hooksAnchor[$path]);
		}
		//更新文件
		if ($save)
		{
			$hooks = array('router'=>$this->hooksRouter, 'anchor'=>$this->hooksAnchor);
			FCApplication::saveConfig('plugin.hooks', $hooks);
		}
	}
	
	//在HOOK列表中更新指定插件
	public function hooksUpdate($plugin)
	{
		$this->hooksDelete($plugin, FALSE);
		
		//路由HOOK
		foreach ($this->loadPlugin($plugin)->getHooksRouter() as $path=>$hook)
		{
			if (empty($this->hooksRouter[$path])) $this->hooksRouter[$path] = array();
			array_push($this->hooksRouter[$path], array('plugin'=>$plugin, 'hook'=>$hook));
		}
		//锚点HOOK
		foreach ($this->loadPlugin($plugin)->getHooksAnchor() as $path=>$hook)
		{
			if (empty($this->hooksAnchor[$path])) $this->hooksAnchor[$path] = array();
			array_push($this->hooksAnchor[$path], array('plugin'=>$plugin, 'hook'=>$hook));
		}
		//更新文件
		$hooks = array('router'=>$this->hooksRouter, 'anchor'=>$this->hooksAnchor);
		FCApplication::saveConfig('plugin.hooks', $hooks);
	}
}
?>