better php 7.4 support
This commit is contained in:
parent
7a4d755f83
commit
312dfeffd7
@ -13,4 +13,5 @@
|
|||||||
|
|
||||||
<exclude-pattern>src/Component/Serializer/Generator/*</exclude-pattern>
|
<exclude-pattern>src/Component/Serializer/Generator/*</exclude-pattern>
|
||||||
<exclude-pattern>src/Component/Serializer/Parser/*</exclude-pattern>
|
<exclude-pattern>src/Component/Serializer/Parser/*</exclude-pattern>
|
||||||
|
<exclude-pattern>src/Component/Serializer/ArraySupportDecorator.php</exclude-pattern>
|
||||||
</ruleset>
|
</ruleset>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
parameters:
|
parameters:
|
||||||
|
excludePaths:
|
||||||
|
- src/Component/Serializer/ArraySupportDecorator.php
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
-
|
-
|
||||||
message: "#^Unsafe call to private method RetailCrm\\\\Api\\\\Builder\\\\ClientBuilder\\:\\:buildHandlersChain\\(\\) through static\\:\\:\\.$#"
|
message: "#^Unsafe call to private method RetailCrm\\\\Api\\\\Builder\\\\ClientBuilder\\:\\:buildHandlersChain\\(\\) through static\\:\\:\\.$#"
|
||||||
|
@ -16,6 +16,7 @@ use Liip\Serializer\Exception\UnsupportedFormatException;
|
|||||||
use Liip\Serializer\SerializerInterface;
|
use Liip\Serializer\SerializerInterface;
|
||||||
use Pnz\JsonException\Json;
|
use Pnz\JsonException\Json;
|
||||||
|
|
||||||
|
if (PHP_VERSION_ID >= 80000) {
|
||||||
/**
|
/**
|
||||||
* Class ArraySupportDecorator
|
* Class ArraySupportDecorator
|
||||||
*
|
*
|
||||||
@ -224,3 +225,213 @@ class ArraySupportDecorator implements SerializerInterface
|
|||||||
return 'mixed';
|
return 'mixed';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* Class ArraySupportDecorator
|
||||||
|
*
|
||||||
|
* @category ArraySupportDecorator
|
||||||
|
* @package RetailCrm\Api\Component\Serializer
|
||||||
|
*/
|
||||||
|
class ArraySupportDecorator implements SerializerInterface
|
||||||
|
{
|
||||||
|
private SerializerInterface $serializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ArraySupportDecorator constructor.
|
||||||
|
*
|
||||||
|
* @param \Liip\Serializer\SerializerInterface $serializer
|
||||||
|
*/
|
||||||
|
public function __construct(SerializerInterface $serializer)
|
||||||
|
{
|
||||||
|
$this->serializer = $serializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
* @throws \JsonException
|
||||||
|
*/
|
||||||
|
public function serialize($data, string $format, ?Context $context = null): string
|
||||||
|
{
|
||||||
|
if ('json' !== $format) {
|
||||||
|
throw new UnsupportedFormatException('Liip serializer only supports JSON for now');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($data)) {
|
||||||
|
try {
|
||||||
|
return Json::encode($this->encodeArray($data, $context), JSON_UNESCAPED_SLASHES);
|
||||||
|
} catch (JsonException $exception) {
|
||||||
|
throw new Exception(
|
||||||
|
sprintf(
|
||||||
|
'Failed to JSON encode data for %s. This is not supposed to happen.',
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
is_object($data) ? get_class($data) : gettype($data)
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
$exception
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->serializer->serialize($data, $format, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function deserialize(string $data, string $type, string $format, ?Context $context = null)
|
||||||
|
{
|
||||||
|
if ('json' !== $format) {
|
||||||
|
throw new UnsupportedFormatException('Liip serializer only supports JSON for now');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static::isArrayType($type)) {
|
||||||
|
try {
|
||||||
|
$array = Json::decode($data, true);
|
||||||
|
} catch (JsonException $exception) {
|
||||||
|
throw new Exception('Failed to JSON decode data. This is not supposed to happen.', 0, $exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->serializer->fromArray($this->decodeArray($array, $type, $context), $type, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->serializer->deserialize($data, $type, $format, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*
|
||||||
|
* @return array<int|string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray($data, ?Context $context = null): array
|
||||||
|
{
|
||||||
|
if (is_array($data)) {
|
||||||
|
return $this->encodeArray($data, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->serializer->toArray($data, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*
|
||||||
|
* @param array<int|string, mixed> $data
|
||||||
|
*
|
||||||
|
* @return array<int|string, mixed>|object
|
||||||
|
*/
|
||||||
|
public function fromArray(array $data, string $type, ?Context $context = null)
|
||||||
|
{
|
||||||
|
if (static::isArrayType($type)) {
|
||||||
|
return $this->decodeArray($data, $type, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->serializer->fromArray($data, $type, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes array of objects into simple multidimensional array.
|
||||||
|
*
|
||||||
|
* @param mixed[] $data
|
||||||
|
* @param \Liip\Serializer\Context|null $context
|
||||||
|
*
|
||||||
|
* @return mixed[]
|
||||||
|
* @throws \Liip\Serializer\Exception\Exception
|
||||||
|
* @throws \Liip\Serializer\Exception\UnsupportedTypeException
|
||||||
|
*/
|
||||||
|
private function encodeArray(array $data, ?Context $context = null): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
switch (gettype($value)) {
|
||||||
|
case 'array':
|
||||||
|
$result[$key] = $this->encodeArray($value, $context);
|
||||||
|
break;
|
||||||
|
case 'object':
|
||||||
|
$result[$key] = $this->serializer->toArray($value, $context);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result[$key] = $value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes array of arrays to array of objects.
|
||||||
|
*
|
||||||
|
* @param mixed[] $data
|
||||||
|
* @param string $type
|
||||||
|
* @param \Liip\Serializer\Context|null $context
|
||||||
|
*
|
||||||
|
* @return array<int|string, mixed>
|
||||||
|
* @throws \Liip\Serializer\Exception\Exception
|
||||||
|
* @throws \Liip\Serializer\Exception\UnsupportedTypeException
|
||||||
|
*/
|
||||||
|
private function decodeArray(array $data, string $type, ?Context $context = null): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
$subtype = static::getArrayValueType($type);
|
||||||
|
|
||||||
|
if (class_exists($subtype)) {
|
||||||
|
foreach ($data as $key => $item) {
|
||||||
|
if (is_array($item)) {
|
||||||
|
$result[$key] = $this->decodeArray($item, $subtype, $context);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[$key] = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if provided type is an array.
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function isArrayType(string $type): bool
|
||||||
|
{
|
||||||
|
return false !== strpos($type, 'array');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns array value type from types like 'array<string|int, Class\Name>' or 'array<string>'.
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function getArrayValueType(string $type): string
|
||||||
|
{
|
||||||
|
$matches = [];
|
||||||
|
|
||||||
|
preg_match_all(
|
||||||
|
'/array(\s+)?\<([\w\|\\\\]+)\s+\,\s+([\w\|\\\\]+)\>/m',
|
||||||
|
$type,
|
||||||
|
$matches,
|
||||||
|
PREG_SET_ORDER,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (count($matches) > 0) {
|
||||||
|
return $matches[count($matches) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
preg_match_all('/array(\s+)?\<([\w\|\\\\]+)\>/m', $type, $matches, PREG_SET_ORDER, 0);
|
||||||
|
|
||||||
|
if (count($matches) > 0) {
|
||||||
|
return $matches[count($matches) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'mixed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user