Skip to content
This repository

DCOM-84 - Improve proxy names #83

Merged
merged 3 commits into from over 2 years ago

4 participants

Benjamin Eberlei Lukas Kahwe Smith Christophe Coevoet Johannes
Benjamin Eberlei
Owner

No description provided.

lib/Doctrine/Common/Persistence/Proxy.php
((6 lines not shown))
26 26
  * @author Roman Borschel <roman@code-factory.org>
27 27
  * @since 2.2
28 28
  */
29 29
 interface Proxy
30 30
 {
31 31
     /**
  32
+     * Marker for Proxy class names.
  33
+     *
  34
+     * @var string
  35
+     */
  36
+    const MARKER = '__CG__';
  37
+    /**
1
Christophe Coevoet Collaborator
stof added a note December 12, 2011

missing empty line here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/Common/Util/ClassUtils.php
((86 lines not shown))
  86
+     */
  87
+    public static function newReflectionObject($object)
  88
+    {
  89
+        return self::newReflectionClass( self::getClass( $object ) );
  90
+    }
  91
+
  92
+    /**
  93
+     * Given a class name and a proxy namespace return the proxy name.
  94
+     *
  95
+     * @param string $className
  96
+     * @param string $proxyNamespace
  97
+     * @return string
  98
+     */
  99
+    public static function generateProxyClassName($className, $proxyNamespace)
  100
+    {
  101
+        return rtrim($proxyNamespace, '\\') . '\\__CG__\\' . ltrim($className, '\\');
1
Christophe Coevoet Collaborator
stof added a note December 12, 2011

shouldn't it use Proxy::MARKER here ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/Common/Util/ClassUtils.php
((30 lines not shown))
  30
+ */
  31
+class ClassUtils
  32
+{
  33
+    /**
  34
+     * Get the real class name of a class name that could be a proxy.
  35
+     *
  36
+     * @param string
  37
+     * @return string
  38
+     */
  39
+    public static function getRealClass($class)
  40
+    {
  41
+        if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) {
  42
+            return $class;
  43
+        }
  44
+
  45
+        return substr($class, $pos + strlen(Proxy::MARKER) + 2);
1
Johannes Collaborator

Maybe add a constant for the length? PHP doesn't optimize this AFAIK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Lukas Kahwe Smith lsmith77 commented on the diff December 12, 2011
lib/Doctrine/Common/Persistence/Proxy.php
((24 lines not shown))
36 42
      * @return void
37 43
      */
38 44
     public function __load();
  45
+
  46
+    /**
  47
+     * Is this proxy initialized or not.
  48
+     *
  49
+     * @return bool
  50
+     */
  51
+    public function __isInitialized();
2
Lukas Kahwe Smith Collaborator

do you guys include public in interfaces?

Benjamin Eberlei Owner

i don't think about that stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Lukas Kahwe Smith
Collaborator

i wonder if an isProxy method like i added in https://github.com/doctrine/common/pull/82/files#L1R56 would be useful to have in ClassUtils?

Christophe Coevoet
Collaborator

@lsmith77 instanceof Proxy ?

Benjamin Eberlei beberlei merged commit 97d9ef4 into from December 12, 2011
Benjamin Eberlei beberlei closed this December 12, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
27  lib/Doctrine/Common/Persistence/Proxy.php
@@ -22,18 +22,39 @@
22 22
 
23 23
 /**
24 24
  * Interface for proxy classes.
25  
- * 
  25
+ *
26 26
  * @author Roman Borschel <roman@code-factory.org>
27 27
  * @since 2.2
28 28
  */
29 29
 interface Proxy
30 30
 {
31 31
     /**
  32
+     * Marker for Proxy class names.
  33
+     *
  34
+     * @var string
  35
+     */
  36
+    const MARKER = '__CG__';
  37
+
  38
+    /**
  39
+     * Length of the proxy marker
  40
+     *
  41
+     * @var int
  42
+     */
  43
+    const MARKER_LENGTH = 6;
  44
+
  45
+    /**
32 46
      * Initialize this proxy if its not yet initialized.
33  
-     * 
  47
+     *
34 48
      * Acts as a no-op if already initialized.
35  
-     * 
  49
+     *
36 50
      * @return void
37 51
      */
38 52
     public function __load();
  53
+
  54
+    /**
  55
+     * Is this proxy initialized or not.
  56
+     *
  57
+     * @return bool
  58
+     */
  59
+    public function __isInitialized();
39 60
 }
103  lib/Doctrine/Common/Util/ClassUtils.php
... ...
@@ -0,0 +1,103 @@
  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\Common\Util;
  21
+
  22
+use Doctrine\Common\Persistence\Proxy;
  23
+
  24
+/**
  25
+ * Class and reflection related functionality for objects that
  26
+ * might or not be proxy objects at the moment.
  27
+ *
  28
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
  29
+ * @author Johannes Schmitt <schmittjoh@gmail.com>
  30
+ */
  31
+class ClassUtils
  32
+{
  33
+    /**
  34
+     * Get the real class name of a class name that could be a proxy.
  35
+     *
  36
+     * @param string
  37
+     * @return string
  38
+     */
  39
+    public static function getRealClass($class)
  40
+    {
  41
+        if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) {
  42
+            return $class;
  43
+        }
  44
+
  45
+        return substr($class, $pos + Proxy::MARKER_LENGTH + 2);
  46
+    }
  47
+
  48
+    /**
  49
+     * Get the real class name of an object (even if its a proxy)
  50
+     *
  51
+     * @param object
  52
+     * @return string
  53
+     */
  54
+    public static function getClass($object)
  55
+    {
  56
+        return self::getRealClass(get_class($object));
  57
+    }
  58
+
  59
+    /**
  60
+     * Get the real parent class name of a class or object
  61
+     *
  62
+     * @param string
  63
+     * @return string
  64
+     */
  65
+    public static function getParentClass($className)
  66
+    {
  67
+        return get_parent_class( self::getRealClass( $className ) );
  68
+    }
  69
+
  70
+    /**
  71
+     * Create a new reflection class
  72
+     *
  73
+     * @param string
  74
+     * @return ReflectionClass
  75
+     */
  76
+    public static function newReflectionClass($class)
  77
+    {
  78
+        return new \ReflectionClass( self::getRealClass( $class ) );
  79
+    }
  80
+
  81
+    /**
  82
+     * Create a new reflection object
  83
+     *
  84
+     * @param object
  85
+     * @return ReflectionObject
  86
+     */
  87
+    public static function newReflectionObject($object)
  88
+    {
  89
+        return self::newReflectionClass( self::getClass( $object ) );
  90
+    }
  91
+
  92
+    /**
  93
+     * Given a class name and a proxy namespace return the proxy name.
  94
+     *
  95
+     * @param string $className
  96
+     * @param string $proxyNamespace
  97
+     * @return string
  98
+     */
  99
+    public static function generateProxyClassName($className, $proxyNamespace)
  100
+    {
  101
+        return rtrim($proxyNamespace, '\\') . '\\'.Proxy::MARKER.'\\' . ltrim($className, '\\');
  102
+    }
  103
+}
64  lib/Doctrine/Common/Util/Debug.php
... ...
@@ -1,7 +1,5 @@
1 1
 <?php
2 2
 /*
3  
- *  $Id$
4  
- *
5 3
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6 4
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7 5
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -27,7 +25,6 @@
27 25
  * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
28 26
  * @link    www.doctrine-project.org
29 27
  * @since   2.0
30  
- * @version $Revision: 3938 $
31 28
  * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
32 29
  * @author  Jonathan Wage <jonwage@gmail.com>
33 30
  * @author  Roman Borschel <roman@code-factory.org>
@@ -53,80 +50,69 @@ private function __construct() {}
53 50
     public static function dump($var, $maxDepth = 2, $stripTags = true)
54 51
     {
55 52
         ini_set('html_errors', 'On');
56  
-        
  53
+
57 54
         if (extension_loaded('xdebug')) {
58 55
             ini_set('xdebug.var_display_max_depth', $maxDepth);
59 56
         }
60  
-        
  57
+
61 58
         $var = self::export($var, $maxDepth++);
62  
-        
  59
+
63 60
         ob_start();
64 61
         var_dump($var);
65 62
         $dump = ob_get_contents();
66 63
         ob_end_clean();
67  
-        
  64
+
68 65
         echo ($stripTags ? strip_tags(html_entity_decode($dump)) : $dump);
69  
-        
  66
+
70 67
         ini_set('html_errors', 'Off');
71 68
     }
72  
-    
  69
+
73 70
     public static function export($var, $maxDepth)
74 71
     {
75 72
         $return = null;
76 73
         $isObj = is_object($var);
77  
-    
  74
+
78 75
         if ($isObj && in_array('Doctrine\Common\Collections\Collection', class_implements($var))) {
79 76
             $var = $var->toArray();
80 77
         }
81  
-        
  78
+
82 79
         if ($maxDepth) {
83 80
             if (is_array($var)) {
84 81
                 $return = array();
85  
-            
  82
+
86 83
                 foreach ($var as $k => $v) {
87 84
                     $return[$k] = self::export($v, $maxDepth - 1);
88 85
                 }
89 86
             } else if ($isObj) {
  87
+                $return = new \stdclass();
90 88
                 if ($var instanceof \DateTime) {
91  
-                    $return = $var->format('c');
  89
+                    $return->__CLASS__ = "DateTime";
  90
+                    $return->date = $var->format('c');
  91
+                    $return->timezone = $var->getTimeZone()->getName();
92 92
                 } else {
93  
-                    $reflClass = new \ReflectionClass(get_class($var));
94  
-                    $return = new \stdclass();
95  
-                    $return->{'__CLASS__'} = get_class($var);
96  
-
97  
-                    if ($var instanceof \Doctrine\ORM\Proxy\Proxy && ! $var->__isInitialized__) {
98  
-                        $reflProperty = $reflClass->getProperty('_identifier');
99  
-                        $reflProperty->setAccessible(true);
100  
-
101  
-                        foreach ($reflProperty->getValue($var) as $name => $value) {
102  
-                            $return->$name = self::export($value, $maxDepth - 1);
103  
-                        }
104  
-                    } else {
105  
-                        $excludeProperties = array();
  93
+                    $reflClass = ClassUtils::newReflectionObject($var);
  94
+                    $return->__CLASS__ = ClassUtils::getClass($var);
106 95
 
107  
-                        if ($var instanceof \Doctrine\ORM\Proxy\Proxy) {
108  
-                            $excludeProperties = array('_entityPersister', '__isInitialized__', '_identifier');
109  
-                        }
110  
-
111  
-                        foreach ($reflClass->getProperties() as $reflProperty) {
112  
-                            $name  = $reflProperty->getName();
  96
+                    if ($var instanceof \Doctrine\Common\Persistence\Proxy) {
  97
+                        $return->__IS_PROXY__ = true;
  98
+                        $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
  99
+                    }
113 100
 
114  
-                            if ( ! in_array($name, $excludeProperties)) {
115  
-                                $reflProperty->setAccessible(true);
  101
+                    foreach ($reflClass->getProperties() as $reflProperty) {
  102
+                        $name  = $reflProperty->getName();
116 103
 
117  
-                                $return->$name = self::export($reflProperty->getValue($var), $maxDepth - 1);
118  
-                            }
119  
-                        }
  104
+                        $reflProperty->setAccessible(true);
  105
+                        $return->$name = self::export($reflProperty->getValue($var), $maxDepth - 1);
120 106
                     }
121 107
                 }
122 108
             } else {
123 109
                 $return = $var;
124 110
             }
125 111
         } else {
126  
-            $return = is_object($var) ? get_class($var) 
  112
+            $return = is_object($var) ? get_class($var)
127 113
                 : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
128 114
         }
129  
-        
  115
+
130 116
         return $return;
131 117
     }
132 118
 
100  tests/Doctrine/Tests/Common/Util/ClassUtilsTest.php
... ...
@@ -0,0 +1,100 @@
  1
+<?php
  2
+
  3
+namespace Doctrine\Tests\Common\Util
  4
+{
  5
+    use Doctrine\Tests\DoctrineTestCase;
  6
+    use Doctrine\Common\Util\ClassUtils;
  7
+
  8
+    class ClassUtilsTest extends DoctrineTestCase
  9
+    {
  10
+        static public function dataGetClass()
  11
+        {
  12
+            return array(
  13
+                array('stdClass', 'stdClass'),
  14
+                array('Doctrine\Common\Util\ClassUtils', 'Doctrine\Common\Util\ClassUtils'),
  15
+                array( 'MyProject\Proxies\__CG__\stdClass', 'stdClass' ),
  16
+                array( 'MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\stdClass', 'stdClass' ),
  17
+                array( 'MyProject\Proxies\__CG__\Doctrine\Tests\Common\Util\ChildObject','Doctrine\Tests\Common\Util\ChildObject' )
  18
+            );
  19
+        }
  20
+
  21
+        /**
  22
+         * @dataProvider dataGetClass
  23
+         */
  24
+        public function testGetRealClass($className, $expectedClassName)
  25
+        {
  26
+            $this->assertEquals($expectedClassName, ClassUtils::getRealClass($className));
  27
+        }
  28
+
  29
+        /**
  30
+         * @dataProvider dataGetClass
  31
+         */
  32
+        public function testGetClass( $className, $expectedClassName )
  33
+        {
  34
+            $object = new $className();
  35
+            $this->assertEquals($expectedClassName, ClassUtils::getClass($object));
  36
+        }
  37
+
  38
+        public function testGetParentClass()
  39
+        {
  40
+            $parentClass = ClassUtils::getParentClass( 'MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\Doctrine\Tests\Common\Util\ChildObject' );
  41
+            $this->assertEquals('stdClass', $parentClass);
  42
+        }
  43
+
  44
+        public function testGenerateProxyClassName()
  45
+        {
  46
+            $this->assertEquals( 'Proxies\__CG__\stdClass', ClassUtils::generateProxyClassName( 'stdClass', 'Proxies' ) );
  47
+        }
  48
+
  49
+        /**
  50
+         * @dataProvider dataGetClass
  51
+         */
  52
+        public function testNewReflectionClass( $className, $expectedClassName )
  53
+        {
  54
+            $reflClass = ClassUtils::newReflectionClass( $className );
  55
+            $this->assertEquals( $expectedClassName, $reflClass->getName() );
  56
+        }
  57
+
  58
+        /**
  59
+         * @dataProvider dataGetClass
  60
+         */
  61
+        public function testNewReflectionObject( $className, $expectedClassName )
  62
+        {
  63
+            $object = new $className;
  64
+            $reflClass = ClassUtils::newReflectionObject( $object );
  65
+            $this->assertEquals( $expectedClassName, $reflClass->getName() );
  66
+        }
  67
+    }
  68
+
  69
+    class ChildObject extends \stdClass
  70
+    {
  71
+    }
  72
+}
  73
