--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/Zend/Loader/Autoloader/Resource.php Mon Dec 13 18:29:26 2010 +0100
@@ -0,0 +1,460 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Loader
+ * @subpackage Autoloader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @version $Id: Resource.php 20096 2010-01-06 02:05:09Z bkarwin $
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/** Zend_Loader_Autoloader_Interface */
+require_once 'Zend/Loader/Autoloader/Interface.php';
+
+/**
+ * Resource loader
+ *
+ * @uses Zend_Loader_Autoloader_Interface
+ * @package Zend_Loader
+ * @subpackage Autoloader
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Loader_Autoloader_Resource implements Zend_Loader_Autoloader_Interface
+{
+ /**
+ * @var string Base path to resource classes
+ */
+ protected $_basePath;
+
+ /**
+ * @var array Components handled within this resource
+ */
+ protected $_components = array();
+
+ /**
+ * @var string Default resource/component to use when using object registry
+ */
+ protected $_defaultResourceType;
+
+ /**
+ * @var string Namespace of classes within this resource
+ */
+ protected $_namespace;
+
+ /**
+ * @var array Available resource types handled by this resource autoloader
+ */
+ protected $_resourceTypes = array();
+
+ /**
+ * Constructor
+ *
+ * @param array|Zend_Config $options Configuration options for resource autoloader
+ * @return void
+ */
+ public function __construct($options)
+ {
+ if ($options instanceof Zend_Config) {
+ $options = $options->toArray();
+ }
+ if (!is_array($options)) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception('Options must be passed to resource loader constructor');
+ }
+
+ $this->setOptions($options);
+
+ $namespace = $this->getNamespace();
+ if ((null === $namespace)
+ || (null === $this->getBasePath())
+ ) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception('Resource loader requires both a namespace and a base path for initialization');
+ }
+
+ if (!empty($namespace)) {
+ $namespace .= '_';
+ }
+ Zend_Loader_Autoloader::getInstance()->unshiftAutoloader($this, $namespace);
+ }
+
+ /**
+ * Overloading: methods
+ *
+ * Allow retrieving concrete resource object instances using 'get<Resourcename>()'
+ * syntax. Example:
+ * <code>
+ * $loader = new Zend_Loader_Autoloader_Resource(array(
+ * 'namespace' => 'Stuff_',
+ * 'basePath' => '/path/to/some/stuff',
+ * ))
+ * $loader->addResourceType('Model', 'models', 'Model');
+ *
+ * $foo = $loader->getModel('Foo'); // get instance of Stuff_Model_Foo class
+ * </code>
+ *
+ * @param string $method
+ * @param array $args
+ * @return mixed
+ * @throws Zend_Loader_Exception if method not beginning with 'get' or not matching a valid resource type is called
+ */
+ public function __call($method, $args)
+ {
+ if ('get' == substr($method, 0, 3)) {
+ $type = strtolower(substr($method, 3));
+ if (!$this->hasResourceType($type)) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception("Invalid resource type $type; cannot load resource");
+ }
+ if (empty($args)) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception("Cannot load resources; no resource specified");
+ }
+ $resource = array_shift($args);
+ return $this->load($resource, $type);
+ }
+
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception("Method '$method' is not supported");
+ }
+
+ /**
+ * Helper method to calculate the correct class path
+ *
+ * @param string $class
+ * @return False if not matched other wise the correct path
+ */
+ public function getClassPath($class)
+ {
+ $segments = explode('_', $class);
+ $namespaceTopLevel = $this->getNamespace();
+ $namespace = '';
+
+ if (!empty($namespaceTopLevel)) {
+ $namespace = array_shift($segments);
+ if ($namespace != $namespaceTopLevel) {
+ // wrong prefix? we're done
+ return false;
+ }
+ }
+
+ if (count($segments) < 2) {
+ // assumes all resources have a component and class name, minimum
+ return false;
+ }
+
+ $final = array_pop($segments);
+ $component = $namespace;
+ $lastMatch = false;
+ do {
+ $segment = array_shift($segments);
+ $component .= empty($component) ? $segment : '_' . $segment;
+ if (isset($this->_components[$component])) {
+ $lastMatch = $component;
+ }
+ } while (count($segments));
+
+ if (!$lastMatch) {
+ return false;
+ }
+
+ $final = substr($class, strlen($lastMatch) + 1);
+ $path = $this->_components[$lastMatch];
+ $classPath = $path . '/' . str_replace('_', '/', $final) . '.php';
+
+ if (Zend_Loader::isReadable($classPath)) {
+ return $classPath;
+ }
+
+ return false;
+ }
+
+ /**
+ * Attempt to autoload a class
+ *
+ * @param string $class
+ * @return mixed False if not matched, otherwise result if include operation
+ */
+ public function autoload($class)
+ {
+ $classPath = $this->getClassPath($class);
+ if (false !== $classPath) {
+ return include $classPath;
+ }
+ return false;
+ }
+
+ /**
+ * Set class state from options
+ *
+ * @param array $options
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function setOptions(array $options)
+ {
+ $methods = get_class_methods($this);
+ foreach ($options as $key => $value) {
+ $method = 'set' . ucfirst($key);
+ if (in_array($method, $methods)) {
+ $this->$method($value);
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Set namespace that this autoloader handles
+ *
+ * @param string $namespace
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function setNamespace($namespace)
+ {
+ $this->_namespace = rtrim((string) $namespace, '_');
+ return $this;
+ }
+
+ /**
+ * Get namespace this autoloader handles
+ *
+ * @return string
+ */
+ public function getNamespace()
+ {
+ return $this->_namespace;
+ }
+
+ /**
+ * Set base path for this set of resources
+ *
+ * @param string $path
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function setBasePath($path)
+ {
+ $this->_basePath = (string) $path;
+ return $this;
+ }
+
+ /**
+ * Get base path to this set of resources
+ *
+ * @return string
+ */
+ public function getBasePath()
+ {
+ return $this->_basePath;
+ }
+
+ /**
+ * Add resource type
+ *
+ * @param string $type identifier for the resource type being loaded
+ * @param string $path path relative to resource base path containing the resource types
+ * @param null|string $namespace sub-component namespace to append to base namespace that qualifies this resource type
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function addResourceType($type, $path, $namespace = null)
+ {
+ $type = strtolower($type);
+ if (!isset($this->_resourceTypes[$type])) {
+ if (null === $namespace) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception('Initial definition of a resource type must include a namespace');
+ }
+ $namespaceTopLevel = $this->getNamespace();
+ $namespace = ucfirst(trim($namespace, '_'));
+ $this->_resourceTypes[$type] = array(
+ 'namespace' => empty($namespaceTopLevel) ? $namespace : $namespaceTopLevel . '_' . $namespace,
+ );
+ }
+ if (!is_string($path)) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception('Invalid path specification provided; must be string');
+ }
+ $this->_resourceTypes[$type]['path'] = $this->getBasePath() . '/' . rtrim($path, '\/');
+
+ $component = $this->_resourceTypes[$type]['namespace'];
+ $this->_components[$component] = $this->_resourceTypes[$type]['path'];
+ return $this;
+ }
+
+ /**
+ * Add multiple resources at once
+ *
+ * $types should be an associative array of resource type => specification
+ * pairs. Each specification should be an associative array containing
+ * minimally the 'path' key (specifying the path relative to the resource
+ * base path) and optionally the 'namespace' key (indicating the subcomponent
+ * namespace to append to the resource namespace).
+ *
+ * As an example:
+ * <code>
+ * $loader->addResourceTypes(array(
+ * 'model' => array(
+ * 'path' => 'models',
+ * 'namespace' => 'Model',
+ * ),
+ * 'form' => array(
+ * 'path' => 'forms',
+ * 'namespace' => 'Form',
+ * ),
+ * ));
+ * </code>
+ *
+ * @param array $types
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function addResourceTypes(array $types)
+ {
+ foreach ($types as $type => $spec) {
+ if (!is_array($spec)) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception('addResourceTypes() expects an array of arrays');
+ }
+ if (!isset($spec['path'])) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception('addResourceTypes() expects each array to include a paths element');
+ }
+ $paths = $spec['path'];
+ $namespace = null;
+ if (isset($spec['namespace'])) {
+ $namespace = $spec['namespace'];
+ }
+ $this->addResourceType($type, $paths, $namespace);
+ }
+ return $this;
+ }
+
+ /**
+ * Overwrite existing and set multiple resource types at once
+ *
+ * @see Zend_Loader_Autoloader_Resource::addResourceTypes()
+ * @param array $types
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function setResourceTypes(array $types)
+ {
+ $this->clearResourceTypes();
+ return $this->addResourceTypes($types);
+ }
+
+ /**
+ * Retrieve resource type mappings
+ *
+ * @return array
+ */
+ public function getResourceTypes()
+ {
+ return $this->_resourceTypes;
+ }
+
+ /**
+ * Is the requested resource type defined?
+ *
+ * @param string $type
+ * @return bool
+ */
+ public function hasResourceType($type)
+ {
+ return isset($this->_resourceTypes[$type]);
+ }
+
+ /**
+ * Remove the requested resource type
+ *
+ * @param string $type
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function removeResourceType($type)
+ {
+ if ($this->hasResourceType($type)) {
+ $namespace = $this->_resourceTypes[$type]['namespace'];
+ unset($this->_components[$namespace]);
+ unset($this->_resourceTypes[$type]);
+ }
+ return $this;
+ }
+
+ /**
+ * Clear all resource types
+ *
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function clearResourceTypes()
+ {
+ $this->_resourceTypes = array();
+ $this->_components = array();
+ return $this;
+ }
+
+ /**
+ * Set default resource type to use when calling load()
+ *
+ * @param string $type
+ * @return Zend_Loader_Autoloader_Resource
+ */
+ public function setDefaultResourceType($type)
+ {
+ if ($this->hasResourceType($type)) {
+ $this->_defaultResourceType = $type;
+ }
+ return $this;
+ }
+
+ /**
+ * Get default resource type to use when calling load()
+ *
+ * @return string|null
+ */
+ public function getDefaultResourceType()
+ {
+ return $this->_defaultResourceType;
+ }
+
+ /**
+ * Object registry and factory
+ *
+ * Loads the requested resource of type $type (or uses the default resource
+ * type if none provided). If the resource has been loaded previously,
+ * returns the previous instance; otherwise, instantiates it.
+ *
+ * @param string $resource
+ * @param string $type
+ * @return object
+ * @throws Zend_Loader_Exception if resource type not specified or invalid
+ */
+ public function load($resource, $type = null)
+ {
+ if (null === $type) {
+ $type = $this->getDefaultResourceType();
+ if (empty($type)) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception('No resource type specified');
+ }
+ }
+ if (!$this->hasResourceType($type)) {
+ require_once 'Zend/Loader/Exception.php';
+ throw new Zend_Loader_Exception('Invalid resource type specified');
+ }
+ $namespace = $this->_resourceTypes[$type]['namespace'];
+ $class = $namespace . '_' . ucfirst($resource);
+ if (!isset($this->_resources[$class])) {
+ $this->_resources[$class] = new $class;
+ }
+ return $this->_resources[$class];
+ }
+}