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::register()   C
last analyzed

Complexity

Conditions 12
Paths 74

Size

Total Lines 70
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 12
eloc 42
c 1
b 0
f 1
nc 74
nop 3
dl 0
loc 70
rs 6.9666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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