Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[DDC-1698] Add autoloader especially for the non PSR-0 Proxy class na…

…mes. This is necessary when you want to deserialize your proxy classes from the session.
  • Loading branch information...
commit 9b4d60897dfc7e9b165712428539e694ec596c80 1 parent c6ef7a7
Benjamin Eberlei authored March 14, 2012
78  lib/Doctrine/ORM/Proxy/Autoloader.php
... ...
@@ -0,0 +1,78 @@
  1
+<?php
  2
+/*
  3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14
+ *
  15
+ * This software consists of voluntary contributions made by many individuals
  16
+ * and is licensed under the LGPL. For more information, see
  17
+ * <http://www.doctrine-project.org>.
  18
+ */
  19
+
  20
+namespace Doctrine\ORM\Proxy;
  21
+
  22
+/**
  23
+ * Special Autoloader for Proxy classes because them not being PSR-0 compatible.
  24
+ *
  25
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
  26
+ */
  27
+class Autoloader
  28
+{
  29
+    /**
  30
+     * Resolve proxy class name to a filename based on the following pattern.
  31
+     *
  32
+     * 1. Remove Proxy namespace from class name
  33
+     * 2. Remove namespace seperators from remaining class name.
  34
+     * 3. Return PHP filename from proxy-dir with the result from 2.
  35
+     *
  36
+     * @param string $proxyDir
  37
+     * @param string $proxyNamespace
  38
+     * @param string $className
  39
+     * @return string
  40
+     */
  41
+    static public function resolveFile($proxyDir, $proxyNamespace, $className)
  42
+    {
  43
+        if (0 !== strpos($className, $proxyNamespace)) {
  44
+            throw ProxyException::notProxyClass($className, $proxyNamespace);
  45
+        }
  46
+
  47
+        $className = str_replace('\\', '', substr($className, strlen($proxyNamespace) +1));
  48
+        return $proxyDir . DIRECTORY_SEPARATOR . $className.'.php';
  49
+    }
  50
+
  51
+    /**
  52
+     * Register and return autoloader callback for the given proxy dir and
  53
+     * namespace.
  54
+     *
  55
+     * @param string $proxyDir
  56
+     * @param string $proxyNamespace
  57
+     * @param Closure $notFoundCallback Invoked when the proxy file is not found.
  58
+     * @return Closure
  59
+     */
  60
+    static public function register($proxyDir, $proxyNamespace, \Closure $notFoundCallback = null)
  61
+    {
  62
+        $proxyNamespace = ltrim($proxyNamespace, "\\");
  63
+        $autoloader = function($className) use ($proxyDir, $proxyNamespace, $notFoundCallback) {
  64
+            if (0 === strpos($className, $proxyNamespace)) {
  65
+                $file = Autoloader::resolveFile($proxyDir, $proxyNamespace, $className);
  66
+
  67
+                if ($notFoundCallback && ! file_exists($file)) {
  68
+                    $notFoundCallback($proxyDir, $proxyNamespace, $className);
  69
+                }
  70
+
  71
+                require $file;
  72
+            }
  73
+        };
  74
+        spl_autoload_register($autoloader);
  75
+        return $autoloader;
  76
+    }
  77
+}
  78
+
10  lib/Doctrine/ORM/Proxy/ProxyException.php
@@ -44,4 +44,12 @@ public static function proxyNamespaceRequired() {
44 44
         return new self("You must configure a proxy namespace. See docs for details");
45 45
     }
46 46
 
47  
-}
  47
+    public static function notProxyClass($className, $proxyNamespace)
  48
+    {
  49
+        return new self(sprintf(
  50
+            "The class %s is not part of the proxy namespace %s",
  51
+            $className, $proxyNamespace
  52
+        ));
  53
+    }
  54
+
  55
+}
62  tests/Doctrine/Tests/ORM/Proxy/AutoloaderTest.php
... ...
@@ -0,0 +1,62 @@
  1
+<?php
  2
+/*
  3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14
+ *
  15
+ * This software consists of voluntary contributions made by many individuals
  16
+ * and is licensed under the LGPL. For more information, see
  17
+ * <http://www.doctrine-project.org>.
  18
+ */
  19
+
  20
+namespace Doctrine\Tests\ORM\Proxy;
  21
+
  22
+use Doctrine\Tests\OrmTestCase;
  23
+use Doctrine\ORM\Proxy\Autoloader;
  24
+
  25
+/**
  26
+ * @group DDC-1698
  27
+ */
  28
+class AutoloaderTest extends OrmTestCase
  29
+{
  30
+    static public function dataResolveFile()
  31
+    {
  32
+        return array(
  33
+            array('/tmp', 'MyProxy', 'MyProxy\__CG__\RealClass', '/tmp/__CG__RealClass.php'),
  34
+            array('/tmp', 'MyProxy\Subdir', 'MyProxy\Subdir\__CG__\RealClass', '/tmp/__CG__RealClass.php'),
  35
+            array('/tmp', 'MyProxy', 'MyProxy\__CG__\Other\RealClass', '/tmp/__CG__OtherRealClass.php'),
  36
+        );
  37
+    }
  38
+
  39
+    /**
  40
+     * @dataProvider dataResolveFile
  41
+     */
  42
+    public function testResolveFile($proxyDir, $proxyNamespace, $className, $expectedProxyFile)
  43
+    {
  44
+        $actualProxyFile = Autoloader::resolveFile($proxyDir, $proxyNamespace, $className);
  45
+        $this->assertEquals($expectedProxyFile, $actualProxyFile);
  46
+    }
  47
+
  48
+    public function testAutoload()
  49
+    {
  50
+        if (file_exists(sys_get_temp_dir() ."/AutoloaderTestClass.php")) {
  51
+            unlink(sys_get_temp_dir() ."/AutoloaderTestClass.php");
  52
+        }
  53
+
  54
+        $autoloader = Autoloader::register(sys_get_temp_dir(), 'ProxyAutoloaderTest', function($proxyDir, $proxyNamespace, $className) {
  55
+            file_put_contents(sys_get_temp_dir() . "/AutoloaderTestClass.php", "<?php namespace ProxyAutoloaderTest; class AutoloaderTestClass {} ");
  56
+        });
  57
+
  58
+        $this->assertTrue(class_exists('ProxyAutoloaderTest\AutoloaderTestClass', true));
  59
+        unlink(sys_get_temp_dir() ."/AutoloaderTestClass.php");
  60
+    }
  61
+}
  62
+

0 notes on commit 9b4d608

Please sign in to comment.
Something went wrong with that request. Please try again.