From 8fbee579d355833c74603a2cd49f2c286c7131c6 Mon Sep 17 00:00:00 2001 From: guilhermeblanco Date: Thu, 16 Jul 2009 22:03:35 +0000 Subject: [PATCH] [2.0] Fixed 4 issues with ProxyGenerator. It was not considering the type hint and it was generating an E_STRICT error with incompatible method declaration. Some cosmetic changes in Query --- .../ORM/Proxy/ProxyClassGenerator.php | 39 +++++++++++++++-- lib/Doctrine/ORM/Query/Parser.php | 15 +++---- lib/Doctrine/ORM/Query/QueryException.php | 42 ++++++++++++++++--- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php b/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php index 66634e76d..538034ba5 100644 --- a/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php +++ b/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php @@ -46,9 +46,11 @@ class ProxyClassGenerator public function __construct(EntityManager $em, $cacheDir = null) { $this->_em = $em; + if ($cacheDir === null) { $cacheDir = sys_get_temp_dir(); } + $this->_cacheDir = rtrim($cacheDir, '/') . '/'; } @@ -64,9 +66,11 @@ class ProxyClassGenerator { $class = $this->_em->getClassMetadata($className); $proxyClassName = str_replace('\\', '_', $className) . 'RProxy'; - if (!class_exists($proxyClassName, false)) { + + if ( ! class_exists($proxyClassName, false)) { $this->_em->getMetadataFactory()->setMetadataFor(self::$_ns . $proxyClassName, $class); $fileName = $this->_cacheDir . $proxyClassName . '.g.php'; + if (file_exists($fileName)) { require $fileName; $proxyClassName = '\\' . self::$_ns . $proxyClassName; @@ -90,56 +94,76 @@ class ProxyClassGenerator file_put_contents($fileName, $file); require $fileName; + $proxyClassName = '\\' . self::$_ns . $proxyClassName; + return $proxyClassName; } protected function _generateMethods(ClassMetadata $class) { $methods = ''; + foreach ($class->reflClass->getMethods() as $method) { if ($method->getName() == '__construct') { continue; } + if ($method->isPublic() && ! $method->isFinal()) { $methods .= PHP_EOL . 'public function ' . $method->getName() . '('; $firstParam = true; - $parameterString = ''; + $parameterString = $argumentString = ''; + foreach ($method->getParameters() as $param) { if ($firstParam) { $firstParam = false; } else { $parameterString .= ', '; + $argumentString .= ', '; } + + // We need to pick the type hint class too + if (($paramClass = $param->getClass()) !== null) { + $parameterString .= '\\' . $paramClass->getName() . ' '; + } + $parameterString .= '$' . $param->getName(); + $argumentString .= '$' . $param->getName(); } + $methods .= $parameterString . ') {' . PHP_EOL; $methods .= '$this->_load();' . PHP_EOL; - $methods .= 'return parent::' . $method->getName() . '(' . $parameterString . ');'; + $methods .= 'return parent::' . $method->getName() . '(' . $argumentString . ');'; $methods .= '}' . PHP_EOL; } } + return $methods; } public function _generateSleep(ClassMetadata $class) { $sleepImpl = ''; + if ($class->reflClass->hasMethod('__sleep')) { $sleepImpl .= 'return parent::__sleep();'; } else { $sleepImpl .= 'return array('; $first = true; + foreach ($class->getReflectionProperties() as $name => $prop) { if ($first) { $first = false; } else { $sleepImpl .= ', '; } + $sleepImpl .= "'" . $name . "'"; } + $sleepImpl .= ');'; } + return $sleepImpl; } @@ -157,19 +181,23 @@ class ProxyClassGenerator $file = self::$_assocProxyClassTemplate; $methods = ''; + foreach ($class->reflClass->getMethods() as $method) { if ($method->isPublic() && ! $method->isFinal()) { $methods .= PHP_EOL . 'public function ' . $method->getName() . '('; $firstParam = true; $parameterString = ''; + foreach ($method->getParameters() as $param) { if ($firstParam) { $firstParam = false; } else { $parameterString .= ', '; } + $parameterString .= '$' . $param->getName(); } + $methods .= $parameterString . ') {' . PHP_EOL; $methods .= '$this->_load();' . PHP_EOL; $methods .= 'return parent::' . $method->getName() . '(' . $parameterString . ');'; @@ -178,19 +206,23 @@ class ProxyClassGenerator } $sleepImpl = ''; + if ($class->reflClass->hasMethod('__sleep')) { $sleepImpl .= 'return parent::__sleep();'; } else { $sleepImpl .= 'return array('; $first = true; + foreach ($class->getReflectionProperties() as $name => $prop) { if ($first) { $first = false; } else { $sleepImpl .= ', '; } + $sleepImpl .= "'" . $name . "'"; } + $sleepImpl .= ');'; } @@ -205,6 +237,7 @@ class ProxyClassGenerator $file = str_replace($placeholders, $replacements, $file); file_put_contents($fileName, $file); + return $fileName; } diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index fffea1fb8..6d578b077 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -47,7 +47,7 @@ class Parser 'trim' => 'Doctrine\ORM\Query\AST\Functions\TrimFunction', 'lower' => 'Doctrine\ORM\Query\AST\Functions\LowerFunction', 'upper' => 'Doctrine\ORM\Query\AST\Functions\UpperFunction' - ); + ); /** Maps registered numeric function names to class names. */ private static $_NUMERIC_FUNCTIONS = array( @@ -256,7 +256,7 @@ class Parser $message .= "'{$this->_lexer->lookahead['value']}'"; } - throw DoctrineException::updateMe($message); + throw QueryException::syntaxError($message); } /** @@ -280,7 +280,7 @@ class Parser $message = 'line 0, col ' . (isset($token['position']) ? $token['position'] : '-1') . " near '" . substr($dql, $token['position'], $length) . "'): Error: " . $message; - throw DoctrineException::updateMe($message); + throw QueryException::semanticalError($message); } /** @@ -352,6 +352,7 @@ class Parser default: $this->syntaxError('SELECT, UPDATE or DELETE'); + break; } } @@ -405,19 +406,19 @@ class Parser switch ($expr->getType()) { case AST\PathExpression::TYPE_STATE_FIELD: $this->_validateStateFieldPathExpression($expr); - break; + break; case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION: $this->_validateSingleValuedAssociationPathExpression($expr); - break; + break; case AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION: $this->_validateCollectionValuedAssociationPathExpression($expr); - break; + break; default: $this->semanticalError('Encountered invalid PathExpression.'); - break; + break; } } } diff --git a/lib/Doctrine/ORM/Query/QueryException.php b/lib/Doctrine/ORM/Query/QueryException.php index a42dad959..a6423945e 100644 --- a/lib/Doctrine/ORM/Query/QueryException.php +++ b/lib/Doctrine/ORM/Query/QueryException.php @@ -1,7 +1,22 @@ . */ namespace Doctrine\ORM\Query; @@ -9,6 +24,23 @@ namespace Doctrine\ORM\Query; /** * Description of QueryException * - * @author robo + * @author Guilherme Blanco + * @author Roman Borschel + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link http://www.doctrine-project.org + * @since 2.0 + * @version $Revision$ */ -class QueryException extends \Doctrine\Common\DoctrineException {} \ No newline at end of file +class QueryException extends \Doctrine\Common\DoctrineException +{ + public static function syntaxError($message) + { + return new self('[Syntax Error] ' . $message); + } + + + public static function semanticalError($message) + { + return new self('[Semantical Error] ' . $message); + } +} \ No newline at end of file