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