$listeners 数组用于存放 已注册的插件(类和方法)
构造函数中 获取所有已激活的插件。实例化他们,存放在$listeners数组中。
实例化的 插件 构造函数中,直接执行 Plugin类的register注册方法,注册自己。
Plugin类有个trigger触发器,需要使用插件的地方直接 触发该插件即可。$this->plugin->trigger(类,方法1,2...);
在触发方法中先检查该插件是否已经注册(即已激活)。如果已注册了,则执行,ELSE RETURN FALSE
拓展插件注册自己的方法我觉得还是很神奇的。今天细想了一下,为什么要在拓展插件自己构造函数中通过插件类注册方法注册自己呢?完全可以直接在插件类构造函数中实例化的时候,注册ADD到_listener数组中。看了一下register方法,有3个参数分别是(钩子即类名称吧、$this类自己、$method用到的方法)。关键就是第3个$method,如果直接在构造函数中ADD的话,就无法动态获取用到的$method方法了。这可能是神奇的地方之一吧!
原笔记分析内容:
关于插件的机制的理解及实现请参阅Saturn写的一篇日志 PHP中插件机制的一种实现方案
STBlog中的插件类存在于application/libraries/Plugin.php,在插件类的构造函数中实现调用utility类的 get_active_plugins()函数获取已激活的插件数组,然后遍历这个数组,依次加载插件文件并初始化。此外还有三个函数,register()用于注册插件方法,check_hook_exist($hook)用于检查插件方法是否存在,trigger($hook)用于触发插件函数。
我们来看一个插件的实例:st_plugins/navigation/Navigation.php
1) 在Plugin类的构造函数中通过utility类的get_active_plugins()函数获取所有已激活的插件,并创建他们的实例;
2) 在每个插件类的构造函数中把插件函数注册到Plugin类的$_listeners成员变量中;如在Navigation插件类的构造函数中通过$plugin->register('Widget::Navigation', $this, 'render');把$_listeners['Widget::Navigation']['Navigation->render']设置为 array(object(Navigation), 'render');
3) 当程序遇到$this->plugin->trigger()函数时,触发插件函数;如在themes/default /header.php视图文件中触发Navigation插件函数:$this->plugin->trigger('Widget::Navigation', '<li><a href="{permalink}">{title}</a></li>'); trigger()函数确定该触发函数是否已注册,并且在该插件对象中存在此函数时,使用call_user_func_array()调用此触发函数,在该例中将执行Navigation类的render()方法,该函数的功能是获取所有的页面,并把参数$format中的{permalink}和 {title}置换成页面的缩略名和标题打印出来;
4) 激活与禁用插件
在admin/plugins.php的Plugins控制器的active方法中首先通过plugins_mdl的get($name)方法获取获取该插件的信息:如作者、版本等;再调用plugins_mdl的active($plugin)方法激活该插件:首先检查是否该插件已激活,如果没有的话,把该插件添加到已激活的插件数组中,并把它序列化保存在settings表的active_plugins项目中;禁用插件与此类似。