Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DCOM-96] ProxyFactory logic moved to doctrine common #168

Merged
merged 1 commit into from
Jan 10, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ build/
logs/
reports/
dist/
tests/Doctrine/Tests/Common/Proxy/generated/
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ env:
- OPCODE_CACHE=apc

php:
- 5.3.3
- 5.3
- 5.4

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

use ReflectionClass;
use ReflectionProperty;
use Doctrine\Common\Reflection\RuntimePublicReflectionProperty;

/**
* PHP Runtime Reflection Service
Expand All @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion lib/Doctrine/Common/Persistence/Proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ interface Proxy
/**
* Length of the proxy marker
*
* @var int
* @var integer
*/
const MARKER_LENGTH = 6;

Expand Down
93 changes: 93 additions & 0 deletions lib/Doctrine/Common/Proxy/Autoloader.php
Original file line number Diff line number Diff line change
@@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curly brace should be on a new line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not for closures, at least in PSR-2

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok then

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;
}
}
81 changes: 81 additions & 0 deletions lib/Doctrine/Common/Proxy/Exception/InvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -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));
}
}
31 changes: 31 additions & 0 deletions lib/Doctrine/Common/Proxy/Exception/ProxyException.php
Original file line number Diff line number Diff line change
@@ -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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we call this class ProxyExceptionInterface ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but the other interfaces are not called like that in doctrine2. This may be a good change for 3.0 (along with all other interfaces)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not suffix with Interface because we do not describe data structure type on class name. It doesn't make sense.
Otherwise, we'd be forced to have FooAbstract or FooClass, all debatable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@guilhermeblanco I'd push this to 3.0 (to be discussed, obviously)

{
}
61 changes: 61 additions & 0 deletions lib/Doctrine/Common/Proxy/Exception/UnexpectedValueException.php
Original file line number Diff line number Diff line change
@@ -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');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see sometimes for a simple string is '' and other times as above in other files is ""

perhaps we want to follow a determined pattern?

}

/**
* @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
);
}
}
Loading