--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/doctrine/lib/Doctrine/ORM/Proxy/ProxyFactory.php Sat Sep 24 15:40:41 2011 +0200
@@ -0,0 +1,316 @@
+<?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\ORM\Proxy;
+
+use Doctrine\ORM\EntityManager,
+ Doctrine\ORM\Mapping\ClassMetadata,
+ Doctrine\ORM\Mapping\AssociationMapping;
+
+/**
+ * This factory is used to create proxy objects for entities at runtime.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
+ * @since 2.0
+ */
+class ProxyFactory
+{
+ /** The EntityManager this factory is bound to. */
+ private $_em;
+ /** Whether to automatically (re)generate proxy classes. */
+ private $_autoGenerate;
+ /** The namespace that contains all proxy classes. */
+ private $_proxyNamespace;
+ /** The directory that contains all proxy classes. */
+ private $_proxyDir;
+
+ /**
+ * Initializes a new instance of the <tt>ProxyFactory</tt> class that is
+ * connected to the given <tt>EntityManager</tt>.
+ *
+ * @param EntityManager $em The EntityManager the new factory works for.
+ * @param string $proxyDir The directory to use for the proxy classes. It must exist.
+ * @param string $proxyNs The namespace to use for the proxy classes.
+ * @param boolean $autoGenerate Whether to automatically generate proxy classes.
+ */
+ public function __construct(EntityManager $em, $proxyDir, $proxyNs, $autoGenerate = false)
+ {
+ if ( ! $proxyDir) {
+ throw ProxyException::proxyDirectoryRequired();
+ }
+ if ( ! $proxyNs) {
+ throw ProxyException::proxyNamespaceRequired();
+ }
+ $this->_em = $em;
+ $this->_proxyDir = $proxyDir;
+ $this->_autoGenerate = $autoGenerate;
+ $this->_proxyNamespace = $proxyNs;
+ }
+
+ /**
+ * Gets a reference proxy instance for the entity of the given type and identified by
+ * the given identifier.
+ *
+ * @param string $className
+ * @param mixed $identifier
+ * @return object
+ */
+ public function getProxy($className, $identifier)
+ {
+ $proxyClassName = str_replace('\\', '', $className) . 'Proxy';
+ $fqn = $this->_proxyNamespace . '\\' . $proxyClassName;
+
+ if (! class_exists($fqn, false)) {
+ $fileName = $this->_proxyDir . DIRECTORY_SEPARATOR . $proxyClassName . '.php';
+ if ($this->_autoGenerate) {
+ $this->_generateProxyClass($this->_em->getClassMetadata($className), $proxyClassName, $fileName, self::$_proxyClassTemplate);
+ }
+ require $fileName;
+ }
+
+ if ( ! $this->_em->getMetadataFactory()->hasMetadataFor($fqn)) {
+ $this->_em->getMetadataFactory()->setMetadataFor($fqn, $this->_em->getClassMetadata($className));
+ }
+
+ $entityPersister = $this->_em->getUnitOfWork()->getEntityPersister($className);
+
+ return new $fqn($entityPersister, $identifier);
+ }
+
+ /**
+ * Generates proxy classes for all given classes.
+ *
+ * @param array $classes The classes (ClassMetadata instances) for which to generate proxies.
+ * @param string $toDir The target directory of the proxy classes. If not specified, the
+ * directory configured on the Configuration of the EntityManager used
+ * by this factory is used.
+ */
+ public function generateProxyClasses(array $classes, $toDir = null)
+ {
+ $proxyDir = $toDir ?: $this->_proxyDir;
+ $proxyDir = rtrim($proxyDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+ foreach ($classes as $class) {
+ /* @var $class ClassMetadata */
+ if ($class->isMappedSuperclass) {
+ continue;
+ }
+
+ $proxyClassName = str_replace('\\', '', $class->name) . 'Proxy';
+ $proxyFileName = $proxyDir . $proxyClassName . '.php';
+ $this->_generateProxyClass($class, $proxyClassName, $proxyFileName, self::$_proxyClassTemplate);
+ }
+ }
+
+ /**
+ * Generates a proxy class file.
+ *
+ * @param $class
+ * @param $originalClassName
+ * @param $proxyClassName
+ * @param $file The path of the file to write to.
+ */
+ private function _generateProxyClass($class, $proxyClassName, $fileName, $file)
+ {
+ $methods = $this->_generateMethods($class);
+ $sleepImpl = $this->_generateSleep($class);
+ $cloneImpl = $class->reflClass->hasMethod('__clone') ? 'parent::__clone();' : ''; // hasMethod() checks case-insensitive
+
+ $placeholders = array(
+ '<namespace>',
+ '<proxyClassName>', '<className>',
+ '<methods>', '<sleepImpl>', '<cloneImpl>'
+ );
+
+ if(substr($class->name, 0, 1) == "\\") {
+ $className = substr($class->name, 1);
+ } else {
+ $className = $class->name;
+ }
+
+ $replacements = array(
+ $this->_proxyNamespace,
+ $proxyClassName, $className,
+ $methods, $sleepImpl, $cloneImpl
+ );
+
+ $file = str_replace($placeholders, $replacements, $file);
+
+ file_put_contents($fileName, $file, LOCK_EX);
+ }
+
+ /**
+ * Generates the methods of a proxy class.
+ *
+ * @param ClassMetadata $class
+ * @return string The code of the generated methods.
+ */
+ private function _generateMethods(ClassMetadata $class)
+ {
+ $methods = '';
+
+ foreach ($class->reflClass->getMethods() as $method) {
+ /* @var $method ReflectionMethod */
+ if ($method->isConstructor() || in_array(strtolower($method->getName()), array("__sleep", "__clone"))) {
+ continue;
+ }
+
+ if ($method->isPublic() && ! $method->isFinal() && ! $method->isStatic()) {
+ $methods .= "\n" . ' public function ';
+ if ($method->returnsReference()) {
+ $methods .= '&';
+ }
+ $methods .= $method->getName() . '(';
+ $firstParam = true;
+ $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() . ' ';
+ } else if ($param->isArray()) {
+ $parameterString .= 'array ';
+ }
+
+ if ($param->isPassedByReference()) {
+ $parameterString .= '&';
+ }
+
+ $parameterString .= '$' . $param->getName();
+ $argumentString .= '$' . $param->getName();
+
+ if ($param->isDefaultValueAvailable()) {
+ $parameterString .= ' = ' . var_export($param->getDefaultValue(), true);
+ }
+ }
+
+ $methods .= $parameterString . ')';
+ $methods .= "\n" . ' {' . "\n";
+ $methods .= ' $this->__load();' . "\n";
+ $methods .= ' return parent::' . $method->getName() . '(' . $argumentString . ');';
+ $methods .= "\n" . ' }' . "\n";
+ }
+ }
+
+ return $methods;
+ }
+
+ /**
+ * Generates the code for the __sleep method for a proxy class.
+ *
+ * @param $class
+ * @return string
+ */
+ private function _generateSleep(ClassMetadata $class)
+ {
+ $sleepImpl = '';
+
+ if ($class->reflClass->hasMethod('__sleep')) {
+ $sleepImpl .= "return array_merge(array('__isInitialized__'), parent::__sleep());";
+ } else {
+ $sleepImpl .= "return array('__isInitialized__', ";
+ $first = true;
+
+ foreach ($class->getReflectionProperties() as $name => $prop) {
+ if ($first) {
+ $first = false;
+ } else {
+ $sleepImpl .= ', ';
+ }
+
+ $sleepImpl .= "'" . $name . "'";
+ }
+
+ $sleepImpl .= ');';
+ }
+
+ return $sleepImpl;
+ }
+
+ /** Proxy class code template */
+ private static $_proxyClassTemplate =
+'<?php
+
+namespace <namespace>;
+
+/**
+ * THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
+ */
+class <proxyClassName> extends \<className> implements \Doctrine\ORM\Proxy\Proxy
+{
+ private $_entityPersister;
+ private $_identifier;
+ public $__isInitialized__ = false;
+ public function __construct($entityPersister, $identifier)
+ {
+ $this->_entityPersister = $entityPersister;
+ $this->_identifier = $identifier;
+ }
+ /** @private */
+ public function __load()
+ {
+ if (!$this->__isInitialized__ && $this->_entityPersister) {
+ $this->__isInitialized__ = true;
+
+ if (method_exists($this, "__wakeup")) {
+ // call this after __isInitialized__to avoid infinite recursion
+ // but before loading to emulate what ClassMetadata::newInstance()
+ // provides.
+ $this->__wakeup();
+ }
+
+ if ($this->_entityPersister->load($this->_identifier, $this) === null) {
+ throw new \Doctrine\ORM\EntityNotFoundException();
+ }
+ unset($this->_entityPersister, $this->_identifier);
+ }
+ }
+
+ <methods>
+
+ public function __sleep()
+ {
+ <sleepImpl>
+ }
+
+ public function __clone()
+ {
+ if (!$this->__isInitialized__ && $this->_entityPersister) {
+ $this->__isInitialized__ = true;
+ $class = $this->_entityPersister->getClassMetadata();
+ $original = $this->_entityPersister->load($this->_identifier);
+ if ($original === null) {
+ throw new \Doctrine\ORM\EntityNotFoundException();
+ }
+ foreach ($class->reflFields AS $field => $reflProperty) {
+ $reflProperty->setValue($this, $reflProperty->getValue($original));
+ }
+ unset($this->_entityPersister, $this->_identifier);
+ }
+ <cloneImpl>
+ }
+}';
+}