vendor/doctrine/common/src/Proxy/AbstractProxyFactory.php line 184
<?phpnamespace Doctrine\Common\Proxy;use Doctrine\Common\Proxy\Exception\InvalidArgumentException;use Doctrine\Common\Proxy\Exception\OutOfBoundsException;use Doctrine\Common\Util\ClassUtils;use Doctrine\Persistence\Mapping\ClassMetadata;use Doctrine\Persistence\Mapping\ClassMetadataFactory;use function class_exists;use function file_exists;use function filemtime;use function in_array;/*** Abstract factory for proxy objects.*/abstract class AbstractProxyFactory{/*** Never autogenerate a proxy and rely that it was generated by some* process before deployment.*/public const AUTOGENERATE_NEVER = 0;/*** Always generates a new proxy in every request.** This is only sane during development.*/public 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.*/public 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.*/public const AUTOGENERATE_EVAL = 3;/*** Autogenerate the proxy class when the proxy file does not exist or* when the proxied file changed.** This strategy causes a file_exists() call whenever any proxy is used the* first time in a request. When the proxied file is changed, the proxy will* be updated.*/public const AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED = 4;private const AUTOGENERATE_MODES = [self::AUTOGENERATE_NEVER,self::AUTOGENERATE_ALWAYS,self::AUTOGENERATE_FILE_NOT_EXISTS,self::AUTOGENERATE_EVAL,self::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED,];/** @var ClassMetadataFactory */private $metadataFactory;/** @var ProxyGenerator the proxy generator responsible for creating the proxy classes/files. */private $proxyGenerator;/** @var int Whether to automatically (re)generate proxy classes. */private $autoGenerate;/** @var ProxyDefinition[] */private $definitions = [];/*** @param bool|int $autoGenerate** @throws InvalidArgumentException When auto generate mode is not valid.*/public function __construct(ProxyGenerator $proxyGenerator, ClassMetadataFactory $metadataFactory, $autoGenerate){$this->proxyGenerator = $proxyGenerator;$this->metadataFactory = $metadataFactory;$this->autoGenerate = (int) $autoGenerate;if (! in_array($this->autoGenerate, self::AUTOGENERATE_MODES, true)) {throw InvalidArgumentException::invalidAutoGenerateMode($autoGenerate);}}/*** Gets a reference proxy instance for the entity of the given type and identified by* the given identifier.** @param string $className* @param array<mixed> $identifier** @return Proxy** @throws OutOfBoundsException*/public function getProxy($className, array $identifier){$definition = $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 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** @return Proxy** @throws InvalidArgumentException*/public function resetUninitializedProxy(Proxy $proxy){if ($proxy->__isInitialized()) {throw InvalidArgumentException::unitializedProxyExpected($proxy);}$className = ClassUtils::getClass($proxy);$definition = $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* @psalm-param class-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;case self::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED:if (! file_exists($fileName) || filemtime($fileName) < filemtime($classMetadata->getReflectionClass()->getFileName())) {$this->proxyGenerator->generateProxyClass($classMetadata, $fileName);}require $fileName;break;}}return $this->definitions[$className];}/*** Determine if this class should be skipped during proxy generation.** @return bool*/abstract protected function skipClass(ClassMetadata $metadata);/*** @param string $className* @psalm-param class-string $className** @return ProxyDefinition*/abstract protected function createProxyDefinition($className);}