vendor/symfony/var-exporter/Internal/LazyObjectState.php line 61

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\VarExporter\Internal;
  11. use Symfony\Component\VarExporter\Hydrator as PublicHydrator;
  12. /**
  13.  * Keeps the state of lazy objects.
  14.  *
  15.  * As a micro-optimization, this class uses no type declarations.
  16.  *
  17.  * @internal
  18.  */
  19. class LazyObjectState
  20. {
  21.     public const STATUS_UNINITIALIZED_FULL 1;
  22.     public const STATUS_UNINITIALIZED_PARTIAL 2;
  23.     public const STATUS_INITIALIZED_FULL 3;
  24.     public const STATUS_INITIALIZED_PARTIAL 4;
  25.     /**
  26.      * @var array<string, true>
  27.      */
  28.     public readonly array $skippedProperties;
  29.     /**
  30.      * @var self::STATUS_*
  31.      */
  32.     public int $status 0;
  33.     public object $realInstance;
  34.     public function __construct(public readonly \Closure|array $initializer$skippedProperties = [])
  35.     {
  36.         $this->skippedProperties $skippedProperties;
  37.         $this->status \is_array($initializer) ? self::STATUS_UNINITIALIZED_PARTIAL self::STATUS_UNINITIALIZED_FULL;
  38.     }
  39.     public function initialize($instance$propertyName$propertyScope)
  40.     {
  41.         if (self::STATUS_INITIALIZED_FULL === $this->status) {
  42.             return self::STATUS_INITIALIZED_FULL;
  43.         }
  44.         if (\is_array($this->initializer)) {
  45.             $class $instance::class;
  46.             $propertyScope ??= $class;
  47.             $propertyScopes Hydrator::$propertyScopes[$class];
  48.             $propertyScopes[$k "\0$propertyScope\0$propertyName"] ?? $propertyScopes[$k "\0*\0$propertyName"] ?? $k $propertyName;
  49.             if ($initializer $this->initializer[$k] ?? null) {
  50.                 $value $initializer(...[$instance$propertyName$propertyScopeLazyObjectRegistry::$defaultProperties[$class][$k] ?? null]);
  51.                 $accessor LazyObjectRegistry::$classAccessors[$propertyScope] ??= LazyObjectRegistry::getClassAccessors($propertyScope);
  52.                 $accessor['set']($instance$propertyName$value);
  53.                 return $this->status self::STATUS_INITIALIZED_PARTIAL;
  54.             }
  55.             $status self::STATUS_UNINITIALIZED_PARTIAL;
  56.             if ($initializer $this->initializer["\0"] ?? null) {
  57.                 if (!\is_array($values $initializer($instanceLazyObjectRegistry::$defaultProperties[$class]))) {
  58.                     throw new \TypeError(sprintf('The lazy-initializer defined for instance of "%s" must return an array, got "%s".'$classget_debug_type($values)));
  59.                 }
  60.                 $properties = (array) $instance;
  61.                 foreach ($values as $key => $value) {
  62.                     if ($k === $key) {
  63.                         $status self::STATUS_INITIALIZED_PARTIAL;
  64.                     }
  65.                     if (!\array_key_exists($key$properties) && [$scope$name$readonlyScope] = $propertyScopes[$key] ?? null) {
  66.                         $scope $readonlyScope ?? ('*' !== $scope $scope $class);
  67.                         $accessor LazyObjectRegistry::$classAccessors[$scope] ??= LazyObjectRegistry::getClassAccessors($scope);
  68.                         $accessor['set']($instance$name$value);
  69.                     }
  70.                 }
  71.             }
  72.             return $status;
  73.         }
  74.         $this->status self::STATUS_INITIALIZED_FULL;
  75.         try {
  76.             if ($defaultProperties array_diff_key(LazyObjectRegistry::$defaultProperties[$instance::class], $this->skippedProperties)) {
  77.                 PublicHydrator::hydrate($instance$defaultProperties);
  78.             }
  79.             ($this->initializer)($instance);
  80.         } catch (\Throwable $e) {
  81.             $this->status self::STATUS_UNINITIALIZED_FULL;
  82.             $this->reset($instance);
  83.             throw $e;
  84.         }
  85.         return self::STATUS_INITIALIZED_FULL;
  86.     }
  87.     public function reset($instance): void
  88.     {
  89.         $class $instance::class;
  90.         $propertyScopes Hydrator::$propertyScopes[$class] ??= Hydrator::getPropertyScopes($class);
  91.         $skippedProperties $this->skippedProperties;
  92.         $properties = (array) $instance;
  93.         $onlyProperties \is_array($this->initializer) ? $this->initializer null;
  94.         foreach ($propertyScopes as $key => [$scope$name$readonlyScope]) {
  95.             $propertyScopes[$k "\0$scope\0$name"] ?? $propertyScopes[$k "\0*\0$name"] ?? $k $name;
  96.             if ($k === $key && (null !== $readonlyScope || !\array_key_exists($k$properties))) {
  97.                 $skippedProperties[$k] = true;
  98.             }
  99.         }
  100.         foreach (LazyObjectRegistry::$classResetters[$class] as $reset) {
  101.             $reset($instance$skippedProperties$onlyProperties);
  102.         }
  103.         $this->status self::STATUS_INITIALIZED_FULL === $this->status self::STATUS_UNINITIALIZED_FULL self::STATUS_UNINITIALIZED_PARTIAL;
  104.     }
  105. }