Completed
Pull Request — master (#179)
by Łukasz
02:48
created

ProductCatalogQuery   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 12
dl 0
loc 127
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
A findByTaxonSlug() 0 18 1
A findByTaxonCode() 0 18 1
A assertLocaleSupport() 0 9 2
A getChannel() 0 9 1
A getLocaleCode() 0 7 1
A findByTaxon() 0 17 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sylius\ShopApiPlugin\Query;
6
7
use Pagerfanta\Adapter\DoctrineORMAdapter;
8
use Pagerfanta\Pagerfanta;
9
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
10
use Sylius\Component\Core\Model\ChannelInterface;
11
use Sylius\Component\Core\Model\TaxonInterface;
12
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
13
use Sylius\Component\Locale\Model\Locale;
14
use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface;
15
use Sylius\ShopApiPlugin\Factory\PageViewFactoryInterface;
16
use Sylius\ShopApiPlugin\Factory\ProductViewFactoryInterface;
17
use Sylius\ShopApiPlugin\Model\PaginatorDetails;
18
use Sylius\ShopApiPlugin\View\PageView;
19
use Webmozart\Assert\Assert;
20
21
final class ProductCatalogQuery
22
{
23
    /** @var ChannelRepositoryInterface */
24
    private $channelRepository;
25
26
    /** @var ProductRepositoryInterface */
27
    private $productRepository;
28
29
    /** @var ProductViewFactoryInterface */
30
    private $productViewFactory;
31
32
    /** @var TaxonRepositoryInterface */
33
    private $taxonRepository;
34
35
    /** @var PageViewFactoryInterface */
36
    private $pageViewFactory;
37
38
    public function __construct(
39
        ChannelRepositoryInterface $channelRepository,
40
        ProductRepositoryInterface $productRepository,
41
        TaxonRepositoryInterface $taxonRepository,
42
        ProductViewFactoryInterface $productViewFactory,
43
        PageViewFactoryInterface $pageViewFactory
44
    ) {
45
        $this->channelRepository = $channelRepository;
46
        $this->productRepository = $productRepository;
47
        $this->productViewFactory = $productViewFactory;
48
        $this->taxonRepository = $taxonRepository;
49
        $this->pageViewFactory = $pageViewFactory;
50
    }
51
52
    public function findByTaxonSlug(string $taxonSlug, ?string $localeCode, string $channelCode, PaginatorDetails $paginatorDetails): PageView
53
    {
54
        $channel = $this->getChannel($channelCode);
55
        $localeCode = $this->getLocaleCode($localeCode, $channel);
56
57
        /** @var TaxonInterface $taxon */
58
        $taxon = $this->taxonRepository->findOneBySlug($taxonSlug, $localeCode);
59
60
        Assert::notNull($taxon, sprintf('Taxon with slug %s in locale %s has not been found', $taxonSlug, $localeCode));
61
        $paginatorDetails->addParameter('taxonomySlug', $taxonSlug);
62
63
        return $this->findByTaxon(
64
            $localeCode,
65
            $paginatorDetails,
66
            $channel,
67
            $taxon
68
        );
69
    }
70
71
    public function findByTaxonCode(string $taxonCode, ?string $localeCode, string $channelCode, PaginatorDetails $paginatorDetails): PageView
72
    {
73
        $channel = $this->getChannel($channelCode);
74
        $localeCode = $this->getLocaleCode($localeCode, $channel);
75
76
        /** @var TaxonInterface $taxon */
77
        $taxon = $this->taxonRepository->findOneBy(['code' => $taxonCode]);
78
79
        Assert::notNull($taxon, sprintf('Taxon with code %s has not been found', $taxonCode));
80
        $paginatorDetails->addParameter('code', $taxonCode);
81
82
        return $this->findByTaxon(
83
            $localeCode,
84
            $paginatorDetails,
85
            $channel,
86
            $taxon
87
        );
88
    }
89
90
    /**
91
     * @param string $localeCode
92
     * @param iterable|Locale[] $supportedLocales
93
     */
94
    private function assertLocaleSupport(string $localeCode, iterable $supportedLocales)
95
    {
96
        $supportedLocaleCodes = [];
97
        foreach ($supportedLocales as $locale) {
98
            $supportedLocaleCodes[] = $locale->getCode();
99
        }
100
101
        Assert::oneOf($localeCode, $supportedLocaleCodes);
102
    }
103
104
    private function getChannel(?string $channelCode): ChannelInterface
105
    {
106
        /** @var ChannelInterface $channel */
107
        $channel = $this->channelRepository->findOneByCode($channelCode);
108
109
        Assert::notNull($channel, sprintf('Channel with code %s has not been found.', $channelCode));
110
111
        return $channel;
112
    }
113
114
    private function getLocaleCode(?string $localeCode, ChannelInterface $channel): string
115
    {
116
        $localeCode = $localeCode ?? $channel->getDefaultLocale()->getCode();
117
        $this->assertLocaleSupport($localeCode, $channel->getLocales());
0 ignored issues
show
Documentation introduced by
$channel->getLocales() is of type object<Doctrine\Common\C...Model\LocaleInterface>>, but the function expects a object<Sylius\ShopApiPlu...t\Locale\Model\Locale>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
118
119
        return $localeCode;
120
    }
121
122
    /**
123
     * @param string $localeCode
124
     * @param PaginatorDetails $paginatorDetails
125
     * @param ChannelInterface $channel
126
     * @param TaxonInterface $taxon
127
     *
128
     * @return PageView
129
     */
130
    private function findByTaxon(string $localeCode, PaginatorDetails $paginatorDetails, ChannelInterface $channel, TaxonInterface $taxon): PageView
131
    {
132
        $queryBuilder = $this->productRepository->createShopListQueryBuilder($channel, $taxon, $localeCode);
133
134
        $pagerfanta = new Pagerfanta(new DoctrineORMAdapter($queryBuilder));
135
136
        $pagerfanta->setMaxPerPage($paginatorDetails->limit());
137
        $pagerfanta->setCurrentPage($paginatorDetails->page());
138
139
        $pageView = $this->pageViewFactory->create($pagerfanta, $paginatorDetails->route(), $paginatorDetails->getParameters());
140
141
        foreach ($pagerfanta->getCurrentPageResults() as $currentPageResult) {
142
            $pageView->items[] = $this->productViewFactory->create($currentPageResult, $channel, $localeCode);
143
        }
144
145
        return $pageView;
146
    }
147
}
148