From 20b17e6f8b312d532ff00188031848cfee20f63a Mon Sep 17 00:00:00 2001 From: Bartek Wajda Date: Thu, 10 Oct 2024 15:03:02 +0200 Subject: [PATCH] Update Generator normalizers --- phpstan-baseline.neon | 51 ++++++++++--------- src/bundle/Resources/config/services.yml | 12 +++++ src/lib/Output/Generator/InMemory/Xml.php | 47 ++--------------- src/lib/Output/Generator/Json.php | 5 +- .../Normalizer/JsonObjectNormalizer.php | 5 +- .../ValueObjectVisitor/BookmarkListTest.php | 1 - 6 files changed, 51 insertions(+), 70 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 52f14221..712d30d0 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -415,6 +415,11 @@ parameters: count: 1 path: src/contracts/Output/Visitor.php + - + message: "#^Method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\VisitorAdapterNormalizer\\:\\:visitValueObject\\(\\) should return array but returns array\\|ArrayObject\\<\\(int\\|string\\), mixed\\>\\|bool\\|float\\|int\\|string\\|null\\.$#" + count: 1 + path: src/contracts/Output/VisitorAdapterNormalizer.php + - message: "#^Method Ibexa\\\\Rest\\\\FieldTypeProcessor\\\\BaseRelationProcessor\\:\\:setLocationService\\(\\) has no return type specified\\.$#" count: 1 @@ -626,27 +631,22 @@ parameters: path: src/lib/Output/FieldTypeSerializer.php - - message: "#^Access to an undefined property Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject\\:\\:\\$\\#text\\.$#" + message: "#^Access to an undefined property Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject\\:\\:\\$\\#\\.$#" count: 1 - path: src/lib/Output/Generator/Json.php + path: src/lib/Output/Generator/InMemory/Xml.php - - message: "#^Argument of an invalid type Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject supplied for foreach, only iterables are supported\\.$#" + message: "#^Access to an undefined property Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject\\:\\:\\$\\#text\\.$#" count: 1 path: src/lib/Output/Generator/Json.php - - message: "#^Cannot call method getParent\\(\\) on array\\.$#" - count: 3 - path: src/lib/Output/Generator/Json.php - - - - message: "#^Method Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\:\\:endAttribute\\(\\) has no return type specified\\.$#" + message: "#^Argument of an invalid type Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject supplied for foreach, only iterables are supported\\.$#" count: 1 path: src/lib/Output/Generator/Json.php - - message: "#^Method Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\:\\:endDocument\\(\\) should return string but returns string\\|false\\.$#" + message: "#^Method Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\:\\:endAttribute\\(\\) has no return type specified\\.$#" count: 1 path: src/lib/Output/Generator/Json.php @@ -701,23 +701,13 @@ parameters: path: src/lib/Output/Generator/Json.php - - message: "#^Parameter \\#1 \\$parent of method Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\FieldTypeHashGenerator\\:\\:generateHashValue\\(\\) expects Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\ArrayObject\\|Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject, array given\\.$#" - count: 1 - path: src/lib/Output/Generator/Json.php - - - - message: "#^Property Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\:\\:\\$json \\(array\\) does not accept Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\ArrayObject\\.$#" + message: "#^Parameter \\#1 \\$parent of method Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\FieldTypeHashGenerator\\:\\:generateHashValue\\(\\) expects Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\ArrayObject\\|Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject, Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Data\\\\ArrayList\\|Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\ArrayObject\\|Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject given\\.$#" count: 1 path: src/lib/Output/Generator/Json.php - - message: "#^Property Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\:\\:\\$json \\(array\\) does not accept Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject\\.$#" - count: 5 - path: src/lib/Output/Generator/Json.php - - - - message: "#^Property Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\:\\:\\$json type has no value type specified in iterable type array\\.$#" - count: 1 + message: "#^Property Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\:\\:\\$json \\(Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Data\\\\ArrayList\\|Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\ArrayObject\\|Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Json\\\\JsonObject\\) does not accept object\\.$#" + count: 3 path: src/lib/Output/Generator/Json.php - @@ -805,6 +795,21 @@ parameters: count: 1 path: src/lib/Output/Generator/Xml.php + - + message: "#^Method Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Xml\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/lib/Output/Generator/Xml.php + + - + message: "#^Method Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Xml\\:\\:transformData\\(\\) has parameter \\$normalizedData with no value type specified in iterable type array\\.$#" + count: 1 + path: src/lib/Output/Generator/Xml.php + + - + message: "#^Method Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Xml\\:\\:transformData\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/lib/Output/Generator/Xml.php + - message: "#^Parameter \\#1 \\$content of method XMLWriter\\:\\:text\\(\\) expects string, bool\\|float\\|int\\|string\\|null given\\.$#" count: 1 diff --git a/src/bundle/Resources/config/services.yml b/src/bundle/Resources/config/services.yml index 0975d87c..f6454f2a 100644 --- a/src/bundle/Resources/config/services.yml +++ b/src/bundle/Resources/config/services.yml @@ -441,6 +441,18 @@ services: tags: - { name: ibexa.rest.serializer.normalizer, priority: -1000 } + Ibexa\Rest\Output\Normalizer\JsonObjectNormalizer: + tags: + - { name: ibexa.rest.serializer.normalizer, priority: -500 } + + Ibexa\Rest\Output\Normalizer\ArrayListNormalizer: + tags: + - { name: ibexa.rest.serializer.normalizer, priority: -400 } + + Ibexa\Rest\Output\Normalizer\ArrayObjectNormalizer: + tags: + - { name: ibexa.rest.serializer.normalizer, priority: -400 } + Ibexa\Contracts\Rest\Output\ValueObjectVisitorResolverInterface: '@Ibexa\Contracts\Rest\Output\ValueObjectVisitor' Ibexa\Contracts\Rest\Output\ValueObjectVisitorResolver: ~ diff --git a/src/lib/Output/Generator/InMemory/Xml.php b/src/lib/Output/Generator/InMemory/Xml.php index 6fe594aa..e21b8560 100644 --- a/src/lib/Output/Generator/InMemory/Xml.php +++ b/src/lib/Output/Generator/InMemory/Xml.php @@ -9,6 +9,7 @@ namespace Ibexa\Rest\Output\Generator\InMemory; use Ibexa\Rest\Output\Generator\Data; +use Ibexa\Rest\Output\Generator\Data\ArrayList; use Ibexa\Rest\Output\Generator\Json; use Ibexa\Rest\Output\Normalizer\ArrayListNormalizer; use Ibexa\Rest\Output\Normalizer\ArrayObjectNormalizer; @@ -65,7 +66,7 @@ public function startValueElement(string $name, $value, array $attributes = []): $jsonValue->{'#'} = $value; } - if ($this->json instanceof Json\ArrayObject) { + if ($this->json instanceof Json\ArrayObject || $this->json instanceof ArrayList) { $this->json->append($jsonValue); } else { $this->json->$name = $jsonValue; @@ -90,6 +91,7 @@ public function endDocument(mixed $data): string $vars = get_object_vars($data); $encoderContext = $this->getEncoderContext($vars); $encoderContext['as_collection'] = true; + $encoderContext['outer_element'] = true; $normalizers = [ new ArrayListNormalizer(), @@ -103,49 +105,6 @@ public function endDocument(mixed $data): string return $serializer->serialize($data, 'xml', $encoderContext); } - /** - * @param array $normalizedData - * - * @return array - */ - private function transformData(array $normalizedData): array - { - $topNodeName = array_key_first($normalizedData); - $data = array_filter( - $normalizedData[$topNodeName] ?? [], - static fn (string $key): bool => str_starts_with($key, '@'), - ARRAY_FILTER_USE_KEY, - ); - - if ($topNodeName !== null) { - $data['#'] = $normalizedData[$topNodeName]; - } - - return $this->clearEmptyArrays($data); - } - - /** - * @param array $array - * - * @return array - */ - private function clearEmptyArrays(array &$array): array - { - foreach ($array as $key => &$value) { - if (is_array($value)) { - // Recursively apply the function to the nested array - $this->clearEmptyArrays($value); - - // Remove the field if it's an empty array after recursion - if (empty($value)) { - unset($array[$key]); - } - } - } - - return $array; - } - protected function getEncoderContext(array $data): array { return [ diff --git a/src/lib/Output/Generator/Json.php b/src/lib/Output/Generator/Json.php index 42064756..bfa337f6 100644 --- a/src/lib/Output/Generator/Json.php +++ b/src/lib/Output/Generator/Json.php @@ -182,8 +182,11 @@ public function startHashElement($name) $object = new Json\JsonObject($this->json); - if ($this->json instanceof Json\ArrayObject) { + if ($this->json instanceof Json\ArrayObject || $this->json instanceof Data\ArrayList) { $this->json->append($object); + if ($this->json instanceof Data\ArrayList) { + $this->json->setName($name); + } $this->json = $object; } else { $this->json->$name = $object; diff --git a/src/lib/Output/Normalizer/JsonObjectNormalizer.php b/src/lib/Output/Normalizer/JsonObjectNormalizer.php index f7b8f0a2..0c6f92a8 100644 --- a/src/lib/Output/Normalizer/JsonObjectNormalizer.php +++ b/src/lib/Output/Normalizer/JsonObjectNormalizer.php @@ -26,13 +26,16 @@ public function normalize($object, ?string $format = null, array $context = []): { $vars = get_object_vars($object); + $isOuterElement = $context['outer_element'] ?? false; + unset($context['outer_element']); + $data = []; foreach ($vars as $key => $value) { if ($value instanceof ArrayList) { $name = $value->getName(); $data[$name] = $this->normalizer->normalize($value, $format, $context); } else { - $data[$key] = $this->normalizer->normalize($value, $format, $context); + $data[$isOuterElement && count($vars) === 1 ? '#' : $key] = $this->normalizer->normalize($value, $format, $context); } } diff --git a/tests/lib/Server/Output/ValueObjectVisitor/BookmarkListTest.php b/tests/lib/Server/Output/ValueObjectVisitor/BookmarkListTest.php index f772d470..9662f773 100644 --- a/tests/lib/Server/Output/ValueObjectVisitor/BookmarkListTest.php +++ b/tests/lib/Server/Output/ValueObjectVisitor/BookmarkListTest.php @@ -94,7 +94,6 @@ public function testResultContainsBookmarkElement(string $result): void $document->loadXML($result); $xpath = new DOMXPath($document); - dump($result); self::assertEquals(count($this->data->items), $xpath->query($query)->length); }