Completed
Push — 1.3 ( 2923d8...a36271 )
by Kamil
32:20
created

ProvinceAddressConstraintValidator   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 7
dl 0
loc 70
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A validate() 0 23 5
A isProvinceValid() 0 28 5
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Bundle\AddressingBundle\Validator\Constraints;
15
16
use Sylius\Component\Addressing\Model\AddressInterface;
17
use Sylius\Component\Addressing\Model\CountryInterface;
18
use Sylius\Component\Addressing\Model\ProvinceInterface;
19
use Sylius\Component\Resource\Repository\RepositoryInterface;
20
use Symfony\Component\Validator\Constraint;
21
use Symfony\Component\Validator\ConstraintValidator;
22
use Webmozart\Assert\Assert;
23
24
class ProvinceAddressConstraintValidator extends ConstraintValidator
25
{
26
    /** @var RepositoryInterface */
27
    private $countryRepository;
28
29
    /** @var RepositoryInterface */
30
    private $provinceRepository;
31
32
    public function __construct(RepositoryInterface $countryRepository, RepositoryInterface $provinceRepository)
33
    {
34
        $this->countryRepository = $countryRepository;
35
        $this->provinceRepository = $provinceRepository;
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function validate($value, Constraint $constraint): void
42
    {
43
        if (!$value instanceof AddressInterface) {
44
            throw new \InvalidArgumentException(
45
                'ProvinceAddressConstraintValidator can only validate instances of "Sylius\Component\Addressing\Model\AddressInterface"'
46
            );
47
        }
48
49
        /** @var ProvinceAddressConstraint $constraint */
50
        Assert::isInstanceOf($constraint, ProvinceAddressConstraint::class);
51
52
        $propertyPath = $this->context->getPropertyPath();
53
54
        foreach (iterator_to_array($this->context->getViolations()) as $violation) {
55
            if (0 === strpos($violation->getPropertyPath(), $propertyPath)) {
56
                return;
57
            }
58
        }
59
60
        if (!$this->isProvinceValid($value)) {
61
            $this->context->addViolation($constraint->message);
62
        }
63
    }
64
65
    protected function isProvinceValid(AddressInterface $address): bool
66
    {
67
        $countryCode = $address->getCountryCode();
68
69
        /** @var CountryInterface|null $country */
70
        $country = $this->countryRepository->findOneBy(['code' => $countryCode]);
71
72
        if (null === $country) {
73
            return true;
74
        }
75
76
        if (!$country->hasProvinces()) {
77
            return true;
78
        }
79
80
        if (null === $address->getProvinceCode()) {
81
            return false;
82
        }
83
84
        /** @var ProvinceInterface|null $province */
85
        $province = $this->provinceRepository->findOneBy(['code' => $address->getProvinceCode()]);
86
87
        if (null === $province) {
88
            return false;
89
        }
90
91
        return $country->hasProvince($province);
92
    }
93
}
94