Completed
Push — master ( 97ef27...8cdac9 )
by Kamil
17:01 queued 07:38
created

getShippingMethods()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 2
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
namespace Sylius\Component\Core\Resolver;
13
14
use Sylius\Component\Addressing\Matcher\ZoneMatcherInterface;
15
use Sylius\Component\Addressing\Model\ZoneInterface;
16
use Sylius\Component\Core\Model\AddressInterface;
17
use Sylius\Component\Core\Model\ChannelInterface;
18
use Sylius\Component\Core\Model\OrderInterface;
19
use Sylius\Component\Core\Model\ShipmentInterface as CoreShipmentInterface;
20
use Sylius\Component\Core\Repository\ShippingMethodRepositoryInterface;
21
use Sylius\Component\Shipping\Checker\ShippingMethodEligibilityCheckerInterface;
22
use Sylius\Component\Shipping\Exception\UnresolvedDefaultShippingMethodException;
23
use Sylius\Component\Shipping\Model\ShipmentInterface;
24
use Sylius\Component\Shipping\Model\ShippingMethodInterface;
25
use Sylius\Component\Shipping\Resolver\DefaultShippingMethodResolverInterface;
26
use Webmozart\Assert\Assert;
27
28
final class EligibleDefaultShippingMethodResolver implements DefaultShippingMethodResolverInterface
29
{
30
    /**
31
     * @var ShippingMethodRepositoryInterface
32
     */
33
    private $shippingMethodRepository;
34
35
    /**
36
     * @var ShippingMethodEligibilityCheckerInterface
37
     */
38
    private $shippingMethodEligibilityChecker;
39
40
    /**
41
     * @var ZoneMatcherInterface
42
     */
43
    private $zoneMatcher;
44
45
    /**
46
     * @param ShippingMethodRepositoryInterface $shippingMethodRepository
47
     * @param ShippingMethodEligibilityCheckerInterface $shippingMethodEligibilityChecker
48
     * @param ZoneMatcherInterface $zoneMatcher
49
     */
50
    public function __construct(
51
        ShippingMethodRepositoryInterface $shippingMethodRepository,
52
        ShippingMethodEligibilityCheckerInterface $shippingMethodEligibilityChecker,
53
        ZoneMatcherInterface $zoneMatcher
54
    ) {
55
        $this->shippingMethodRepository = $shippingMethodRepository;
56
        $this->shippingMethodEligibilityChecker = $shippingMethodEligibilityChecker;
57
        $this->zoneMatcher = $zoneMatcher;
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function getDefaultShippingMethod(ShipmentInterface $shipment): ShippingMethodInterface
64
    {
65
        /** @var CoreShipmentInterface $shipment */
66
        Assert::isInstanceOf($shipment, CoreShipmentInterface::class);
67
68
        /** @var OrderInterface $order */
69
        $order = $shipment->getOrder();
70
        /** @var ChannelInterface $channel */
71
        $channel = $order->getChannel();
72
73
        $shippingMethods = $this->getShippingMethods($channel, $order->getShippingAddress());
74
75
        foreach ($shippingMethods as $key => $shippingMethod) {
76
            if ($this->shippingMethodEligibilityChecker->isEligible($shipment, $shippingMethod)) {
77
                return $shippingMethod;
78
            }
79
        }
80
81
        throw new UnresolvedDefaultShippingMethodException();
82
    }
83
84
    /**
85
     * @param ChannelInterface $channel
86
     * @param AddressInterface|null $address
87
     *
88
     * @return array|ShippingMethodInterface[]
89
     */
90
    private function getShippingMethods(ChannelInterface $channel, ?AddressInterface $address): array
91
    {
92
        if (null === $address) {
93
            return $this->shippingMethodRepository->findEnabledForChannel($channel);
94
        }
95
96
        /** @var ZoneInterface[] $zones */
97
        $zones = $this->zoneMatcher->matchAll($address);
98
99
        return $this->shippingMethodRepository->findEnabledForZonesAndChannel($zones, $channel);
100
    }
101
}
102