source: trunk/library/Zend/Loader/Autoloader/Resource.php @ 4456

Revision 4456, 14.0 KB checked in by airton, 13 years ago (diff)

Ticket #1991 - Parametrizacao das buscas LDAP no Expresso Mail - Adicionando arquivos e bibliotecas

  • Property svn:executable set to *
Line 
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-2010 Zend Technologies USA Inc. (http://www.zend.com)
19 * @version    $Id: Resource.php 23568 2010-12-20 08:13:20Z mjh_ca $
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-2010 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_shift($segments);
149            if ($namespace != $namespaceTopLevel) {
150                // wrong prefix? we're done
151                return false;
152            }
153        }
154
155        if (count($segments) < 2) {
156            // assumes all resources have a component and class name, minimum
157            return false;
158        }
159
160        $final     = array_pop($segments);
161        $component = $namespace;
162        $lastMatch = false;
163        do {
164            $segment    = array_shift($segments);
165            $component .= empty($component) ? $segment : '_' . $segment;
166            if (isset($this->_components[$component])) {
167                $lastMatch = $component;
168            }
169        } while (count($segments));
170
171        if (!$lastMatch) {
172            return false;
173        }
174
175        $final = substr($class, strlen($lastMatch) + 1);
176        $path = $this->_components[$lastMatch];
177        $classPath = $path . '/' . str_replace('_', '/', $final) . '.php';
178
179        if (Zend_Loader::isReadable($classPath)) {
180            return $classPath;
181        }
182
183        return false;
184    }
185
186    /**
187     * Attempt to autoload a class
188     *
189     * @param  string $class
190     * @return mixed False if not matched, otherwise result if include operation
191     */
192    public function autoload($class)
193    {
194        $classPath = $this->getClassPath($class);
195        if (false !== $classPath) {
196            return include $classPath;
197        }
198        return false;
199    }
200
201    /**
202     * Set class state from options
203     *
204     * @param  array $options
205     * @return Zend_Loader_Autoloader_Resource
206     */
207    public function setOptions(array $options)
208    {
209        // Set namespace first, see ZF-10836
210        if (isset($options['namespace'])) {
211            $this->setNamespace($options['namespace']);
212            unset($options['namespace']);
213        }
214
215        $methods = get_class_methods($this);
216        foreach ($options as $key => $value) {
217            $method = 'set' . ucfirst($key);
218            if (in_array($method, $methods)) {
219                $this->$method($value);
220            }
221        }
222        return $this;
223    }
224
225    /**
226     * Set namespace that this autoloader handles
227     *
228     * @param  string $namespace
229     * @return Zend_Loader_Autoloader_Resource
230     */
231    public function setNamespace($namespace)
232    {
233        $this->_namespace = rtrim((string) $namespace, '_');
234        return $this;
235    }
236
237    /**
238     * Get namespace this autoloader handles
239     *
240     * @return string
241     */
242    public function getNamespace()
243    {
244        return $this->_namespace;
245    }
246
247    /**
248     * Set base path for this set of resources
249     *
250     * @param  string $path
251     * @return Zend_Loader_Autoloader_Resource
252     */
253    public function setBasePath($path)
254    {
255        $this->_basePath = (string) $path;
256        return $this;
257    }
258
259    /**
260     * Get base path to this set of resources
261     *
262     * @return string
263     */
264    public function getBasePath()
265    {
266        return $this->_basePath;
267    }
268
269    /**
270     * Add resource type
271     *
272     * @param  string $type identifier for the resource type being loaded
273     * @param  string $path path relative to resource base path containing the resource types
274     * @param  null|string $namespace sub-component namespace to append to base namespace that qualifies this resource type
275     * @return Zend_Loader_Autoloader_Resource
276     */
277    public function addResourceType($type, $path, $namespace = null)
278    {
279        $type = strtolower($type);
280        if (!isset($this->_resourceTypes[$type])) {
281            if (null === $namespace) {
282                require_once 'Zend/Loader/Exception.php';
283                throw new Zend_Loader_Exception('Initial definition of a resource type must include a namespace');
284            }
285            $namespaceTopLevel = $this->getNamespace();
286            $namespace = ucfirst(trim($namespace, '_'));
287            $this->_resourceTypes[$type] = array(
288                'namespace' => empty($namespaceTopLevel) ? $namespace : $namespaceTopLevel . '_' . $namespace,
289            );
290        }
291        if (!is_string($path)) {
292            require_once 'Zend/Loader/Exception.php';
293            throw new Zend_Loader_Exception('Invalid path specification provided; must be string');
294        }
295        $this->_resourceTypes[$type]['path'] = $this->getBasePath() . '/' . rtrim($path, '\/');
296
297        $component = $this->_resourceTypes[$type]['namespace'];
298        $this->_components[$component] = $this->_resourceTypes[$type]['path'];
299        return $this;
300    }
301
302    /**
303     * Add multiple resources at once
304     *
305     * $types should be an associative array of resource type => specification
306     * pairs. Each specification should be an associative array containing
307     * minimally the 'path' key (specifying the path relative to the resource
308     * base path) and optionally the 'namespace' key (indicating the subcomponent
309     * namespace to append to the resource namespace).
310     *
311     * As an example:
312     * <code>
313     * $loader->addResourceTypes(array(
314     *     'model' => array(
315     *         'path'      => 'models',
316     *         'namespace' => 'Model',
317     *     ),
318     *     'form' => array(
319     *         'path'      => 'forms',
320     *         'namespace' => 'Form',
321     *     ),
322     * ));
323     * </code>
324     *
325     * @param  array $types
326     * @return Zend_Loader_Autoloader_Resource
327     */
328    public function addResourceTypes(array $types)
329    {
330        foreach ($types as $type => $spec) {
331            if (!is_array($spec)) {
332                require_once 'Zend/Loader/Exception.php';
333                throw new Zend_Loader_Exception('addResourceTypes() expects an array of arrays');
334            }
335            if (!isset($spec['path'])) {
336                require_once 'Zend/Loader/Exception.php';
337                throw new Zend_Loader_Exception('addResourceTypes() expects each array to include a paths element');
338            }
339            $paths  = $spec['path'];
340            $namespace = null;
341            if (isset($spec['namespace'])) {
342                $namespace = $spec['namespace'];
343            }
344            $this->addResourceType($type, $paths, $namespace);
345        }
346        return $this;
347    }
348
349    /**
350     * Overwrite existing and set multiple resource types at once
351     *
352     * @see    Zend_Loader_Autoloader_Resource::addResourceTypes()
353     * @param  array $types
354     * @return Zend_Loader_Autoloader_Resource
355     */
356    public function setResourceTypes(array $types)
357    {
358        $this->clearResourceTypes();
359        return $this->addResourceTypes($types);
360    }
361
362    /**
363     * Retrieve resource type mappings
364     *
365     * @return array
366     */
367    public function getResourceTypes()
368    {
369        return $this->_resourceTypes;
370    }
371
372    /**
373     * Is the requested resource type defined?
374     *
375     * @param  string $type
376     * @return bool
377     */
378    public function hasResourceType($type)
379    {
380        return isset($this->_resourceTypes[$type]);
381    }
382
383    /**
384     * Remove the requested resource type
385     *
386     * @param  string $type
387     * @return Zend_Loader_Autoloader_Resource
388     */
389    public function removeResourceType($type)
390    {
391        if ($this->hasResourceType($type)) {
392            $namespace = $this->_resourceTypes[$type]['namespace'];
393            unset($this->_components[$namespace]);
394            unset($this->_resourceTypes[$type]);
395        }
396        return $this;
397    }
398
399    /**
400     * Clear all resource types
401     *
402     * @return Zend_Loader_Autoloader_Resource
403     */
404    public function clearResourceTypes()
405    {
406        $this->_resourceTypes = array();
407        $this->_components    = array();
408        return $this;
409    }
410
411    /**
412     * Set default resource type to use when calling load()
413     *
414     * @param  string $type
415     * @return Zend_Loader_Autoloader_Resource
416     */
417    public function setDefaultResourceType($type)
418    {
419        if ($this->hasResourceType($type)) {
420            $this->_defaultResourceType = $type;
421        }
422        return $this;
423    }
424
425    /**
426     * Get default resource type to use when calling load()
427     *
428     * @return string|null
429     */
430    public function getDefaultResourceType()
431    {
432        return $this->_defaultResourceType;
433    }
434
435    /**
436     * Object registry and factory
437     *
438     * Loads the requested resource of type $type (or uses the default resource
439     * type if none provided). If the resource has been loaded previously,
440     * returns the previous instance; otherwise, instantiates it.
441     *
442     * @param  string $resource
443     * @param  string $type
444     * @return object
445     * @throws Zend_Loader_Exception if resource type not specified or invalid
446     */
447    public function load($resource, $type = null)
448    {
449        if (null === $type) {
450            $type = $this->getDefaultResourceType();
451            if (empty($type)) {
452                require_once 'Zend/Loader/Exception.php';
453                throw new Zend_Loader_Exception('No resource type specified');
454            }
455        }
456        if (!$this->hasResourceType($type)) {
457            require_once 'Zend/Loader/Exception.php';
458            throw new Zend_Loader_Exception('Invalid resource type specified');
459        }
460        $namespace = $this->_resourceTypes[$type]['namespace'];
461        $class     = $namespace . '_' . ucfirst($resource);
462        if (!isset($this->_resources[$class])) {
463            $this->_resources[$class] = new $class;
464        }
465        return $this->_resources[$class];
466    }
467}
Note: See TracBrowser for help on using the repository browser.