Browse Source

ZF-6543, ZF-6591: Fixed emission of all notices and resolved recursive dependency issues

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@15550 44c647ce-9c0f-0410-b52a-842ac1e357ba
matthew 16 năm trước cách đây
mục cha
commit
eb1cfecd9b

+ 1 - 1
library/Zend/Application.php

@@ -263,7 +263,7 @@ class Zend_Application
             $class = 'Bootstrap';
         }
 
-        if (!class_exists($class)) {
+        if (!class_exists($class, false)) {
             require_once $path;
         }
         $this->_bootstrap = new $class($this);

+ 111 - 37
library/Zend/Application/Bootstrap/BootstrapAbstract.php

@@ -226,29 +226,16 @@ abstract class Zend_Application_Bootstrap_BootstrapAbstract
      */
     public function registerPluginResource($resource, $options = null)
     {
+        /*
         if (is_string($resource) && class_exists($resource)) {
             $options = (array) $options;
             $options['bootstrap'] = $this;
             $resource = new $resource($options);
         }
+         */
         if ($resource instanceof Zend_Application_Resource_Resource) {
             $resource->setBootstrap($this);
-
-            $vars = get_object_vars($resource);
-            if (isset($vars['_explicitType'])) {
-                $pluginName = strtolower($vars['_explicitType']);
-            } else  {
-                $className  = get_class($resource);
-                $pluginName = strtolower($className);
-                $loader     = $this->getPluginLoader();
-                foreach ($loader->getPaths() as $prefix => $paths) {
-                    if (0 === strpos($className, $prefix)) {
-                        $pluginName = substr($className, strlen($prefix));
-                        $pluginName = strtolower(trim($pluginName, '_'));
-                    }
-                }
-            }
-
+            $pluginName = $this->_resolvePluginResourceName($resource);
             $this->_pluginResources[$pluginName] = $resource;
             return $this;
         }
@@ -257,7 +244,7 @@ abstract class Zend_Application_Bootstrap_BootstrapAbstract
             throw new Zend_Application_Bootstrap_Exception('Invalid resource provided to ' . __METHOD__);
         }
 
-        $resource = strtolower($resource);
+        // $resource = strtolower($resource);
         $this->_pluginResources[$resource] = $options;
         return $this;
     }
@@ -298,8 +285,7 @@ abstract class Zend_Application_Bootstrap_BootstrapAbstract
      */
     public function hasPluginResource($resource)
     {
-        $resource = strtolower($resource);
-        return array_key_exists($resource, $this->_pluginResources);
+        return (null !== $this->getPluginResource($resource));
     }
     
     /**
@@ -310,23 +296,51 @@ abstract class Zend_Application_Bootstrap_BootstrapAbstract
      */
     public function getPluginResource($resource)
     {
-        $resource = strtolower($resource);
-        
-        if (!array_key_exists($resource, $this->_pluginResources)) {
-            return null;            
+        if (array_key_exists(strtolower($resource), $this->_pluginResources)) {
+            $resource = strtolower($resource);
+            if (!$this->_pluginResources[$resource] instanceof Zend_Application_Resource_Resource) {
+                $resourceName = $this->_loadPluginResource($resource, $this->_pluginResources[$resource]);
+                if (!$resourceName) {
+                    throw new Zend_Application_Bootstrap_Exception(sprintf('Unable to resolve plugin "%s"; no corresponding plugin with that name', $resource));
+                }
+                $resource = $resourceName;
+            }
+            return $this->_pluginResources[$resource];
         }
 
-        if (!$this->_pluginResources[$resource] instanceof Zend_Application_Resource_Resource) {
-            $options   = (array) $this->_pluginResources[$resource];
-            $options['bootstrap'] = $this;
-            $className = $this->getPluginLoader()->load($resource);
-            $this->_pluginResources[$resource] = new $className($options);
+        foreach ($this->_pluginResources as $plugin => $spec) {
+            if ($spec instanceof Zend_Application_Resource_Resource) {
+                $pluginName = $this->_resolvePluginResourceName($spec);
+                if (0 === strcasecmp($resource, $pluginName)) {
+                    unset($this->_pluginResources[$plugin]);
+                    $this->_pluginResources[$pluginName] = $spec;
+                    return $spec;
+                }
+                continue;
+            }
+
+
+            if (false !== $pluginName = $this->_loadPluginResource($plugin, $spec)) {
+                if (0 === strcasecmp($resource, $pluginName)) {
+                    return $this->_pluginResources[$pluginName];
+                }
+            }
+
+            if (class_exists($plugin)) {
+                $spec = (array) $spec;
+                $spec['bootstrap'] = $this;
+                $instance = new $plugin($spec);
+                $pluginName = $this->_resolvePluginResourceName($instance);
+                unset($this->_pluginResources[$plugin]);
+                $this->_pluginResources[$pluginName] = $instance;
+
+                if (0 === strcasecmp($resource, $pluginName)) {
+                    return $instance;
+                }
+            }
         }
 
-        $plugin = $this->_pluginResources[$resource];
-        $plugin->setBootstrap($this);
-        
-        return $plugin;
+        return null;            
     }
 
     /**
@@ -336,13 +350,10 @@ abstract class Zend_Application_Bootstrap_BootstrapAbstract
      */
     public function getPluginResources()
     {
-        $resources = array();
-        
         foreach (array_keys($this->_pluginResources) as $resource) {
-            $resources[$resource] = $this->getPluginResource($resource);
+            $this->getPluginResource($resource);
         }
-        
-        return $resources;
+        return $this->_pluginResources;
     }
 
     /**
@@ -352,6 +363,7 @@ abstract class Zend_Application_Bootstrap_BootstrapAbstract
      */
     public function getPluginResourceNames()
     {
+        $this->getPluginResources();
         return array_keys($this->_pluginResources);
     }
 
@@ -627,6 +639,36 @@ abstract class Zend_Application_Bootstrap_BootstrapAbstract
     }
 
     /**
+     * Load a plugin resource
+     * 
+     * @param  string $resource 
+     * @param  array|object|null $options 
+     * @return string|false
+     */
+    protected function _loadPluginResource($resource, $options)
+    {
+        $options   = (array) $options;
+        $options['bootstrap'] = $this;
+        $className = $this->getPluginLoader()->load(strtolower($resource), false);
+
+        if (!$className) {
+            return false;
+        }
+
+        $instance = new $className($options);
+
+        unset($this->_pluginResources[$resource]);
+
+        if (isset($instance->_explicitType)) {
+            $resource = $instance->_explicitType;
+        }
+        $resource = strtolower($resource);
+        $this->_pluginResources[$resource] = $instance;
+
+        return $resource;
+    }
+
+    /**
      * Mark a resource as having run
      * 
      * @param  string $resource 
@@ -638,4 +680,36 @@ abstract class Zend_Application_Bootstrap_BootstrapAbstract
             $this->_run[] = $resource;
         }
     }
+
+    /**
+     * Resolve a plugin resource name
+     *
+     * Uses, in order of preference
+     * - $_explicitType property of resource
+     * - Short name of resource (if a matching prefix path is found)
+     * - class name (if none of the above are true)
+     *
+     * The name is then cast to lowercase.
+     * 
+     * @param  Zend_Application_Resource_Resource $resource 
+     * @return string
+     */
+    protected function _resolvePluginResourceName($resource)
+    {
+        if (isset($resource->_explicitType)) {
+            $pluginName = $resource->_explicitType;
+        } else  {
+            $className  = get_class($resource);
+            $pluginName = $className;
+            $loader     = $this->getPluginLoader();
+            foreach ($loader->getPaths() as $prefix => $paths) {
+                if (0 === strpos($className, $prefix)) {
+                    $pluginName = substr($className, strlen($prefix));
+                    $pluginName = trim($pluginName, '_');
+                }
+            }
+        }
+        $pluginName = strtolower($pluginName);
+        return $pluginName;
+    }
 }

