vendor/jms/serializer/src/JsonSerializationVisitor.php line 90

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace JMS\Serializer;
  4. use JMS\Serializer\Exception\NotAcceptableException;
  5. use JMS\Serializer\Exception\RuntimeException;
  6. use JMS\Serializer\Metadata\ClassMetadata;
  7. use JMS\Serializer\Metadata\PropertyMetadata;
  8. use JMS\Serializer\Visitor\SerializationVisitorInterface;
  9. final class JsonSerializationVisitor extends AbstractVisitor implements SerializationVisitorInterface
  10. {
  11.     /**
  12.      * @var int
  13.      */
  14.     private $options;
  15.     /**
  16.      * @var array
  17.      */
  18.     private $dataStack;
  19.     /**
  20.      * @var \ArrayObject|array
  21.      */
  22.     private $data;
  23.     public function __construct(
  24.         int $options JSON_PRESERVE_ZERO_FRACTION
  25.     ) {
  26.         $this->dataStack = [];
  27.         $this->options $options;
  28.     }
  29.     /**
  30.      * {@inheritdoc}
  31.      */
  32.     public function visitNull($data, array $type)
  33.     {
  34.         return null;
  35.     }
  36.     /**
  37.      * {@inheritdoc}
  38.      */
  39.     public function visitString(string $data, array $type)
  40.     {
  41.         return $data;
  42.     }
  43.     /**
  44.      * {@inheritdoc}
  45.      */
  46.     public function visitBoolean(bool $data, array $type)
  47.     {
  48.         return $data;
  49.     }
  50.     /**
  51.      * {@inheritdoc}
  52.      */
  53.     public function visitInteger(int $data, array $type)
  54.     {
  55.         return $data;
  56.     }
  57.     /**
  58.      * {@inheritdoc}
  59.      */
  60.     public function visitDouble(float $data, array $type)
  61.     {
  62.         $precision $type['params'][0] ?? null;
  63.         if (!is_int($precision)) {
  64.             return $data;
  65.         }
  66.         $roundMode $type['params'][1] ?? null;
  67.         $roundMode $this->mapRoundMode($roundMode);
  68.         return round($data$precision$roundMode);
  69.     }
  70.     /**
  71.      * @param array $data
  72.      * @param array $type
  73.      *
  74.      * @return array|\ArrayObject
  75.      */
  76.     public function visitArray(array $data, array $type)
  77.     {
  78.         \array_push($this->dataStack$data);
  79.         $rs = isset($type['params'][1]) ? new \ArrayObject() : [];
  80.         $isList = isset($type['params'][0]) && !isset($type['params'][1]);
  81.         $elType $this->getElementType($type);
  82.         foreach ($data as $k => $v) {
  83.             try {
  84.                 $v $this->navigator->accept($v$elType);
  85.             } catch (NotAcceptableException $e) {
  86.                 continue;
  87.             }
  88.             if ($isList) {
  89.                 $rs[] = $v;
  90.             } else {
  91.                 $rs[$k] = $v;
  92.             }
  93.         }
  94.         \array_pop($this->dataStack);
  95.         return $rs;
  96.     }
  97.     public function startVisitingObject(ClassMetadata $metadataobject $data, array $type): void
  98.     {
  99.         \array_push($this->dataStack$this->data);
  100.         $this->data true === $metadata->isMap ? new \ArrayObject() : [];
  101.     }
  102.     /**
  103.      * @return array|\ArrayObject
  104.      */
  105.     public function endVisitingObject(ClassMetadata $metadataobject $data, array $type)
  106.     {
  107.         $rs $this->data;
  108.         $this->data = \array_pop($this->dataStack);
  109.         if (true !== $metadata->isList && empty($rs)) {
  110.             return new \ArrayObject();
  111.         }
  112.         return $rs;
  113.     }
  114.     /**
  115.      * {@inheritdoc}
  116.      */
  117.     public function visitProperty(PropertyMetadata $metadata$v): void
  118.     {
  119.         try {
  120.             $v $this->navigator->accept($v$metadata->type);
  121.         } catch (NotAcceptableException $e) {
  122.             return;
  123.         }
  124.         if (true === $metadata->skipWhenEmpty && ($v instanceof \ArrayObject || \is_array($v)) && === count($v)) {
  125.             return;
  126.         }
  127.         if ($metadata->inline) {
  128.             if (\is_array($v) || ($v instanceof \ArrayObject)) {
  129.                 // concatenate the two array-like structures
  130.                 // is there anything faster?
  131.                 foreach ($v as $key => $value) {
  132.                     $this->data[$key] = $value;
  133.                 }
  134.             }
  135.         } else {
  136.             $this->data[$metadata->serializedName] = $v;
  137.         }
  138.     }
  139.     /**
  140.      * Checks if some data key exists.
  141.      */
  142.     public function hasData(string $key): bool
  143.     {
  144.         return isset($this->data[$key]);
  145.     }
  146.     /**
  147.      * @deprecated Use `::visitProperty(new StaticPropertyMetadata('', 'name', 'value'), 'value')` instead
  148.      *
  149.      * Allows you to replace existing data on the current object element.
  150.      *
  151.      * @param mixed $value This value must either be a regular scalar, or an array.
  152.      *                                                       It must not contain any objects anymore.
  153.      */
  154.     public function setData(string $key$value): void
  155.     {
  156.         $this->data[$key] = $value;
  157.     }
  158.     /**
  159.      * {@inheritdoc}
  160.      */
  161.     public function getResult($data)
  162.     {
  163.         unset($this->navigator);
  164.         $result = @json_encode($data$this->options);
  165.         switch (json_last_error()) {
  166.             case JSON_ERROR_NONE:
  167.                 return $result;
  168.             case JSON_ERROR_UTF8:
  169.                 throw new RuntimeException('Your data could not be encoded because it contains invalid UTF8 characters.');
  170.             default:
  171.                 throw new RuntimeException(sprintf('An error occurred while encoding your data (error code %d).'json_last_error()));
  172.         }
  173.     }
  174. }