Overview

Packages

  • Auth
  • Config
  • Controller
  • Date
  • Db
  • Feed
    • Abstract
    • Writers
  • File
    • Decorator
  • Form
    • Element
  • Image
  • Log
    • Writer
  • Net
    • Exception
    • REST
  • None
  • PHP
  • PHPMailer
  • Session
  • Util
  • Validate
    • Validator
  • Zend
    • Db
      • Adapter
      • Expr
      • Profiler
      • Select
      • Statement
      • Table
    • Loader
      • Autoloader
      • PluginLoader
    • Registry

Classes

  • Zend_Loader_Autoloader
  • Zend_Loader_Autoloader_Resource

Interfaces

  • Zend_Loader_Autoloader_Interface
  • Overview
  • Package
  • Class
  • Tree
  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 */
 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:         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: }
468: 
Pry Framework API documentation generated by ApiGen 2.6.1