Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

DCOM-84 - Improve proxy names #83

Merged
merged 3 commits into from

4 participants

@beberlei
Owner

No description provided.

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 Collaborator
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
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 Collaborator
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
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 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
@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 Collaborator

do you guys include public in interfaces?

@beberlei 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
@lsmith77
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?

@stof
Collaborator

@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
This page is out of date. Refresh to see the latest.
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 Collaborator

do you guys include public in interfaces?

@beberlei 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
}
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.