Skip to content

Commit

Permalink
Handle XML
Browse files Browse the repository at this point in the history
  • Loading branch information
barw4 committed Sep 4, 2024
1 parent d210f89 commit e71209e
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 11 deletions.
14 changes: 14 additions & 0 deletions src/contracts/Output/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -436,4 +436,18 @@ abstract public function serializeBool($boolValue);
* @return array<mixed>
*/
abstract public function toArray(): array;

/**
* @param array<mixed> $data
*
* @return array<mixed>
*/
abstract public function getEncoderContext(array $data): array;

/**
* @param array<mixed> $normalizedData
*
* @return array<mixed>
*/
abstract public function transformData(array $normalizedData): array;
}
6 changes: 4 additions & 2 deletions src/contracts/Output/Visitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function setStatus($statusCode)
*/
public function visit(mixed $data): Response
{
$normalizedData = $this->normalizer->normalize($data);
[$normalizedData, $encoderContext] = $this->normalizer->normalize($data, $this->format);

//@todo Needs refactoring!
// A hackish solution to enable outer visitors to disable setting
Expand All @@ -89,7 +89,9 @@ public function visit(mixed $data): Response

$response = clone $this->response;

$response->setContent($this->encoder->encode($normalizedData, $this->format));
$content = $this->encoder->encode($normalizedData, $this->format, $encoderContext);

$response->setContent($content);

// reset the inner response
$this->response = new Response(null, 200);
Expand Down
27 changes: 18 additions & 9 deletions src/contracts/Output/VisitorAdapterNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace Ibexa\Contracts\Rest\Output;

use Ibexa\Rest\Output\Generator\InMemory\Xml as InMemoryXml;
use Ibexa\Rest\Output\Generator\Json;
use LogicException;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
Expand Down Expand Up @@ -38,7 +39,7 @@ public function normalize(mixed $object, ?string $format = null, array $context
: null;

if ($eligibleVisitor instanceof ValueObjectVisitor) {
return $this->visitValueObject($object, $eligibleVisitor);
return $this->visitValueObject($object, $eligibleVisitor, $format);
}

return $this->normalizer->normalize($object, $format, $context);
Expand Down Expand Up @@ -79,11 +80,14 @@ public function supportsNormalization(mixed $data, ?string $format = null, array
}

/**
* @return array<mixed>
* @return array<array<mixed>, array<mixed>>
*/
private function visitValueObject(object $object, ValueObjectVisitor $valueObjectVisitor): array
{
$visitor = $this->createVisitor();
private function visitValueObject(
object $object,
ValueObjectVisitor $valueObjectVisitor,
string $format
): array {
$visitor = $this->createVisitor($format);
$generator = $visitor->getGenerator();

$generator->reset();
Expand All @@ -93,21 +97,26 @@ private function visitValueObject(object $object, ValueObjectVisitor $valueObjec

$generator->endDocument($object);

return $generator->toArray();
$normalizedData = $generator->toArray();
$encoderContext = $generator->getEncoderContext($normalizedData);

return [$generator->transformData($normalizedData), $encoderContext];
}

private function createVisitor(): Visitor
private function createVisitor(string $format): Visitor
{
$fieldTypeHashGenerator = new Json\FieldTypeHashGenerator($this->normalizer);

$generator = new Json($fieldTypeHashGenerator);
$generator = $format === 'xml'
? new InMemoryXml($fieldTypeHashGenerator)
: new Json($fieldTypeHashGenerator);

return new Visitor(
$generator,
$this->normalizer,
$this->encoder,
$this->valueObjectVisitorResolver,
'json',
$format,
);
}
}
51 changes: 51 additions & 0 deletions src/lib/Output/Generator/InMemory/Xml.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/**
* @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\InMemory;

use Ibexa\Rest\Output\Generator\Json;
use Symfony\Component\Serializer\Encoder\XmlEncoder;

final class Xml extends Json
{
public function getMediaType($name): string
{
return $this->generateMediaTypeWithVendor($name, 'xml', $this->vendor);
}

/**
* @param string $name
* @param string $value
*/
public function startAttribute($name, $value): void
{
$this->checkStartAttribute($name);

$this->json->{'@' . $name} = $value;
}

public 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,
);
$data['#'] = $normalizedData[$topNodeName];

return $data;
}

public function getEncoderContext(array $data): array
{
return [
XmlEncoder::ROOT_NODE_NAME => array_key_first($data),
];
}
}
10 changes: 10 additions & 0 deletions src/lib/Output/Generator/Json.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,14 @@ public function toArray(): array
{
return json_decode(json_encode($this->json, JSON_THROW_ON_ERROR), true, JSON_THROW_ON_ERROR);
}

public function getEncoderContext(array $data): array
{
return [];
}

public function transformData(array $normalizedData): array
{
return $normalizedData;
}
}
10 changes: 10 additions & 0 deletions src/lib/Output/Generator/Xml.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,14 @@ public function toArray(): array
{
return [];
}

public function getEncoderContext(array $data): array
{
return [];
}

public function transformData(array $normalizedData): array
{
return $normalizedData;
}
}

0 comments on commit e71209e

Please sign in to comment.