Introduce Image Normalizer

This commit is contained in:
arti0090 2021-07-28 11:06:32 +02:00
parent 1ab2ca56eb
commit 7bedeb6a92
9 changed files with 156 additions and 4 deletions

View file

@ -1,5 +1,28 @@
# UPGRADE FROM `v1.10.X` TO `v1.11.0`
1. The product images should have a proper prefix added to the path, so the images could be resolved.
This is now done and response of `Product Image` resource has been extended with parameter `media_path`.
```diff
{
"@context": "/api/v2/contexts/ProductImage",
"@id": "/api/v2/shop/product-images/123",
"@type": "ProductImage",
"id": "123",
"type": "thumbnail",
"path": "uo/product.jpg",
+ "media_path": "/media/image/uo/product.jpg"
}
```
To change the prefix you need to set parameter in ``app/config/packages/_sylius.yaml``:
```yaml
sylius_api:
product_image_prefix: 'media/image'
```
1. `Sylius\Bundle\ApiBundle\Doctrine\Filters\ExchangeRateFilter` and `Sylius\Bundle\ApiBundle\Doctrine\Filters\TranslationOrderNameAndLocaleFilter` has been moved to `Sylius\Bundle\ApiBundle\Doctrine\Filter\ExchangeRateFilter` and `Sylius\Bundle\ApiBundle\Doctrine\Filter\TranslationOrderNameAndLocaleFilter` respectively.
1. `Sylius\Bundle\ApiBundle\View\CartShippingMethodInterface` and `Sylius\Bundle\ApiBundle\View\CartShippingMethod` have been removed.
1. `Sylius\Bundle\ApiBundle\View\Factory\CartShippingMethodFactoryInterface` and `Sylius\Bundle\ApiBundle\View\Factory\CartShippingMethodFactory` have been removed.

View file

@ -33,6 +33,11 @@ final class Configuration implements ConfigurationInterface
->defaultFalse()
->end()
->end()
->children()
->variableNode('product_image_prefix')
->defaultValue('media/image')
->end()
->end()
;
return $treeBuilder;

View file

@ -27,6 +27,7 @@ final class SyliusApiExtension extends Extension
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$container->setParameter('sylius_api.enabled', $config['enabled']);
$container->setParameter('sylius_api.product_image_prefix', $config['product_image_prefix']);
$loader->load('services.xml');
}

View file

@ -0,0 +1,70 @@
<?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.
*/
namespace Sylius\Bundle\ApiBundle\Serializer;
use Sylius\Component\Core\Model\ProductImageInterface;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Webmozart\Assert\Assert;
/** @experimental */
class ProductImageNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface
{
use NormalizerAwareTrait;
private const ALREADY_CALLED = 'product_image_normalizer_already_called';
/** @var string */
private $prefix;
public function __construct(string $prefix)
{
$this->prefix = $this->validatePrefix($prefix);
}
public function normalize($object, string $format = null, array $context = [])
{
Assert::isInstanceOf($object, ProductImageInterface::class);
Assert::keyNotExists($context, self::ALREADY_CALLED);
$context[self::ALREADY_CALLED] = true;
$data = $this->normalizer->normalize($object, $format, $context);
$data['media_path'] = $this->prefix . $data['path'];
return $data;
}
public function supportsNormalization($data, string $format = null, array $context = []): bool
{
if (isset($context[self::ALREADY_CALLED])) {
return false;
}
return $data instanceof ProductImageInterface;
}
private function validatePrefix(string $prefix): string
{
if ('/' !== substr($prefix, 0)) {
$prefix = '/'.$prefix;
}
if ('/' === substr($prefix, -1)) {
return $prefix;
}
return $prefix . '/';
}
}

View file

@ -0,0 +1,50 @@
<?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 spec\Sylius\Bundle\ApiBundle\Serializer;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ProductImageInterface;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
final class ProductImageNormalizerSpec extends ObjectBehavior
{
function let(): void
{
$this->beConstructedWith('prefix');
}
function it_implements_context_aware_normalizer_interface(): void
{
$this->shouldImplement(ContextAwareNormalizerInterface::class);
}
function it_supports_only_product_image_interface(ProductImageInterface $productImage, OrderInterface $order): void
{
$this->supportsNormalization($productImage)->shouldReturn(true);
$this->supportsNormalization($order)->shouldReturn(false);
}
function it_serializes_product_image_with_proper_prefix(
NormalizerInterface $normalizer,
ProductImageInterface $productImage
): void {
$this->setNormalizer($normalizer);
$normalizer->normalize($productImage, null, ['product_image_normalizer_already_called' => true])->willReturn(['path' => 'some_path']);
$this->normalize($productImage, null, [])->shouldReturn(['path' => 'some_path', 'media_path' => '/prefix/some_path']);
}
}

View file

@ -8,4 +8,4 @@ Sylius\Component\Core\Model\Product:
Sylius\Component\Core\Model\ProductImage:
product_thumbnail:
type: "thumbnail"
path: "/uo/product.jpg"
path: "uo/product.jpg"

View file

@ -4,5 +4,6 @@
"@type": "ProductImage",
"id": "@integer@",
"type": "thumbnail",
"path": "\/uo\/product.jpg"
"path": "uo\/product.jpg",
"media_path": "\/media\/image\/uo\/product.jpg"
}

View file

@ -8,7 +8,8 @@
"@type": "ProductImage",
"id": "@integer@",
"type": "thumbnail",
"path": "\/uo\/product.jpg"
"path": "uo\/product.jpg",
"media_path": "\/media\/image\/uo\/product.jpg"
}
],
"hydra:totalItems": 1

View file

@ -4,5 +4,6 @@
"@type": "ProductImage",
"id": "@integer@",
"type": "thumbnail",
"path": "\/uo\/product.jpg"
"path": "uo\/product.jpg",
"media_path": "\/media\/image\/uo\/product.jpg"
}