lib/composer/LisaBundle/src/VisualMedia/LisaBundle/Component/Serializer.php line 221

Open in your IDE?
  1. <?php
  2. /**
  3.  * Serializer
  4.  *
  5.  * @author Bertin van den Ham <b.vandenham@visualmedia.nl>
  6.  * @author Vincent van Waasbergen <v.vanwaasbergen@visualmedia.nl>
  7.  */
  8. namespace VisualMedia\LisaBundle\Component;
  9. use DateTime;
  10. use ReflectionClass;
  11. use ReflectionMethod;
  12. use Doctrine\Common\Collections\ArrayCollection;
  13. use Doctrine\Common\Collections\Collection;
  14. use Doctrine\ORM\EntityManagerInterface;
  15. use VisualMedia\LisaBundle\Component\Interfaces\SingletonInterface;
  16. use VisualMedia\LisaBundle\Helper\EntityHelper;
  17. use VisualMedia\LisaBundle\Helper\Helper;
  18. use VisualMedia\LisaBundle\Component\Interfaces\EntityInterface;
  19. /**
  20.  * Serializer
  21.  */
  22. abstract class Serializer implements SerializerInterface
  23. {
  24.     /**
  25.      * @var string
  26.      */
  27.     protected $class;
  28.     /**
  29.      * @var EntityManagerInterface
  30.      */
  31.     protected $em;
  32.     /**
  33.      * @var array
  34.      */
  35.     public $registry = array();
  36.     /**
  37.      * @param EntityManagerInterface $em
  38.      */
  39.     public function __construct(EntityManagerInterface $em)
  40.     {
  41.         $this->em $em;
  42.     }
  43.     /**
  44.      * {@inheritdoc}
  45.      */
  46.     public function serialize($model): string
  47.     {
  48.         if ($model !== null) {
  49.             $this->class get_class($model);
  50.         }
  51.         return $this->encode($this->normalize($model));
  52.     }
  53.     /**
  54.      * {@inheritdoc}
  55.      */
  56.     public function deserialize(?string $json)
  57.     {
  58.         return $this->denormalize($this->decode($json));
  59.     }
  60.     /**
  61.      * {@inheritdoc}
  62.      */
  63.     public function encode(array $data): string
  64.     {
  65.         return json_encode($dataJSON_PRETTY_PRINT);
  66.     }
  67.     /**
  68.      * {@inheritdoc}
  69.      */
  70.     public function decode(?string $json): array
  71.     {
  72.         return json_decode($jsontrue) ?: [];
  73.     }
  74.     /**
  75.      * {@inheritdoc}
  76.      */
  77.     public function normalize($model): array
  78.     {
  79.         if ($model !== null) {
  80.             $this->class get_class($model);
  81.         }
  82.         $this->registry = array();
  83.         return $this->normalizeInternal($model);
  84.     }
  85.     /**
  86.      * {@inheritdoc}
  87.      */
  88.     public function normalizeInternal($model): array
  89.     {
  90.         if ($model === null) {
  91.             return array();
  92.         }
  93.         if ($model instanceof EntityInterface && get_class($model) !== $this->class && $model->getId() !== null) {
  94.             return $this->normalizeValue($model);
  95.         }
  96.         $data = array(
  97.             static::META_INSTANCE => sprintf('%s%s%s'get_class($model), static::META_INSTANCE_DELIMITERspl_object_id($model)),
  98.         );
  99.         $this->registry[spl_object_id($model)] = $model;
  100.         $reflection = new ReflectionClass($model);
  101.         foreach ($reflection->getProperties() as $reflectionProperty) {
  102.             // Property name.
  103.             if (null === $name $reflectionProperty->name) {
  104.                 continue;
  105.             }
  106.             // Get data.
  107.             $getter EntityHelper::getter($name);
  108.             if (method_exists($model$getter)) {
  109.                 $value $model->{$getter}();
  110.             }
  111.             elseif (property_exists($model$name) && $reflectionProperty->isPublic()) {
  112.                 $value $model->{$name};
  113.             }
  114.             else {
  115.                 continue;
  116.             }
  117.             // Array.
  118.             if ($value instanceof Collection) {
  119.                 $data[$name][static::META_COLLECTION] = true;
  120.                 foreach ($value as $k=>$v) {
  121.                     $data[$name][$k] = $this->normalizeValue($v);
  122.                 }
  123.             }
  124.             elseif (is_array($value)) {
  125.                 foreach ($value as $k=>$v) {
  126.                     $data[$name][$k] = $this->normalizeValue($v);
  127.                 }
  128.             }
  129.             else {
  130.                 $data[$name] = $this->normalizeValue($value);
  131.             }
  132.         }
  133.         return $data;
  134.     }
  135.     /**
  136.      * {@inheritdoc}
  137.      */
  138.     public function normalizeValue($value)
  139.     {
  140.         // Native.
  141.         if (is_string($value) || is_bool($value) || is_numeric($value)) {
  142.             return $value;
  143.         }
  144.         // DateTime.
  145.         if ($value instanceof DateTime) {
  146.             return $value->format('Y-m-d H:i:s');
  147.         }
  148.         // Object.
  149.         if (is_object($value)) {
  150.             return $this->normalizeOnce($value);
  151.         }
  152.         return null;
  153.     }
  154.     /**
  155.      * {@inheritdoc}
  156.      */
  157.     public function normalizeOnce($model): array
  158.     {
  159.         // Entity.
  160.         if ($model instanceof EntityInterface && $model->getId() !== null) {
  161.             $data = array(static::META_DATABASE => sprintf('%s%s%s'get_class($model), static::META_DATABASE_DELIMITER$model->getId()));
  162.         }
  163.         // New instance.
  164.         elseif (null === $instance $this->registry[$id spl_object_id($model)] ?? null) {
  165.             $this->registry[$id] = $model;
  166.             $data $this->normalizeInternal($model);
  167.         }
  168.         // Instance reference.
  169.         else {
  170.             $data = array(static::META_INSTANCE => sprintf('%s%s%s'get_class($model), static::META_INSTANCE_DELIMITER$id));
  171.         }
  172.         return $data;
  173.     }
  174.     /**
  175.      * {@inheritdoc}
  176.      */
  177.     public function denormalize(array $datastring $class null)
  178.     {
  179.         $this->registry = array();
  180.         return $this->denormalizeInternal($data$class);
  181.     }
  182.     /**
  183.      * {@inheritdoc}
  184.      */
  185.     public function denormalizeInternal(array $datastring $class null)
  186.     {
  187.         if (null !== $database $data[static::META_DATABASE] ?? null) {
  188.             return $this->denormalizeValue($data);
  189.         }
  190.         @list($instanceClass$id) = explode(static::META_INSTANCE_DELIMITER$data[static::META_INSTANCE]);
  191.         if (null === $class $instanceClass ?: $class) {
  192.             return null;
  193.         }
  194.         $reflection = new ReflectionClass($class);
  195.         if ($reflection->implementsInterface(SingletonInterface::class)) {
  196.             $model $class::getSingleInstance();
  197.         }
  198.         else {
  199.             $model = new $class();
  200.         }
  201.         $this->registry[$id] = $model;
  202.         foreach ($data as $key=>$value) {
  203.             $setter EntityHelper::setter($key);
  204.             // Object.
  205.             if (null !== $id $value[static::META_INSTANCE] ?? null) {
  206.                 $value $this->denormalizeOnce($value);
  207.             }
  208.             // Array.
  209.             elseif (is_array($value)) {
  210.                 foreach ($value as $k=>$v) {
  211.                     if (null !== $id $v[static::META_INSTANCE] ?? null) {
  212.                         $value[$k] = $this->denormalizeOnce($v);
  213.                     }
  214.                 }
  215.             }
  216.             // Value.
  217.             if (null === $value $this->denormalizeValue($value)) {
  218.                 continue;
  219.             }
  220.             // Set data.
  221.             if (method_exists($model$setter)) {
  222.                 $model->{$setter}($value);
  223.             }
  224.             elseif (property_exists($model$key) && $reflection->getProperty($key)->isPublic()) {
  225.                 $model->{$key} = $value;
  226.             }
  227.         }
  228.         return $model;
  229.     }
  230.     /**
  231.      * {@inheritdoc}
  232.      */
  233.     public function denormalizeValue($value)
  234.     {
  235.         // Empty.
  236.         if ($value === '') {
  237.             return null;
  238.         }
  239.         // Numeric.
  240.         if (is_numeric($value)) {
  241.             if ((int)$value !== $value) {
  242.                 $value = (float)$value;
  243.             }
  244.             else {
  245.                 $value = (int)$value;
  246.             }
  247.         }
  248.         // DateTime.
  249.         if (is_string($value) && preg_match('/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/'$value)) {
  250.             $value = new DateTime($value);
  251.         }
  252.         // Collection.
  253.         if (is_array($value) && true === $collection $value[static::META_COLLECTION] ?? null) {
  254.             $collection = new ArrayCollection();
  255.             foreach ($value as $k=>$v) {
  256.                 if ($k === static::META_COLLECTION) {
  257.                     continue;
  258.                 }
  259.                 $collection->add($this->denormalizeValue($v));
  260.             }
  261.             $value $collection;
  262.         }
  263.         // Database.
  264.         if (is_array($value) && null !== $key $value[static::META_DATABASE] ?? null) {
  265.             @list($class$id) = explode(static::META_DATABASE_DELIMITER$key);
  266.             $repository $this->em->getRepository($class);
  267.             $value $repository->getFirst(new ManagerData(array($repository::OPTION_ID => $id)));
  268.         }
  269.         return $value;
  270.     }
  271.     /**
  272.      * {@inheritdoc}
  273.      */
  274.     public function denormalizeOnce(array $data)
  275.     {
  276.         @list($class$id) = explode(static::META_INSTANCE_DELIMITER$data[static::META_INSTANCE]);
  277.         // New instance.
  278.         if (null === $instance $this->registry[$id] ?? null) {
  279.             $model $this->denormalizeInternal($data);
  280.             $this->registry[$id] = $model;
  281.         }
  282.         // Instance reference.
  283.         else {
  284.             $model $this->registry[$id];
  285.         }
  286.         return $model;
  287.     }
  288. }