Skip to content

Commit

Permalink
TranslationConstraintViolationListNormalizer: add support for hydra p…
Browse files Browse the repository at this point in the history
…roblem format

Issue: #2902
  • Loading branch information
BacLuc committed Oct 7, 2022
1 parent 89dbda3 commit 70a9022
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
4 changes: 3 additions & 1 deletion api/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ services:
decorates: 'api_platform.hal.normalizer.collection'

App\Serializer\Normalizer\TranslationConstraintViolationListNormalizer:
decorates: 'api_platform.problem.normalizer.constraint_violation_list'
arguments:
- '@api_platform.hydra.normalizer.constraint_violation_list'
- '@api_platform.problem.normalizer.constraint_violation_list'

App\Serializer\SerializerContextBuilder:
decorates: 'api_platform.serializer.context_builder'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,39 @@
use ApiPlatform\Core\Serializer\AbstractConstraintViolationListNormalizer;
use App\Serializer\Normalizer\Error\TranslationInfoOfConstraintViolation;
use App\Service\TranslateToAllLocalesService;
use Doctrine\Common\Collections\ArrayCollection;
use RuntimeException;
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;

class TranslationConstraintViolationListNormalizer implements NormalizerInterface, CacheableSupportsMethodInterface {
public function __construct(
private readonly AbstractConstraintViolationListNormalizer $decorated,
private readonly AbstractConstraintViolationListNormalizer $hydraNormalizer,
private readonly AbstractConstraintViolationListNormalizer $problemNormalizer,
private readonly TranslationInfoOfConstraintViolation $translationInfoOfConstraintViolation,
private readonly TranslateToAllLocalesService $translateToAllLocalesService
) {
}

public function supportsNormalization(mixed $data, string $format = null, array $context = []): bool {
return $this->decorated->supportsNormalization($data, $format);
return $this->getNormalizerCollection()->exists(fn ($_, $elem) => $elem->supportsNormalization($data, $format));
}

public function normalize(mixed $object, string $format = null, array $context = []): float|int|bool|\ArrayObject|array|string|null {
$result = $this->decorated->normalize($object, $format, $context);
$normalizer = $this->getNormalizerCollection()->filter(fn ($elem) => $elem->supportsNormalization($object, $format))->first();
if (false === $normalizer) {
throw new RuntimeException("Did not find a normalizer to normalize response to format {$format}");
}
$result = $normalizer->normalize($object, $format, $context);

/** @var ConstraintViolationList $object */
foreach ($object as $violation) {
foreach ($result['violations'] as &$resultItem) {
$code = $resultItem['code'];
$code = $resultItem['code'] ?? null;
$propertyPath = $resultItem['propertyPath'];
$message = $resultItem['message'];
$message = $resultItem['message'] ?? null;

if ($violation->getPropertyPath() === $propertyPath
&& $violation->getCode() === $code
Expand Down Expand Up @@ -64,6 +71,10 @@ public function normalize(mixed $object, string $format = null, array $context =
}

public function hasCacheableSupportsMethod(): bool {
return $this->decorated->hasCacheableSupportsMethod();
return $this->getNormalizerCollection()->forAll(fn ($_, $elem) => $elem->hasCacheableSupportsMethod());
}

private function getNormalizerCollection(): ArrayCollection {
return new ArrayCollection([$this->hydraNormalizer, $this->problemNormalizer]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
namespace App\Tests\Integration\Serializer\Normalizer;

use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestAssertionsTrait;
use ApiPlatform\Core\Problem\Serializer\ConstraintViolationListNormalizer;
use ApiPlatform\Core\Hydra\Serializer\ConstraintViolationListNormalizer as HydraConstraintViolationListNormalizer;
use ApiPlatform\Core\Problem\Serializer\ConstraintViolationListNormalizer as JsonProblemConstraintViolationListNormalizer;
use App\Entity\CampCollaboration;
use App\Serializer\Normalizer\TranslationConstraintViolationListNormalizer;
use App\Validator\AllowTransition\AssertAllowTransitions;
Expand Down Expand Up @@ -31,20 +32,22 @@ protected function setUp(): void {
parent::setUp();

/** @var TranslationConstraintViolationListNormalizer $obj */
$obj = self::getContainer()->get('api_platform.problem.normalizer.constraint_violation_list');
$obj = self::getContainer()->get('App\Serializer\Normalizer\TranslationConstraintViolationListNormalizer');
$this->translationConstraintViolationListNormalizer = $obj;
}

/**
* @throws ExceptionInterface
* @throws \Exception
*
* @dataProvider getFormats()
*/
public function testAddsTranslationKeyAndParameters() {
public function testAddsTranslationKeyAndParameters(string $format) {
$constraintViolationList = new ConstraintViolationList(self::getConstraintViolations());

$result = $this->translationConstraintViolationListNormalizer->normalize(
$constraintViolationList,
ConstraintViolationListNormalizer::FORMAT,
$format,
[]
);

Expand Down Expand Up @@ -84,13 +87,15 @@ public function testAddsTranslationKeyAndParameters() {
/**
* @throws ExceptionInterface
* @throws \Exception
*
* @dataProvider getFormats()
*/
public function testAddsTranslations() {
public function testAddsTranslations(string $format) {
$constraintViolationList = new ConstraintViolationList(self::getConstraintViolations());

$result = $this->translationConstraintViolationListNormalizer->normalize(
$constraintViolationList,
ConstraintViolationListNormalizer::FORMAT,
$format,
[]
);

Expand Down Expand Up @@ -142,6 +147,16 @@ public function testAddsTranslations() {
]], $result);
}

public static function getFormats() {
$hydra = HydraConstraintViolationListNormalizer::FORMAT;
$problem = JsonProblemConstraintViolationListNormalizer::FORMAT;

return [
$hydra => [$hydra],
$problem => [$problem],
];
}

public static function getConstraintViolations(): array {
return [
new ConstraintViolation(
Expand Down

0 comments on commit 70a9022

Please sign in to comment.