*prechod na novsiu verziu ZF
[sport-group.git] / library / Zend / Loader / Autoloader / Resource.php
blob2acd1f419f70d4f5f28517dba8eb9ba7a6af077c
1 <?php
2 /**
3 * Zend Framework
5 * LICENSE
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.
15 * @category Zend
16 * @package Zend_Loader
17 * @subpackage Autoloader
18 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
19 * @version $Id: Resource.php 17417 2009-08-06 18:06:04Z matthew $
20 * @license http://framework.zend.com/license/new-bsd New BSD License
23 /** Zend_Loader_Autoloader_Interface */
24 require_once 'Zend/Loader/Autoloader/Interface.php';
26 /**
27 * Resource loader
29 * @uses Zend_Loader_Autoloader_Interface
30 * @package Zend_Loader
31 * @subpackage Autoloader
32 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
33 * @license http://framework.zend.com/license/new-bsd New BSD License
35 class Zend_Loader_Autoloader_Resource implements Zend_Loader_Autoloader_Interface
37 /**
38 * @var string Base path to resource classes
40 protected $_basePath;
42 /**
43 * @var array Components handled within this resource
45 protected $_components = array();
47 /**
48 * @var string Default resource/component to use when using object registry
50 protected $_defaultResourceType;
52 /**
53 * @var string Namespace of classes within this resource
55 protected $_namespace;
57 /**
58 * @var array Available resource types handled by this resource autoloader
60 protected $_resourceTypes = array();
62 /**
63 * Constructor
65 * @param array|Zend_Config $options Configuration options for resource autoloader
66 * @return void
68 public function __construct($options)
70 if ($options instanceof Zend_Config) {
71 $options = $options->toArray();
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');
78 $this->setOptions($options);
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');
88 if (!empty($namespace)) {
89 $namespace .= '_';
91 Zend_Loader_Autoloader::getInstance()->unshiftAutoloader($this, $namespace);
94 /**
95 * Overloading: methods
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');
106 * $foo = $loader->getModel('Foo'); // get instance of Stuff_Model_Foo class
107 * </code>
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
114 public function __call($method, $args)
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");
122 if (empty($args)) {
123 require_once 'Zend/Loader/Exception.php';
124 throw new Zend_Loader_Exception("Cannot load resources; no resource specified");
126 $resource = array_shift($args);
127 return $this->load($resource, $type);
130 require_once 'Zend/Loader/Exception.php';
131 throw new Zend_Loader_Exception("Method '$method' is not supported");
135 * Attempt to autoload a class
137 * @param string $class
138 * @return mixed False if not matched, otherwise result if include operation
140 public function autoload($class)
142 $segments = explode('_', $class);
143 $namespaceTopLevel = $this->getNamespace();
144 $namespace = '';
146 if (!empty($namespaceTopLevel)) {
147 $namespace = array_shift($segments);
148 if ($namespace != $namespaceTopLevel) {
149 // wrong prefix? we're done
150 return false;
154 if (count($segments) < 2) {
155 // assumes all resources have a component and class name, minimum
156 return false;
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;
168 } while (count($segments));
170 if (!$lastMatch) {
171 return false;
174 $final = substr($class, strlen($lastMatch));
175 $path = $this->_components[$lastMatch];
176 return include $path . '/' . str_replace('_', '/', $final) . '.php';
180 * Set class state from options
182 * @param array $options
183 * @return Zend_Loader_Autoloader_Resource
185 public function setOptions(array $options)
187 $methods = get_class_methods($this);
188 foreach ($options as $key => $value) {
189 $method = 'set' . ucfirst($key);
190 if (in_array($method, $methods)) {
191 $this->$method($value);
194 return $this;
198 * Set namespace that this autoloader handles
200 * @param string $namespace
201 * @return Zend_Loader_Autoloader_Resource
203 public function setNamespace($namespace)
205 $this->_namespace = rtrim((string) $namespace, '_');
206 return $this;
210 * Get namespace this autoloader handles
212 * @return string
214 public function getNamespace()
216 return $this->_namespace;
220 * Set base path for this set of resources
222 * @param string $path
223 * @return Zend_Loader_Autoloader_Resource
225 public function setBasePath($path)
227 $this->_basePath = (string) $path;
228 return $this;
232 * Get base path to this set of resources
234 * @return string
236 public function getBasePath()
238 return $this->_basePath;
242 * Add resource type
244 * @param string $type identifier for the resource type being loaded
245 * @param string $path path relative to resource base path containing the resource types
246 * @param null|string $namespace sub-component namespace to append to base namespace that qualifies this resource type
247 * @return Zend_Loader_Autoloader_Resource
249 public function addResourceType($type, $path, $namespace = null)
251 $type = strtolower($type);
252 if (!isset($this->_resourceTypes[$type])) {
253 if (null === $namespace) {
254 require_once 'Zend/Loader/Exception.php';
255 throw new Zend_Loader_Exception('Initial definition of a resource type must include a namespace');
257 $namespaceTopLevel = $this->getNamespace();
258 $namespace = ucfirst(trim($namespace, '_'));
259 $this->_resourceTypes[$type] = array(
260 'namespace' => empty($namespaceTopLevel) ? $namespace : $namespaceTopLevel . '_' . $namespace,
263 if (!is_string($path)) {
264 require_once 'Zend/Loader/Exception.php';
265 throw new Zend_Loader_Exception('Invalid path specification provided; must be string');
267 $this->_resourceTypes[$type]['path'] = $this->getBasePath() . '/' . $path;
269 $component = $this->_resourceTypes[$type]['namespace'];
270 $this->_components[$component] = $this->_resourceTypes[$type]['path'];
271 return $this;
275 * Add multiple resources at once
277 * $types should be an associative array of resource type => specification
278 * pairs. Each specification should be an associative array containing
279 * minimally the 'path' key (specifying the path relative to the resource
280 * base path) and optionally the 'namespace' key (indicating the subcomponent
281 * namespace to append to the resource namespace).
283 * As an example:
284 * <code>
285 * $loader->addResourceTypes(array(
286 * 'model' => array(
287 * 'path' => 'models',
288 * 'namespace' => 'Model',
289 * ),
290 * 'form' => array(
291 * 'path' => 'forms',
292 * 'namespace' => 'Form',
293 * ),
294 * ));
295 * </code>
297 * @param array $types
298 * @return Zend_Loader_Autoloader_Resource
300 public function addResourceTypes(array $types)
302 foreach ($types as $type => $spec) {
303 if (!is_array($spec)) {
304 require_once 'Zend/Loader/Exception.php';
305 throw new Zend_Loader_Exception('addResourceTypes() expects an array of arrays');
307 if (!isset($spec['path'])) {
308 require_once 'Zend/Loader/Exception.php';
309 throw new Zend_Loader_Exception('addResourceTypes() expects each array to include a paths element');
311 $paths = $spec['path'];
312 $namespace = null;
313 if (isset($spec['namespace'])) {
314 $namespace = $spec['namespace'];
316 $this->addResourceType($type, $paths, $namespace);
318 return $this;
322 * Overwrite existing and set multiple resource types at once
324 * @see Zend_Loader_Autoloader_Resource::addResourceTypes()
325 * @param array $types
326 * @return Zend_Loader_Autoloader_Resource
328 public function setResourceTypes(array $types)
330 $this->clearResourceTypes();
331 return $this->addResourceTypes($types);
335 * Retrieve resource type mappings
337 * @return array
339 public function getResourceTypes()
341 return $this->_resourceTypes;
345 * Is the requested resource type defined?
347 * @param string $type
348 * @return bool
350 public function hasResourceType($type)
352 return isset($this->_resourceTypes[$type]);
356 * Remove the requested resource type
358 * @param string $type
359 * @return Zend_Loader_Autoloader_Resource
361 public function removeResourceType($type)
363 if ($this->hasResourceType($type)) {
364 $namespace = $this->_resourceTypes[$type]['namespace'];
365 unset($this->_components[$namespace]);
366 unset($this->_resourceTypes[$type]);
368 return $this;
372 * Clear all resource types
374 * @return Zend_Loader_Autoloader_Resource
376 public function clearResourceTypes()
378 $this->_resourceTypes = array();
379 $this->_components = array();
380 return $this;
384 * Set default resource type to use when calling load()
386 * @param string $type
387 * @return Zend_Loader_Autoloader_Resource
389 public function setDefaultResourceType($type)
391 if ($this->hasResourceType($type)) {
392 $this->_defaultResourceType = $type;
394 return $this;
398 * Get default resource type to use when calling load()
400 * @return string|null
402 public function getDefaultResourceType()
404 return $this->_defaultResourceType;
408 * Object registry and factory
410 * Loads the requested resource of type $type (or uses the default resource
411 * type if none provided). If the resource has been loaded previously,
412 * returns the previous instance; otherwise, instantiates it.
414 * @param string $resource
415 * @param string $type
416 * @return object
417 * @throws Zend_Loader_Exception if resource type not specified or invalid
419 public function load($resource, $type = null)
421 if (null === $type) {
422 $type = $this->getDefaultResourceType();
423 if (empty($type)) {
424 require_once 'Zend/Loader/Exception.php';
425 throw new Zend_Loader_Exception('No resource type specified');
428 if (!$this->hasResourceType($type)) {
429 require_once 'Zend/Loader/Exception.php';
430 throw new Zend_Loader_Exception('Invalid resource type specified');
432 $namespace = $this->_resourceTypes[$type]['namespace'];
433 $class = $namespace . '_' . ucfirst($resource);
434 if (!isset($this->_resources[$class])) {
435 $this->_resources[$class] = new $class;
437 return $this->_resources[$class];