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

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.         switch ($class) {
  50.             case 'stdClass':
  51.                 return self::$hydrators[$class] = static function ($properties$objects) {
  52.                     foreach ($properties as $name => $values) {
  53.                         foreach ($values as $i => $v) {
  54.                             $objects[$i]->$name $v;
  55.                         }
  56.                     }
  57.                 };
  58.             case 'ErrorException':
  59.                 return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \ErrorException {
  60.                 });
  61.             case 'TypeError':
  62.                 return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \Error {
  63.                 });
  64.             case 'SplObjectStorage':
  65.                 return self::$hydrators[$class] = static function ($properties$objects) {
  66.                     foreach ($properties as $name => $values) {
  67.                         if ("\0" === $name) {
  68.                             foreach ($values as $i => $v) {
  69.                                 for ($j 0$j \count($v); ++$j) {
  70.                                     $objects[$i]->attach($v[$j], $v[++$j]);
  71.                                 }
  72.                             }
  73.                             continue;
  74.                         }
  75.                         foreach ($values as $i => $v) {
  76.                             $objects[$i]->$name $v;
  77.                         }
  78.                     }
  79.                 };
  80.         }
  81.         if (!class_exists($class) && !interface_exists($classfalse) && !trait_exists($classfalse)) {
  82.             throw new ClassNotFoundException($class);
  83.         }
  84.         $classReflector = new \ReflectionClass($class);
  85.         switch ($class) {
  86.             case 'ArrayIterator':
  87.             case 'ArrayObject':
  88.                 $constructor \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']);
  89.                 return self::$hydrators[$class] = static function ($properties$objects) use ($constructor) {
  90.                     foreach ($properties as $name => $values) {
  91.                         if ("\0" !== $name) {
  92.                             foreach ($values as $i => $v) {
  93.                                 $objects[$i]->$name $v;
  94.                             }
  95.                         }
  96.                     }
  97.                     foreach ($properties["\0"] ?? [] as $i => $v) {
  98.                         $constructor($objects[$i], $v);
  99.                     }
  100.                 };
  101.         }
  102.         if (!$classReflector->isInternal()) {
  103.             return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null$class);
  104.         }
  105.         if ($classReflector->name !== $class) {
  106.             return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name);
  107.         }
  108.         $propertySetters = [];
  109.         foreach ($classReflector->getProperties() as $propertyReflector) {
  110.             if (!$propertyReflector->isStatic()) {
  111.                 $propertyReflector->setAccessible(true);
  112.                 $propertySetters[$propertyReflector->name] = \Closure::fromCallable([$propertyReflector'setValue']);
  113.             }
  114.         }
  115.         if (!$propertySetters) {
  116.             return self::$hydrators[$class] = self::$hydrators['stdClass'] ?? self::getHydrator('stdClass');
  117.         }
  118.         return self::$hydrators[$class] = static function ($properties$objects) use ($propertySetters) {
  119.             foreach ($properties as $name => $values) {
  120.                 if ($setValue $propertySetters[$name] ?? null) {
  121.                     foreach ($values as $i => $v) {
  122.                         $setValue($objects[$i], $v);
  123.                     }
  124.                     continue;
  125.                 }
  126.                 foreach ($values as $i => $v) {
  127.                     $objects[$i]->$name $v;
  128.                 }
  129.             }
  130.         };
  131.     }
  132. }