怎样让自己的组件支持插件 原
遇到了这样的一个问题,我自己开发了一组件附件管理组件,当某一个用户下载附件的时候,我需要扣除它一定的积分。当他上传一个附件的时候,我需要给 他加分。当然加分和减分的功能并不是我自己的组件来完成的。其实,我要做的事情就是:当用户要下载和上传的时候,我需要将这个事件广播出去,并且告诉别人 是谁要下载,要在什么。好让其他的人来处理。这么一说,你可能就明白了,这不就是插件机制吗!
本节我们将要讨论一下,如何在自己的组件中触发一些事件,好让第三方的开发者来响应。
背景:
观察者模式有两个角色,一个是主题,一个是观察者。joomla通过全局的JPlugin和JEventDispathcer这个两个类来实现观察者和主 题。如果你对某一个主题感兴趣,那么你就向该主题注册自己,使自己成为一个观察者。这样主题已有什么风吹草动,你就会及时知道,并且可以做出一定的响应。 joomla中注册主题的方法和简单,你可以写一个类,这个类派生子JPlugin就行了。其他的事情就交给Joomla搞定。当系统加载插件所在的分类 的时候,JPlugin的子类将会自动注册自己到全局的JEventDispathcer类。JEventDispatcher类实现了派发机制,他负责 接受主题的事件,并且将这个事件告诉该主题的所有观察者。如果你依旧不明白观察者是啥?那建议你看一下headfirst的设计模式吧,经典!
为什么要在组件中实现插件机制呢?这个问题的就相当于joomla为什么要提供插件机制一样。简而言之,灵活,方便,代码整洁,容易扩展。
实现:
如何让自己成为主题?
由于在joomla中所有的事件派发都是有joomla的核心来处理的。因此成为一个主题不是很困难。事实上,你只需要简单的调用JEventDispatcher类的触发方法,系统就会加载你自定的插件组的所有插件,这样你就成为了一个主题了。
在 joomla中插件是用插件组的形式来组件的。你可以在plugins目录中看到。系统预定义了8个插件组,当然你可以定义更多。每一个插件组都负责处理 不同的任务。你想触发那一个插件组,那完全取决于你。在写插件的时候,xml文件中我们必须指定group属性就是这个原因,不然系统不会将你注册为观察 者的。比较好理解的就是user组了,这个组主要处理用户相关的事情,比喻说一个用户被删除了,一个用户被添加了等等。当然插件组中的插件只是在被需要的 才会被加载。你可以创建你自己的插件组,并且在你想触发的时候触发就行了。由于你已经在你的组件中定义好了需要触发的插件组,所有观察知道哪一个插件组中 的插件应该被调用。
怎样去触发?
1,加载插件组
JPluginHelper::importPlugin('myplugingroup');
2,获得JEventDispatcher实例
$dispatcher = JEventDispatcher::getInstance();
注意,我们用的是JEventDispatcher的getInstance()方法来获得实例,而不是new来创建一个新的实例。
3,触发事件
$results = $dispatcher->trigger('onCdAddedToLibrary' ,array(&$artist ,$title));
要出点多少个参数有你决定。你应该在你的组件的文档中对这些参数进行描述,好让第三方开发者可以起了解。
注意:
在定义插件的时候最好想好一点,一旦发布,第三方开发者写的代码就要依赖你的事件的名称和传递的参数,如果你计划改变这些。那么可能会存在兼容性问题。
另 外,trigger方法并没有指定到底是触发那一个插件组的事件。因此,这里可能存在冲突的问题。事实上,系统会通知所有已经被加载的插件组。所以,确保 你定义的事件的名称不要和其他插件组定义的事件的名称相冲突将会非常重要。当然,大多数情况下,你不必担心这个问题。因为你知道你的组件加载了哪些插件 组。然而,系统插件会在每一个请求的开始自动被加载。确保你定义的事件名称不要和系统事件名称相冲突是非常必要的。