vendor/symfony/var-exporter/Internal/Hydrator.php line 43

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\Exception\ClassNotFoundException;
  12. /**
  13.  * @author Nicolas Grekas <p@tchwork.com>
  14.  *
  15.  * @internal
  16.  */
  17. class Hydrator
  18. {
  19.     public static $hydrators = [];
  20.     public $registry;
  21.     public $values;
  22.     public $properties;
  23.     public $value;
  24.     public $wakeups;
  25.     public function __construct(?Registry $registry, ?Values $values, array $properties$value, array $wakeups)
  26.     {
  27.         $this->registry $registry;
  28.         $this->values $values;
  29.         $this->properties $properties;
  30.         $this->value $value;
  31.         $this->wakeups $wakeups;
  32.     }
  33.     public static function hydrate($objects$values$properties$value$wakeups)
  34.     {
  35.         foreach ($properties as $class => $vars) {
  36.             (self::$hydrators[$class] ?? self::getHydrator($class))($vars$objects);
  37.         }
  38.         foreach ($wakeups as $k => $v) {
  39.             if (\is_array($v)) {
  40.                 $objects[-$k]->__unserialize($v);
  41.             } else {
  42.                 $objects[$v]->__wakeup();
  43.             }
  44.         }
  45.         return $value;
  46.     }
  47.     public static function getHydrator($class)
  48.     {
  49.         if ('stdClass' === $class) {
  50.             return self::$hydrators[$class] = static function ($properties$objects) {
  51.                 foreach ($properties as $name => $values) {
  52.                     foreach ($values as $i => $v) {
  53.                         $objects[$i]->$name $v;
  54.                     }
  55.                 }
  56.             };
  57.         }
  58.         if (!class_exists($class) && !interface_exists($classfalse) && !trait_exists($classfalse)) {
  59.             throw new ClassNotFoundException($class);
  60.         }
  61.         $classReflector = new \ReflectionClass($class);
  62.         if (!$classReflector->isInternal()) {
  63.             return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null$class);
  64.         }
  65.         if ($classReflector->name !== $class) {
  66.             return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name);
  67.         }
  68.         switch ($class) {
  69.             case 'ArrayIterator':
  70.             case 'ArrayObject':
  71.                 $constructor \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']);
  72.                 return self::$hydrators[$class] = static function ($properties$objects) use ($constructor) {
  73.                     foreach ($properties as $name => $values) {
  74.                         if ("\0" !== $name) {
  75.                             foreach ($values as $i => $v) {
  76.                                 $objects[$i]->$name $v;
  77.                             }
  78.                         }
  79.                     }
  80.                     foreach ($properties["\0"] ?? [] as $i => $v) {
  81.                         $constructor($objects[$i], $v);
  82.                     }
  83.                 };
  84.             case 'ErrorException':
  85.                 return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \ErrorException {
  86.                 });
  87.             case 'TypeError':
  88.                 return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \Error {
  89.                 });
  90.             case 'SplObjectStorage':
  91.                 return self::$hydrators[$class] = static function ($properties$objects) {
  92.                     foreach ($properties as $name => $values) {
  93.                         if ("\0" === $name) {
  94.                             foreach ($values as $i => $v) {
  95.                                 for ($j 0$j \count($v); ++$j) {
  96.                                     $objects[$i]->attach($v[$j], $v[++$j]);
  97.                                 }
  98.                             }
  99.                             continue;
  100.                         }
  101.                         foreach ($values as $i => $v) {
  102.                             $objects[$i]->$name $v;
  103.                         }
  104.                     }
  105.                 };
  106.         }
  107.         $propertySetters = [];
  108.         foreach ($classReflector->getProperties() as $propertyReflector) {
  109.             if (!$propertyReflector->isStatic()) {
  110.                 $propertyReflector->setAccessible(true);
  111.                 $propertySetters[$propertyReflector->name] = \Closure::fromCallable([$propertyReflector'setValue']);
  112.             }
  113.         }
  114.         if (!$propertySetters) {
  115.             return self::$hydrators[$class] = self::$hydrators['stdClass'] ?? self::getHydrator('stdClass');
  116.         }
  117.         return self::$hydrators[$class] = static function ($properties$objects) use ($propertySetters) {
  118.             foreach ($properties as $name => $values) {
  119.                 if ($setValue $propertySetters[$name] ?? null) {
  120.                     foreach ($values as $i => $v) {
  121.                         $setValue($objects[$i], $v);
  122.                     }
  123.                     continue;
  124.                 }
  125.                 foreach ($values as $i => $v) {
  126.                     $objects[$i]->$name $v;
  127.                 }
  128.             }
  129.         };
  130.     }
  131. }