[CoreBundle] Add ProductCodeExistsValidator class

This commit is contained in:
Wojdylak 2023-11-21 13:06:57 +01:00
parent c61d53e7b0
commit f4a3a3e722
7 changed files with 169 additions and 2 deletions

View file

@ -44,7 +44,7 @@
<value>shipping_percentage_discount</value>
</option>
<option name="min">0</option>
<option name="max">1</option>
<option name="max">100</option>
<option name="notInRangeMessage">sylius.promotion_action.percentage_discount_configuration.not_in_range</option>
</constraint>
</value>
@ -113,7 +113,7 @@
<constraint name="Range">
<option name="groups">unit_percentage_discount</option>
<option name="min">0</option>
<option name="max">1</option>
<option name="max">100</option>
<option name="notInRangeMessage">sylius.promotion_action.percentage_discount_configuration.not_in_range</option>
</constraint>
</value>

View file

@ -142,6 +142,9 @@
<option name="groups">contains_product</option>
<option name="type">string</option>
</constraint>
<constraint name="Sylius\Bundle\CoreBundle\Validator\Constraints\ProductCodeExists">
<option name="groups">contains_product</option>
</constraint>
</value>
</option>
</constraint>

View file

@ -92,5 +92,10 @@
<argument type="service" id="sylius.repository.taxon" />
<tag name="validator.constraint_validator" alias="sylius_taxon_code_exists" />
</service>
<service id="sylius.validator.product_code_exists" class="Sylius\Bundle\CoreBundle\Validator\Constraints\ProductCodeExistsValidator">
<argument type="service" id="sylius.repository.product" />
<tag name="validator.constraint_validator" alias="sylius_product_code_exists" />
</service>
</services>
</container>

View file

@ -90,6 +90,8 @@ sylius:
product:
variants:
all_prices_defined: You have to define product variants' prices for newly assigned channels first.
code:
no_exist: Product with code {{ code }} does not exist.
product_attribute:
invalid: Position must be an integer.
product_image:

View file

@ -0,0 +1,31 @@
<?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\CoreBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
final class ProductCodeExists extends Constraint
{
public string $message = 'sylius.product.code.no_exist';
public function validatedBy(): string
{
return 'sylius_product_code_exists';
}
public function getTargets(): string
{
return Constraint::PROPERTY_CONSTRAINT;
}
}

View file

@ -0,0 +1,44 @@
<?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\CoreBundle\Validator\Constraints;
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
final class ProductCodeExistsValidator extends ConstraintValidator
{
public function __construct(private ProductRepositoryInterface $productRepository)
{
}
public function validate($value, Constraint $constraint): void
{
if (!$constraint instanceof ProductCodeExists) {
throw new UnexpectedTypeException($constraint, ProductCodeExists::class);
}
if (empty($value)) {
return;
}
if ($this->productRepository->findOneByCode($value) === null) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ code }}', $value)
->addViolation()
;
}
}
}

View file

@ -0,0 +1,82 @@
<?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\CoreBundle\Validator\Constraints;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\CoreBundle\Validator\Constraints\ProductCodeExists;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
final class ProductCodeExistsValidatorSpec extends ObjectBehavior
{
const MESSAGE = 'sylius.product.code.no_exist';
function let(ProductRepositoryInterface $productRepository, ExecutionContextInterface $context): void
{
$this->beConstructedWith($productRepository);
$this->initialize($context);
}
function it_throws_an_exception_if_constraint_is_not_an_instance_of_product_code_exists(
Constraint $constraint,
): void {
$this
->shouldThrow(UnexpectedTypeException::class)
->during('validate', ['product_code', $constraint])
;
}
function it_does_nothing_if_value_is_empty(
ProductRepositoryInterface $productRepository,
ExecutionContextInterface $context,
): void {
$this->validate('', new ProductCodeExists());
$context->buildViolation(self::MESSAGE)->shouldNotHaveBeenCalled();
$productRepository->findOneBy(Argument::any())->shouldNotHaveBeenCalled();
}
function it_does_nothing_if_product_with_given_code_exists(
ProductRepositoryInterface $productRepository,
ExecutionContextInterface $context,
ProductInterface $product,
): void {
$productRepository->findOneByCode('product_code')->willReturn($product);
$this->validate('product_code', new ProductCodeExists());
$context->buildViolation(self::MESSAGE)->shouldNotHaveBeenCalled();
}
function it_adds_a_violation_if_product_with_given_code_does_not_exist(
ProductRepositoryInterface $productRepository,
ExecutionContextInterface $context,
ConstraintViolationBuilderInterface $constraintViolationBuilder,
): void {
$productRepository->findOneByCode('product_code')->willReturn(null);
$constraintViolationBuilder->addViolation()->shouldBeCalled();
$constraintViolationBuilder->atPath(Argument::any())->willReturn($constraintViolationBuilder);
$constraintViolationBuilder->setParameter(Argument::cetera())->willReturn($constraintViolationBuilder);
$context->buildViolation(self::MESSAGE)->shouldBeCalled()->willReturn($constraintViolationBuilder);
$this->validate('product_code', new ProductCodeExists());
}
}