AbstractProxyFactory.php in Plug 7
Namespace
Doctrine\Common\ProxyFile
lib/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.phpView source
<?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\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
use Doctrine\Common\Proxy\Exception\InvalidArgumentException;
use Doctrine\Common\Proxy\Exception\OutOfBoundsException;
use Doctrine\Common\Util\ClassUtils;
/**
* Abstract factory for proxy objects.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
abstract class AbstractProxyFactory {
/**
* Never autogenerate a proxy and rely that it was generated by some
* process before deployment.
*
* @var integer
*/
const AUTOGENERATE_NEVER = 0;
/**
* Always generates a new proxy in every request.
*
* This is only sane during development.
*
* @var integer
*/
const AUTOGENERATE_ALWAYS = 1;
/**
* Autogenerate the proxy class when the proxy file does not exist.
*
* This strategy causes a file exists call whenever any proxy is used the
* first time in a request.
*
* @var integer
*/
const AUTOGENERATE_FILE_NOT_EXISTS = 2;
/**
* Generate the proxy classes using eval().
*
* This strategy is only sane for development, and even then it gives me
* the creeps a little.
*
* @var integer
*/
const AUTOGENERATE_EVAL = 3;
/**
* @var \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory
*/
private $metadataFactory;
/**
* @var \Doctrine\Common\Proxy\ProxyGenerator the proxy generator responsible for creating the proxy classes/files.
*/
private $proxyGenerator;
/**
* @var bool Whether to automatically (re)generate proxy classes.
*/
private $autoGenerate;
/**
* @var \Doctrine\Common\Proxy\ProxyDefinition[]
*/
private $definitions = array();
/**
* @param \Doctrine\Common\Proxy\ProxyGenerator $proxyGenerator
* @param \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory $metadataFactory
* @param bool|int $autoGenerate
*/
public function __construct(ProxyGenerator $proxyGenerator, ClassMetadataFactory $metadataFactory, $autoGenerate) {
$this->proxyGenerator = $proxyGenerator;
$this->metadataFactory = $metadataFactory;
$this->autoGenerate = (int) $autoGenerate;
}
/**
* Gets a reference proxy instance for the entity of the given type and identified by
* the given identifier.
*
* @param string $className
* @param array $identifier
*
* @return \Doctrine\Common\Proxy\Proxy
*
* @throws \Doctrine\Common\Proxy\Exception\OutOfBoundsException
*/
public function getProxy($className, array $identifier) {
$definition = isset($this->definitions[$className]) ? $this->definitions[$className] : $this
->getProxyDefinition($className);
$fqcn = $definition->proxyClassName;
$proxy = new $fqcn($definition->initializer, $definition->cloner);
foreach ($definition->identifierFields as $idField) {
if (!isset($identifier[$idField])) {
throw OutOfBoundsException::missingPrimaryKeyValue($className, $idField);
}
$definition->reflectionFields[$idField]
->setValue($proxy, $identifier[$idField]);
}
return $proxy;
}
/**
* Generates proxy classes for all given classes.
*
* @param \Doctrine\Common\Persistence\Mapping\ClassMetadata[] $classes The classes (ClassMetadata instances)
* for which to generate proxies.
* @param string $proxyDir 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.
* @return int Number of generated proxies.
*/
public function generateProxyClasses(array $classes, $proxyDir = null) {
$generated = 0;
foreach ($classes as $class) {
if ($this
->skipClass($class)) {
continue;
}
$proxyFileName = $this->proxyGenerator
->getProxyFileName($class
->getName(), $proxyDir);
$this->proxyGenerator
->generateProxyClass($class, $proxyFileName);
$generated += 1;
}
return $generated;
}
/**
* Reset initialization/cloning logic for an un-initialized proxy
*
* @param \Doctrine\Common\Proxy\Proxy $proxy
*
* @return \Doctrine\Common\Proxy\Proxy
*
* @throws \Doctrine\Common\Proxy\Exception\InvalidArgumentException
*/
public function resetUninitializedProxy(Proxy $proxy) {
if ($proxy
->__isInitialized()) {
throw InvalidArgumentException::unitializedProxyExpected($proxy);
}
$className = ClassUtils::getClass($proxy);
$definition = isset($this->definitions[$className]) ? $this->definitions[$className] : $this
->getProxyDefinition($className);
$proxy
->__setInitializer($definition->initializer);
$proxy
->__setCloner($definition->cloner);
return $proxy;
}
/**
* Get a proxy definition for the given class name.
*
* @param string $className
*
* @return ProxyDefinition
*/
private function getProxyDefinition($className) {
$classMetadata = $this->metadataFactory
->getMetadataFor($className);
$className = $classMetadata
->getName();
// aliases and case sensitivity
$this->definitions[$className] = $this
->createProxyDefinition($className);
$proxyClassName = $this->definitions[$className]->proxyClassName;
if (!class_exists($proxyClassName, false)) {
$fileName = $this->proxyGenerator
->getProxyFileName($className);
switch ($this->autoGenerate) {
case self::AUTOGENERATE_NEVER:
require $fileName;
break;
case self::AUTOGENERATE_FILE_NOT_EXISTS:
if (!file_exists($fileName)) {
$this->proxyGenerator
->generateProxyClass($classMetadata, $fileName);
}
require $fileName;
break;
case self::AUTOGENERATE_ALWAYS:
$this->proxyGenerator
->generateProxyClass($classMetadata, $fileName);
require $fileName;
break;
case self::AUTOGENERATE_EVAL:
$this->proxyGenerator
->generateProxyClass($classMetadata, false);
break;
}
}
return $this->definitions[$className];
}
/**
* Determine if this class should be skipped during proxy generation.
*
* @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $metadata
*
* @return bool
*/
protected abstract function skipClass(ClassMetadata $metadata);
/**
* @param string $className
*
* @return ProxyDefinition
*/
protected abstract function createProxyDefinition($className);
}
Classes
Name | Description |
---|---|
AbstractProxyFactory | Abstract factory for proxy objects. |