ZoneMatcher   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 0
dl 0
loc 60
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A match() 0 17 4
A addressBelongsToZone() 0 10 3
A addressBelongsToZoneMember() 0 9 3
A getZones() 0 8 2
1
<?php
2
3
/*
4
 * This file has been created by developers from BitBag.
5
 * Feel free to contact us once you face any issues or want to start
6
 * another great project.
7
 * You can find more information about us on https://bitbag.io and write us
8
 * an email on [email protected].
9
 */
10
11
declare(strict_types=1);
12
13
namespace BitBag\SyliusVueStorefrontPlugin\Sylius\Matcher;
14
15
use Sylius\Component\Addressing\Model\Scope;
16
use Sylius\Component\Addressing\Model\ZoneInterface;
17
use Sylius\Component\Addressing\Model\ZoneMemberInterface;
18
use Sylius\Component\Resource\Repository\RepositoryInterface;
19
20
final class ZoneMatcher
21
{
22
    private const TYPE_COUNTRY = 'country';
23
24
    /** @var RepositoryInterface */
25
    private $zoneRepository;
26
27
    public function __construct(RepositoryInterface $zoneRepository)
28
    {
29
        $this->zoneRepository = $zoneRepository;
30
    }
31
32
    public function match(string $countryCode, ?string $scope = null): ?ZoneInterface
33
    {
34
        $zones = [];
35
36
        /** @var ZoneInterface $zone */
37
        foreach ($this->getZones($scope) as $zone) {
38
            if ($this->addressBelongsToZone($countryCode, $zone)) {
39
                $zones[$zone->getType()] = $zone;
40
            }
41
        }
42
43
        if (isset($zones[self::TYPE_COUNTRY])) {
44
            return $zones[self::TYPE_COUNTRY];
45
        }
46
47
        return null;
48
    }
49
50
    private function addressBelongsToZone(string $countryCode, ZoneInterface $zone): bool
51
    {
52
        foreach ($zone->getMembers() as $member) {
53
            if ($this->addressBelongsToZoneMember($countryCode, $member)) {
54
                return true;
55
            }
56
        }
57
58
        return false;
59
    }
60
61
    private function addressBelongsToZoneMember(string $countryCode, ZoneMemberInterface $member): bool
62
    {
63
        switch ($type = $member->getBelongsTo()->getType()) {
64
            case ZoneInterface::TYPE_COUNTRY:
65
                return null !== $countryCode && $countryCode === $member->getCode();
66
            default:
67
                throw new \InvalidArgumentException(sprintf('Unexpected zone type "%s".', $type));
68
        }
69
    }
70
71
    private function getZones(?string $scope = null): array
72
    {
73
        if (null === $scope) {
74
            return $this->zoneRepository->findAll();
75
        }
76
77
        return $this->zoneRepository->findBy(['scope' => [$scope, Scope::ALL]]);
78
    }
79
}
80