GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

ProductRegisterHandler   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
eloc 86
c 2
b 0
f 2
dl 0
loc 189
rs 10
wmc 22

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getVariantPrice() 0 11 2
A getProductUrl() 0 22 3
A __construct() 0 12 1
C register() 0 70 12
A unregister() 0 20 3
A getImageUrl() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Odiseo\SyliusMailchimpPlugin\Handler;
6
7
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
8
use Odiseo\SyliusMailchimpPlugin\Api\EcommerceInterface;
9
use Sylius\Component\Core\Model\ChannelInterface;
10
use Sylius\Component\Core\Model\ChannelPricingInterface;
11
use Sylius\Component\Core\Model\ProductImageInterface;
12
use Sylius\Component\Core\Model\ProductInterface;
13
use Sylius\Component\Core\Model\ProductVariant;
14
use Symfony\Component\EventDispatcher\GenericEvent;
15
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
16
use Symfony\Component\Routing\RouterInterface;
17
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
18
19
final class ProductRegisterHandler implements ProductRegisterHandlerInterface
20
{
21
    /** @var EcommerceInterface */
22
    private $ecommerceApi;
23
24
    /** @var RouterInterface */
25
    private $router;
26
27
    /** @var CacheManager */
28
    private $cacheManager;
29
30
    /** @var EventDispatcherInterface */
31
    private $eventDispatcher;
32
33
    /** @var bool */
34
    private $enabled;
35
36
    public function __construct(
37
        EcommerceInterface $ecommerceApi,
38
        RouterInterface $router,
39
        CacheManager $cacheManager,
40
        EventDispatcherInterface $eventDispatcher,
41
        bool $enabled
42
    ) {
43
        $this->ecommerceApi = $ecommerceApi;
44
        $this->router = $router;
45
        $this->cacheManager = $cacheManager;
46
        $this->eventDispatcher = $eventDispatcher;
47
        $this->enabled = $enabled;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function register(ProductInterface $product, ChannelInterface $channel, bool $createOnly = false)
54
    {
55
        if (!$this->enabled) {
56
            return false;
57
        }
58
59
        $productId = (string) $product->getId();
60
        $storeId = $channel->getCode();
61
62
        $response = $this->ecommerceApi->getProduct($storeId, $productId);
0 ignored issues
show
Bug introduced by
It seems like $storeId can also be of type null; however, parameter $storeId of Odiseo\SyliusMailchimpPl...Interface::getProduct() 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

62
        $response = $this->ecommerceApi->getProduct(/** @scrutinizer ignore-type */ $storeId, $productId);
Loading history...
63
        $isNew = !isset($response['id']);
64
65
        // Do nothing if the product exists
66
        if (false === $isNew && true === $createOnly) {
67
            return false;
68
        }
69
70
        $variants = [];
71
        /** @var ProductVariant $productVariant */
72
        foreach ($product->getVariants() as $productVariant) {
73
            $variant = [
74
                'id' => (string) $productVariant->getId(),
75
                'title' => $productVariant->getName() ? $productVariant->getName() : $product->getName(),
76
                'inventory_quantity' => $productVariant->isTracked() ? $productVariant->getOnHand() : 1,
77
            ];
78
79
            if ($variantPrice = $this->getVariantPrice($productVariant, $channel)) {
80
                $variant['price'] = $variantPrice / 100;
81
            }
82
83
            $variants[] = $variant;
84
        }
85
86
        $productImages = [];
87
        /** @var ProductImageInterface $image */
88
        foreach ($product->getImages() as $image) {
89
            $productImages[] = [
90
                'id' => (string) $image->getId(),
91
                'url' => $this->getImageUrl($image, $channel),
92
            ];
93
        }
94
95
        $data = [
96
            'id' => $productId,
97
            'title' => $product->getName(),
98
            'url' => $this->getProductUrl($product, $channel),
99
            'description' => $product->getDescription() ?: '',
100
            'images' => $productImages,
101
            'variants' => $variants,
102
        ];
103
104
        if (count($productImages) > 0) {
105
            $data['image_url'] = $productImages[0]['url'];
106
        }
107
108
        if ($isNew) {
109
            $event = new GenericEvent($product, ['data' => $data, 'channel' => $channel]);
110
            $this->eventDispatcher->dispatch($event, 'mailchimp.product.pre_add');
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with 'mailchimp.product.pre_add'. ( Ignorable by Annotation )

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

110
            $this->eventDispatcher->/** @scrutinizer ignore-call */ 
111
                                    dispatch($event, 'mailchimp.product.pre_add');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
111
            $data = $event->getArgument('data');
112
113
            $response = $this->ecommerceApi->addProduct($storeId, $data);
0 ignored issues
show
Bug introduced by
It seems like $storeId can also be of type null; however, parameter $storeId of Odiseo\SyliusMailchimpPl...Interface::addProduct() 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

113
            $response = $this->ecommerceApi->addProduct(/** @scrutinizer ignore-type */ $storeId, $data);
Loading history...
114
        } else {
115
            $event = new GenericEvent($product, ['data' => $data, 'channel' => $channel]);
116
            $this->eventDispatcher->dispatch($event, 'mailchimp.product.pre_update');
117
            $data = $event->getArgument('data');
118
119
            $response = $this->ecommerceApi->updateProduct($storeId, $productId, $data);
0 ignored issues
show
Bug introduced by
It seems like $storeId can also be of type null; however, parameter $storeId of Odiseo\SyliusMailchimpPl...erface::updateProduct() 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

119
            $response = $this->ecommerceApi->updateProduct(/** @scrutinizer ignore-type */ $storeId, $productId, $data);
Loading history...
120
        }
121
122
        return $response;
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function unregister(ProductInterface $product, ChannelInterface $channel)
129
    {
130
        if (!$this->enabled) {
131
            return false;
132
        }
133
134
        $productId = (string) $product->getId();
135
        $storeId = $channel->getCode();
136
137
        $response = $this->ecommerceApi->getProduct($storeId, $productId);
0 ignored issues
show
Bug introduced by
It seems like $storeId can also be of type null; however, parameter $storeId of Odiseo\SyliusMailchimpPl...Interface::getProduct() 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

137
        $response = $this->ecommerceApi->getProduct(/** @scrutinizer ignore-type */ $storeId, $productId);
Loading history...
138
        $isNew = !isset($response['id']);
139
140
        if (!$isNew) {
141
            $event = new GenericEvent($product, ['channel' => $channel]);
142
            $this->eventDispatcher->dispatch($event, 'mailchimp.product.pre_remove');
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with 'mailchimp.product.pre_remove'. ( Ignorable by Annotation )

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

142
            $this->eventDispatcher->/** @scrutinizer ignore-call */ 
143
                                    dispatch($event, 'mailchimp.product.pre_remove');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
143
144
            return $this->ecommerceApi->removeProduct($storeId, $productId);
0 ignored issues
show
Bug introduced by
It seems like $storeId can also be of type null; however, parameter $storeId of Odiseo\SyliusMailchimpPl...erface::removeProduct() 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

144
            return $this->ecommerceApi->removeProduct(/** @scrutinizer ignore-type */ $storeId, $productId);
Loading history...
145
        }
146
147
        return false;
148
    }
149
150
    /**
151
     * @param ProductVariant $variant
152
     * @param ChannelInterface $channel
153
     * @return int|null
154
     */
155
    private function getVariantPrice(ProductVariant $variant, ChannelInterface $channel): ?int
156
    {
157
        /** @var ChannelPricingInterface $channelPricing */
158
        $channelPricing = $variant->getChannelPricingForChannel($channel);
159
160
        $variantPrice = null;
161
        if ($channelPricing instanceof ChannelPricingInterface) {
0 ignored issues
show
introduced by
$channelPricing is always a sub-type of Sylius\Component\Core\Mo...ChannelPricingInterface.
Loading history...
162
            $variantPrice = $channelPricing->getPrice();
163
        }
164
165
        return $variantPrice;
166
    }
167
168
    /**
169
     * @param ProductInterface $product
170
     * @param ChannelInterface $channel
171
     * @return string
172
     */
173
    private function getProductUrl(ProductInterface $product, ChannelInterface $channel): string
174
    {
175
        $context = $this->router->getContext();
176
        $context->setHost($channel->getHostname());
177
178
        $locale = 'en';
179
        $channelDefaultLocale = $channel->getDefaultLocale();
180
181
        if (null !== $channelDefaultLocale) {
182
            $locale = $channelDefaultLocale->getCode();
183
        } else {
184
            if (count($channel->getLocales()) > 0) {
185
                $locale = $channel->getLocales()->first()->getCode();
186
            }
187
        }
188
189
        $product->setCurrentLocale($locale);
190
191
        return $this->router->generate('sylius_shop_product_show', [
192
            '_locale' => $locale,
193
            'slug' => $product->getSlug(),
194
        ], UrlGeneratorInterface::ABSOLUTE_URL);
195
    }
196
197
    /**
198
     * @param ProductImageInterface $image
199
     * @param ChannelInterface $channel
200
     * @return string
201
     */
202
    private function getImageUrl(ProductImageInterface $image, ChannelInterface $channel): string
203
    {
204
        $context = $this->router->getContext();
205
        $context->setHost($channel->getHostname());
206
207
        return $this->cacheManager->generateUrl($image->getPath(), 'sylius_large');
208
    }
209
}
210