Permalink
Browse files

Merge pull request #168 from Ocramius/DCOM-96

[DCOM-96] ProxyFactory logic moved to doctrine common
  • Loading branch information...
2 parents 28b0e7f + 2979513 commit d5843a462a4dfe4a42daf4645fc867c431a4170e @beberlei beberlei committed Jan 10, 2013
View
@@ -2,3 +2,4 @@ build/
logs/
reports/
dist/
+tests/Doctrine/Tests/Common/Proxy/generated/
View
@@ -4,6 +4,7 @@ env:
- OPCODE_CACHE=apc
php:
+ - 5.3.3
- 5.3
- 5.4
@@ -21,6 +21,7 @@
use ReflectionClass;
use ReflectionProperty;
+use Doctrine\Common\Reflection\RuntimePublicReflectionProperty;
/**
* PHP Runtime Reflection Service
@@ -30,69 +31,59 @@
class RuntimeReflectionService implements ReflectionService
{
/**
- * Return an array of the parent classes (not interfaces) for the given class.
- *
- * @param string $class
- * @return array
+ * {@inheritDoc}
*/
public function getParentClasses($class)
{
return class_parents($class);
}
/**
- * Return the shortname of a class.
- *
- * @param string $class
- * @return string
+ * {@inheritDoc}
*/
public function getClassShortName($class)
{
- $r = new ReflectionClass($class);
- return $r->getShortName();
+ $reflectionClass = new ReflectionClass($class);
+
+ return $reflectionClass->getShortName();
}
/**
- * @param string $class
- * @return string
+ * {@inheritDoc}
*/
public function getClassNamespace($class)
{
- $r = new ReflectionClass($class);
- return $r->getNamespaceName();
+ $reflectionClass = new ReflectionClass($class);
+
+ return $reflectionClass->getNamespaceName();
}
/**
- * Return a reflection class instance or null
- *
- * @param string $class
- * @return ReflectionClass|null
+ * {@inheritDoc}
*/
public function getClass($class)
{
return new ReflectionClass($class);
}
/**
- * Return an accessible property (setAccessible(true)) or null.
- *
- * @param string $class
- * @param string $property
- * @return ReflectionProperty|null
+ * {@inheritDoc}
*/
public function getAccessibleProperty($class, $property)
{
- $property = new ReflectionProperty($class, $property);
- $property->setAccessible(true);
- return $property;
+ $reflectionProperty = new ReflectionProperty($class, $property);
+
+ if ($reflectionProperty->isPublic()) {
+ $reflectionProperty = new RuntimePublicReflectionProperty($class, $property);
+ }
+
+ $reflectionProperty->setAccessible(true);
+
+ return $reflectionProperty;
}
/**
- * Check if the class have a public method with the given name.
- *
- * @param mixed $class
- * @param mixed $method
- * @return bool
+ * {@inheritDoc}
*/
public function hasPublicMethod($class, $method)
{
@@ -38,7 +38,7 @@
/**
* Length of the proxy marker
*
- * @var int
+ * @var integer
*/
const MARKER_LENGTH = 6;
@@ -0,0 +1,93 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Proxy;
+
+use Doctrine\Common\Proxy\Exception\InvalidArgumentException;
+
+/**
+ * Special Autoloader for Proxy classes, which are not PSR-0 compliant.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Autoloader
+{
+ /**
+ * Resolves proxy class name to a filename based on the following pattern.
+ *
+ * 1. Remove Proxy namespace from class name
+ * 2. Remove namespace separators from remaining class name.
+ * 3. Return PHP filename from proxy-dir with the result from 2.
+ *
+ * @param string $proxyDir
+ * @param string $proxyNamespace
+ * @param string $className
+ *
+ * @return string
+ *
+ * @throws InvalidArgumentException
+ */
+ public static function resolveFile($proxyDir, $proxyNamespace, $className)
+ {
+ if (0 !== strpos($className, $proxyNamespace)) {
+ throw InvalidArgumentException::notProxyClass($className, $proxyNamespace);
+ }
+
+ $className = str_replace('\\', '', substr($className, strlen($proxyNamespace) + 1));
+
+ return $proxyDir . DIRECTORY_SEPARATOR . $className . '.php';
+ }
+
+ /**
+ * Register and return autoloader callback for the given proxy dir and
+ * namespace.
+ *
+ * @param string $proxyDir
+ * @param string $proxyNamespace
+ * @param callable $notFoundCallback Invoked when the proxy file is not found.
+ *
+ * @return \Closure
+ *
+ * @throws InvalidArgumentException
+ */
+ public static function register($proxyDir, $proxyNamespace, $notFoundCallback = null)
+ {
+ $proxyNamespace = ltrim($proxyNamespace, '\\');
+
+ if ( ! (null === $notFoundCallback || is_callable($notFoundCallback))) {
+ throw InvalidArgumentException::invalidClassNotFoundCallback($notFoundCallback);
+ }
+
+ $autoloader = function ($className) use ($proxyDir, $proxyNamespace, $notFoundCallback) {
+ if (0 === strpos($className, $proxyNamespace)) {
+ $file = Autoloader::resolveFile($proxyDir, $proxyNamespace, $className);
+
+ if ($notFoundCallback && ! file_exists($file)) {
+ call_user_func($notFoundCallback, $proxyDir, $proxyNamespace, $className);
+ }
+
+ require $file;
+ }
+ };
+
+ spl_autoload_register($autoloader);
+
+ return $autoloader;
+ }
+}
@@ -0,0 +1,81 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Proxy\Exception;
+
+use InvalidArgumentException as BaseInvalidArgumentException;
+
+/**
+ * Proxy Invalid Argument Exception
+ *
+ * @link www.doctrine-project.com
+ * @since 2.4
+ * @author Marco Pivetta <ocramius@gmail.com>
+ */
+class InvalidArgumentException extends BaseInvalidArgumentException implements ProxyException
+{
+ /**
+ * @return self
+ */
+ public static function proxyDirectoryRequired()
+ {
+ return new self('You must configure a proxy directory. See docs for details');
+ }
+
+ /**
+ * @param string $className
+ * @param string $proxyNamespace
+ *
+ * @return self
+ */
+ public static function notProxyClass($className, $proxyNamespace)
+ {
+ return new self(sprintf('The class "%s" is not part of the proxy namespace "%s"', $className, $proxyNamespace));
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return self
+ */
+ public static function invalidPlaceholder($name)
+ {
+ return new self(sprintf('Provided placeholder for "%s" must be either a string or a valid callable', $name));
+ }
+
+ /**
+ * @return self
+ */
+ public static function proxyNamespaceRequired()
+ {
+ return new self('You must configure a proxy namespace');
+ }
+
+ /**
+ * @param mixed $callback
+ *
+ * @return self
+ */
+ public static function invalidClassNotFoundCallback($callback)
+ {
+ $type = is_object($callback) ? get_class($callback) : gettype($callback);
+
+ return new self(sprintf('Invalid \$notFoundCallback given: must be a callable, "%s" given', $type));
+ }
+}
@@ -0,0 +1,31 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Proxy\Exception;
+
+/**
+ * Base exception interface for proxy exceptions
+ *
+ * @link www.doctrine-project.com
+ * @since 2.4
+ * @author Marco Pivetta <ocramius@gmail.com>
+ */
+interface ProxyException
+{
+}
@@ -0,0 +1,61 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Proxy\Exception;
+
+use UnexpectedValueException as BaseUnexpectedValueException;
+
+/**
+ * Proxy Unexpected Value Exception
+ *
+ * @link www.doctrine-project.com
+ * @since 2.4
+ * @author Marco Pivetta <ocramius@gmail.com>
+ */
+class UnexpectedValueException extends BaseUnexpectedValueException implements ProxyException
+{
+ /**
+ * @return self
+ */
+ public static function proxyDirectoryNotWritable()
+ {
+ return new self('Your proxy directory must be writable');
+ }
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ * @param string $parameterName
+ *
+ * @return self
+ */
+ public static function invalidParameterTypeHint($className, $methodName, $parameterName, \Exception $previous)
+ {
+ return new self(
+ sprintf(
+ 'The type hint of parameter "%s" in method "%s" in class "%s" is invalid.',
+ $parameterName,
+ $methodName,
+ $className
+ ),
+ 0,
+ $previous
+ );
+ }
+}
Oops, something went wrong.

0 comments on commit d5843a4

Please sign in to comment.