[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/Loader/Autoloader/ -> Resource.php (source)

   1  <?php
   2  /**
   3   * Zend Framework
   4   *
   5   * LICENSE
   6   *
   7   * This source file is subject to the new BSD license that is bundled
   8   * with this package in the file LICENSE.txt.
   9   * It is also available through the world-wide-web at this URL:
  10   * http://framework.zend.com/license/new-bsd
  11   * If you did not receive a copy of the license and are unable to
  12   * obtain it through the world-wide-web, please send an email
  13   * to [email protected] so we can send you a copy immediately.
  14   *
  15   * @category   Zend
  16   * @package    Zend_Loader
  17   * @subpackage Autoloader
  18   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19   * @version    $Id$
  20   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  21   */
  22  
  23  /** Zend_Loader_Autoloader_Interface */
  24  require_once 'Zend/Loader/Autoloader/Interface.php';
  25  
  26  /**
  27   * Resource loader
  28   *
  29   * @uses       Zend_Loader_Autoloader_Interface
  30   * @package    Zend_Loader
  31   * @subpackage Autoloader
  32   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  33   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  34   */
  35  class Zend_Loader_Autoloader_Resource implements Zend_Loader_Autoloader_Interface
  36  {
  37      /**
  38       * @var string Base path to resource classes
  39       */
  40      protected $_basePath;
  41  
  42      /**
  43       * @var array Components handled within this resource
  44       */
  45      protected $_components = array();
  46  
  47      /**
  48       * @var string Default resource/component to use when using object registry
  49       */
  50      protected $_defaultResourceType;
  51  
  52      /**
  53       * @var string Namespace of classes within this resource
  54       */
  55      protected $_namespace;
  56  
  57      /**
  58       * @var array Available resource types handled by this resource autoloader
  59       */
  60      protected $_resourceTypes = array();
  61  
  62      /**
  63       * Constructor
  64       *
  65       * @param  array|Zend_Config $options Configuration options for resource autoloader
  66       * @return void
  67       */
  68      public function __construct($options)
  69      {
  70          if ($options instanceof Zend_Config) {
  71              $options = $options->toArray();
  72          }
  73          if (!is_array($options)) {
  74              require_once 'Zend/Loader/Exception.php';
  75              throw new Zend_Loader_Exception('Options must be passed to resource loader constructor');
  76          }
  77  
  78          $this->setOptions($options);
  79  
  80          $namespace = $this->getNamespace();
  81          if ((null === $namespace)
  82              || (null === $this->getBasePath())
  83          ) {
  84              require_once 'Zend/Loader/Exception.php';
  85              throw new Zend_Loader_Exception('Resource loader requires both a namespace and a base path for initialization');
  86          }
  87  
  88          if (!empty($namespace)) {
  89              $namespace .= '_';
  90          }
  91          Zend_Loader_Autoloader::getInstance()->unshiftAutoloader($this, $namespace);
  92      }
  93  
  94      /**
  95       * Overloading: methods
  96       *
  97       * Allow retrieving concrete resource object instances using 'get<Resourcename>()'
  98       * syntax. Example:
  99       * <code>
 100       * $loader = new Zend_Loader_Autoloader_Resource(array(
 101       *     'namespace' => 'Stuff_',
 102       *     'basePath'  => '/path/to/some/stuff',
 103       * ))
 104       * $loader->addResourceType('Model', 'models', 'Model');
 105       *
 106       * $foo = $loader->getModel('Foo'); // get instance of Stuff_Model_Foo class
 107       * </code>
 108       *
 109       * @param  string $method
 110       * @param  array $args
 111       * @return mixed
 112       * @throws Zend_Loader_Exception if method not beginning with 'get' or not matching a valid resource type is called
 113       */
 114      public function __call($method, $args)
 115      {
 116          if ('get' == substr($method, 0, 3)) {
 117              $type  = strtolower(substr($method, 3));
 118              if (!$this->hasResourceType($type)) {
 119                  require_once 'Zend/Loader/Exception.php';
 120                  throw new Zend_Loader_Exception("Invalid resource type $type; cannot load resource");
 121              }
 122              if (empty($args)) {
 123                  require_once 'Zend/Loader/Exception.php';
 124                  throw new Zend_Loader_Exception("Cannot load resources; no resource specified");
 125              }
 126              $resource = array_shift($args);
 127              return $this->load($resource, $type);
 128          }
 129  
 130          require_once 'Zend/Loader/Exception.php';
 131          throw new Zend_Loader_Exception("Method '$method' is not supported");
 132      }
 133  
 134      /**
 135       * Helper method to calculate the correct class path
 136       *
 137       * @param string $class
 138       * @return False if not matched other wise the correct path
 139       */
 140      public function getClassPath($class)
 141      {
 142          $segments          = explode('_', $class);
 143          $namespaceTopLevel = $this->getNamespace();
 144          $namespace         = '';
 145  
 146          if (!empty($namespaceTopLevel)) {
 147              $namespace = array_shift($segments);
 148              if ($namespace != $namespaceTopLevel) {
 149                  // wrong prefix? we're done
 150                  return false;
 151              }
 152          }
 153  
 154          if (count($segments) < 2) {
 155              // assumes all resources have a component and class name, minimum
 156              return false;
 157          }
 158  
 159          $final     = array_pop($segments);
 160          $component = $namespace;
 161          $lastMatch = false;
 162          do {
 163              $segment    = array_shift($segments);
 164              $component .= empty($component) ? $segment : '_' . $segment;
 165              if (isset($this->_components[$component])) {
 166                  $lastMatch = $component;
 167              }
 168          } while (count($segments));
 169  
 170          if (!$lastMatch) {
 171              return false;
 172          }
 173  
 174          $final = substr($class, strlen($lastMatch) + 1);
 175          $path = $this->_components[$lastMatch];
 176          $classPath = $path . '/' . str_replace('_', '/', $final) . '.php';
 177  
 178          if (Zend_Loader::isReadable($classPath)) {
 179              return $classPath;
 180          }
 181  
 182          return false;
 183      }
 184  
 185      /**
 186       * Attempt to autoload a class
 187       *
 188       * @param  string $class
 189       * @return mixed False if not matched, otherwise result if include operation
 190       */
 191      public function autoload($class)
 192      {
 193          $classPath = $this->getClassPath($class);
 194          if (false !== $classPath) {
 195              return include $classPath;
 196          }
 197          return false;
 198      }
 199  
 200      /**
 201       * Set class state from options
 202       *
 203       * @param  array $options
 204       * @return Zend_Loader_Autoloader_Resource
 205       */
 206      public function setOptions(array $options)
 207      {
 208          $methods = get_class_methods($this);
 209          foreach ($options as $key => $value) {
 210              $method = 'set' . ucfirst($key);
 211              if (in_array($method, $methods)) {
 212                  $this->$method($value);
 213              }
 214          }
 215          return $this;
 216      }
 217  
 218      /**
 219       * Set namespace that this autoloader handles
 220       *
 221       * @param  string $namespace
 222       * @return Zend_Loader_Autoloader_Resource
 223       */
 224      public function setNamespace($namespace)
 225      {
 226          $this->_namespace = rtrim((string) $namespace, '_');
 227          return $this;
 228      }
 229  
 230      /**
 231       * Get namespace this autoloader handles
 232       *
 233       * @return string
 234       */
 235      public function getNamespace()
 236      {
 237          return $this->_namespace;
 238      }
 239  
 240      /**
 241       * Set base path for this set of resources
 242       *
 243       * @param  string $path
 244       * @return Zend_Loader_Autoloader_Resource
 245       */
 246      public function setBasePath($path)
 247      {
 248          $this->_basePath = (string) $path;
 249          return $this;
 250      }
 251  
 252      /**
 253       * Get base path to this set of resources
 254       *
 255       * @return string
 256       */
 257      public function getBasePath()
 258      {
 259          return $this->_basePath;
 260      }
 261  
 262      /**
 263       * Add resource type
 264       *
 265       * @param  string $type identifier for the resource type being loaded
 266       * @param  string $path path relative to resource base path containing the resource types
 267       * @param  null|string $namespace sub-component namespace to append to base namespace that qualifies this resource type
 268       * @return Zend_Loader_Autoloader_Resource
 269       */
 270      public function addResourceType($type, $path, $namespace = null)
 271      {
 272          $type = strtolower($type);
 273          if (!isset($this->_resourceTypes[$type])) {
 274              if (null === $namespace) {
 275                  require_once 'Zend/Loader/Exception.php';
 276                  throw new Zend_Loader_Exception('Initial definition of a resource type must include a namespace');
 277              }
 278              $namespaceTopLevel = $this->getNamespace();
 279              $namespace = ucfirst(trim($namespace, '_'));
 280              $this->_resourceTypes[$type] = array(
 281                  'namespace' => empty($namespaceTopLevel) ? $namespace : $namespaceTopLevel . '_' . $namespace,
 282              );
 283          }
 284          if (!is_string($path)) {
 285              require_once 'Zend/Loader/Exception.php';
 286              throw new Zend_Loader_Exception('Invalid path specification provided; must be string');
 287          }
 288          $this->_resourceTypes[$type]['path'] = $this->getBasePath() . '/' . rtrim($path, '\/');
 289  
 290          $component = $this->_resourceTypes[$type]['namespace'];
 291          $this->_components[$component] = $this->_resourceTypes[$type]['path'];
 292          return $this;
 293      }
 294  
 295      /**
 296       * Add multiple resources at once
 297       *
 298       * $types should be an associative array of resource type => specification
 299       * pairs. Each specification should be an associative array containing
 300       * minimally the 'path' key (specifying the path relative to the resource
 301       * base path) and optionally the 'namespace' key (indicating the subcomponent
 302       * namespace to append to the resource namespace).
 303       *
 304       * As an example:
 305       * <code>
 306       * $loader->addResourceTypes(array(
 307       *     'model' => array(
 308       *         'path'      => 'models',
 309       *         'namespace' => 'Model',
 310       *     ),
 311       *     'form' => array(
 312       *         'path'      => 'forms',
 313       *         'namespace' => 'Form',
 314       *     ),
 315       * ));
 316       * </code>
 317       *
 318       * @param  array $types
 319       * @return Zend_Loader_Autoloader_Resource
 320       */
 321      public function addResourceTypes(array $types)
 322      {
 323          foreach ($types as $type => $spec) {
 324              if (!is_array($spec)) {
 325                  require_once 'Zend/Loader/Exception.php';
 326                  throw new Zend_Loader_Exception('addResourceTypes() expects an array of arrays');
 327              }
 328              if (!isset($spec['path'])) {
 329                  require_once 'Zend/Loader/Exception.php';
 330                  throw new Zend_Loader_Exception('addResourceTypes() expects each array to include a paths element');
 331              }
 332              $paths  = $spec['path'];
 333              $namespace = null;
 334              if (isset($spec['namespace'])) {
 335                  $namespace = $spec['namespace'];
 336              }
 337              $this->addResourceType($type, $paths, $namespace);
 338          }
 339          return $this;
 340      }
 341  
 342      /**
 343       * Overwrite existing and set multiple resource types at once
 344       *
 345       * @see    Zend_Loader_Autoloader_Resource::addResourceTypes()
 346       * @param  array $types
 347       * @return Zend_Loader_Autoloader_Resource
 348       */
 349      public function setResourceTypes(array $types)
 350      {
 351          $this->clearResourceTypes();
 352          return $this->addResourceTypes($types);
 353      }
 354  
 355      /**
 356       * Retrieve resource type mappings
 357       *
 358       * @return array
 359       */
 360      public function getResourceTypes()
 361      {
 362          return $this->_resourceTypes;
 363      }
 364  
 365      /**
 366       * Is the requested resource type defined?
 367       *
 368       * @param  string $type
 369       * @return bool
 370       */
 371      public function hasResourceType($type)
 372      {
 373          return isset($this->_resourceTypes[$type]);
 374      }
 375  
 376      /**
 377       * Remove the requested resource type
 378       *
 379       * @param  string $type
 380       * @return Zend_Loader_Autoloader_Resource
 381       */
 382      public function removeResourceType($type)
 383      {
 384          if ($this->hasResourceType($type)) {
 385              $namespace = $this->_resourceTypes[$type]['namespace'];
 386              unset($this->_components[$namespace]);
 387              unset($this->_resourceTypes[$type]);
 388          }
 389          return $this;
 390      }
 391  
 392      /**
 393       * Clear all resource types
 394       *
 395       * @return Zend_Loader_Autoloader_Resource
 396       */
 397      public function clearResourceTypes()
 398      {
 399          $this->_resourceTypes = array();
 400          $this->_components    = array();
 401          return $this;
 402      }
 403  
 404      /**
 405       * Set default resource type to use when calling load()
 406       *
 407       * @param  string $type
 408       * @return Zend_Loader_Autoloader_Resource
 409       */
 410      public function setDefaultResourceType($type)
 411      {
 412          if ($this->hasResourceType($type)) {
 413              $this->_defaultResourceType = $type;
 414          }
 415          return $this;
 416      }
 417  
 418      /**
 419       * Get default resource type to use when calling load()
 420       *
 421       * @return string|null
 422       */
 423      public function getDefaultResourceType()
 424      {
 425          return $this->_defaultResourceType;
 426      }
 427  
 428      /**
 429       * Object registry and factory
 430       *
 431       * Loads the requested resource of type $type (or uses the default resource
 432       * type if none provided). If the resource has been loaded previously,
 433       * returns the previous instance; otherwise, instantiates it.
 434       *
 435       * @param  string $resource
 436       * @param  string $type
 437       * @return object
 438       * @throws Zend_Loader_Exception if resource type not specified or invalid
 439       */
 440      public function load($resource, $type = null)
 441      {
 442          if (null === $type) {
 443              $type = $this->getDefaultResourceType();
 444              if (empty($type)) {
 445                  require_once 'Zend/Loader/Exception.php';
 446                  throw new Zend_Loader_Exception('No resource type specified');
 447              }
 448          }
 449          if (!$this->hasResourceType($type)) {
 450              require_once 'Zend/Loader/Exception.php';
 451              throw new Zend_Loader_Exception('Invalid resource type specified');
 452          }
 453          $namespace = $this->_resourceTypes[$type]['namespace'];
 454          $class     = $namespace . '_' . ucfirst($resource);
 455          if (!isset($this->_resources[$class])) {
 456              $this->_resources[$class] = new $class;
 457          }
 458          return $this->_resources[$class];
 459      }
 460  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1