Completed
Pull Request — master (#51)
by Konrad
03:32
created

ListProductsByPartialNameAction   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 41
dl 0
loc 96
rs 10
c 0
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __invoke() 0 30 4
A __construct() 0 12 1
A resolveChannelProductPrice() 0 16 3
A resolveProductImage() 0 12 2
1
<?php
2
3
/*
4
 * This file has been created by developers from BitBag.
5
 * Feel free to contact us once you face any issues or want to start
6
 * another great project.
7
 * You can find more information about us on https://bitbag.shop and write us
8
 * an email on [email protected].
9
 */
10
11
declare(strict_types=1);
12
13
namespace BitBag\SyliusElasticsearchPlugin\Controller\Action\Api;
14
15
use BitBag\SyliusElasticsearchPlugin\Controller\Response\DTO\Item;
16
use BitBag\SyliusElasticsearchPlugin\Controller\Response\ItemsResponse;
17
use BitBag\SyliusElasticsearchPlugin\Finder\NamedProductsFinderInterface;
18
use Liip\ImagineBundle\Service\FilterService;
19
use Sylius\Bundle\MoneyBundle\Formatter\MoneyFormatterInterface;
20
use Sylius\Component\Channel\Context\ChannelContextInterface;
21
use Sylius\Component\Core\Model\ChannelInterface;
22
use Sylius\Component\Core\Model\ImageInterface;
23
use Sylius\Component\Core\Model\ProductInterface;
24
use Sylius\Component\Core\Model\ProductVariantInterface;
25
use Sylius\Component\Product\Resolver\ProductVariantResolverInterface;
26
use Symfony\Component\HttpFoundation\JsonResponse;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\HttpFoundation\Response;
29
30
final class ListProductsByPartialNameAction
31
{
32
    private const SYLIUS_THUMBNAIL_TYPE = 'thumbnail';
33
    private const SYLIUS_THUMBNAIL_FILTER = 'sylius_shop_product_thumbnail';
34
35
    /** @var NamedProductsFinderInterface */
36
    private $namedProductsFinder;
37
38
    /** @var ProductVariantResolverInterface */
39
    private $productVariantResolver;
40
41
    /** @var ChannelContextInterface */
42
    private $channelContext;
43
44
    /** @var MoneyFormatterInterface */
45
    private $moneyFormatter;
46
47
    /** @var FilterService */
48
    private $imagineFilter;
49
50
    public function __construct(
51
        NamedProductsFinderInterface $namedProductsFinder,
52
        ProductVariantResolverInterface $productVariantResolver,
53
        ChannelContextInterface $channelContext,
54
        MoneyFormatterInterface $moneyFormatter,
55
        FilterService $imagineFilter
56
    ) {
57
        $this->namedProductsFinder = $namedProductsFinder;
58
        $this->productVariantResolver = $productVariantResolver;
59
        $this->channelContext = $channelContext;
60
        $this->moneyFormatter = $moneyFormatter;
61
        $this->imagineFilter = $imagineFilter;
62
    }
63
64
    public function __invoke(Request $request): Response
65
    {
66
        $itemsResponse = ItemsResponse::createEmpty();
67
68
        if (null === $request->query->get('query')) {
69
            return JsonResponse::create($itemsResponse->toArray());
70
        }
71
72
        /** @var ChannelInterface $channel */
73
        $channel = $this->channelContext->getChannel();
74
75
        $products = $this->namedProductsFinder->findByNamePart($request->query->get('query'));
76
77
        /** @var ProductInterface $product */
78
        foreach ($products as $product) {
79
            if (null === $productMainTaxon = $product->getMainTaxon()) {
80
                continue;
81
            }
82
83
            $itemsResponse->addItem(new Item(
84
                $productMainTaxon->getName(),
85
                $product->getName(),
86
                $product->getShortDescription(),
87
                $product->getSlug(),
88
                $this->resolveChannelProductPrice($channel, $product),
0 ignored issues
show
Bug introduced by
It seems like $this->resolveChannelPro...ice($channel, $product) can also be of type null; however, parameter $price of BitBag\SyliusElasticsear...DTO\Item::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

88
                /** @scrutinizer ignore-type */ $this->resolveChannelProductPrice($channel, $product),
Loading history...
89
                $this->resolveProductImage($product)
0 ignored issues
show
Bug introduced by
It seems like $this->resolveProductImage($product) can also be of type null; however, parameter $image of BitBag\SyliusElasticsear...DTO\Item::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

89
                /** @scrutinizer ignore-type */ $this->resolveProductImage($product)
Loading history...
90
            ));
91
        }
92
93
        return JsonResponse::create($itemsResponse->toArray());
94
    }
95
96
    private function resolveChannelProductPrice(ChannelInterface $channel, ProductInterface $product): ?string
97
    {
98
        if (null === $channelBaseCurrency = $channel->getBaseCurrency()) {
99
            throw new \RuntimeException('No channel currency configured');
100
        }
101
102
        /** @var ProductVariantInterface $productVariant */
103
        $productVariant = $this->productVariantResolver->getVariant($product);
104
105
        $productVariantPricing = $productVariant->getChannelPricingForChannel($channel);
106
107
        if (null === $productVariantPricing) {
108
            return null;
109
        }
110
111
        return $this->moneyFormatter->format($productVariantPricing->getPrice(), $channelBaseCurrency->getCode());
0 ignored issues
show
Bug introduced by
It seems like $channelBaseCurrency->getCode() can also be of type null; however, parameter $currencyCode of Sylius\Bundle\MoneyBundl...tterInterface::format() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

111
        return $this->moneyFormatter->format($productVariantPricing->getPrice(), /** @scrutinizer ignore-type */ $channelBaseCurrency->getCode());
Loading history...
Bug introduced by
It seems like $productVariantPricing->getPrice() can also be of type null; however, parameter $amount of Sylius\Bundle\MoneyBundl...tterInterface::format() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

111
        return $this->moneyFormatter->format(/** @scrutinizer ignore-type */ $productVariantPricing->getPrice(), $channelBaseCurrency->getCode());
Loading history...
112
    }
113
114
    private function resolveProductImage(ProductInterface $product): ?string
115
    {
116
        $productThumbnails = $product->getImagesByType(self::SYLIUS_THUMBNAIL_TYPE);
117
118
        if ($productThumbnails->isEmpty()) {
119
            return null;
120
        }
121
122
        /** @var ImageInterface $productImage */
123
        $productImage = $productThumbnails->first();
124
125
        return $this->imagineFilter->getUrlOfFilteredImage($productImage->getPath(), self::SYLIUS_THUMBNAIL_FILTER);
126
    }
127
}
128