+
  74
+namespace MyProject\Proxies\__CG__
  75
+{
  76
+    class stdClass extends \stdClass
  77
+    {
  78
+    }
  79
+}
  80
+
  81
+namespace MyProject\Proxies\__CG__\Doctrine\Tests\Common\Util
  82
+{
  83
+    class ChildObject extends \Doctrine\Tests\Common\Util\ChildObject
  84
+    {
  85
+    }
  86
+}
  87
+
  88
+namespace MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__
  89
+{
  90
+    class stdClass extends \MyProject\Proxies\__CG__\stdClass
  91
+    {
  92
+    }
  93
+}
  94
+
  95
+namespace MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\Doctrine\Tests\Common\Util
  96
+{
  97
+    class ChildObject extends \MyProject\Proxies\__CG__\Doctrine\Tests\Common\Util\ChildObject
  98
+    {
  99
+    }
  100
+}
27  tests/Doctrine/Tests/Common/Util/DebugTest.php
... ...
@@ -0,0 +1,27 @@
  1
+<?php
  2
+
  3
+namespace Doctrine\Tests\Common\Util;
  4
+
  5
+use Doctrine\Tests\DoctrineTestCase;
  6
+use Doctrine\Common\Util\Debug;
  7
+
  8
+class DebugTest extends DoctrineTestCase
  9
+{
  10
+    public function testExportObject( )
  11
+    {
  12
+        $obj = new \stdClass;
  13
+        $obj->foo = "bar";
  14
+        $obj->bar = 1234;
  15
+
  16
+        $var = Debug::export($obj, 2);
  17
+        $this->assertEquals( "stdClass", $var->__CLASS__ );
  18
+    }
  19
+
  20
+    public function testExportDateTime()
  21
+    {
  22
+        $obj = new \DateTime( "2010-10-10 10:10:10" );
  23
+
  24
+        $var = Debug::export( $obj, 2 );
  25
+        $this->assertEquals( "DateTime", $var->__CLASS__ );
  26
+    }
  27
+}
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.