Completed
Branch master (9d8d38)
by Łukasz
03:25
created

ShowProductCatalogAction   B

Complexity

Total Complexity 8

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 17

Importance

Changes 0
Metric Value
wmc 8
c 0
b 0
f 0
lcom 0
cbo 17
dl 0
loc 128
rs 7.8571

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
B __invoke() 0 66 7
1
<?php
2
3
namespace Sylius\ShopApiPlugin\Controller\Product;
4
5
use FOS\RestBundle\View\View;
6
use FOS\RestBundle\View\ViewHandlerInterface;
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\Taxonomy\Repository\TaxonRepositoryInterface;
14
use Sylius\ShopApiPlugin\Factory\ProductViewFactoryInterface;
15
use Sylius\ShopApiPlugin\View\PageLinksView;
16
use Sylius\ShopApiPlugin\View\PageView;
17
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
21
use Symfony\Component\Routing\RouterInterface;
22
23
final class ShowProductCatalogAction extends Controller
24
{
25
    /**
26
     * @var ChannelRepositoryInterface
27
     */
28
    private $channelRepository;
29
30
    /**
31
     * @var ProductRepositoryInterface
32
     */
33
    private $productRepository;
34
35
    /**
36
     * @var TaxonRepositoryInterface
37
     */
38
    private $taxonRepository;
39
40
    /**
41
     * @var ViewHandlerInterface
42
     */
43
    private $viewHandler;
44
45
    /**
46
     * @var ProductViewFactoryInterface
47
     */
48
    private $productViewFactory;
49
50
    /**
51
     * @var RouterInterface
52
     */
53
    private $router;
54
55
    /**
56
     * @param ChannelRepositoryInterface $channelRepository
57
     * @param ProductRepositoryInterface $productRepository
58
     * @param TaxonRepositoryInterface $taxonRepository
59
     * @param ViewHandlerInterface $viewHandler
60
     * @param ProductViewFactoryInterface $productViewFactory
61
     * @param RouterInterface $router
62
     */
63
    public function __construct(
64
        ChannelRepositoryInterface $channelRepository,
65
        ProductRepositoryInterface $productRepository,
66
        TaxonRepositoryInterface $taxonRepository,
67
        ViewHandlerInterface $viewHandler,
68
        ProductViewFactoryInterface $productViewFactory,
69
        RouterInterface $router
70
    ) {
71
        $this->channelRepository = $channelRepository;
72
        $this->productRepository = $productRepository;
73
        $this->taxonRepository = $taxonRepository;
74
        $this->viewHandler = $viewHandler;
75
        $this->productViewFactory = $productViewFactory;
76
        $this->router = $router;
77
    }
78
79
    /**
80
     * @param Request $request
81
     *
82
     * @return Response
83
     */
84
    public function __invoke(Request $request)
85
    {
86
        if (!$request->query->has('channel')) {
87
            throw new NotFoundHttpException('Cannot find product without channel provided');
88
        }
89
90
        $channelCode = $request->query->get('channel');
91
        /** @var ChannelInterface $channel */
92
        $channel = $this->channelRepository->findOneByCode($channelCode);
93
94
        if (null === $channel) {
95
            throw new NotFoundHttpException(sprintf('Channel with code %s has not been found', $channelCode));
96
        }
97
98
        $locale = $request->query->has('locale') ? $request->query->get('locale') : $channel->getDefaultLocale()->getCode();
99
100
        $taxonSlug = $request->attributes->get('taxonomy');
101
        /** @var TaxonInterface $taxon */
102
        $taxon = $this->taxonRepository->findOneBySlug($taxonSlug, $locale);
103
104
        if (null === $taxon) {
105
            throw new NotFoundHttpException(sprintf('Taxon with slug %s in locale %s has not been found', $taxonSlug, $locale));
106
        }
107
108
        $queryBuilder = $this->productRepository->createShopListQueryBuilder($channel, $taxon, $locale);
109
        $adapter = new DoctrineORMAdapter($queryBuilder);
110
        $pagerfanta = new Pagerfanta($adapter);
111
112
        $pagerfanta->setMaxPerPage($request->query->get('limit', 10));
113
        $pagerfanta->setCurrentPage($request->query->get('page', 1));
114
115
        $page = new PageView();
116
        $page->page = $pagerfanta->getCurrentPage();
117
        $page->limit = $pagerfanta->getMaxPerPage();
118
        $page->pages = $pagerfanta->getNbPages();
119
        $page->total = $pagerfanta->getNbResults();
120
121
        $page->links = new PageLinksView();
122
123
        $page->links->self = $this->router->generate('shop_api_product_show_catalog', [
124
            'taxonomy' => $taxonSlug,
125
            'page' => $pagerfanta->getCurrentPage(),
126
            'limit' => $pagerfanta->getMaxPerPage(),
127
        ]);
128
        $page->links->first = $this->router->generate('shop_api_product_show_catalog', [
129
            'taxonomy' => $taxonSlug,
130
            'page' => 1,
131
            'limit' => $pagerfanta->getMaxPerPage(),
132
        ]);
133
        $page->links->last = $this->router->generate('shop_api_product_show_catalog', [
134
            'taxonomy' => $taxonSlug,
135
            'page' => $pagerfanta->getNbPages(),
136
            'limit' => $pagerfanta->getMaxPerPage(),
137
        ]);
138
        $page->links->next = $this->router->generate('shop_api_product_show_catalog', [
139
            'taxonomy' => $taxonSlug,
140
            'page' => ($pagerfanta->getCurrentPage() < $pagerfanta->getNbPages()) ? $pagerfanta->getCurrentPage() + 1 : $pagerfanta->getCurrentPage(),
141
            'limit' => $pagerfanta->getMaxPerPage(),
142
        ]);
143
144
        foreach ($pagerfanta->getCurrentPageResults() as $currentPageResult) {
145
            $page->items[] = $this->productViewFactory->create($currentPageResult, $channel, $locale);
146
        }
147
148
        return $this->viewHandler->handle(View::create($page, Response::HTTP_OK));
149
    }
150
}
151