ProductDetailsViewRepository::findOneBySlug()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Sylius\ShopApiPlugin\ViewRepository;
6
7
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
8
use Sylius\Component\Core\Model\ChannelInterface;
9
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
10
use Sylius\Component\Locale\Model\LocaleInterface;
11
use Sylius\ShopApiPlugin\Factory\ProductViewFactoryInterface;
12
use Sylius\ShopApiPlugin\View\ProductView;
13
use Webmozart\Assert\Assert;
14
15
final class ProductDetailsViewRepository implements ProductDetailsViewRepositoryInterface
16
{
17
    /** @var ChannelRepositoryInterface */
18
    private $channelRepository;
19
20
    /** @var ProductRepositoryInterface */
21
    private $productRepository;
22
23
    /** @var ProductViewFactoryInterface */
24
    private $productViewFactory;
25
26
    public function __construct(
27
        ChannelRepositoryInterface $channelRepository,
28
        ProductRepositoryInterface $productRepository,
29
        ProductViewFactoryInterface $productViewFactory
30
    ) {
31
        $this->channelRepository = $channelRepository;
32
        $this->productRepository = $productRepository;
33
        $this->productViewFactory = $productViewFactory;
34
    }
35
36
    public function findOneBySlug(string $productSlug, string $channelCode, ?string $localeCode): ProductView
37
    {
38
        $channel = $this->getChannel($channelCode);
39
        $localeCode = $this->getLocaleCode($localeCode, $channel);
40
41
        $product = $this->productRepository->findOneByChannelAndSlug($channel, $localeCode, $productSlug);
42
43
        Assert::notNull($product, sprintf('Product with slug %s has not been found in %s locale.', $productSlug, $localeCode));
44
45
        return $this->productViewFactory->create($product, $channel, $localeCode);
46
    }
47
48
    public function findOneByCode(string $productCode, string $channelCode, ?string $localeCode): ProductView
49
    {
50
        $channel = $this->getChannel($channelCode);
51
        $localeCode = $this->getLocaleCode($localeCode, $channel);
52
53
        $product = $this->productRepository->findOneByCode($productCode);
54
55
        Assert::notNull($product, sprintf('Product with code %s has not been found.', $productCode));
56
        Assert::true($product->hasChannel($channel), sprintf('Channel with code %s has not been found.', $channelCode));
57
58
        return $this->productViewFactory->create($product, $channel, $localeCode);
59
    }
60
61
    /**
62
     * @param string $localeCode
63
     * @param iterable|LocaleInterface[] $supportedLocales
64
     */
65
    private function assertLocaleSupport(string $localeCode, iterable $supportedLocales)
66
    {
67
        $supportedLocaleCodes = [];
68
        foreach ($supportedLocales as $locale) {
69
            $supportedLocaleCodes[] = $locale->getCode();
70
        }
71
72
        Assert::oneOf($localeCode, $supportedLocaleCodes);
73
    }
74
75
    private function getChannel(string $channelCode): ChannelInterface
76
    {
77
        /** @var ChannelInterface $channel */
78
        $channel = $this->channelRepository->findOneByCode($channelCode);
79
80
        Assert::notNull($channel, sprintf('Channel with code %s has not been found.', $channelCode));
81
82
        return $channel;
83
    }
84
85
    private function getLocaleCode(?string $localeCode, ChannelInterface $channel): string
86
    {
87
        $localeCode = $localeCode ?? $channel->getDefaultLocale()->getCode();
88
        $this->assertLocaleSupport($localeCode, $channel->getLocales());
89
90
        return $localeCode;
91
    }
92
}
93