vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php line 217

Open in your IDE?
  1. <?php
  2. namespace Doctrine\Common\Proxy;
  3. use Doctrine\Common\Persistence\Mapping\ClassMetadata;
  4. use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
  5. use Doctrine\Common\Proxy\Exception\InvalidArgumentException;
  6. use Doctrine\Common\Proxy\Exception\OutOfBoundsException;
  7. use Doctrine\Common\Util\ClassUtils;
  8. /**
  9.  * Abstract factory for proxy objects.
  10.  *
  11.  * @author Benjamin Eberlei <kontakt@beberlei.de>
  12.  *
  13.  * @deprecated The Doctrine\Common\Proxy component is deprecated, please use ocramius/proxy-manager instead.
  14.  */
  15. abstract class AbstractProxyFactory
  16. {
  17.     /**
  18.      * Never autogenerate a proxy and rely that it was generated by some
  19.      * process before deployment.
  20.      *
  21.      * @var integer
  22.      */
  23.     const AUTOGENERATE_NEVER 0;
  24.     /**
  25.      * Always generates a new proxy in every request.
  26.      *
  27.      * This is only sane during development.
  28.      *
  29.      * @var integer
  30.      */
  31.     const AUTOGENERATE_ALWAYS 1;
  32.     /**
  33.      * Autogenerate the proxy class when the proxy file does not exist.
  34.      *
  35.      * This strategy causes a file exists call whenever any proxy is used the
  36.      * first time in a request.
  37.      *
  38.      * @var integer
  39.      */
  40.     const AUTOGENERATE_FILE_NOT_EXISTS 2;
  41.     /**
  42.      * Generate the proxy classes using eval().
  43.      *
  44.      * This strategy is only sane for development, and even then it gives me
  45.      * the creeps a little.
  46.      *
  47.      * @var integer
  48.      */
  49.     const AUTOGENERATE_EVAL 3;
  50.     private const AUTOGENERATE_MODES = [
  51.         self::AUTOGENERATE_NEVER,
  52.         self::AUTOGENERATE_ALWAYS,
  53.         self::AUTOGENERATE_FILE_NOT_EXISTS,
  54.         self::AUTOGENERATE_EVAL,
  55.     ];
  56.     /**
  57.      * @var \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory
  58.      */
  59.     private $metadataFactory;
  60.     /**
  61.      * @var \Doctrine\Common\Proxy\ProxyGenerator the proxy generator responsible for creating the proxy classes/files.
  62.      */
  63.     private $proxyGenerator;
  64.     /**
  65.      * @var int Whether to automatically (re)generate proxy classes.
  66.      */
  67.     private $autoGenerate;
  68.     /**
  69.      * @var \Doctrine\Common\Proxy\ProxyDefinition[]
  70.      */
  71.     private $definitions = [];
  72.     /**
  73.      * @param \Doctrine\Common\Proxy\ProxyGenerator                     $proxyGenerator
  74.      * @param \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory $metadataFactory
  75.      * @param bool|int                                                  $autoGenerate
  76.      *
  77.      * @throws \Doctrine\Common\Proxy\Exception\InvalidArgumentException When auto generate mode is not valid.
  78.      */
  79.     public function __construct(ProxyGenerator $proxyGeneratorClassMetadataFactory $metadataFactory$autoGenerate)
  80.     {
  81.         $this->proxyGenerator  $proxyGenerator;
  82.         $this->metadataFactory $metadataFactory;
  83.         $this->autoGenerate    = (int) $autoGenerate;
  84.         if ( ! in_array($this->autoGenerateself::AUTOGENERATE_MODEStrue)) {
  85.             throw InvalidArgumentException::invalidAutoGenerateMode($autoGenerate);
  86.         }
  87.     }
  88.     /**
  89.      * Gets a reference proxy instance for the entity of the given type and identified by
  90.      * the given identifier.
  91.      *
  92.      * @param  string $className
  93.      * @param  array  $identifier
  94.      *
  95.      * @return \Doctrine\Common\Proxy\Proxy
  96.      *
  97.      * @throws \Doctrine\Common\Proxy\Exception\OutOfBoundsException
  98.      */
  99.     public function getProxy($className, array $identifier)
  100.     {
  101.         $definition = isset($this->definitions[$className])
  102.             ? $this->definitions[$className]
  103.             : $this->getProxyDefinition($className);
  104.         $fqcn       $definition->proxyClassName;
  105.         $proxy      = new $fqcn($definition->initializer$definition->cloner);
  106.         foreach ($definition->identifierFields as $idField) {
  107.             if ( ! isset($identifier[$idField])) {
  108.                 throw OutOfBoundsException::missingPrimaryKeyValue($className$idField);
  109.             }
  110.             $definition->reflectionFields[$idField]->setValue($proxy$identifier[$idField]);
  111.         }
  112.         return $proxy;
  113.     }
  114.     /**
  115.      * Generates proxy classes for all given classes.
  116.      *
  117.      * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata[] $classes The classes (ClassMetadata instances)
  118.      *                                                                      for which to generate proxies.
  119.      * @param string $proxyDir The target directory of the proxy classes. If not specified, the
  120.      *                         directory configured on the Configuration of the EntityManager used
  121.      *                         by this factory is used.
  122.      * @return int Number of generated proxies.
  123.      */
  124.     public function generateProxyClasses(array $classes$proxyDir null)
  125.     {
  126.         $generated 0;
  127.         foreach ($classes as $class) {
  128.             if ($this->skipClass($class)) {
  129.                 continue;
  130.             }
  131.             $proxyFileName $this->proxyGenerator->getProxyFileName($class->getName(), $proxyDir);
  132.             $this->proxyGenerator->generateProxyClass($class$proxyFileName);
  133.             $generated += 1;
  134.         }
  135.         return $generated;
  136.     }
  137.     /**
  138.      * Reset initialization/cloning logic for an un-initialized proxy
  139.      *
  140.      * @param \Doctrine\Common\Proxy\Proxy $proxy
  141.      *
  142.      * @return \Doctrine\Common\Proxy\Proxy
  143.      *
  144.      * @throws \Doctrine\Common\Proxy\Exception\InvalidArgumentException
  145.      */
  146.     public function resetUninitializedProxy(Proxy $proxy)
  147.     {
  148.         if ($proxy->__isInitialized()) {
  149.             throw InvalidArgumentException::unitializedProxyExpected($proxy);
  150.         }
  151.         $className  ClassUtils::getClass($proxy);
  152.         $definition = isset($this->definitions[$className])
  153.             ? $this->definitions[$className]
  154.             : $this->getProxyDefinition($className);
  155.         $proxy->__setInitializer($definition->initializer);
  156.         $proxy->__setCloner($definition->cloner);
  157.         return $proxy;
  158.     }
  159.     /**
  160.      * Get a proxy definition for the given class name.
  161.      *
  162.      * @param string $className
  163.      *
  164.      * @return ProxyDefinition
  165.      */
  166.     private function getProxyDefinition($className)
  167.     {
  168.         $classMetadata $this->metadataFactory->getMetadataFor($className);
  169.         $className     $classMetadata->getName(); // aliases and case sensitivity
  170.         $this->definitions[$className] = $this->createProxyDefinition($className);
  171.         $proxyClassName                $this->definitions[$className]->proxyClassName;
  172.         if ( ! class_exists($proxyClassNamefalse)) {
  173.             $fileName $this->proxyGenerator->getProxyFileName($className);
  174.             switch ($this->autoGenerate) {
  175.                 case self::AUTOGENERATE_NEVER:
  176.                     require $fileName;
  177.                     break;
  178.                 case self::AUTOGENERATE_FILE_NOT_EXISTS:
  179.                     if ( ! file_exists($fileName)) {
  180.                         $this->proxyGenerator->generateProxyClass($classMetadata$fileName);
  181.                     }
  182.                     require $fileName;
  183.                     break;
  184.                 case self::AUTOGENERATE_ALWAYS:
  185.                     $this->proxyGenerator->generateProxyClass($classMetadata$fileName);
  186.                     require $fileName;
  187.                     break;
  188.                 case self::AUTOGENERATE_EVAL:
  189.                     $this->proxyGenerator->generateProxyClass($classMetadatafalse);
  190.                     break;
  191.             }
  192.         }
  193.         return $this->definitions[$className];
  194.     }
  195.     /**
  196.      * Determine if this class should be skipped during proxy generation.
  197.      *
  198.      * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $metadata
  199.      *
  200.      * @return bool
  201.      */
  202.     abstract protected function skipClass(ClassMetadata $metadata);
  203.     /**
  204.      * @param string $className
  205.      *
  206.      * @return ProxyDefinition
  207.      */
  208.     abstract protected function createProxyDefinition($className);
  209. }