Browse Source

ZF-11219: Better detection of multi-level namespaces

- Updated autoloader to search for longest matching namespace
- Updated resource autoloader to match full namespace prior to checking against
  components

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@23859 44c647ce-9c0f-0410-b52a-842ac1e357ba
matthew 14 years ago
parent
commit
81ee6036e2

+ 4 - 3
library/Zend/Loader/Autoloader.php

@@ -335,9 +335,10 @@ class Zend_Loader_Autoloader
                 continue;
             }
             if (0 === strpos($class, $ns)) {
-                $namespace   = $ns;
-                $autoloaders = $autoloaders + $this->getNamespaceAutoloaders($ns);
-                break;
+                if ((false === $namespace) || (strlen($ns) > strlen($namespace))) {
+                    $namespace = $ns;
+                    $autoloaders = $this->getNamespaceAutoloaders($ns);
+                }
             }
         }
 

+ 6 - 1
library/Zend/Loader/Autoloader/Resource.php

@@ -145,7 +145,12 @@ class Zend_Loader_Autoloader_Resource implements Zend_Loader_Autoloader_Interfac
         $namespace         = '';
 
         if (!empty($namespaceTopLevel)) {
-            $namespace = array_shift($segments);
+            $namespace = array();
+            $topLevelSegments = count(explode('_', $namespaceTopLevel));
+            for ($i = 0; $i < $topLevelSegments; $i++) {
+                $namespace[] = array_shift($segments);
+            }
+            $namespace = implode('_', $namespace);
             if ($namespace != $namespaceTopLevel) {
                 // wrong prefix? we're done
                 return false;

+ 13 - 1
tests/Zend/Loader/Autoloader/ResourceTest.php

@@ -411,7 +411,7 @@ class Zend_Loader_Autoloader_ResourceTest extends PHPUnit_Framework_TestCase
      * @group ZF-8364
      * @group ZF-6727
      */
-    public function testAuloaderResourceGetClassPathReturnFalse()
+    public function testAutoloaderResourceGetClassPathReturnFalse()
     {
         $this->loader->addResourceTypes(array(
             'model' => array('path' => 'models', 'namespace' => 'Model'),
@@ -454,6 +454,18 @@ class Zend_Loader_Autoloader_ResourceTest extends PHPUnit_Framework_TestCase
         // Check that autoloaders are configured the same
         $this->assertEquals($loader1, $loader2);
     }
+
+    /**
+     * @group ZF-11219
+     */
+    public function testMatchesMultiLevelNamespaces()
+    {
+        $this->loader->setNamespace('Foo_Bar')
+            ->setBasePath(dirname(__FILE__) . '/_files')
+            ->addResourceType('model', 'models', 'Model');
+        $path = $this->loader->getClassPath('Foo_Bar_Model_Baz');
+        $this->assertEquals(dirname(__FILE__) . '/_files/models/Baz.php', $path, var_export($path, 1));
+    }
 }
 
 if (PHPUnit_MAIN_METHOD == 'Zend_Loader_Autoloader_ResourceTest::main') {

+ 32 - 0
tests/Zend/Loader/Autoloader/_files/models/Baz.php

@@ -0,0 +1,32 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Loader
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * @category   Zend
+ * @package    Zend_Loader
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Foo_Bar_Model_Baz
+{
+}

+ 24 - 0
tests/Zend/Loader/AutoloaderTest.php

@@ -391,6 +391,20 @@ class Zend_Loader_AutoloaderTest extends PHPUnit_Framework_TestCase
         $this->assertTrue(Zend_Loader_Autoloader::autoload('AutoloaderTest_AutoloaderClosure'));
     }
 
+    /**
+     * @group ZF-11219
+     */
+    public function testRetrievesAutoloadersFromLongestMatchingNamespace()
+    {
+        $this->autoloader->pushAutoloader(array($this, 'autoloadFirstLevel'), 'Level1_')
+                         ->pushAutoloader(array($this, 'autoloadSecondLevel'), 'Level1_Level2');
+        $class = 'Level1_Level2_Foo';
+        $als   = $this->autoloader->getClassAutoloaders($class);
+        $this->assertEquals(1, count($als));
+        $al    = array_shift($als);
+        $this->assertEquals(array($this, 'autoloadSecondLevel'), $al);
+    }
+
     public function addTestIncludePath()
     {
         set_include_path(dirname(__FILE__) . '/_files/' . PATH_SEPARATOR . $this->includePath);
@@ -405,6 +419,16 @@ class Zend_Loader_AutoloaderTest extends PHPUnit_Framework_TestCase
     {
         return $class;
     }
+
+    public function autoloadFirstLevel($class)
+    {
+        return $class;
+    }
+
+    public function autoloadSecondLevel($class)
+    {
+        return $class;
+    }
 }
 
 function ZendLoaderAutoloader_Autoload($class)