+ 9 - 2
library/Zend/Loader/PluginLoader.php

@@ -336,10 +336,13 @@ class Zend_Loader_PluginLoader implements Zend_Loader_PluginLoader_Interface
      * Load a plugin via the name provided
      *
      * @param  string $name
-     * @return string Class name of loaded class
+     * @param  bool $throwExceptions Whether or not to throw exceptions if the 
+     * class is not resolved
+     * @return string|false Class name of loaded class; false if $throwExceptions 
+     * if false and no class found
      * @throws Zend_Loader_Exception if class not found
      */
-    public function load($name)
+    public function load($name, $throwExceptions = true)
     {
         $name = $this->_formatName($name);
         if ($this->isLoaded($name)) {
@@ -382,6 +385,10 @@ class Zend_Loader_PluginLoader implements Zend_Loader_PluginLoader_Interface
         }
 
         if (!$found) {
+            if (!$throwExceptions) {
+                return false;
+            }
+
             $message = "Plugin by name '$name' was not found in the registry; used paths:";
             foreach ($registry as $prefix => $paths) {
                 $message .= "\n$prefix: " . implode(PATH_SEPARATOR, $paths);

+ 22 - 3
tests/Zend/Application/Bootstrap/BootstrapAbstractTest.php

@@ -600,11 +600,11 @@ class Zend_Application_Bootstrap_BootstrapAbstractTest extends PHPUnit_Framework
                 'Zend_Application_Bootstrap_BootstrapAbstractTest' => dirname(__FILE__),
             ),
             'resources' => array(
-                'Layout' => array(),
+                'Foo' => array(),
             ),
         ));
         $bootstrap = new Zend_Application_Bootstrap_Bootstrap($this->application);
-        $resource = $bootstrap->getPluginResource('layout');
+        $resource = $bootstrap->getPluginResource('foo');
         $this->assertTrue($resource->bootstrapSetInConstructor, var_export(get_object_vars($resource), 1));
     }
 
@@ -624,7 +624,7 @@ class Zend_Application_Bootstrap_BootstrapAbstractTest extends PHPUnit_Framework
         $bootstrap = new Zend_Application_Bootstrap_Bootstrap($this->application);
         $resource = $bootstrap->getPluginResource('FrontController');
         restore_error_handler();
-        $this->assertTrue(false !== $this->error);
+        $this->assertTrue(false === $this->error, $this->error);
     }
 }
 
@@ -657,6 +657,25 @@ class Zend_Application_Bootstrap_BootstrapAbstractTest_Layout
     }
 }
 
+class Zend_Application_Bootstrap_BootstrapAbstractTest_Foo
+    extends Zend_Application_Resource_ResourceAbstract
+{
+    public $bootstrapSetInConstructor = false;
+
+    public function __construct($options = null)
+    {
+        parent::__construct($options);
+        if (null !== $this->getBootstrap()) {
+            $this->bootstrapSetInConstructor = true;
+        }
+    }
+
+    public function init()
+    {
+        return $this;
+    }
+}
+
 if (PHPUnit_MAIN_METHOD == 'Zend_Application_Bootstrap_BootstrapAbstractTest::main') {
     Zend_Application_Bootstrap_BootstrapAbstractTest::main();
 }