web/lib/Zend/Application/Bootstrap/BootstrapAbstract.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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_Application
       
    17  * @subpackage Bootstrap
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: BootstrapAbstract.php 23278 2010-10-30 12:50:21Z ramon $
       
    21  */
       
    22 
       
    23 /**
       
    24  * Abstract base class for bootstrap classes
       
    25  *
       
    26  * @uses       Zend_Application_Bootstrap_Bootstrapper
       
    27  * @uses       Zend_Application_Bootstrap_ResourceBootstrapper
       
    28  * @category   Zend
       
    29  * @package    Zend_Application
       
    30  * @subpackage Bootstrap
       
    31  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    32  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    33  */
       
    34 abstract class Zend_Application_Bootstrap_BootstrapAbstract
       
    35     implements Zend_Application_Bootstrap_Bootstrapper,
       
    36                Zend_Application_Bootstrap_ResourceBootstrapper
       
    37 {
       
    38     /**
       
    39      * @var Zend_Application|Zend_Application_Bootstrap_Bootstrapper
       
    40      */
       
    41     protected $_application;
       
    42 
       
    43     /**
       
    44      * @var array Internal resource methods (resource/method pairs)
       
    45      */
       
    46     protected $_classResources;
       
    47 
       
    48     /**
       
    49      * @var object Resource container
       
    50      */
       
    51     protected $_container;
       
    52 
       
    53     /**
       
    54      * @var string
       
    55      */
       
    56     protected $_environment;
       
    57 
       
    58     /**
       
    59      * Flattened (lowercase) option keys used for lookups
       
    60      *
       
    61      * @var array
       
    62      */
       
    63     protected $_optionKeys = array();
       
    64 
       
    65     /**
       
    66      * @var array
       
    67      */
       
    68     protected $_options = array();
       
    69 
       
    70     /**
       
    71      * @var Zend_Loader_PluginLoader_Interface
       
    72      */
       
    73     protected $_pluginLoader;
       
    74 
       
    75     /**
       
    76      * @var array Class-based resource plugins
       
    77      */
       
    78     protected $_pluginResources = array();
       
    79 
       
    80     /**
       
    81      * @var array Initializers that have been run
       
    82      */
       
    83     protected $_run = array();
       
    84 
       
    85     /**
       
    86      * @var array Initializers that have been started but not yet completed (circular dependency detection)
       
    87      */
       
    88     protected $_started = array();
       
    89 
       
    90     /**
       
    91      * Constructor
       
    92      *
       
    93      * Sets application object, initializes options, and prepares list of
       
    94      * initializer methods.
       
    95      *
       
    96      * @param  Zend_Application|Zend_Application_Bootstrap_Bootstrapper $application
       
    97      * @return void
       
    98      * @throws Zend_Application_Bootstrap_Exception When invalid application is provided
       
    99      */
       
   100     public function __construct($application)
       
   101     {
       
   102         $this->setApplication($application);
       
   103         $options = $application->getOptions();
       
   104         $this->setOptions($options);
       
   105     }
       
   106 
       
   107     /**
       
   108      * Set class state
       
   109      *
       
   110      * @param  array $options
       
   111      * @return Zend_Application_Bootstrap_BootstrapAbstract
       
   112      */
       
   113     public function setOptions(array $options)
       
   114     {
       
   115         $this->_options = $this->mergeOptions($this->_options, $options);
       
   116 
       
   117         $options = array_change_key_case($options, CASE_LOWER);
       
   118         $this->_optionKeys = array_merge($this->_optionKeys, array_keys($options));
       
   119 
       
   120         $methods = get_class_methods($this);
       
   121         foreach ($methods as $key => $method) {
       
   122             $methods[$key] = strtolower($method);
       
   123         }
       
   124 
       
   125         if (array_key_exists('pluginpaths', $options)) {
       
   126             $pluginLoader = $this->getPluginLoader();
       
   127 
       
   128             foreach ($options['pluginpaths'] as $prefix => $path) {
       
   129                 $pluginLoader->addPrefixPath($prefix, $path);
       
   130             }
       
   131             unset($options['pluginpaths']);
       
   132         }
       
   133 
       
   134         foreach ($options as $key => $value) {
       
   135             $method = 'set' . strtolower($key);
       
   136 
       
   137             if (in_array($method, $methods)) {
       
   138                 $this->$method($value);
       
   139             } elseif ('resources' == $key) {
       
   140                 foreach ($value as $resource => $resourceOptions) {
       
   141                     $this->registerPluginResource($resource, $resourceOptions);
       
   142                 }
       
   143             }
       
   144         }
       
   145         return $this;
       
   146     }
       
   147 
       
   148     /**
       
   149      * Get current options from bootstrap
       
   150      *
       
   151      * @return array
       
   152      */
       
   153     public function getOptions()
       
   154     {
       
   155         return $this->_options;
       
   156     }
       
   157 
       
   158     /**
       
   159      * Is an option present?
       
   160      *
       
   161      * @param  string $key
       
   162      * @return bool
       
   163      */
       
   164     public function hasOption($key)
       
   165     {
       
   166         return in_array(strtolower($key), $this->_optionKeys);
       
   167     }
       
   168 
       
   169     /**
       
   170      * Retrieve a single option
       
   171      *
       
   172      * @param  string $key
       
   173      * @return mixed
       
   174      */
       
   175     public function getOption($key)
       
   176     {
       
   177         if ($this->hasOption($key)) {
       
   178             $options = $this->getOptions();
       
   179             $options = array_change_key_case($options, CASE_LOWER);
       
   180             return $options[strtolower($key)];
       
   181         }
       
   182         return null;
       
   183     }
       
   184 
       
   185     /**
       
   186      * Merge options recursively
       
   187      *
       
   188      * @param  array $array1
       
   189      * @param  mixed $array2
       
   190      * @return array
       
   191      */
       
   192     public function mergeOptions(array $array1, $array2 = null)
       
   193     {
       
   194         if (is_array($array2)) {
       
   195             foreach ($array2 as $key => $val) {
       
   196                 if (is_array($array2[$key])) {
       
   197                     $array1[$key] = (array_key_exists($key, $array1) && is_array($array1[$key]))
       
   198                                   ? $this->mergeOptions($array1[$key], $array2[$key])
       
   199                                   : $array2[$key];
       
   200                 } else {
       
   201                     $array1[$key] = $val;
       
   202                 }
       
   203             }
       
   204         }
       
   205         return $array1;
       
   206     }
       
   207 
       
   208     /**
       
   209      * Get class resources (as resource/method pairs)
       
   210      *
       
   211      * Uses get_class_methods() by default, reflection on prior to 5.2.6,
       
   212      * as a bug prevents the usage of get_class_methods() there.
       
   213      *
       
   214      * @return array
       
   215      */
       
   216     public function getClassResources()
       
   217     {
       
   218         if (null === $this->_classResources) {
       
   219             if (version_compare(PHP_VERSION, '5.2.6') === -1) {
       
   220                 $class        = new ReflectionObject($this);
       
   221                 $classMethods = $class->getMethods();
       
   222                 $methodNames  = array();
       
   223 
       
   224                 foreach ($classMethods as $method) {
       
   225                     $methodNames[] = $method->getName();
       
   226                 }
       
   227             } else {
       
   228                 $methodNames = get_class_methods($this);
       
   229             }
       
   230 
       
   231             $this->_classResources = array();
       
   232             foreach ($methodNames as $method) {
       
   233                 if (5 < strlen($method) && '_init' === substr($method, 0, 5)) {
       
   234                     $this->_classResources[strtolower(substr($method, 5))] = $method;
       
   235                 }
       
   236             }
       
   237         }
       
   238 
       
   239         return $this->_classResources;
       
   240     }
       
   241 
       
   242     /**
       
   243      * Get class resource names
       
   244      *
       
   245      * @return array
       
   246      */
       
   247     public function getClassResourceNames()
       
   248     {
       
   249         $resources = $this->getClassResources();
       
   250         return array_keys($resources);
       
   251     }
       
   252 
       
   253     /**
       
   254      * Register a new resource plugin
       
   255      *
       
   256      * @param  string|Zend_Application_Resource_Resource $resource
       
   257      * @param  mixed  $options
       
   258      * @return Zend_Application_Bootstrap_BootstrapAbstract
       
   259      * @throws Zend_Application_Bootstrap_Exception When invalid resource is provided
       
   260      */
       
   261     public function registerPluginResource($resource, $options = null)
       
   262     {
       
   263         if ($resource instanceof Zend_Application_Resource_Resource) {
       
   264             $resource->setBootstrap($this);
       
   265             $pluginName = $this->_resolvePluginResourceName($resource);
       
   266             $this->_pluginResources[$pluginName] = $resource;
       
   267             return $this;
       
   268         }
       
   269 
       
   270         if (!is_string($resource)) {
       
   271             throw new Zend_Application_Bootstrap_Exception('Invalid resource provided to ' . __METHOD__);
       
   272         }
       
   273 
       
   274         $this->_pluginResources[$resource] = $options;
       
   275         return $this;
       
   276     }
       
   277 
       
   278     /**
       
   279      * Unregister a resource from the bootstrap
       
   280      *
       
   281      * @param  string|Zend_Application_Resource_Resource $resource
       
   282      * @return Zend_Application_Bootstrap_BootstrapAbstract
       
   283      * @throws Zend_Application_Bootstrap_Exception When unknown resource type is provided
       
   284      */
       
   285     public function unregisterPluginResource($resource)
       
   286     {
       
   287         if ($resource instanceof Zend_Application_Resource_Resource) {
       
   288             if ($index = array_search($resource, $this->_pluginResources, true)) {
       
   289                 unset($this->_pluginResources[$index]);
       
   290             }
       
   291             return $this;
       
   292         }
       
   293 
       
   294         if (!is_string($resource)) {
       
   295             throw new Zend_Application_Bootstrap_Exception('Unknown resource type provided to ' . __METHOD__);
       
   296         }
       
   297 
       
   298         $resource = strtolower($resource);
       
   299         if (array_key_exists($resource, $this->_pluginResources)) {
       
   300             unset($this->_pluginResources[$resource]);
       
   301         }
       
   302 
       
   303         return $this;
       
   304     }
       
   305 
       
   306     /**
       
   307      * Is the requested plugin resource registered?
       
   308      *
       
   309      * @param  string $resource
       
   310      * @return bool
       
   311      */
       
   312     public function hasPluginResource($resource)
       
   313     {
       
   314         return (null !== $this->getPluginResource($resource));
       
   315     }
       
   316 
       
   317     /**
       
   318      * Get a registered plugin resource
       
   319      *
       
   320      * @param  string $resourceName
       
   321      * @return Zend_Application_Resource_Resource
       
   322      */
       
   323     public function getPluginResource($resource)
       
   324     {
       
   325         if (array_key_exists(strtolower($resource), $this->_pluginResources)) {
       
   326             $resource = strtolower($resource);
       
   327             if (!$this->_pluginResources[$resource] instanceof Zend_Application_Resource_Resource) {
       
   328                 $resourceName = $this->_loadPluginResource($resource, $this->_pluginResources[$resource]);
       
   329                 if (!$resourceName) {
       
   330                     throw new Zend_Application_Bootstrap_Exception(sprintf('Unable to resolve plugin "%s"; no corresponding plugin with that name', $resource));
       
   331                 }
       
   332                 $resource = $resourceName;
       
   333             }
       
   334             return $this->_pluginResources[$resource];
       
   335         }
       
   336 
       
   337         foreach ($this->_pluginResources as $plugin => $spec) {
       
   338             if ($spec instanceof Zend_Application_Resource_Resource) {
       
   339                 $pluginName = $this->_resolvePluginResourceName($spec);
       
   340                 if (0 === strcasecmp($resource, $pluginName)) {
       
   341                     unset($this->_pluginResources[$plugin]);
       
   342                     $this->_pluginResources[$pluginName] = $spec;
       
   343                     return $spec;
       
   344                 }
       
   345                 continue;
       
   346             }
       
   347 
       
   348             if (false !== $pluginName = $this->_loadPluginResource($plugin, $spec)) {
       
   349                 if (0 === strcasecmp($resource, $pluginName)) {
       
   350                     return $this->_pluginResources[$pluginName];
       
   351                 }
       
   352                 continue;
       
   353             }
       
   354 
       
   355             if (class_exists($plugin)) { //@SEE ZF-7550
       
   356                 $spec = (array) $spec;
       
   357                 $spec['bootstrap'] = $this;
       
   358                 $instance = new $plugin($spec);
       
   359                 $pluginName = $this->_resolvePluginResourceName($instance);
       
   360                 unset($this->_pluginResources[$plugin]);
       
   361                 $this->_pluginResources[$pluginName] = $instance;
       
   362 
       
   363                 if (0 === strcasecmp($resource, $pluginName)) {
       
   364                     return $instance;
       
   365                 }
       
   366             }
       
   367         }
       
   368 
       
   369         return null;
       
   370     }
       
   371 
       
   372     /**
       
   373      * Retrieve all plugin resources
       
   374      *
       
   375      * @return array
       
   376      */
       
   377     public function getPluginResources()
       
   378     {
       
   379         foreach (array_keys($this->_pluginResources) as $resource) {
       
   380             $this->getPluginResource($resource);
       
   381         }
       
   382         return $this->_pluginResources;
       
   383     }
       
   384 
       
   385     /**
       
   386      * Retrieve plugin resource names
       
   387      *
       
   388      * @return array
       
   389      */
       
   390     public function getPluginResourceNames()
       
   391     {
       
   392         $this->getPluginResources();
       
   393         return array_keys($this->_pluginResources);
       
   394     }
       
   395 
       
   396     /**
       
   397      * Set plugin loader for loading resources
       
   398      *
       
   399      * @param  Zend_Loader_PluginLoader_Interface $loader
       
   400      * @return Zend_Application_Bootstrap_BootstrapAbstract
       
   401      */
       
   402     public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader)
       
   403     {
       
   404         $this->_pluginLoader = $loader;
       
   405         return $this;
       
   406     }
       
   407 
       
   408     /**
       
   409      * Get the plugin loader for resources
       
   410      *
       
   411      * @return Zend_Loader_PluginLoader_Interface
       
   412      */
       
   413     public function getPluginLoader()
       
   414     {
       
   415         if ($this->_pluginLoader === null) {
       
   416             $options = array(
       
   417                 'Zend_Application_Resource' => 'Zend/Application/Resource'
       
   418             );
       
   419 
       
   420             $this->_pluginLoader = new Zend_Loader_PluginLoader($options);
       
   421         }
       
   422 
       
   423         return $this->_pluginLoader;
       
   424     }
       
   425 
       
   426     /**
       
   427      * Set application/parent bootstrap
       
   428      *
       
   429      * @param  Zend_Application|Zend_Application_Bootstrap_Bootstrapper $application
       
   430      * @return Zend_Application_Bootstrap_BootstrapAbstract
       
   431      */
       
   432     public function setApplication($application)
       
   433     {
       
   434         if (($application instanceof Zend_Application)
       
   435             || ($application instanceof Zend_Application_Bootstrap_Bootstrapper)
       
   436         ) {
       
   437             if ($application === $this) {
       
   438                 throw new Zend_Application_Bootstrap_Exception('Cannot set application to same object; creates recursion');
       
   439             }
       
   440             $this->_application = $application;
       
   441         } else {
       
   442             throw new Zend_Application_Bootstrap_Exception('Invalid application provided to bootstrap constructor (received "' . get_class($application) . '" instance)');
       
   443         }
       
   444         return $this;
       
   445     }
       
   446 
       
   447     /**
       
   448      * Retrieve parent application instance
       
   449      *
       
   450      * @return Zend_Application|Zend_Application_Bootstrap_Bootstrapper
       
   451      */
       
   452     public function getApplication()
       
   453     {
       
   454         return $this->_application;
       
   455     }
       
   456 
       
   457     /**
       
   458      * Retrieve application environment
       
   459      *
       
   460      * @return string
       
   461      */
       
   462     public function getEnvironment()
       
   463     {
       
   464         if (null === $this->_environment) {
       
   465             $this->_environment = $this->getApplication()->getEnvironment();
       
   466         }
       
   467         return $this->_environment;
       
   468     }
       
   469 
       
   470     /**
       
   471      * Set resource container
       
   472      *
       
   473      * By default, if a resource callback has a non-null return value, this
       
   474      * value will be stored in a container using the resource name as the
       
   475      * key.
       
   476      *
       
   477      * Containers must be objects, and must allow setting public properties.
       
   478      *
       
   479      * @param  object $container
       
   480      * @return Zend_Application_Bootstrap_BootstrapAbstract
       
   481      */
       
   482     public function setContainer($container)
       
   483     {
       
   484         if (!is_object($container)) {
       
   485             throw new Zend_Application_Bootstrap_Exception('Resource containers must be objects');
       
   486         }
       
   487         $this->_container = $container;
       
   488         return $this;
       
   489     }
       
   490 
       
   491     /**
       
   492      * Retrieve resource container
       
   493      *
       
   494      * @return object
       
   495      */
       
   496     public function getContainer()
       
   497     {
       
   498         if (null === $this->_container) {
       
   499             $this->setContainer(new Zend_Registry());
       
   500         }
       
   501         return $this->_container;
       
   502     }
       
   503 
       
   504     /**
       
   505      * Determine if a resource has been stored in the container
       
   506      *
       
   507      * During bootstrap resource initialization, you may return a value. If
       
   508      * you do, it will be stored in the {@link setContainer() container}.
       
   509      * You can use this method to determine if a value was stored.
       
   510      *
       
   511      * @param  string $name
       
   512      * @return bool
       
   513      */
       
   514     public function hasResource($name)
       
   515     {
       
   516         $resource  = strtolower($name);
       
   517         $container = $this->getContainer();
       
   518         return isset($container->{$resource});
       
   519     }
       
   520 
       
   521     /**
       
   522      * Retrieve a resource from the container
       
   523      *
       
   524      * During bootstrap resource initialization, you may return a value. If
       
   525      * you do, it will be stored in the {@link setContainer() container}.
       
   526      * You can use this method to retrieve that value.
       
   527      *
       
   528      * If no value was returned, this will return a null value.
       
   529      *
       
   530      * @param  string $name
       
   531      * @return null|mixed
       
   532      */
       
   533     public function getResource($name)
       
   534     {
       
   535         $resource  = strtolower($name);
       
   536         $container = $this->getContainer();
       
   537         if ($this->hasResource($resource)) {
       
   538             return $container->{$resource};
       
   539         }
       
   540         return null;
       
   541     }
       
   542 
       
   543     /**
       
   544      * Implement PHP's magic to retrieve a ressource
       
   545      * in the bootstrap
       
   546      *
       
   547      * @param string $prop
       
   548      * @return null|mixed
       
   549      */
       
   550     public function __get($prop)
       
   551     {
       
   552         return $this->getResource($prop);
       
   553     }
       
   554 
       
   555     /**
       
   556      * Implement PHP's magic to ask for the
       
   557      * existence of a ressource in the bootstrap
       
   558      *
       
   559      * @param string $prop
       
   560      * @return bool
       
   561      */
       
   562     public function __isset($prop)
       
   563     {
       
   564         return $this->hasResource($prop);
       
   565     }
       
   566 
       
   567     /**
       
   568      * Bootstrap individual, all, or multiple resources
       
   569      *
       
   570      * Marked as final to prevent issues when subclassing and naming the
       
   571      * child class 'Bootstrap' (in which case, overriding this method
       
   572      * would result in it being treated as a constructor).
       
   573      *
       
   574      * If you need to override this functionality, override the
       
   575      * {@link _bootstrap()} method.
       
   576      *
       
   577      * @param  null|string|array $resource
       
   578      * @return Zend_Application_Bootstrap_BootstrapAbstract
       
   579      * @throws Zend_Application_Bootstrap_Exception When invalid argument was passed
       
   580      */
       
   581     final public function bootstrap($resource = null)
       
   582     {
       
   583         $this->_bootstrap($resource);
       
   584         return $this;
       
   585     }
       
   586 
       
   587     /**
       
   588      * Overloading: intercept calls to bootstrap<resourcename>() methods
       
   589      *
       
   590      * @param  string $method
       
   591      * @param  array  $args
       
   592      * @return void
       
   593      * @throws Zend_Application_Bootstrap_Exception On invalid method name
       
   594      */
       
   595     public function __call($method, $args)
       
   596     {
       
   597         if (9 < strlen($method) && 'bootstrap' === substr($method, 0, 9)) {
       
   598             $resource = substr($method, 9);
       
   599             return $this->bootstrap($resource);
       
   600         }
       
   601 
       
   602         throw new Zend_Application_Bootstrap_Exception('Invalid method "' . $method . '"');
       
   603     }
       
   604 
       
   605     /**
       
   606      * Bootstrap implementation
       
   607      *
       
   608      * This method may be overridden to provide custom bootstrapping logic.
       
   609      * It is the sole method called by {@link bootstrap()}.
       
   610      *
       
   611      * @param  null|string|array $resource
       
   612      * @return void
       
   613      * @throws Zend_Application_Bootstrap_Exception When invalid argument was passed
       
   614      */
       
   615     protected function _bootstrap($resource = null)
       
   616     {
       
   617         if (null === $resource) {
       
   618             foreach ($this->getClassResourceNames() as $resource) {
       
   619                 $this->_executeResource($resource);
       
   620             }
       
   621 
       
   622             foreach ($this->getPluginResourceNames() as $resource) {
       
   623                 $this->_executeResource($resource);
       
   624             }
       
   625         } elseif (is_string($resource)) {
       
   626             $this->_executeResource($resource);
       
   627         } elseif (is_array($resource)) {
       
   628             foreach ($resource as $r) {
       
   629                 $this->_executeResource($r);
       
   630             }
       
   631         } else {
       
   632             throw new Zend_Application_Bootstrap_Exception('Invalid argument passed to ' . __METHOD__);
       
   633         }
       
   634     }
       
   635 
       
   636     /**
       
   637      * Execute a resource
       
   638      *
       
   639      * Checks to see if the resource has already been run. If not, it searches
       
   640      * first to see if a local method matches the resource, and executes that.
       
   641      * If not, it checks to see if a plugin resource matches, and executes that
       
   642      * if found.
       
   643      *
       
   644      * Finally, if not found, it throws an exception.
       
   645      *
       
   646      * @param  string $resource
       
   647      * @return void
       
   648      * @throws Zend_Application_Bootstrap_Exception When resource not found
       
   649      */
       
   650     protected function _executeResource($resource)
       
   651     {
       
   652         $resourceName = strtolower($resource);
       
   653 
       
   654         if (in_array($resourceName, $this->_run)) {
       
   655             return;
       
   656         }
       
   657 
       
   658         if (isset($this->_started[$resourceName]) && $this->_started[$resourceName]) {
       
   659             throw new Zend_Application_Bootstrap_Exception('Circular resource dependency detected');
       
   660         }
       
   661 
       
   662         $classResources = $this->getClassResources();
       
   663         if (array_key_exists($resourceName, $classResources)) {
       
   664             $this->_started[$resourceName] = true;
       
   665             $method = $classResources[$resourceName];
       
   666             $return = $this->$method();
       
   667             unset($this->_started[$resourceName]);
       
   668             $this->_markRun($resourceName);
       
   669 
       
   670             if (null !== $return) {
       
   671                 $this->getContainer()->{$resourceName} = $return;
       
   672             }
       
   673 
       
   674             return;
       
   675         }
       
   676 
       
   677         if ($this->hasPluginResource($resource)) {
       
   678             $this->_started[$resourceName] = true;
       
   679             $plugin = $this->getPluginResource($resource);
       
   680             $return = $plugin->init();
       
   681             unset($this->_started[$resourceName]);
       
   682             $this->_markRun($resourceName);
       
   683 
       
   684             if (null !== $return) {
       
   685                 $this->getContainer()->{$resourceName} = $return;
       
   686             }
       
   687 
       
   688             return;
       
   689         }
       
   690 
       
   691         throw new Zend_Application_Bootstrap_Exception('Resource matching "' . $resource . '" not found');
       
   692     }
       
   693 
       
   694     /**
       
   695      * Load a plugin resource
       
   696      *
       
   697      * @param  string $resource
       
   698      * @param  array|object|null $options
       
   699      * @return string|false
       
   700      */
       
   701     protected function _loadPluginResource($resource, $options)
       
   702     {
       
   703         $options   = (array) $options;
       
   704         $options['bootstrap'] = $this;
       
   705         $className = $this->getPluginLoader()->load(strtolower($resource), false);
       
   706 
       
   707         if (!$className) {
       
   708             return false;
       
   709         }
       
   710 
       
   711         $instance = new $className($options);
       
   712 
       
   713         unset($this->_pluginResources[$resource]);
       
   714 
       
   715         if (isset($instance->_explicitType)) {
       
   716             $resource = $instance->_explicitType;
       
   717         }
       
   718         $resource = strtolower($resource);
       
   719         $this->_pluginResources[$resource] = $instance;
       
   720 
       
   721         return $resource;
       
   722     }
       
   723 
       
   724     /**
       
   725      * Mark a resource as having run
       
   726      *
       
   727      * @param  string $resource
       
   728      * @return void
       
   729      */
       
   730     protected function _markRun($resource)
       
   731     {
       
   732         if (!in_array($resource, $this->_run)) {
       
   733             $this->_run[] = $resource;
       
   734         }
       
   735     }
       
   736 
       
   737     /**
       
   738      * Resolve a plugin resource name
       
   739      *
       
   740      * Uses, in order of preference
       
   741      * - $_explicitType property of resource
       
   742      * - Short name of resource (if a matching prefix path is found)
       
   743      * - class name (if none of the above are true)
       
   744      *
       
   745      * The name is then cast to lowercase.
       
   746      *
       
   747      * @param  Zend_Application_Resource_Resource $resource
       
   748      * @return string
       
   749      */
       
   750     protected function _resolvePluginResourceName($resource)
       
   751     {
       
   752         if (isset($resource->_explicitType)) {
       
   753             $pluginName = $resource->_explicitType;
       
   754         } else  {
       
   755             $className  = get_class($resource);
       
   756             $pluginName = $className;
       
   757             $loader     = $this->getPluginLoader();
       
   758             foreach ($loader->getPaths() as $prefix => $paths) {
       
   759                 if (0 === strpos($className, $prefix)) {
       
   760                     $pluginName = substr($className, strlen($prefix));
       
   761                     $pluginName = trim($pluginName, '_');
       
   762                     break;
       
   763                 }
       
   764             }
       
   765         }
       
   766         $pluginName = strtolower($pluginName);
       
   767         return $pluginName;
       
   768     }
       
   769 }