[Product] Replace the use of VariantWithNoOptionsValuesException from Resource with a custom one (#17295)

| Q               | A
|-----------------|-----
| Branch?         | 2.0
| Bug fix?        | no
| New feature?    | no
| BC breaks?      | no
| Deprecations? | no<!-- don't forget to update the UPGRADE-*.md file
-->
| Related tickets | 
| License         | MIT

<!--
 - Bug fixes must be submitted against the 1.13 branch
 - Features and deprecations must be submitted against the 1.14 branch
- Features, removing deprecations and BC breaks must be submitted
against the 2.0 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
-->
This commit is contained in:
Karol 2024-10-23 10:03:24 +02:00 committed by GitHub
commit 351fc83dbc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 79 additions and 16 deletions

View file

@ -28,6 +28,8 @@ use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Core\Uploader\ImageUploaderInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Product\Exception\ProductWithoutOptionsException;
use Sylius\Component\Product\Exception\ProductWithoutOptionsValuesException;
use Sylius\Component\Product\Generator\ProductVariantGeneratorInterface;
use Sylius\Component\Product\Generator\SlugGeneratorInterface;
use Sylius\Component\Product\Model\ProductAttributeInterface;
@ -205,7 +207,7 @@ class ProductExampleFactory extends AbstractExampleFactory implements ExampleFac
{
try {
$this->variantGenerator->generate($product);
} catch (\InvalidArgumentException) {
} catch (ProductWithoutOptionsException|ProductWithoutOptionsValuesException) {
/** @var ProductVariantInterface $productVariant */
$productVariant = $this->productVariantFactory->createNew();

View file

@ -13,9 +13,10 @@ declare(strict_types=1);
namespace Sylius\Bundle\ProductBundle\Form\EventSubscriber;
use Sylius\Component\Product\Exception\ProductWithoutOptionsException;
use Sylius\Component\Product\Exception\ProductWithoutOptionsValuesException;
use Sylius\Component\Product\Generator\ProductVariantGeneratorInterface;
use Sylius\Component\Product\Model\ProductInterface;
use Sylius\Resource\Exception\VariantWithNoOptionsValuesException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
@ -47,7 +48,7 @@ final readonly class GenerateProductVariantsSubscriber implements EventSubscribe
try {
$this->generator->generate($product);
} catch (VariantWithNoOptionsValuesException $exception) {
} catch (ProductWithoutOptionsException|ProductWithoutOptionsValuesException $exception) {
$this->getFlashBag()->add('error', $exception->getMessage());
}
}

View file

@ -15,9 +15,9 @@ namespace spec\Sylius\Bundle\ProductBundle\Form\EventSubscriber;
use PhpSpec\ObjectBehavior;
use Sylius\Bundle\ProductBundle\Form\EventSubscriber\GenerateProductVariantsSubscriber;
use Sylius\Component\Product\Exception\ProductWithoutOptionsValuesException;
use Sylius\Component\Product\Generator\ProductVariantGeneratorInterface;
use Sylius\Component\Product\Model\ProductInterface;
use Sylius\Resource\Exception\VariantWithNoOptionsValuesException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
@ -70,7 +70,7 @@ final class GenerateProductVariantsSubscriberSpec extends ObjectBehavior
FlashBagInterface $flashBag,
): void {
$event->getData()->willReturn($product);
$generator->generate($product)->willThrow(new VariantWithNoOptionsValuesException());
$generator->generate($product)->willThrow(new ProductWithoutOptionsValuesException());
$requestStack->getSession()->willReturn($session);
$session->getBag('flashes')->willReturn($flashBag);

View file

@ -0,0 +1,22 @@
<?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\Component\Product\Exception;
final class ProductWithoutOptionsException extends \Exception
{
public function __construct(?\Exception $previousException = null)
{
parent::__construct('Cannot generate variants for a product without options.', 0, $previousException);
}
}

View file

@ -0,0 +1,22 @@
<?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\Component\Product\Exception;
final class ProductWithoutOptionsValuesException extends \Exception
{
public function __construct(?\Exception $previousException = null)
{
parent::__construct('sylius.product_variant.cannot_generate_variants', 0, $previousException);
}
}

View file

@ -14,11 +14,11 @@ declare(strict_types=1);
namespace Sylius\Component\Product\Generator;
use Sylius\Component\Product\Checker\ProductVariantsParityCheckerInterface;
use Sylius\Component\Product\Exception\ProductWithoutOptionsException;
use Sylius\Component\Product\Exception\ProductWithoutOptionsValuesException;
use Sylius\Component\Product\Factory\ProductVariantFactoryInterface;
use Sylius\Component\Product\Model\ProductInterface;
use Sylius\Component\Product\Model\ProductVariantInterface;
use Sylius\Resource\Exception\VariantWithNoOptionsValuesException;
use Webmozart\Assert\Assert;
final class ProductVariantGenerator implements ProductVariantGeneratorInterface
{
@ -33,7 +33,9 @@ final class ProductVariantGenerator implements ProductVariantGeneratorInterface
public function generate(ProductInterface $product): void
{
Assert::true($product->hasOptions(), 'Cannot generate variants for an object without options.');
if (!$product->hasOptions()) {
throw new ProductWithoutOptionsException();
}
$optionSet = [];
$optionMap = [];
@ -46,7 +48,7 @@ final class ProductVariantGenerator implements ProductVariantGeneratorInterface
}
if (empty($optionSet)) {
throw new VariantWithNoOptionsValuesException();
throw new ProductWithoutOptionsValuesException();
}
$permutations = $this->setBuilder->build($optionSet);

View file

@ -13,14 +13,15 @@ declare(strict_types=1);
namespace Sylius\Component\Product\Generator;
use Sylius\Component\Product\Exception\ProductWithoutOptionsException;
use Sylius\Component\Product\Exception\ProductWithoutOptionsValuesException;
use Sylius\Component\Product\Model\ProductInterface;
use Sylius\Resource\Exception\VariantWithNoOptionsValuesException;
interface ProductVariantGeneratorInterface
{
/**
* @throws VariantWithNoOptionsValuesException
* @throws \InvalidArgumentException
* @throws ProductWithoutOptionsException
* @throws ProductWithoutOptionsValuesException
*/
public function generate(ProductInterface $product): void;
}

View file

@ -17,6 +17,8 @@ use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Product\Checker\ProductVariantsParityCheckerInterface;
use Sylius\Component\Product\Exception\ProductWithoutOptionsException;
use Sylius\Component\Product\Exception\ProductWithoutOptionsValuesException;
use Sylius\Component\Product\Factory\ProductVariantFactoryInterface;
use Sylius\Component\Product\Generator\ProductVariantGeneratorInterface;
use Sylius\Component\Product\Model\ProductInterface;
@ -33,16 +35,27 @@ final class ProductVariantGeneratorSpec extends ObjectBehavior
$this->beConstructedWith($productVariantFactory, $variantsParityChecker);
}
function it_implements_product_variant_generator_interfave(): void
function it_implements_product_variant_generator_interface(): void
{
$this->shouldImplement(ProductVariantGeneratorInterface::class);
}
function it_cannot_generate_variants_for_an_object_without_options(ProductInterface $variable): void
function it_throws_an_exception_if_product_has_no_options(ProductInterface $product): void
{
$variable->hasOptions()->willReturn(false);
$product->hasOptions()->willReturn(false);
$this->shouldThrow(\InvalidArgumentException::class)->duringGenerate($variable);
$this->shouldThrow(ProductWithoutOptionsException::class)->during('generate', [$product]);
}
function it_throws_an_exception_if_product_has_no_options_values(
ProductInterface $product,
ProductOptionInterface $colorOption,
): void {
$product->hasOptions()->willReturn(true);
$product->getOptions()->willReturn(new ArrayCollection([$colorOption->getWrappedObject()]));
$colorOption->getValues()->willReturn(new ArrayCollection([]));
$this->shouldThrow(ProductWithoutOptionsValuesException::class)->during('generate', [$product]);
}
function it_generates_variants_for_every_value_of_an_objects_single_option(