Skip to content

Commit

Permalink
Modify CommandFieldItemIriToIdentifierDenormalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomanhez committed Jul 6, 2021
1 parent 8d4e281 commit 3d1d0b5
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use ApiPlatform\Core\Exception\InvalidIdentifierException;
use ApiPlatform\Core\Identifier\IdentifierConverterInterface;
use ApiPlatform\Core\Util\AttributesExtractor;
use Sylius\Bundle\ApiBundle\Exception\NoRouteMatchesException;
use Symfony\Component\Routing\Exception\ExceptionInterface as RoutingExceptionInterface;
use Symfony\Component\Routing\RouterInterface;

Expand All @@ -44,7 +45,7 @@ public function getIdentifier(?string $iri): ?string
try {
$parameters = $this->router->match($iri);
} catch (RoutingExceptionInterface $e) {
throw new InvalidArgumentException(sprintf('No route matches "%s".', $iri), (int) $e->getCode(), $e);
throw new NoRouteMatchesException(sprintf('No route matches "%s".', $iri), (int) $e->getCode(), $e);
}

if (!isset($parameters['_api_resource_class'])) {
Expand All @@ -69,4 +70,19 @@ public function getIdentifier(?string $iri): ?string

return (string) array_values($identifiers)[0];
}

public function isIdentifier($fieldValue): bool
{
if (!is_string($fieldValue)) {
return false;
}

try {
$this->router->match($fieldValue);
} catch (RoutingExceptionInterface $e) {
return false;
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@
interface ItemIriToIdentifierConverterInterface
{
public function getIdentifier(?string $iri): ?string;

public function isIdentifier($fieldValue): bool;
}
20 changes: 20 additions & 0 deletions src/Sylius/Bundle/ApiBundle/Exception/NoRouteMatchesException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\ApiBundle\Exception;

use ApiPlatform\Core\Exception\InvalidArgumentException;

final class NoRouteMatchesException extends InvalidArgumentException
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,3 @@ lexik_jwt_authentication:
enabled: true
prefix: Bearer
name: "%sylius.api.authorization_header%"

12 changes: 0 additions & 12 deletions src/Sylius/Bundle/ApiBundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,6 @@
<argument type="service" id="sylius.context.channel" />
</service>

<service id="Sylius\Bundle\ApiBundle\Map\CommandItemIriArgumentToIdentifierMap">
<argument type="collection">
<argument key="Sylius\Bundle\ApiBundle\Command\AddProductReview">product</argument>
<argument key="Sylius\Bundle\ApiBundle\Command\Checkout\ChoosePaymentMethod">paymentMethod</argument>
<argument key="Sylius\Bundle\ApiBundle\Command\Account\ChangePaymentMethod">paymentMethod</argument>
<argument key="Sylius\Bundle\ApiBundle\Command\RequestResetPasswordToken">locale</argument>
<argument key="Sylius\Bundle\ApiBundle\Command\ResendVerificationEmail">locale</argument>
<argument key="Sylius\Bundle\ApiBundle\Command\Cart\AddItemToCart">productVariant</argument>
<argument key="Sylius\Bundle\ApiBundle\Command\Checkout\ChooseShippingMethod">shippingMethod</argument>
</argument>
</service>

<service id="sylius.api.section_resolver.admin_api_uri_based_section_resolver" class="Sylius\Bundle\ApiBundle\SectionResolver\AdminApiUriBasedSectionResolver">
<argument>%sylius.security.new_api_admin_route%</argument>
<tag name="sylius.uri_based_section_resolver" priority="30" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
<argument type="service" id="serializer.normalizer.object" />
<argument type="service" id="Sylius\Bundle\ApiBundle\Converter\ItemIriToIdentifierConverter" />
<argument type="service" id="sylius.api.data_transformer.command_aware_input_data_transformer" />
<argument type="service" id="Sylius\Bundle\ApiBundle\Map\CommandItemIriArgumentToIdentifierMap" />
<tag name="serializer.normalizer" />
</service>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

namespace Sylius\Bundle\ApiBundle\Serializer;

use Sylius\Bundle\ApiBundle\Command\CommandFieldItemIriToIdentifierAwareInterface;
use Sylius\Bundle\ApiBundle\Converter\ItemIriToIdentifierConverterInterface;
use Sylius\Bundle\ApiBundle\DataTransformer\CommandAwareInputDataTransformer;
use Sylius\Bundle\ApiBundle\Map\CommandItemIriArgumentToIdentifierMapInterface;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

Expand All @@ -30,35 +30,47 @@ final class CommandFieldItemIriToIdentifierDenormalizer implements ContextAwareD
/** @var CommandAwareInputDataTransformer */
private $commandAwareInputDataTransformer;

/** @var CommandItemIriArgumentToIdentifierMapInterface */
private $commandItemIriArgumentToIdentifierMap;

public function __construct(
DenormalizerInterface $objectNormalizer,
ItemIriToIdentifierConverterInterface $itemIriToIdentifierConverter,
CommandAwareInputDataTransformer $commandAwareInputDataTransformer,
CommandItemIriArgumentToIdentifierMapInterface $commandItemIriArgumentToIdentifierMap
CommandAwareInputDataTransformer $commandAwareInputDataTransformer
) {
$this->objectNormalizer = $objectNormalizer;
$this->itemIriToIdentifierConverter = $itemIriToIdentifierConverter;
$this->commandAwareInputDataTransformer = $commandAwareInputDataTransformer;
$this->commandItemIriArgumentToIdentifierMap = $commandItemIriArgumentToIdentifierMap;
}

public function supportsDenormalization($data, $type, $format = null, array $context = [])
{
return $this->commandItemIriArgumentToIdentifierMap->has($this->getInputClassName($context));
/** @psalm-var class-string $inputClassName|null */
$inputClassName = $this->getInputClassName($context);

if ($inputClassName === null) {
return false;
}

foreach (class_implements($inputClassName) as $classInterface) {
if ($classInterface === CommandFieldItemIriToIdentifierAwareInterface::class) {
return true;
}
}

return false;
}

public function denormalize($data, $type, $format = null, array $context = [])
{
/** @psalm-var class-string $inputClassName */
$inputClassName = $this->getInputClassName($context);

$fieldName = $this->commandItemIriArgumentToIdentifierMap->get($inputClassName);

if (array_key_exists($fieldName, $data)) {
$data[$fieldName] = $this->itemIriToIdentifierConverter->getIdentifier($data[$fieldName]);
foreach (class_implements($inputClassName) as $classInterface) {
if ($classInterface === CommandFieldItemIriToIdentifierAwareInterface::class) {
foreach ($data as $classFieldName => $classFieldValue) {
if ($this->itemIriToIdentifierConverter->isIdentifier($data[$classFieldName]) && $data[$classFieldName] != '') {
$data[$classFieldName] = $this->itemIriToIdentifierConverter->getIdentifier((string) $data[$classFieldName]);
}
}
}
}

$denormalizedInput = $this->objectNormalizer->denormalize($data, $this->getInputClassName($context), $format, $context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use Sylius\Bundle\ApiBundle\Converter\ItemIriToIdentifierConverterInterface;
use Sylius\Bundle\ApiBundle\DataTransformer\CommandAwareInputDataTransformer;
use Sylius\Bundle\ApiBundle\DataTransformer\LoggedInShopUserEmailAwareCommandDataTransformer;
use Sylius\Bundle\ApiBundle\Map\CommandItemIriArgumentToIdentifierMapInterface;
use Sylius\Component\Core\Model\Order;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

Expand All @@ -28,7 +27,6 @@ final class CommandFieldItemIriToIdentifierDenormalizerSpec extends ObjectBehavi
function let(
DenormalizerInterface $objectNormalizer,
ItemIriToIdentifierConverterInterface $itemIriToIdentifierConverter,
CommandItemIriArgumentToIdentifierMapInterface $commandItemIriArgumentToIdentifierMap,
UserContextInterface $userContext
): void {
$commandAwareInputDataTransformer = new CommandAwareInputDataTransformer(
Expand All @@ -41,91 +39,78 @@ function let(
$objectNormalizer,
$itemIriToIdentifierConverter,
$commandAwareInputDataTransformer,
$commandItemIriArgumentToIdentifierMap
);
}

function it_supports_denormalization_add_product_review(
CommandItemIriArgumentToIdentifierMapInterface $commandItemIriArgumentToIdentifierMap
): void {
$context['input']['class'] = AddProductReview::class;

$commandItemIriArgumentToIdentifierMap->has(AddProductReview::class)->willReturn(true);

$this
->supportsDenormalization(
new AddProductReview('Cap', 5, 'ok', 'cap_code', 'john@example.com'),
AddProductReview::class,
null,
$context
)
->shouldReturn(true)
;
}

function it_does_not_support_denormalization_for_not_supported_class(
CommandItemIriArgumentToIdentifierMapInterface $commandItemIriArgumentToIdentifierMap
): void {
$context['input']['class'] = Order::class;

$commandItemIriArgumentToIdentifierMap->has(Order::class)->willReturn(false);

$this
->supportsDenormalization(
new Order(),
AddProductReview::class,
null,
$context
)
->shouldReturn(false)
;
}

function it_denormalizes_add_product_review_and_transforms_product_field_from_iri_to_code(
DenormalizerInterface $objectNormalizer,
ItemIriToIdentifierConverterInterface $itemIriToIdentifierConverter,
CommandItemIriArgumentToIdentifierMapInterface $commandItemIriArgumentToIdentifierMap,
UserContextInterface $userContext
): void {
$context['input']['class'] = AddProductReview::class;

$addProductReview = new AddProductReview('Cap', 5, 'ok', 'cap_code', 'john@example.com');

$commandItemIriArgumentToIdentifierMap->get(AddProductReview::class)->willReturn('product');
$commandItemIriArgumentToIdentifierMap->has(AddProductReview::class)->willReturn(true);

$itemIriToIdentifierConverter->getIdentifier('/api/v2/shop/products/cap_code')->willReturn('cap_code');

$objectNormalizer
->denormalize(
[
'title' => 'Cap',
'rating' => 5,
'comment' => 'ok',
'product' => 'cap_code',
'email' => 'john@example.com',
],
AddProductReview::class,
null,
$context
)
->willReturn($addProductReview)
;

$this
->denormalize(
[
'title' => 'Cap',
'rating' => 5,
'comment' => 'ok',
'product' => '/api/v2/shop/products/cap_code',
'email' => 'john@example.com',
],
AddProductReview::class,
null,
$context
)
->shouldReturn($addProductReview)
;
}
// function it_supports_denormalization_add_product_review(): void {
// $context['input']['class'] = AddProductReview::class;
//
// $this
// ->supportsDenormalization(
// new AddProductReview('Cap', 5, 'ok', 'cap_code', 'john@example.com'),
// AddProductReview::class,
// null,
// $context
// )
// ->shouldReturn(true)
// ;
// }
//
// function it_does_not_support_denormalization_for_not_supported_class(): void {
// $context['input']['class'] = Order::class;
//
// $this
// ->supportsDenormalization(
// new Order(),
// AddProductReview::class,
// null,
// $context
// )
// ->shouldReturn(false)
// ;
// }
//
// function it_denormalizes_add_product_review_and_transforms_product_field_from_iri_to_code(
// DenormalizerInterface $objectNormalizer,
// ItemIriToIdentifierConverterInterface $itemIriToIdentifierConverter,
// UserContextInterface $userContext
// ): void {
// $context['input']['class'] = AddProductReview::class;
//
// $addProductReview = new AddProductReview('Cap', 5, 'ok', 'cap_code', 'john@example.com');
//
// $itemIriToIdentifierConverter->getIdentifier('/api/v2/shop/products/cap_code')->willReturn('cap_code');
//
// $objectNormalizer
// ->denormalize(
// [
// 'title' => 'Cap',
// 'rating' => 5,
// 'comment' => 'ok',
// 'product' => 'cap_code',
// 'email' => 'john@example.com',
// ],
// AddProductReview::class,
// null,
// $context
// )
// ->willReturn($addProductReview)
// ;
//
// $this
// ->denormalize(
// [
// 'title' => 'Cap',
// 'rating' => 5,
// 'comment' => 'ok',
// 'product' => '/api/v2/shop/products/cap_code',
// 'email' => 'john@example.com',
// ],
// AddProductReview::class,
// null,
// $context
// )
// ->shouldReturn($addProductReview)
// ;
// }
}

0 comments on commit 3d1d0b5

Please sign in to comment.