diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 079fac3f..98731c21 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -50,11 +50,6 @@ parameters: count: 1 path: src/bundle/DependencyInjection/Compiler/OutputVisitorPass.php - - - message: "#^Method Ibexa\\\\Bundle\\\\Rest\\\\DependencyInjection\\\\Compiler\\\\ValueObjectVisitorPass\\:\\:process\\(\\) has no return type specified\\.$#" - count: 1 - path: src/bundle/DependencyInjection/Compiler/ValueObjectVisitorPass.php - - message: "#^Method Ibexa\\\\Bundle\\\\Rest\\\\DependencyInjection\\\\Configuration\\:\\:addRestRootResourcesSection\\(\\) has parameter \\$rootNode with no type specified\\.$#" count: 1 @@ -405,26 +400,6 @@ parameters: count: 1 path: src/contracts/Output/ValueObjectVisitor.php - - - message: "#^Method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcher\\:\\:addVisitor\\(\\) has no return type specified\\.$#" - count: 1 - path: src/contracts/Output/ValueObjectVisitorDispatcher.php - - - - message: "#^Method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcher\\:\\:setOutputGenerator\\(\\) has no return type specified\\.$#" - count: 1 - path: src/contracts/Output/ValueObjectVisitorDispatcher.php - - - - message: "#^Method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcher\\:\\:setOutputVisitor\\(\\) has no return type specified\\.$#" - count: 1 - path: src/contracts/Output/ValueObjectVisitorDispatcher.php - - - - message: "#^Method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) has no return type specified\\.$#" - count: 1 - path: src/contracts/Output/Visitor.php - - message: "#^Method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setStatus\\(\\) has no return type specified\\.$#" count: 1 @@ -440,16 +415,6 @@ parameters: count: 1 path: src/contracts/Output/Visitor.php - - - message: "#^Property Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:\\$statusCode \\(int\\) does not accept null\\.$#" - count: 1 - path: src/contracts/Output/Visitor.php - - - - message: "#^Property Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:\\$valueObjectVisitorDispatcher \\(Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcher\\) does not accept default value of type array\\.$#" - count: 1 - path: src/contracts/Output/Visitor.php - - message: "#^Method Ibexa\\\\Rest\\\\FieldTypeProcessor\\\\BaseRelationProcessor\\:\\:setLocationService\\(\\) has no return type specified\\.$#" count: 1 @@ -2540,11 +2505,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/ContentList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/ContentList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\ContentTypeGroup\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -2560,11 +2520,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/ContentTypeGroupList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/ContentTypeGroupList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\ContentTypeGroupRefList\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -2575,21 +2530,11 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/ContentTypeInfoList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/ContentTypeInfoList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\ContentTypeList\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 path: src/lib/Server/Output/ValueObjectVisitor/ContentTypeList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/ContentTypeList.php - - message: "#^Access to offset 'Alpha2' on an unknown class Ibexa\\\\Core\\\\Repository\\\\Values\\\\ContentType\\\\Countries\\.$#" count: 2 @@ -2615,11 +2560,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/CountryList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/CountryList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\CreatedContent\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -2830,11 +2770,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/FieldDefinitionList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/FieldDefinitionList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\ImageVariation\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -2890,31 +2825,16 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/ObjectStateGroupList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/ObjectStateGroupList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\ObjectStateList\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 path: src/lib/Server/Output/ValueObjectVisitor/ObjectStateList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/ObjectStateList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\Options\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 path: src/lib/Server/Output/ValueObjectVisitor/Options.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, int given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/Options.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\PermanentRedirect\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -2940,11 +2860,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/PolicyList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/PolicyList.php - - message: "#^Access to an undefined property Ibexa\\\\Rest\\\\Server\\\\Values\\\\RestRole\\:\\:\\$id\\.$#" count: 1 @@ -3130,11 +3045,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/RoleList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/RoleList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\Root\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -3155,11 +3065,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/SectionList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/SectionList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\SeeOther\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -3235,41 +3140,21 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/UserGroupList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/UserGroupList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\UserGroupRefList\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 path: src/lib/Server/Output/ValueObjectVisitor/UserGroupRefList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/UserGroupRefList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\UserList\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 path: src/lib/Server/Output/ValueObjectVisitor/UserList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/UserList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\UserRefList\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 path: src/lib/Server/Output/ValueObjectVisitor/UserRefList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/UserRefList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\UserSession\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -3280,11 +3165,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/UserSession.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/UserSession.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\Version\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -3315,11 +3195,6 @@ parameters: count: 1 path: src/lib/Server/Output/ValueObjectVisitor/VersionList.php - - - message: "#^Parameter \\#2 \\$value of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor\\:\\:setHeader\\(\\) expects string, false given\\.$#" - count: 1 - path: src/lib/Server/Output/ValueObjectVisitor/VersionList.php - - message: "#^Method Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\VersionTranslationInfo\\:\\:visit\\(\\) has no return type specified\\.$#" count: 1 @@ -3560,11 +3435,6 @@ parameters: count: 1 path: tests/bundle/DependencyInjection/Compiler/OutputVisitorPassTest.php - - - message: "#^Method Ibexa\\\\Tests\\\\Bundle\\\\Rest\\\\DependencyInjection\\\\Compiler\\\\ValueObjectVisitorPassTest\\:\\:testProcess\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/bundle/DependencyInjection/Compiler/ValueObjectVisitorPassTest.php - - message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\\\|int\\|string given\\.$#" count: 1 @@ -6685,101 +6555,11 @@ parameters: count: 1 path: tests/lib/Output/ValueObjectVisitorBaseTest.php - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcherTest\\:\\:testVisitValueObject\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/ValueObjectVisitorDispatcherTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcherTest\\:\\:testVisitValueObjectInvalidType\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/ValueObjectVisitorDispatcherTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcherTest\\:\\:testVisitValueObjectNoMatch\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/ValueObjectVisitorDispatcherTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcherTest\\:\\:testVisitValueObjectParentMatch\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/ValueObjectVisitorDispatcherTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcherTest\\:\\:testVisitValueObjectSecondRuleParentMatch\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/ValueObjectVisitorDispatcherTest.php - - - - message: "#^Parameter \\#1 \\$data of method Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcher\\:\\:visit\\(\\) expects object, int given\\.$#" - count: 1 - path: tests/lib/Output/ValueObjectVisitorDispatcherTest.php - - - - message: "#^Property Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcherTest\\:\\:\\$outputGeneratorMock \\(Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Generator&PHPUnit\\\\Framework\\\\MockObject\\\\MockObject\\) in isset\\(\\) is not nullable\\.$#" - count: 1 - path: tests/lib/Output/ValueObjectVisitorDispatcherTest.php - - - - message: "#^Property Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorDispatcherTest\\:\\:\\$outputVisitorMock \\(Ibexa\\\\Contracts\\\\Rest\\\\Output\\\\Visitor&PHPUnit\\\\Framework\\\\MockObject\\\\MockObject\\) in isset\\(\\) is not nullable\\.$#" - count: 1 - path: tests/lib/Output/ValueObjectVisitorDispatcherTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:getGeneratorMock\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:getVisitorMock\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testSetFilteredHeaders\\(\\) has no return type specified\\.$#" count: 1 path: tests/lib/Output/VisitorTest.php - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testSetHeaderResetAfterVisit\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testSetHeaders\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testSetHeadersNoOverwrite\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testSetStatusCode\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testSetStatusCodeNoOverride\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testVisitDocument\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testVisitEmptyDocument\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\VisitorTest\\:\\:testVisitValueObject\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/VisitorTest.php - - message: "#^Call to method setRequestParser\\(\\) on an unknown class Ibexa\\\\Rest\\\\Server\\\\Input\\\\Parser\\\\Base\\.$#" count: 1 diff --git a/src/contracts/Output/Visitor.php b/src/contracts/Output/Visitor.php index 3e2d9f58..5b665901 100644 --- a/src/contracts/Output/Visitor.php +++ b/src/contracts/Output/Visitor.php @@ -43,11 +43,8 @@ public function __construct( * * Does not allow overwriting of response headers. The first definition of * a header will be used. - * - * @param string $name - * @param string $value */ - public function setHeader($name, $value) + public function setHeader(string $name, mixed $value): void { if (!$this->response->headers->has($name)) { $this->response->headers->set($name, $value); @@ -74,7 +71,13 @@ public function setStatus($statusCode) */ public function visit(mixed $data): Response { - [$normalizedData, $encoderContext] = $this->normalizer->normalize($data, $this->format, ['visitor' => $this]); + $normalizedData = $this->normalizer->normalize($data, $this->format, ['visitor' => $this]); + $encoderContext = []; + + if (isset($normalizedData[VisitorAdapterNormalizer::ENCODER_CONTEXT])) { + $encoderContext = $normalizedData[VisitorAdapterNormalizer::ENCODER_CONTEXT]; + unset($normalizedData[VisitorAdapterNormalizer::ENCODER_CONTEXT]); + } //@todo Needs refactoring! // A hackish solution to enable outer visitors to disable setting @@ -145,9 +148,4 @@ public function getGenerator(): Generator { return $this->generator; } - - public function setGenerator(Generator $generator): void - { - $this->generator = $generator; - } } diff --git a/src/contracts/Output/VisitorAdapterNormalizer.php b/src/contracts/Output/VisitorAdapterNormalizer.php index e834ca08..9925cb10 100644 --- a/src/contracts/Output/VisitorAdapterNormalizer.php +++ b/src/contracts/Output/VisitorAdapterNormalizer.php @@ -23,6 +23,8 @@ final class VisitorAdapterNormalizer implements NormalizerInterface, NormalizerA private const string CALLED_CONTEXT = __CLASS__ . '_CALLED'; + public const string ENCODER_CONTEXT = 'ENCODER_CONTEXT'; + public function __construct( private readonly EncoderInterface $encoder, private readonly ValueObjectVisitorResolverInterface $valueObjectVisitorResolver, @@ -82,12 +84,12 @@ public function supportsNormalization(mixed $data, ?string $format = null, array /** * @param array $context * - * @return array, array> + * @return array */ private function visitValueObject( object $object, ValueObjectVisitor $valueObjectVisitor, - string $format, + ?string $format, array $context, ): array { $visitor = $context['visitor'] ?? $this->createVisitor($format); @@ -102,8 +104,11 @@ private function visitValueObject( $normalizedData = $generator->toArray(); $encoderContext = $generator->getEncoderContext($normalizedData); + $transformedData = $generator->transformData($normalizedData); + + $transformedData[self::ENCODER_CONTEXT] = $encoderContext; - return [$generator->transformData($normalizedData), $encoderContext]; + return $transformedData; } private function createGenerator(string $format): Generator @@ -115,8 +120,10 @@ private function createGenerator(string $format): Generator : new Json($fieldTypeHashGenerator); } - private function createVisitor(string $format): Visitor + private function createVisitor(?string $format): Visitor { + $format = $format ?: 'json'; + $generator = $this->createGenerator($format); return new Visitor( diff --git a/src/lib/Output/Generator/InMemory/Xml.php b/src/lib/Output/Generator/InMemory/Xml.php index 92f6c0c9..b4a9c9ba 100644 --- a/src/lib/Output/Generator/InMemory/Xml.php +++ b/src/lib/Output/Generator/InMemory/Xml.php @@ -29,6 +29,28 @@ public function startAttribute($name, $value): void $this->json->{'@' . $name} = $value; } + public function startValueElement(string $name, $value, array $attributes = []): void + { + $this->checkStartValueElement($name); + + if (empty($attributes)) { + $jsonValue = $value; + } else { + $jsonValue = new Json\JsonObject($this->json); + foreach ($attributes as $attributeName => $attributeValue) { + $jsonValue->{'@' . $attributeName} = $attributeValue; + } + /** @phpstan-ignore-next-line */ + $jsonValue->{'#'} = $value; + } + + if ($this->json instanceof Json\ArrayObject) { + $this->json[] = $jsonValue; + } else { + $this->json->$name = $jsonValue; + } + } + public function transformData(array $normalizedData): array { $topNodeName = array_key_first($normalizedData);