diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 98731c21..8fda6752 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6526,7 +6526,7 @@ parameters: path: tests/lib/Output/ValueObjectVisitorBaseTest.php - - message: "#^Property Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorBaseTest\\:\\:\\$generator \\(Ibexa\\\\Rest\\\\Output\\\\Generator\\\\Xml\\) in isset\\(\\) is not nullable\\.$#" + message: "#^Property Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorBaseTest\\:\\:\\$generator \\(Ibexa\\\\Rest\\\\Output\\\\Generator\\\\InMemory\\\\Xml\\) in isset\\(\\) is not nullable\\.$#" count: 1 path: tests/lib/Output/ValueObjectVisitorBaseTest.php diff --git a/src/lib/Output/Generator/InMemory/Xml.php b/src/lib/Output/Generator/InMemory/Xml.php index 1ab615ed..5523759d 100644 --- a/src/lib/Output/Generator/InMemory/Xml.php +++ b/src/lib/Output/Generator/InMemory/Xml.php @@ -10,6 +10,8 @@ use Ibexa\Rest\Output\Generator\Json; use Symfony\Component\Serializer\Encoder\XmlEncoder; +use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; +use Symfony\Component\Serializer\Serializer; final class Xml extends Json { @@ -29,6 +31,11 @@ public function startAttribute($name, $value): void $this->json->{'@' . $name} = $value; } + public function serializeBool($boolValue) + { + return $boolValue ? 'true' : 'false'; + } + public function startValueElement(string $name, $value, array $attributes = []): void { $this->checkStartValueElement($name); @@ -51,6 +58,26 @@ public function startValueElement(string $name, $value, array $attributes = []): } } + /** + * End document. + * + * Returns the generated document as a string. + */ + public function endDocument(mixed $data): string + { + parent::endDocument($data); + + $normalizedData = $this->toArray(); + + $encoderContext = $this->getEncoderContext($normalizedData); + $encoderContext['as_collection'] = true; + $transformedData = $this->transformData($normalizedData); + + $serializer = new Serializer([new ObjectNormalizer()], [new XmlEncoder()]); + + return $serializer->encode($transformedData, 'xml', $encoderContext); + } + public function transformData(array $normalizedData): array { $topNodeName = array_key_first($normalizedData); @@ -64,28 +91,30 @@ public function transformData(array $normalizedData): array $data['#'] = $normalizedData[$topNodeName]; } - return $this->clearEmptyArrays($data); + return $data; } - /** - * @param array $array - * - * @return array - */ - private function clearEmptyArrays(array &$array): array - { - foreach ($array as $key => $value) { - if (is_array($value)) { - $array[$key] = $this->clearEmptyArrays($value); - - if (empty($array[$key])) { - unset($array[$key]); - } - } - } - - return $array; - } +// /** +// * @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; +// } public function getEncoderContext(array $data): array { diff --git a/src/lib/Output/Generator/Json.php b/src/lib/Output/Generator/Json.php index 5aad23ce..b934129b 100644 --- a/src/lib/Output/Generator/Json.php +++ b/src/lib/Output/Generator/Json.php @@ -318,7 +318,7 @@ public function generateFieldTypeHash($hashElementName, $hashValue) * * @param bool $boolValue * - * @return bool + * @return mixed */ public function serializeBool($boolValue) { diff --git a/src/lib/Output/Generator/Json/JsonObject.php b/src/lib/Output/Generator/Json/JsonObject.php index 5245c6e8..8bc517e4 100644 --- a/src/lib/Output/Generator/Json/JsonObject.php +++ b/src/lib/Output/Generator/Json/JsonObject.php @@ -4,15 +4,19 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ +declare(strict_types=1); namespace Ibexa\Rest\Output\Generator\Json; +use AllowDynamicProperties; + /** * Json object. * * Special JSON object (\stdClass) implementation, which allows to access the * parent object it is assigned to again. */ +#[AllowDynamicProperties] class JsonObject { /** diff --git a/tests/lib/Output/ValueObjectVisitorBaseTest.php b/tests/lib/Output/ValueObjectVisitorBaseTest.php index 51ac42ec..b98688cd 100644 --- a/tests/lib/Output/ValueObjectVisitorBaseTest.php +++ b/tests/lib/Output/ValueObjectVisitorBaseTest.php @@ -30,7 +30,7 @@ abstract class ValueObjectVisitorBaseTest extends Server\BaseTest /** * Output generator. * - * @var \Ibexa\Rest\Output\Generator\Xml + * @var \Ibexa\Rest\Output\Generator\InMemory\Xml */ protected $generator; @@ -90,15 +90,15 @@ protected function getResponseMock() /** * Gets the output generator. * - * @return \Ibexa\Rest\Output\Generator\Xml + * @return \Ibexa\Rest\Output\Generator\InMemory\Xml */ protected function getGenerator() { if (!isset($this->generator)) { - $this->generator = new Generator\Xml( - new Generator\Xml\FieldTypeHashGenerator( - $this->createMock(NormalizerInterface::class) - ) + $this->generator = new Generator\InMemory\Xml( + new Generator\InMemory\Xml\FieldTypeHashGenerator( + $this->createMock(NormalizerInterface::class), + ), ); } diff --git a/tests/lib/Server/Output/ValueObjectVisitor/ExceptionTest.php b/tests/lib/Server/Output/ValueObjectVisitor/ExceptionTest.php index 8aefc8f0..50821f43 100644 --- a/tests/lib/Server/Output/ValueObjectVisitor/ExceptionTest.php +++ b/tests/lib/Server/Output/ValueObjectVisitor/ExceptionTest.php @@ -10,7 +10,7 @@ use DOMDocument; use DOMXPath; use Ibexa\Contracts\Rest\Output\ValueObjectVisitor; -use Ibexa\Rest\Output\Generator\Xml; +use Ibexa\Rest\Output\Generator\InMemory\Xml; use Ibexa\Rest\Server\Output\ValueObjectVisitor\Exception as ExceptionValueObjectVisitor; use Ibexa\Tests\Rest\Output\ValueObjectVisitorBaseTest; use Symfony\Contracts\Translation\TranslatorInterface;