Преглед изворни кода

[HttpFoundation] added a directory fallback for when the class is not found in registered namespaces and class prefixes

Fabien Potencier пре 14 година
родитељ
комит
24ff22af07

+ 66 - 0
src/Symfony/Component/HttpFoundation/UniversalClassLoader.php

@@ -55,17 +55,69 @@ class UniversalClassLoader
 {
     protected $namespaces = array();
     protected $prefixes = array();
+    protected $namespaceFallback;
+    protected $prefixFallback;
 
+    /**
+     * Gets the configured namespaces.
+     *
+     * @return array A hash with namespaces as keys and directories as values
+     */
     public function getNamespaces()
     {
         return $this->namespaces;
     }
 
+    /**
+     * Gets the configured class prefixes.
+     *
+     * @return array A hash with class prefixes as keys and directories as values
+     */
     public function getPrefixes()
     {
         return $this->prefixes;
     }
 
+    /**
+     * Gets the directory to use as a fallback for namespaces.
+     *
+     * @return string A directory path
+     */
+    public function getNamespaceFallback()
+    {
+        return $this->namespaceFallback;
+    }
+
+    /**
+     * Gets the directory to use as a fallback for class prefixes.
+     *
+     * @return string A directory path
+     */
+    public function getPrefixFallback()
+    {
+        return $this->prefixFallback;
+    }
+
+    /**
+     * Registers the directory to use as a fallback for namespaces.
+     *
+     * @return string $dir A directory path
+     */
+    public function registerNamespaceFallback($dir)
+    {
+        $this->namespaceFallback = $dir;
+    }
+
+    /**
+     * Registers the directory to use as a fallback for class prefixes.
+     *
+     * @param string $dir A directory path
+     */
+    public function registerPrefixFallback($dir)
+    {
+        $this->prefixFallback = $dir;
+    }
+
     /**
      * Registers an array of namespaces
      *
@@ -140,6 +192,13 @@ class UniversalClassLoader
                     }
                 }
             }
+
+            if (null !== $this->namespaceFallback) {
+                $file = $this->namespaceFallback.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
+                if (file_exists($file)) {
+                    require $file;
+                }
+            }
         } else {
             // PEAR-like class name
             foreach ($this->prefixes as $prefix => $dir) {
@@ -151,6 +210,13 @@ class UniversalClassLoader
                     }
                 }
             }
+
+            if (null !== $this->prefixFallback) {
+                $file = $this->prefixFallback.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
+                if (file_exists($file)) {
+                    require $file;
+                }
+            }
         }
     }
 }

+ 3 - 2
tests/Symfony/Tests/Component/HttpFoundation/Fixtures/Namespaced/Bar.php

@@ -2,6 +2,7 @@
 
 namespace Namespaced;
 
-class Bar {
+class Bar
+{
     public static $loaded = true;
-}
+}

+ 8 - 0
tests/Symfony/Tests/Component/HttpFoundation/Fixtures/Namespaced/Baz.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace Namespaced;
+
+class Baz
+{
+    public static $loaded = true;
+}

+ 3 - 2
tests/Symfony/Tests/Component/HttpFoundation/Fixtures/Namespaced/Foo.php

@@ -2,6 +2,7 @@
 
 namespace Namespaced;
 
-class Foo {
+class Foo
+{
     public static $loaded = true;
-}
+}

+ 3 - 2
tests/Symfony/Tests/Component/HttpFoundation/Fixtures/Pearlike/Bar.php

@@ -1,5 +1,6 @@
 <?php
 
-class Pearlike_Bar {
+class Pearlike_Bar
+{
     public static $loaded = true;
-}
+}

+ 6 - 0
tests/Symfony/Tests/Component/HttpFoundation/Fixtures/Pearlike/Baz.php

@@ -0,0 +1,6 @@
+<?php
+
+class Pearlike_Baz
+{
+    public static $loaded = true;
+}

+ 3 - 2
tests/Symfony/Tests/Component/HttpFoundation/Fixtures/Pearlike/Foo.php

@@ -1,5 +1,6 @@
 <?php
 
-class Pearlike_Foo {
+class Pearlike_Foo
+{
     public static $loaded = true;
-}
+}

+ 8 - 0
tests/Symfony/Tests/Component/HttpFoundation/Fixtures/fallback/Namespaced/FooBar.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace Namespaced;
+
+class FooBar
+{
+    public static $loaded = true;
+}

+ 6 - 0
tests/Symfony/Tests/Component/HttpFoundation/Fixtures/fallback/Pearlike/FooBar.php

@@ -0,0 +1,6 @@
+<?php
+
+class Pearlike_FooBar
+{
+    public static $loaded = true;
+}

+ 48 - 25
tests/Symfony/Tests/Component/HttpFoundation/UniversalClassLoaderTest.php

@@ -16,19 +16,18 @@ use Symfony\Component\HttpFoundation\UniversalClassLoader;
 class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @covers Symfony\Component\HttpFoundation\UniversalClassLoader::loadClass
-     * @dataProvider testClassProvider
+     * @dataProvider getLoadClassTests
      */
     public function testLoadClass($className, $testClassName, $message)
     {
         $loader = new UniversalClassLoader();
-        $loader->registerNamespace('Namespaced', __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures');
-        $loader->registerPrefix('Pearlike_', __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures');
+        $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
+        $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
         $loader->loadClass($testClassName);
         $this->assertTrue(class_exists($className), $message);
     }
 
-    public static function testClassProvider()
+    public function getLoadClassTests()
     {
         return array(
             array('\\Namespaced\\Foo', 'Namespaced\\Foo',   '->loadClass() loads Namespaced\Foo class'),
@@ -39,7 +38,31 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @dataProvider namespaceCollisionClassProvider
+     * @dataProvider getLoadClassFromFallbackTests
+     */
+    public function testLoadClassFromFallback($className, $testClassName, $message)
+    {
+        $loader = new UniversalClassLoader();
+        $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
+        $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
+        $loader->registerNamespaceFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback');
+        $loader->registerPrefixFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback');
+        $loader->loadClass($testClassName);
+        $this->assertTrue(class_exists($className), $message);
+    }
+
+    public function getLoadClassFromFallbackTests()
+    {
+        return array(
+            array('\\Namespaced\\Baz',    'Namespaced\\Baz',    '->loadClass() loads Namespaced\Baz class'),
+            array('\\Pearlike_Baz',       'Pearlike_Baz',       '->loadClass() loads Pearlike_Baz class'),
+            array('\\Namespaced\\FooBar', 'Namespaced\\FooBar', '->loadClass() loads Namespaced\Baz class from fallback dir'),
+            array('\\Pearlike_FooBar',    'Pearlike_FooBar',    '->loadClass() loads Pearlike_Baz class from fallback dir'),
+        );
+    }
+
+    /**
+     * @dataProvider getLoadClassNamespaceCollisionTests
      */
     public function testLoadClassNamespaceCollision($namespaces, $className, $message)
     {
@@ -50,37 +73,37 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue(class_exists($className), $message);
     }
 
-    public static function namespaceCollisionClassProvider()
+    public function getLoadClassNamespaceCollisionTests()
     {
         return array(
             array(
                 array(
-                    'NamespaceCollision\\A' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/alpha',
-                    'NamespaceCollision\\A\\B' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/beta',
+                    'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
+                    'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
                 ),
                 'NamespaceCollision\A\Foo',
                 '->loadClass() loads NamespaceCollision\A\Foo from alpha.',
             ),
             array(
                 array(
-                    'NamespaceCollision\\A\\B' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/beta',
-                    'NamespaceCollision\\A' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/alpha',
+                    'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
+                    'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
                 ),
                 'NamespaceCollision\A\Bar',
                 '->loadClass() loads NamespaceCollision\A\Bar from alpha.',
             ),
             array(
                 array(
-                    'NamespaceCollision\\A' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/alpha',
-                    'NamespaceCollision\\A\\B' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/beta',
+                    'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
+                    'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
                 ),
                 'NamespaceCollision\A\B\Foo',
                 '->loadClass() loads NamespaceCollision\A\B\Foo from beta.',
             ),
             array(
                 array(
-                    'NamespaceCollision\\A\\B' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/beta',
-                    'NamespaceCollision\\A' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/alpha',
+                    'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
+                    'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
                 ),
                 'NamespaceCollision\A\B\Bar',
                 '->loadClass() loads NamespaceCollision\A\B\Bar from beta.',
@@ -89,7 +112,7 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @dataProvider prefixCollisionClassProvider
+     * @dataProvider getLoadClassPrefixCollisionTests
      */
     public function testLoadClassPrefixCollision($prefixes, $className, $message)
     {
@@ -100,37 +123,37 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue(class_exists($className), $message);
     }
 
-    public static function prefixCollisionClassProvider()
+    public function getLoadClassPrefixCollisionTests()
     {
         return array(
             array(
                 array(
-                    'PrefixCollision_A_' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/alpha',
-                    'PrefixCollision_A_B_' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/beta',
+                    'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
+                    'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
                 ),
                 'PrefixCollision_A_Foo',
                 '->loadClass() loads PrefixCollision_A_Foo from alpha.',
             ),
             array(
                 array(
-                    'PrefixCollision_A_B_' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/beta',
-                    'PrefixCollision_A_' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/alpha',
+                    'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
+                    'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
                 ),
                 'PrefixCollision_A_Bar',
                 '->loadClass() loads PrefixCollision_A_Bar from alpha.',
             ),
             array(
                 array(
-                    'PrefixCollision_A_' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/alpha',
-                    'PrefixCollision_A_B_' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/beta',
+                    'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
+                    'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
                 ),
                 'PrefixCollision_A_B_Foo',
                 '->loadClass() loads PrefixCollision_A_B_Foo from beta.',
             ),
             array(
                 array(
-                    'PrefixCollision_A_B_' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/beta',
-                    'PrefixCollision_A_' => __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures/alpha',
+                    'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
+                    'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
                 ),
                 'PrefixCollision_A_B_Bar',
                 '->loadClass() loads PrefixCollision_A_B_Bar from beta.',