Completed
Pull Request — master (#180)
by Łukasz
02:58
created

ProductReviewsViewRepository   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

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

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
A getByProductSlug() 0 12 1
A getByProductCode() 0 13 1
A assertLocaleSupport() 0 9 2
A getChannel() 0 9 1
A createProductReviewPage() 0 15 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sylius\ShopApiPlugin\ViewRepository;
6
7
use Pagerfanta\Adapter\ArrayAdapter;
8
use Pagerfanta\Pagerfanta;
9
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
10
use Sylius\Component\Core\Model\ChannelInterface;
11
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
12
use Sylius\Component\Core\Repository\ProductReviewRepositoryInterface;
13
use Sylius\Component\Locale\Model\Locale;
14
use Sylius\Component\Review\Model\ReviewInterface;
15
use Sylius\ShopApiPlugin\Factory\PageViewFactoryInterface;
16
use Sylius\ShopApiPlugin\Factory\ProductReviewViewFactoryInterface;
17
use Sylius\ShopApiPlugin\Model\PaginatorDetails;
18
use Sylius\ShopApiPlugin\View\PageView;
19
use Webmozart\Assert\Assert;
20
21
final class ProductReviewsViewRepository implements ProductReviewsViewRepositoryInterface
22
{
23
    /** @var ChannelRepositoryInterface */
24
    private $channelRepository;
25
26
    /** @var ProductReviewRepositoryInterface */
27
    private $productReviewRepository;
28
29
    /** @var ProductRepositoryInterface */
30
    private $productRepository;
31
32
    /** @var ProductReviewViewFactoryInterface */
33
    private $productReviewViewFactory;
34
35
    /** @var PageViewFactoryInterface */
36
    private $pageViewFactory;
37
38
    public function __construct(
39
        ChannelRepositoryInterface $channelRepository,
40
        ProductReviewRepositoryInterface $productReviewRepository,
41
        ProductRepositoryInterface $productRepository,
42
        ProductReviewViewFactoryInterface $productReviewViewFactory,
43
        PageViewFactoryInterface $pageViewFactory
44
    ) {
45
        $this->channelRepository = $channelRepository;
46
        $this->productReviewRepository = $productReviewRepository;
47
        $this->productRepository = $productRepository;
48
        $this->productReviewViewFactory = $productReviewViewFactory;
49
        $this->pageViewFactory = $pageViewFactory;
50
    }
51
52
    public function getByProductSlug(string $productSlug, ?string $localeCode, string $channelCode, PaginatorDetails $paginatorDetails): PageView
53
    {
54
        $channel = $this->getChannel($channelCode);
55
        $localeCode = $localeCode ?? $channel->getDefaultLocale()->getCode();
56
        $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...
57
58
        $reviews = $this->productReviewRepository->findAcceptedByProductSlugAndChannel($productSlug, $localeCode, $channel);
59
60
        $paginatorDetails->addToParameters('slug', $productSlug);
61
62
        return $this->createProductReviewPage($reviews, $paginatorDetails);
63
    }
64
65
    public function getByProductCode(string $productCode, string $channelCode, PaginatorDetails $paginatorDetails): PageView
66
    {
67
        $channel = $this->getChannel($channelCode);
68
69
        $product = $this->productRepository->findOneByCode($productCode);
70
        Assert::true($product->hasChannel($channel));
71
72
        $reviews = $this->productReviewRepository->findBy(['reviewSubject' => $product->getId(), 'status' => ReviewInterface::STATUS_ACCEPTED]);
73
74
        $paginatorDetails->addToParameters('code', $productCode);
75
76
        return $this->createProductReviewPage($reviews, $paginatorDetails);
77
    }
78
79
    /**
80
     * @param string $localeCode
81
     * @param iterable|Locale[] $supportedLocales
82
     */
83
    private function assertLocaleSupport(string $localeCode, iterable $supportedLocales)
84
    {
85
        $supportedLocaleCodes = [];
86
        foreach ($supportedLocales as $locale) {
87
            $supportedLocaleCodes[] = $locale->getCode();
88
        }
89
90
        Assert::oneOf($localeCode, $supportedLocaleCodes);
91
    }
92
93
    private function getChannel(string $channelCode): ChannelInterface
94
    {
95
        /** @var ChannelInterface $channel */
96
        $channel = $this->channelRepository->findOneByCode($channelCode);
97
98
        Assert::notNull($channel, sprintf('Channel with code %s has not been found.', $channelCode));
99
100
        return $channel;
101
    }
102
103
    private function createProductReviewPage(array $reviews, PaginatorDetails $paginatorDetails): PageView
104
    {
105
        $pagerfanta = new Pagerfanta(new ArrayAdapter($reviews));
106
107
        $pagerfanta->setMaxPerPage($paginatorDetails->limit());
108
        $pagerfanta->setCurrentPage($paginatorDetails->page());
109
110
        $pageView = $this->pageViewFactory->create($pagerfanta, $paginatorDetails->route(), $paginatorDetails->parameters());
111
112
        foreach ($pagerfanta->getCurrentPageResults() as $currentPageResult) {
113
            $pageView->items[] = $this->productReviewViewFactory->create($currentPageResult);
114
        }
115
116
        return $pageView;
117
    }
118
}
119