PageRenderTime 230ms CodeModel.GetById 112ms app.highlight 14ms RepoModel.GetById 68ms app.codeStats 0ms

/concreteOLD/libraries/3rdparty/Zend/Loader/Autoloader/Resource.php

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