[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/ -> AkPlugin.php (source)

   1  <?php
   2  
   3  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   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  // +----------------------------------------------------------------------+
  11  
  12  
  13  
  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');
  16  
  17  /**
  18   * Base class that all Akelos plugins should extend
  19   * 
  20   * @package    Plugins
  21   * @subpackage Base
  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>
  25   */
  26  class AkPlugin
  27  {
  28  
  29      /**
  30       * Plugin priority
  31       * @var    integer
  32       * @access public 
  33       */
  34      var $priority = 100;
  35  
  36      /**
  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
  39       * 
  40       * You can extend the same object from multiple plugins. So you can doo something like
  41       * 
  42       * Example:
  43       * 
  44       * finder_on_steroids
  45       * 
  46       *  @ app/vendor/plugins/finder_on_steroids/init.php
  47       * 
  48       * class FinderOnSteroidsPlugin extends AkPlugin {
  49       *      function load(){
  50       *          $this->extendClassWithCode('AkActiveRecord', 'lib/FinderOnSteroids.php');
  51       *      }
  52       * }
  53       * 
  54       *  @ app/vendor/plugins/finder_on_steroids/lib/FinderOnSteroids.php
  55       * 
  56       * class FinderOnSteroids extends AkActiveRecord {
  57       *      function findSteroids(){
  58       *          //
  59       *      }
  60       * }
  61       * 
  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
  64       * 
  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.
  69       */
  70      function extendClassWithCode($class_name, $path_to_code, $priority = 100)
  71      {
  72          if(empty($this->PluginManager->ClassExtender)){
  73              require_once (AK_LIB_DIR.DS.'AkClassExtender.php');
  74              $this->PluginManager->ClassExtender =& new AkClassExtender();
  75          }
  76  
  77          $this->PluginManager->ClassExtender->extendClassWithSource($class_name, $this->getPath().DS.ltrim($path_to_code, './\\'), $priority);
  78      }
  79  
  80  
  81      function observeModel($model_name, &$Observer, $priority = 100)
  82      {
  83  
  84      }
  85      
  86      function addHelper($helper_name, $helper_path = null)
  87      {
  88          require_once (AK_LIB_DIR.DS.'AkActionView'.DS.'AkHelperLoader.php');
  89          $helper_name = AkInflector::camelize($helper_name);
  90          $helper_path = empty($helper_path) ? $this->getPath().DS.'lib'.DS.AkInflector::underscore($helper_name).'.php' : $helper_path;
  91          AkHelperLoader::addPluginHelper($helper_name, array('path' => $helper_path));
  92      }
  93  
  94      /**
  95       * Gets the base path for a given plugin
  96       * 
  97       * @return string Plugin path
  98       * @access public
  99       */
 100      function getPath()
 101      {
 102          return $this->PluginManager->getBasePath($this->name);
 103      }
 104  }
 105  
 106  
 107  /**
 108   * The Plugin loader inspects for plugins, loads them in order and instantiates them.
 109   * 
 110   * @package    Plugins
 111   * @subpackage Loader
 112   * @author     Bermi Ferrer <bermi a.t akelos c.om> 2007
 113   * @copyright  Copyright (c) 2002-2007, Akelos Media, S.L. http://www.akelos.org
 114   * @license    GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
 115   */
 116  class AkPluginLoader
 117  {
 118  
 119      /**
 120       * Base path for plugins
 121       * @var    string
 122       * @access public 
 123       */
 124      var $plugins_path = AK_PLUGINS_DIR;
 125  
 126      /**
 127       * List of available plugins
 128       * @var    array
 129       * @access private
 130       */
 131      var $_available_plugins = array();
 132  
 133      /**
 134       * Plugin instances
 135       * @var    array  
 136       * @access private
 137       */
 138      var $_plugin_instances = array();
 139  
 140      /**
 141       * Priority plugins
 142       * @var    array  
 143       * @access private
 144       */
 145      var $_priorized_plugins = array();
 146  
 147      /**
 148       * Goes trough the plugins directory and loads them.
 149       * 
 150       * @return void  
 151       * @access public
 152       */
 153      function loadPlugins()
 154      {
 155          $this->instantiatePlugins();
 156          $Plugins =& $this->_getPriorizedPlugins();
 157          foreach (array_keys($Plugins) as $k) {
 158              if(method_exists($Plugins[$k], 'load')){
 159                  $Plugins[$k]->load();
 160              }
 161          }
 162  
 163          $this->extendClasses();
 164      }
 165  
 166      /**
 167       * Extends core classes with plugin code. EXPERIMENTAL
 168       * 
 169       * @return void  
 170       * @access public
 171       */
 172      function extendClasses()
 173      {
 174          if(isset($this->ClassExtender)){
 175              $this->ClassExtender->extendClasses();
 176          }
 177      }
 178  
 179  
 180      /**
 181       * Short description for function
 182       * 
 183       * Long description (if any) ...
 184       * 
 185       * @return void  
 186       * @access public
 187       */
 188      function instantiatePlugins()
 189      {
 190          foreach ($this->getAvailablePlugins() as $plugin){
 191              $this->instantiatePlugin($plugin);
 192          }
 193      }
 194  
 195      /**
 196       * Instantiates a plugin
 197       * 
 198       * If the plugin has a init.php file in its root path with a PluginNamePlugin class, it will instantiate the plugin
 199       * and add it to the plugin instance stack
 200       * 
 201       * @param  string $plugin_name Plugin name
 202       * @return boolean Returns true if can instantiate the plugin and false if the plugin could not be intantiated.   
 203       * @access public 
 204       */
 205      function instantiatePlugin($plugin_name)
 206      {
 207          $init_path = $this->getBasePath($plugin_name).DS.'init.php';
 208          if(file_exists($init_path)){
 209              $plugin_class_name = AkInflector::camelize($plugin_name).'Plugin';
 210              require_once($init_path);
 211              if(class_exists($plugin_class_name)){
 212                  $Plugin =& new $plugin_class_name();
 213                  $Plugin->name = $plugin_name;
 214                  $Plugin->priority = empty($Plugin->priority) ? 10 : $Plugin->priority;
 215                  $Plugin->PluginManager =& $this;
 216                  $this->_plugin_instances[$Plugin->priority][] =& $Plugin;
 217                  return true;
 218              }else{
 219                  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);
 220              }
 221          }
 222          
 223          return false;
 224      }
 225  
 226      /**
 227       * Gets a list of available plugins.
 228       * 
 229       * If AK_PLUGINS is set to 'auto' it will get a list of existing directories at AK_PLUGINS_DIR
 230       * 
 231       * @return array    Array of existing plugins
 232       * @access public
 233       */
 234      function getAvailablePlugins()
 235      {
 236          if(empty($this->_available_plugins)){
 237              if(AK_PLUGINS == 'auto'){
 238                  $this->_findPlugins();
 239              }else{
 240                  $this->_available_plugins = AK_PLUGINS === false ? array() : Ak::toArray(AK_PLUGINS);
 241              }
 242          }
 243          return $this->_available_plugins;
 244      }
 245  
 246      /**
 247       * Gets a plugin base path.) ...
 248       * 
 249       * @param  string $plugin_name Plugins name
 250       * @return string Plugin root path
 251       * @access public 
 252       */
 253      function getBasePath($plugin_name)
 254      {
 255          return AK_PLUGINS_DIR.DS.Ak::sanitize_include($plugin_name);
 256      }
 257      
 258      /**
 259       * Gets a priorized list of plugins, where the priority is defined by the var $priority attribute
 260       * 
 261       * @return array   Priorized plugins
 262       * @access private
 263       */
 264      function &_getPriorizedPlugins()
 265      {
 266          if(!empty($this->_plugin_instances) && empty($this->_priorized_plugins)){
 267              ksort($this->_plugin_instances);
 268              foreach (array_keys($this->_plugin_instances) as $priority){
 269                  foreach (array_keys($this->_plugin_instances[$priority]) as $k){
 270                      $this->_priorized_plugins[] =& $this->_plugin_instances[$priority][$k];
 271                  }
 272              }
 273          }
 274          return $this->_priorized_plugins;
 275      }
 276  
 277      /**
 278       * Loads a list of existing plugins to $this->_available_plugins by inspecting the plugins directory.
 279       * 
 280       * @return void   
 281       * @access private
 282       */
 283      function _findPlugins()
 284      {
 285          $plugin_dirs = Ak::dir(AK_PLUGINS_DIR, array('dirs' => true, 'files' => false));
 286          $this->_available_plugins = array();
 287          foreach ($plugin_dirs as $plugin_dir){
 288              $plugin_dir = array_pop($plugin_dir);
 289              if($plugin_dir[0] != '.'){
 290                  $this->_available_plugins[] = $plugin_dir;
 291              }
 292          }
 293      }
 294  }
 295  
 296  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6