Skip to content

Commit

Permalink
minor #15780 [API] Add BC layer for transition from :read to :index a…
Browse files Browse the repository at this point in the history
…nd :show serialization groups (TheMilek)

This PR was merged into the 1.13 branch.

Discussion
----------

| Q               | A                                                            |
|-----------------|--------------------------------------------------------------|
| Branch?         | 1.13 <!-- see the comment below -->                  |
| Bug fix?        | no                                                      |
| New feature?    | no                                                       |
| BC breaks?      | no                                                       |
| Deprecations?   | yes <!-- don't forget to update the UPGRADE-*.md file --> |
| License         | MIT                                                          |

<!--
 - Bug fixes must be submitted against the 1.12 branch
 - Features and deprecations must be submitted against the 1.13 branch
 - Make sure that the correct base branch is set

 To be sure you are not breaking any Backward Compatibilities, check the documentation:
 https://docs.sylius.com/en/latest/book/organization/backward-compatibility-promise.html
-->
BC layer for #15770

Commits
-------
  Add BC layer for transition from :read to :index and :show serialization groups
  Add parameters that allow skipping adding read ord index and show serialization groups
  Add information to upgrade file
  • Loading branch information
NoResponseMate committed Jan 31, 2024
2 parents d4cf3b5 + 1ce17d8 commit a223d99
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 0 deletions.
13 changes: 13 additions & 0 deletions UPGRADE-API-1.13.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# UPGRADE FROM `v1.12.x` TO `v1.13.0`

1. All the `:read` serialization groups are now split to `index` and `show`.
By this change, the `:read` serialization group is now deprecated and will no more used in the future.
There is a BC layer that will allow you to use the `:read` serialization group `Sylius\Bundle\ApiBundle\SerializerContextBuilder\ReadOperationContextBuilder` by adding the `read` serialization group to your context.
Inside of this service there are 2 configurable parameters `$skipAddingReadGroup` and `$skipAddingIndexAndShowGroups` that will allow you to skip adding the chosen serialization group to your context.
To configure skipping adding the index and show or read serialization groups to the context, add the following configuration to your `config/packages/_sylius.yaml` file:

```yaml
sylius_api:
serialization_groups:
skip_adding_index_and_show_groups: true
skip_adding_read_group: true
```

1. The constructor of `Sylius\Bundle\ApiBundle\Serializer\ChannelDenormalizer` has been changed:

