3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5 // +----------------------------------------------------------------------+
6 // | Akelos Framework - http://www.akelos.org |
7 // +----------------------------------------------------------------------+
8 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
9 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
10 // +----------------------------------------------------------------------+
14 defined('AK_PLUGINS_DIR') ?
null : define('AK_PLUGINS_DIR', AK_APP_DIR
.DS
.'vendor'.DS
.'plugins');
15 defined('AK_PLUGINS') ?
null : define('AK_PLUGINS', 'auto');
18 * Base class that all Akelos plugins should extend
22 * @author Bermi Ferrer <bermi a.t akelos c.om> 2007
23 * @copyright Copyright (c) 2002-2007, Akelos Media, S.L. http://www.akelos.org
24 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
37 * This method will add the functionality of the code available at $path_to_code which
38 * inherits from $class_name to a new class named Extensible$class_name
40 * You can extend the same object from multiple plugins. So you can doo something like
46 * @ app/vendor/plugins/finder_on_steroids/init.php
48 * class FinderOnSteroidsPlugin extends AkPlugin {
50 * $this->extendClassWithCode('AkActiveRecord', 'lib/FinderOnSteroids.php');
54 * @ app/vendor/plugins/finder_on_steroids/lib/FinderOnSteroids.php
56 * class FinderOnSteroids extends AkActiveRecord {
57 * function findSteroids(){
62 * This will create a new class named ExtensibleAkActiveRecord class you can use
63 * as parent of your ActiveRecord class at app/shared_model.php
65 * @param string $class_name Class name to extend
66 * @param string $path_to_code Path to the source code file relative to your plugin base path.
67 * @priority int $priority Multiple plugins can chain methods for extending classes.
68 * A higher priority will will take precedence over a low priority.
70 function extendClassWithCode($class_name, $path_to_code, $priority = 100)
72 if(empty($this->PluginManager
->ClassExtender
)){
73 require_once(AK_LIB_DIR
.DS
.'AkClassExtender.php');
74 $this->PluginManager
->ClassExtender
=& new AkClassExtender();
77 $this->PluginManager
->ClassExtender
->extendClassWithSource($class_name, $this->getPath().DS
.ltrim($path_to_code, './\\'), $priority);
81 function observeModel($model_name, &$Observer, $priority = 100)
86 function addHelper($helper_name, $helper_path = null)
88 $helper_name = AkInflector
::camelize($helper_name);
89 $helper_path = empty($helper_path) ?
$this->getPath().DS
.'lib'.DS
.AkInflector
::underscore($helper_name).'.php' : $helper_path;
90 AkActionController
::addPluginHelper($helper_name, array('path' => $helper_path));
94 * Gets the base path for a given plugin
96 * @return string Plugin path
101 return $this->PluginManager
->getBasePath($this->name
);
107 * The Plugin loader inspects for plugins, loads them in order and instantiates them.
111 * @author Bermi Ferrer <bermi a.t akelos c.om> 2007
112 * @copyright Copyright (c) 2002-2007, Akelos Media, S.L. http://www.akelos.org
113 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
119 * Base path for plugins
123 var $plugins_path = AK_PLUGINS_DIR
;
126 * List of available plugins
130 var $_available_plugins = array();
137 var $_plugin_instances = array();
144 var $_priorized_plugins = array();
147 * Goes trough the plugins directory and loads them.
152 function loadPlugins()
154 $this->instantiatePlugins();
155 $Plugins =& $this->_getPriorizedPlugins();
156 foreach (array_keys($Plugins) as $k) {
157 if(method_exists($Plugins[$k], 'load')){
158 $Plugins[$k]->load();
162 $this->extendClasses();
166 * Extends core classes with plugin code. EXPERIMENTAL
171 function extendClasses()
173 if(isset($this->ClassExtender
)){
174 $this->ClassExtender
->extendClasses();
180 * Short description for function
182 * Long description (if any) ...
187 function instantiatePlugins()
189 foreach ($this->getAvailablePlugins() as $plugin){
190 $this->instantiatePlugin($plugin);
195 * Instantiates a plugin
197 * If the plugin has a init.php file in its root path with a PluginNamePlugin class, it will instantiate the plugin
198 * and add it to the plugin instance stack
200 * @param string $plugin_name Plugin name
201 * @return boolean Returns true if can instantiate the plugin and false if the plugin could not be intantiated.
204 function instantiatePlugin($plugin_name)
206 $init_path = $this->getBasePath($plugin_name).DS
.'init.php';
207 if(file_exists($init_path)){
208 $plugin_class_name = AkInflector
::camelize($plugin_name).'Plugin';
209 require_once($init_path);
210 if(class_exists($plugin_class_name)){
211 $Plugin =& new $plugin_class_name();
212 $Plugin->name
= $plugin_name;
213 $Plugin->priority
= empty($Plugin->priority
) ?
10 : $Plugin->priority
;
214 $Plugin->PluginManager
=& $this;
215 $this->_plugin_instances
[$Plugin->priority
][] =& $Plugin;
218 trigger_error(Ak
::t('"%name" class does not exist and it\'s needed by the "%plugin_name" plugin. ', array('%name'=>$plugin_class_name, '%plugin_name'=>$plugin_name)), E_USER_WARNING
);
226 * Gets a list of available plugins.
228 * If AK_PLUGINS is set to 'auto' it will get a list of existing directories at AK_PLUGINS_DIR
230 * @return array Array of existing plugins
233 function getAvailablePlugins()
235 if(empty($this->_available_plugins
)){
236 if(AK_PLUGINS
== 'auto'){
237 $this->_findPlugins();
239 $this->_available_plugins
= AK_PLUGINS
=== false ?
array() : Ak
::toArray(AK_PLUGINS
);
242 return $this->_available_plugins
;
246 * Gets a plugin base path.) ...
248 * @param string $plugin_name Plugins name
249 * @return string Plugin root path
252 function getBasePath($plugin_name)
254 return AK_PLUGINS_DIR
.DS
.Ak
::sanitize_include($plugin_name);
258 * Gets a priorized list of plugins, where the priority is defined by the var $priority attribute
260 * @return array Priorized plugins
263 function &_getPriorizedPlugins()
265 if(!empty($this->_plugin_instances
) && empty($this->_priorized_plugins
)){
266 ksort($this->_plugin_instances
);
267 foreach (array_keys($this->_plugin_instances
) as $priority){
268 foreach (array_keys($this->_plugin_instances
[$priority]) as $k){
269 $this->_priorized_plugins
[] =& $this->_plugin_instances
[$priority][$k];
273 return $this->_priorized_plugins
;
277 * Loads a list of existing plugins to $this->_available_plugins by inspecting the plugins directory.
282 function _findPlugins()
284 $plugin_dirs = Ak
::dir(AK_PLUGINS_DIR
, array('dirs' => true, 'files' => false));
285 $this->_available_plugins
= array();
286 foreach ($plugin_dirs as $plugin_dir){
287 $plugin_dir = array_pop($plugin_dir);
288 if($plugin_dir[0] != '.'){
289 $this->_available_plugins
[] = $plugin_dir;