Skip to content

Loading…

DCOM-84 - Improve proxy names #83

Merged
merged 3 commits into from

4 participants

@beberlei
Doctrine member

No description provided.

@stof stof commented on an outdated diff
lib/Doctrine/Common/Persistence/Proxy.php
((6 lines not shown))
* @author Roman Borschel <roman@code-factory.org>
* @since 2.2
*/
interface Proxy
{
/**
+ * Marker for Proxy class names.
+ *
+ * @var string
+ */
+ const MARKER = '__CG__';
+ /**
@stof Doctrine member
stof added a note

missing empty line here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@stof stof commented on an outdated diff
lib/Doctrine/Common/Util/ClassUtils.php
((86 lines not shown))
+ */
+ public static function newReflectionObject($object)
+ {
+ return self::newReflectionClass( self::getClass( $object ) );
+ }
+
+ /**
+ * Given a class name and a proxy namespace return the proxy name.
+ *
+ * @param string $className
+ * @param string $proxyNamespace
+ * @return string
+ */
+ public static function generateProxyClassName($className, $proxyNamespace)
+ {
+ return rtrim($proxyNamespace, '\\') . '\\__CG__\\' . ltrim($className, '\\');
@stof Doctrine member
stof added a note

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
@schmittjoh schmittjoh commented on an outdated diff
lib/Doctrine/Common/Util/ClassUtils.php
((30 lines not shown))
+ */
+class ClassUtils
+{
+ /**
+ * Get the real class name of a class name that could be a proxy.
+ *
+ * @param string
+ * @return string
+ */
+ public static function getRealClass($class)
+ {
+ if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) {
+ return $class;
+ }
+
+ return substr($class, $pos + strlen(Proxy::MARKER) + 2);
@schmittjoh Doctrine member

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
@lsmith77 lsmith77 commented on the diff
lib/Doctrine/Common/Persistence/Proxy.php
((24 lines not shown))
* @return void
*/
public function __load();
+
+ /**
+ * Is this proxy initialized or not.
+ *
+ * @return bool
+ */
+ public function __isInitialized();
@lsmith77 Doctrine member

do you guys include public in interfaces?

@beberlei Doctrine member

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
@lsmith77
Doctrine member

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?

@stof
Doctrine member

@lsmith77 instanceof Proxy ?

@beberlei beberlei merged commit 97d9ef4 into master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
View
27 lib/Doctrine/Common/Persistence/Proxy.php
@@ -22,18 +22,39 @@
/**
* Interface for proxy classes.
- *
+ *
* @author Roman Borschel <roman@code-factory.org>
* @since 2.2
*/
interface Proxy
{
/**
+ * Marker for Proxy class names.
+ *
+ * @var string
+ */
+ const MARKER = '__CG__';
+
+ /**
+ * Length of the proxy marker
+ *
+ * @var int
+ */
+ const MARKER_LENGTH = 6;
+
+ /**
* Initialize this proxy if its not yet initialized.
- *
+ *
* Acts as a no-op if already initialized.
- *
+ *
* @return void
*/
public function __load();
+
+ /**
+ * Is this proxy initialized or not.
+ *
+ * @return bool
+ */
+ public function __isInitialized();
@lsmith77 Doctrine member

do you guys include public in interfaces?

@beberlei Doctrine member

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
}
View
103 lib/Doctrine/Common/Util/ClassUtils.php
@@ -0,0 +1,103 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Util;
+
+use Doctrine\Common\Persistence\Proxy;
+
+/**
+ * Class and reflection related functionality for objects that
+ * might or not be proxy objects at the moment.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Johannes Schmitt <schmittjoh@gmail.com>
+ */
+class ClassUtils
+{
+ /**
+ * Get the real class name of a class name that could be a proxy.
+ *
+ * @param string
+ * @return string
+ */
+ public static function getRealClass($class)
+ {
+ if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) {
+ return $class;
+ }
+
+ return substr($class, $pos + Proxy::MARKER_LENGTH + 2);
+ }
+
+ /**
+ * Get the real class name of an object (even if its a proxy)
+ *
+ * @param object
+ * @return string
+ */
+ public static function getClass($object)
+ {
+ return self::getRealClass(get_class($object));
+ }
+
+ /**
+ * Get the real parent class name of a class or object
+ *
+ * @param string
+ * @return string
+ */
+ public static function getParentClass($className)
+ {
+ return get_parent_class( self::getRealClass( $className ) );
+ }
+
+ /**
+ * Create a new reflection class
+ *
+ * @param string
+ * @return ReflectionClass
+ */
+ public static function newReflectionClass($class)
+ {
+ return new \ReflectionClass( self::getRealClass( $class ) );
+ }
+
+ /**
+ * Create a new reflection object
+ *
+ * @param object
+ * @return ReflectionObject
+ */
+ public static function newReflectionObject($object)
+ {
+ return self::newReflectionClass( self::getClass( $object ) );
+ }
+
+ /**
+ * Given a class name and a proxy namespace return the proxy name.
+ *
+ * @param string $className
+ * @param string $proxyNamespace
+ * @return string
+ */
+ public static function generateProxyClassName($className, $proxyNamespace)
+ {
+ return rtrim($proxyNamespace, '\\') . '\\'.Proxy::MARKER.'\\' . ltrim($className, '\\');
+ }
+}
View
64 lib/Doctrine/Common/Util/Debug.php
@@ -1,7 +1,5 @@
<?php
/*
- * $Id$
- *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -27,7 +25,6 @@
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
- * @version $Revision: 3938 $
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
@@ -53,80 +50,69 @@ private function __construct() {}
public static function dump($var, $maxDepth = 2, $stripTags = true)
{
ini_set('html_errors', 'On');
-
+
if (extension_loaded('xdebug')) {
ini_set('xdebug.var_display_max_depth', $maxDepth);
}
-
+
$var = self::export($var, $maxDepth++);
-
+
ob_start();
var_dump($var);
$dump = ob_get_contents();
ob_end_clean();
-
+
echo ($stripTags ? strip_tags(html_entity_decode($dump)) : $dump);
-
+
ini_set('html_errors', 'Off');
}
-
+
public static function export($var, $maxDepth)
{
$return = null;
$isObj = is_object($var);
-
+
if ($isObj && in_array('Doctrine\Common\Collections\Collection', class_implements($var))) {
$var = $var->toArray();
}
-
+
if ($maxDepth) {
if (is_array($var)) {
$return = array();
-
+
foreach ($var as $k => $v) {
$return[$k] = self::export($v, $maxDepth - 1);
}
} else if ($isObj) {
+ $return = new \stdclass();
if ($var instanceof \DateTime) {
- $return = $var->format('c');
+ $return->__CLASS__ = "DateTime";
+ $return->date = $var->format('c');
+ $return->timezone = $var->getTimeZone()->getName();
} else {
- $reflClass = new \ReflectionClass(get_class($var));
- $return = new \stdclass();
- $return->{'__CLASS__'} = get_class($var);
-
- if ($var instanceof \Doctrine\ORM\Proxy\Proxy && ! $var->__isInitialized__) {
- $reflProperty = $reflClass->getProperty('_identifier');
- $reflProperty->setAccessible(true);
-
- foreach ($reflProperty->getValue($var) as $name => $value) {
- $return->$name = self::export($value, $maxDepth - 1);
- }
- } else {
- $excludeProperties = array();
+ $reflClass = ClassUtils::newReflectionObject($var);
+ $return->__CLASS__ = ClassUtils::getClass($var);
- if ($var instanceof \Doctrine\ORM\Proxy\Proxy) {
- $excludeProperties = array('_entityPersister', '__isInitialized__', '_identifier');
- }
-
- foreach ($reflClass->getProperties() as $reflProperty) {
- $name = $reflProperty->getName();
+ if ($var instanceof \Doctrine\Common\Persistence\Proxy) {
+ $return->__IS_PROXY__ = true;
+ $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
+ }
- if ( ! in_array($name, $excludeProperties)) {
- $reflProperty->setAccessible(true);
+ foreach ($reflClass->getProperties() as $reflProperty) {
+ $name = $reflProperty->getName();
- $return->$name = self::export($reflProperty->getValue($var), $maxDepth - 1);
- }
- }
+ $reflProperty->setAccessible(true);
+ $return->$name = self::export($reflProperty->getValue($var), $maxDepth - 1);
}
}
} else {
$return = $var;
}
} else {
- $return = is_object($var) ? get_class($var)
+ $return = is_object($var) ? get_class($var)
: (is_array($var) ? 'Array(' . count($var) . ')' : $var);
}
-
+
return $return;
}
View
100 tests/Doctrine/Tests/Common/Util/ClassUtilsTest.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Doctrine\Tests\Common\Util
+{
+ use Doctrine\Tests\DoctrineTestCase;
+ use Doctrine\Common\Util\ClassUtils;
+
+ class ClassUtilsTest extends DoctrineTestCase
+ {
+ static public function dataGetClass()
+ {
+ return array(
+ array('stdClass', 'stdClass'),
+ array('Doctrine\Common\Util\ClassUtils', 'Doctrine\Common\Util\ClassUtils'),
+ array( 'MyProject\Proxies\__CG__\stdClass', 'stdClass' ),
+ array( 'MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\stdClass', 'stdClass' ),
+ array( 'MyProject\Proxies\__CG__\Doctrine\Tests\Common\Util\ChildObject','Doctrine\Tests\Common\Util\ChildObject' )
+ );
+ }
+
+ /**
+ * @dataProvider dataGetClass
+ */
+ public function testGetRealClass($className, $expectedClassName)
+ {
+ $this->assertEquals($expectedClassName, ClassUtils::getRealClass($className));
+ }
+
+ /**
+ * @dataProvider dataGetClass
+ */
+ public function testGetClass( $className, $expectedClassName )
+ {
+ $object = new $className();
+ $this->assertEquals($expectedClassName, ClassUtils::getClass($object));
+ }
+
+ public function testGetParentClass()
+ {
+ $parentClass = ClassUtils::getParentClass( 'MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\Doctrine\Tests\Common\Util\ChildObject' );
+ $this->assertEquals('stdClass', $parentClass);
+ }
+
+ public function testGenerateProxyClassName()
+ {
+ $this->assertEquals( 'Proxies\__CG__\stdClass', ClassUtils::generateProxyClassName( 'stdClass', 'Proxies' ) );
+ }
+
+ /**
+ * @dataProvider dataGetClass
+ */
+ public function testNewReflectionClass( $className, $expectedClassName )
+ {
+ $reflClass = ClassUtils::newReflectionClass( $className );
+ $this->assertEquals( $expectedClassName, $reflClass->getName() );
+ }
+
+ /**
+ * @dataProvider dataGetClass
+ */
+ public function testNewReflectionObject( $className, $expectedClassName )
+ {
+ $object = new $className;
+ $reflClass = ClassUtils::newReflectionObject( $object );
+ $this->assertEquals( $expectedClassName, $reflClass->getName() );
+ }
+ }
+
+ class ChildObject extends \stdClass
+ {
+ }
+}
+
+namespace MyProject\Proxies\__CG__
+{
+ class stdClass extends \stdClass
+ {
+ }
+}
+
+namespace MyProject\Proxies\__CG__\Doctrine\Tests\Common\Util
+{
+ class ChildObject extends \Doctrine\Tests\Common\Util\ChildObject
+ {
+ }
+}
+
+namespace MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__
+{
+ class stdClass extends \MyProject\Proxies\__CG__\stdClass
+ {
+ }
+}
+
+namespace MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\Doctrine\Tests\Common\Util
+{
+ class ChildObject extends \MyProject\Proxies\__CG__\Doctrine\Tests\Common\Util\ChildObject
+ {
+ }
+}
View
27 tests/Doctrine/Tests/Common/Util/DebugTest.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Doctrine\Tests\Common\Util;
+
+use Doctrine\Tests\DoctrineTestCase;
+use Doctrine\Common\Util\Debug;
+
+class DebugTest extends DoctrineTestCase
+{
+ public function testExportObject( )
+ {
+ $obj = new \stdClass;
+ $obj->foo = "bar";
+ $obj->bar = 1234;
+
+ $var = Debug::export($obj, 2);
+ $this->assertEquals( "stdClass", $var->__CLASS__ );
+ }
+
+ public function testExportDateTime()
+ {
+ $obj = new \DateTime( "2010-10-10 10:10:10" );
+
+ $var = Debug::export( $obj, 2 );
+ $this->assertEquals( "DateTime", $var->__CLASS__ );
+ }
+}
Something went wrong with that request. Please try again.