```diff
Expand Down
13 changes: 13 additions & 0 deletions src/Sylius/Bundle/ApiBundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ public function getConfigTreeBuilder(): TreeBuilder
->scalarPrototype()->end()
->end()
->end()
->children()
->arrayNode('serialization_groups')
->addDefaultsIfNotSet()
->children()
->booleanNode('skip_adding_read_group')
->defaultFalse()
->end()
->booleanNode('skip_adding_index_and_show_groups')
->defaultFalse()
->end()
->end()
->end()
->end()
->children()
->variableNode('product_image_prefix')
->defaultValue('media/image')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public function load(array $configs, ContainerBuilder $container): void
$config['filter_eager_loading_extension']['restricted_resources'],
);
$container->setParameter('sylius_api.order_states_to_filter_out', $config['order_states_to_filter_out']);
$container->setParameter('sylius_api.serialization_groups.skip_adding_read_group', $config['serialization_groups']['skip_adding_read_group']);
$container->setParameter('sylius_api.serialization_groups.skip_adding_index_and_show_groups', $config['serialization_groups']['skip_adding_index_and_show_groups']);

$loader->load('services.xml');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@
<argument type="service" id="sylius.context.channel" />
</service>

<service
id="Sylius\Bundle\ApiBundle\SerializerContextBuilder\ReadOperationContextBuilder"
decorates="api_platform.serializer.context_builder"
decoration-priority="64"
>
<argument type="service" id=".inner" />
<argument>%sylius_api.serialization_groups.skip_adding_read_group%</argument>
<argument>%sylius_api.serialization_groups.skip_adding_index_and_show_groups%</argument>
</service>

<service
id="Sylius\Bundle\ApiBundle\SerializerContextBuilder\LocaleContextBuilder"
decorates="api_platform.serializer.context_builder"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* 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\SerializerContextBuilder;

use ApiPlatform\Serializer\SerializerContextBuilderInterface;
use Symfony\Component\HttpFoundation\Request;

final class ReadOperationContextBuilder implements SerializerContextBuilderInterface
{
public function __construct(
private SerializerContextBuilderInterface $decorated,
private bool $skipAddingReadGroup,
private bool $skipAddingIndexAndShowGroups,
) {
}

/**
* @param array<mixed> $extractedAttributes
*
* @return array<mixed>
*/
public function createFromRequest(Request $request, bool $normalization, array $extractedAttributes = null): array
{
$context = $this->decorated->createFromRequest($request, $normalization, $extractedAttributes);

$groups = $context['groups'] ?? [];
$groups = is_string($groups) ? [$groups] : $groups;

if ($groups === []) {
return $context;
}

foreach ($groups as $group) {
if ($this->shouldReadGroupBeAdded($group) && !$this->skipAddingReadGroup) {
$readGroup = str_replace([':show', ':index'], ':read', $group);

if (in_array($readGroup, $groups, true)) {
continue;
}

$groups[] = $readGroup;
}

if ($this->shouldIndexAndShowGroupsBeAdded($group) && !$this->skipAddingIndexAndShowGroups) {
$indexGroup = str_replace(':read', ':index', $group);
$showGroup = str_replace(':read', ':show', $group);

if (!in_array($indexGroup, $groups, true)) {
$groups[] = $indexGroup;
}

if (!in_array($showGroup, $groups, true)) {
$groups[] = $showGroup;
}
}
}

$context['groups'] = $groups;

return $context;
}

private function shouldReadGroupBeAdded(string $group): bool
{
return str_ends_with($group, ':show') || str_ends_with($group, ':index');
}

private function shouldIndexAndShowGroupsBeAdded(string $group): bool
{
return str_ends_with($group, ':read');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,28 @@ public function it_loads_order_states_to_filter_out_parameter_properly(): void
);
}

/** @test */
public function it_loads_skip_read_and_skip_index_and_show_serialization_groups_parameters_properly(): void
{
$this->container->setParameter('kernel.bundles_metadata', ['SyliusApiBundle' => ['path' => __DIR__ . '../..']]);

$this->load([
'serialization_groups' => [
'skip_adding_read_group' => true,
'skip_adding_index_and_show_groups' => false,
],
]);

$this->assertContainerBuilderHasParameter(
'sylius_api.serialization_groups.skip_adding_read_group',
true,
);
$this->assertContainerBuilderHasParameter(
'sylius_api.serialization_groups.skip_adding_index_and_show_groups',
false,
);
}

/** @test */
public function it_loads_default_filter_eager_loading_extension_restricted_operations_configuration_properly(): void
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace spec\Sylius\Bundle\ApiBundle\SerializerContextBuilder;

use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use PhpSpec\ObjectBehavior;
use Symfony\Component\HttpFoundation\Request;

final class ReadOperationContextBuilderSpec extends ObjectBehavior
{
function let(
SerializerContextBuilderInterface $decoratedSerializerContextBuilder,
): void {
$this->beConstructedWith($decoratedSerializerContextBuilder, false, false);
}

function it_updates_an_context_with_index_and_show_serialization_groups_if_only_read_provided(
Request $request,
SerializerContextBuilderInterface $decoratedSerializerContextBuilder,
): void {
$decoratedSerializerContextBuilder->createFromRequest($request, true, [])->willReturn([
'groups' => ['foo:read'],
]);

$this->createFromRequest($request, true, [])->shouldReturn([
'groups' => ['foo:read', 'foo:index', 'foo:show'],
]);
}

function it_updates_an_context_with_read_serialization_groups_if_only_index_and_show_provided(
Request $request,
SerializerContextBuilderInterface $decoratedSerializerContextBuilder,
): void {
$decoratedSerializerContextBuilder->createFromRequest($request, true, [])->willReturn([
'groups' => ['foo:read'],
]);

$this->createFromRequest($request, true, [])->shouldReturn([
'groups' => ['foo:read', 'foo:index', 'foo:show'],
]);
}

function it_does_not_update_context_with_read_group_if_skip_adding_read_parameter_is_set_to_true(
Request $request,
SerializerContextBuilderInterface $decoratedSerializerContextBuilder,
): void {
$this->beConstructedWith($decoratedSerializerContextBuilder, true, false);

$decoratedSerializerContextBuilder->createFromRequest($request, true, [])->willReturn([
'groups' => ['foo:show'],
]);

$this->createFromRequest($request, true, [])->shouldReturn([
'groups' => ['foo:show'],
]);
}

function it_does_not_update_context_with_show_and_index_group_if_skip_adding_show_and_index_is_set_to_true(
Request $request,
SerializerContextBuilderInterface $decoratedSerializerContextBuilder,
): void {
$this->beConstructedWith($decoratedSerializerContextBuilder, false, true);

$decoratedSerializerContextBuilder->createFromRequest($request, true, [])->willReturn([
'groups' => ['foo:read'],
]);

$this->createFromRequest($request, true, [])->shouldReturn([
'groups' => ['foo:read'],
]);
}
}

0 comments on commit a223d99

Please sign in to comment.