Passed
Push — master ( e4ea65...5bc50c )
by Christian
15:36 queued 10s
created

StoreClient::listMyExtensions()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 45
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 28
c 0
b 0
f 0
nc 7
nop 2
dl 0
loc 45
rs 8.5386
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\Framework\Store\Services;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Exception\ClientException;
7
use Shopware\Core\Framework\Api\Context\AdminApiSource;
8
use Shopware\Core\Framework\Api\Context\Exception\InvalidContextSourceException;
9
use Shopware\Core\Framework\Context;
10
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
11
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
12
use Shopware\Core\Framework\Plugin\PluginCollection;
13
use Shopware\Core\Framework\Store\Authentication\AbstractAuthenticationProvider;
14
use Shopware\Core\Framework\Store\Exception\StoreApiException;
15
use Shopware\Core\Framework\Store\Search\ExtensionCriteria;
16
use Shopware\Core\Framework\Store\Struct\AccessTokenStruct;
17
use Shopware\Core\Framework\Store\Struct\CartStruct;
18
use Shopware\Core\Framework\Store\Struct\ExtensionCollection;
19
use Shopware\Core\Framework\Store\Struct\ExtensionStruct;
20
use Shopware\Core\Framework\Store\Struct\LicenseStruct;
21
use Shopware\Core\Framework\Store\Struct\PluginDownloadDataStruct;
22
use Shopware\Core\Framework\Store\Struct\ReviewStruct;
23
use Shopware\Core\Framework\Store\Struct\ShopUserTokenStruct;
24
use Shopware\Core\Framework\Store\Struct\StoreActionStruct;
25
use Shopware\Core\Framework\Store\Struct\StoreLicenseStruct;
26
use Shopware\Core\Framework\Store\Struct\StoreLicenseSubscriptionStruct;
27
use Shopware\Core\Framework\Store\Struct\StoreLicenseTypeStruct;
28
use Shopware\Core\Framework\Store\Struct\StoreLicenseViolationStruct;
29
use Shopware\Core\Framework\Store\Struct\StoreLicenseViolationTypeStruct;
30
use Shopware\Core\Framework\Store\Struct\StoreUpdateStruct;
31
use Shopware\Core\System\SystemConfig\SystemConfigService;
32
33
/**
34
 * @internal
35
 */
36
class StoreClient
37
{
38
    public const PLUGIN_LICENSE_VIOLATION_EXTENSION_KEY = 'licenseViolation';
39
    public const SBP_API_LIST_MY_EXTENSIONS = '/swplatform/licenseenvironment';
40
    private const SHOPWARE_PLATFORM_TOKEN_HEADER = 'X-Shopware-Platform-Token';
41
42
    private const SHOPWARE_SHOP_SECRET_HEADER = 'X-Shopware-Shop-Secret';
43
44
    private const SBP_API_URL_PING = '/ping';
45
    private const SBP_API_URL_LOGIN = '/swplatform/login';
46
    private const SBP_API_URL_LICENSES = '/swplatform/licenses';
47
    private const SBP_API_URL_PLUGIN_LICENSES = '/swplatform/pluginlicenses';
48
    private const SBP_API_URL_PLUGIN_UPDATES = '/swplatform/pluginupdates';
49
    private const SBP_API_URL_PLUGIN_VIOLATIONS = '/swplatform/environmentinformation';
50
    private const SBP_API_URL_PLUGIN_COMPATIBILITY = '/swplatform/autoupdate';
51
    private const SBP_API_URL_PLUGIN_DOWNLOAD_INFO = '/swplatform/pluginfiles/{pluginName}';
52
    private const SBP_API_URL_UPDATE_PERMISSIONS = '/swplatform/autoupdate/permission';
53
    private const SBP_API_URL_GENERATE_SIGNATURE = '/swplatform/generatesignature';
54
    private const SBP_API_LIST_CATEGORIES = '/swplatform/extensionstore/categories';
55
    private const SBP_API_LIST_EXTENSIONS = '/swplatform/extensionstore/extensions';
56
    private const SBP_API_DETAIL_EXTENSION = '/swplatform/extensionstore/extensions/%d';
57
    private const SBP_API_DETAIL_EXTENSION_REVIEWS = '/swplatform/extensionstore/extensions/%d/reviews';
58
    private const SBP_API_CREATE_CART = '/swplatform/extensionstore/baskets';
59
    private const SBP_API_ORDER_CART = '/swplatform/extensionstore/orders';
60
    private const SBP_API_CANCEL_LICENSE = '/swplatform/pluginlicenses/%s/cancel';
61
    private const SBP_API_LIST_FILTERS = '/swplatform/extensionstore/extensions/filter';
62
63
    /**
64
     * @var Client|null
65
     */
66
    private $client;
67
68
    /**
69
     * @var EntityRepositoryInterface
70
     */
71
    private $pluginRepo;
72
73
    /**
74
     * @var SystemConfigService
75
     */
76
    private $configService;
77
78
    /**
79
     * @var StoreService
80
     */
81
    private $storeService;
82
83
    /**
84
     * @var AbstractAuthenticationProvider|null
85
     */
86
    private $authenticationProvider;
87
88
    /**
89
     * @var ExtensionLoader|null
90
     */
91
    private $extensionLoader;
92
93
    final public function __construct(
94
        StoreService $storeService,
95
        EntityRepositoryInterface $pluginRepo,
96
        SystemConfigService $configService,
97
        ?AbstractAuthenticationProvider $authenticationProvider,
98
        ?ExtensionLoader $extensionLoader
99
    ) {
100
        $this->storeService = $storeService;
101
        $this->configService = $configService;
102
        $this->pluginRepo = $pluginRepo;
103
        $this->authenticationProvider = $authenticationProvider;
104
        $this->extensionLoader = $extensionLoader;
105
    }
106
107
    public function ping(): void
108
    {
109
        $this->getClient()->get(self::SBP_API_URL_PING);
110
    }
111
112
    public function loginWithShopwareId(string $shopwareId, string $password, string $language, Context $context): AccessTokenStruct
113
    {
114
        if (!$context->getSource() instanceof AdminApiSource) {
115
            throw new InvalidContextSourceException(AdminApiSource::class, \get_class($context->getSource()));
116
        }
117
118
        $response = $this->getClient()->post(
119
            self::SBP_API_URL_LOGIN,
120
            [
121
                'body' => json_encode([
122
                    'shopwareId' => $shopwareId,
123
                    'password' => $password,
124
                    'shopwareUserId' => $context->getSource()->getUserId(),
125
                ]),
126
                'query' => $this->storeService->getDefaultQueryParameters($language),
127
            ]
128
        );
129
130
        $data = json_decode($response->getBody()->getContents(), true);
131
132
        $userToken = new ShopUserTokenStruct();
133
        $userToken->assign($data['shopUserToken']);
134
135
        $accessTokenStruct = new AccessTokenStruct();
136
        $accessTokenStruct->assign($data);
137
        $accessTokenStruct->setShopUserToken($userToken);
138
139
        return $accessTokenStruct;
140
    }
141
142
    /**
143
     * @return StoreLicenseStruct[]
144
     */
145
    public function getLicenseList(string $storeToken, string $language, Context $context): array
146
    {
147
        $response = $this->getClient()->get(
148
            self::SBP_API_URL_PLUGIN_LICENSES,
149
            [
150
                'query' => $this->storeService->getDefaultQueryParameters($language),
151
                'headers' => $this->getHeaders($storeToken),
152
            ]
153
        );
154
155
        $data = json_decode($response->getBody()->getContents(), true);
156
157
        $licenseList = [];
158
        $installedPlugins = [];
159
160
        /** @var PluginCollection $pluginCollection */
161
        $pluginCollection = $this->pluginRepo->search(new Criteria(), $context)->getEntities();
162
163
        foreach ($pluginCollection as $plugin) {
164
            $installedPlugins[$plugin->getName()] = $plugin->getVersion();
165
        }
166
167
        foreach ($data['data'] as $license) {
168
            $licenseStruct = new StoreLicenseStruct();
169
            $licenseStruct->assign($license);
170
171
            $licenseStruct->setInstalled(\array_key_exists($licenseStruct->getTechnicalPluginName(), $installedPlugins));
172
            if (isset($license['availableVersion'])) {
173
                if ($licenseStruct->getInstalled()) {
174
                    $installedVersion = $installedPlugins[$licenseStruct->getTechnicalPluginName()];
175
176
                    $licenseStruct->setUpdateAvailable(version_compare($installedVersion, $licenseStruct->getAvailableVersion()) === -1);
177
                } else {
178
                    $licenseStruct->setUpdateAvailable(false);
179
                }
180
            }
181
            if (isset($license['type']['name'])) {
182
                $type = new StoreLicenseTypeStruct();
183
                $type->assign($license['type']);
184
                $licenseStruct->setType($type);
185
            }
186
            if (isset($license['subscription']['expirationDate'])) {
187
                $subscription = new StoreLicenseSubscriptionStruct();
188
                $subscription->assign($license['subscription']);
189
                $licenseStruct->setSubscription($subscription);
190
            }
191
192
            $licenseList[] = $licenseStruct;
193
        }
194
195
        return $licenseList;
196
    }
197
198
    /**
199
     * @return StoreUpdateStruct[]
200
     */
201
    public function getUpdatesList(?string $storeToken, PluginCollection $pluginCollection, string $language, string $hostName, Context $context): array
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

201
    public function getUpdatesList(?string $storeToken, PluginCollection $pluginCollection, string $language, string $hostName, /** @scrutinizer ignore-unused */ Context $context): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
202
    {
203
        $pluginArray = [];
204
205
        foreach ($pluginCollection as $plugin) {
206
            $pluginArray[] = [
207
                'name' => $plugin->getName(),
208
                'version' => $plugin->getVersion(),
209
            ];
210
        }
211
212
        $query = $this->storeService->getDefaultQueryParameters($language, false);
213
        $query['hostName'] = $hostName;
214
215
        $response = $this->getClient()->post(
216
            self::SBP_API_URL_PLUGIN_UPDATES,
217
            [
218
                'query' => $query,
219
                'body' => json_encode(['plugins' => $pluginArray]),
220
                'headers' => $this->getHeaders($storeToken),
221
            ]
222
        );
223
224
        $data = json_decode($response->getBody()->getContents(), true);
225
226
        $updateList = [];
227
        foreach ($data['data'] as $update) {
228
            $updateStruct = new StoreUpdateStruct();
229
            $updateStruct->assign($update);
230
            $updateList[] = $updateStruct;
231
        }
232
233
        return $updateList;
234
    }
235
236
    public function checkForViolations(
237
        ?string $storeToken,
238
        PluginCollection $plugins,
239
        string $language,
240
        string $hostName,
241
        Context $context
242
    ): void {
243
        $violations = $this->getLicenseViolations($storeToken, $plugins, $language, $hostName, $context);
244
        $indexed = [];
245
        /** @var StoreLicenseViolationStruct $violation */
246
        foreach ($violations as $violation) {
247
            $indexed[$violation->getName()] = $violation;
248
        }
249
250
        foreach ($plugins as $plugin) {
251
            if (isset($indexed[$plugin->getName()])) {
252
                $plugin->addExtension(self::PLUGIN_LICENSE_VIOLATION_EXTENSION_KEY, $indexed[$plugin->getName()]);
253
            }
254
        }
255
    }
256
257
    public function getLicenseViolations(
258
        ?string $storeToken,
259
        PluginCollection $plugins,
260
        string $language,
261
        string $hostName,
262
        Context $context
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

262
        /** @scrutinizer ignore-unused */ Context $context

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
263
    ): array {
264
        $pluginData = [];
265
266
        foreach ($plugins as $plugin) {
267
            $pluginData[] = [
268
                'name' => $plugin->getName(),
269
                'version' => $plugin->getVersion(),
270
            ];
271
        }
272
273
        $query = $this->storeService->getDefaultQueryParameters($language, false);
274
        $query['hostName'] = $hostName;
275
276
        $response = $this->getClient()->post(
277
            self::SBP_API_URL_PLUGIN_VIOLATIONS,
278
            [
279
                'query' => $query,
280
                'body' => json_encode(['plugins' => $pluginData]),
281
                'headers' => $this->getHeaders($storeToken),
282
            ]
283
        );
284
285
        $data = json_decode($response->getBody()->getContents(), true);
286
287
        return $this->getViolations($data['notices']);
288
    }
289
290
    public function getDownloadDataForPlugin(string $pluginName, string $storeToken, string $language, bool $checkLicenseDomain = true): PluginDownloadDataStruct
291
    {
292
        $response = $this->getClient()->get(
293
            str_replace('{pluginName}', $pluginName, self::SBP_API_URL_PLUGIN_DOWNLOAD_INFO),
294
            [
295
                'query' => $this->storeService->getDefaultQueryParameters($language, $checkLicenseDomain),
296
                'headers' => $this->getHeaders($storeToken),
297
            ]
298
        );
299
300
        $data = json_decode($response->getBody()->getContents(), true);
301
        $dataStruct = new PluginDownloadDataStruct();
302
        $dataStruct->assign($data);
303
304
        return $dataStruct;
305
    }
306
307
    public function getPluginCompatibilities(string $futureVersion, string $language, PluginCollection $pluginCollection): array
308
    {
309
        $pluginArray = [];
310
311
        foreach ($pluginCollection as $plugin) {
312
            $pluginArray[] = [
313
                'name' => $plugin->getName(),
314
                'version' => $plugin->getVersion(),
315
            ];
316
        }
317
318
        $response = $this->getClient()->post(
319
            self::SBP_API_URL_PLUGIN_COMPATIBILITY,
320
            [
321
                'query' => $this->storeService->getDefaultQueryParameters($language, false),
322
                'headers' => $this->getHeaders(),
323
                'json' => [
324
                    'futureShopwareVersion' => $futureVersion,
325
                    'plugins' => $pluginArray,
326
                ],
327
            ]
328
        );
329
330
        return json_decode((string) $response->getBody(), true);
331
    }
332
333
    public function isShopUpgradeable(): bool
334
    {
335
        $response = $this->getClient()->get(self::SBP_API_URL_UPDATE_PERMISSIONS, [
336
            'query' => $this->storeService->getDefaultQueryParameters('en-GB', false),
337
            'headers' => $this->getHeaders(),
338
        ]);
339
340
        return json_decode((string) $response->getBody(), true)['updateAllowed'];
341
    }
342
343
    public function signPayloadWithAppSecret(string $payload, string $appName): string
344
    {
345
        $response = $this->getClient()->post(self::SBP_API_URL_GENERATE_SIGNATURE, [
346
            'headers' => $this->getHeaders(),
347
            'json' => [
348
                'payload' => $payload,
349
                'appName' => $appName,
350
            ],
351
        ]);
352
353
        return json_decode((string) $response->getBody(), true)['signature'];
354
    }
355
356
    public function getCategories(Context $context): array
357
    {
358
        $language = $this->storeService->getLanguageByContext($context);
359
360
        try {
361
            $response = $this->getClient()->get(self::SBP_API_LIST_CATEGORIES, [
362
                'query' => $this->storeService->getDefaultQueryParameters($language, false),
363
                'headers' => $this->getHeaders(),
364
            ]);
365
        } catch (ClientException $e) {
366
            throw new StoreApiException($e);
367
        }
368
369
        return json_decode((string) $response->getBody(), true);
370
    }
371
372
    public function listMyExtensions(ExtensionCollection $extensions, Context $context): ExtensionCollection
373
    {
374
        if ($this->authenticationProvider === null || $this->extensionLoader === null) {
375
            throw new \RuntimeException('App Store is not active');
376
        }
377
378
        $language = $this->storeService->getLanguageByContext($context);
379
        $storeToken = $this->authenticationProvider->getUserStoreToken($context);
380
381
        try {
382
            $response = $this->getClient()->post(self::SBP_API_LIST_MY_EXTENSIONS, [
383
                'query' => $this->storeService->getDefaultQueryParameters($language, false),
384
                'headers' => $this->getHeaders($storeToken),
385
                'json' => ['plugins' => array_map(function (ExtensionStruct $e) {
386
                    return [
387
                        'name' => $e->getName(),
388
                        'version' => $e->getVersion(),
389
                    ];
390
                }, $extensions->getElements())],
391
            ]);
392
        } catch (ClientException $e) {
393
            throw new StoreApiException($e);
394
        }
395
396
        $body = json_decode((string) $response->getBody(), true);
397
398
        $myExtensions = new ExtensionCollection();
399
400
        foreach ($body as $item) {
401
            $extension = $this->extensionLoader->loadFromArray($context, $item['extension']);
402
            $extension->setSource(ExtensionStruct::SOURCE_STORE);
403
            if (isset($item['license'])) {
404
                $extension->setStoreLicense(LicenseStruct::fromArray($item['license']));
405
            }
406
407
            if (isset($item['update'])) {
408
                $extension->setVersion($item['update']['installedVersion']);
409
                $extension->setLatestVersion($item['update']['availableVersion']);
410
                $extension->setUpdateSource(ExtensionStruct::SOURCE_STORE);
411
            }
412
413
            $myExtensions->set($extension->getName(), $extension);
414
        }
415
416
        return $myExtensions;
417
    }
418
419
    public function listExtensions(ExtensionCriteria $criteria, Context $context): array
420
    {
421
        $language = $this->storeService->getLanguageByContext($context);
422
423
        try {
424
            $response = $this->getClient()->get(self::SBP_API_LIST_EXTENSIONS, [
425
                'query' => array_merge($this->storeService->getDefaultQueryParameters($language, false), $criteria->getQueryParameter()),
426
                'headers' => $this->getHeaders(),
427
            ]);
428
        } catch (ClientException $e) {
429
            throw new StoreApiException($e);
430
        }
431
432
        $body = json_decode((string) $response->getBody(), true);
433
434
        return [
435
            'headers' => $response->getHeaders(),
436
            'data' => $body,
437
        ];
438
    }
439
440
    public function listListingFilters(Context $context): array
441
    {
442
        $language = $this->storeService->getLanguageByContext($context);
443
444
        try {
445
            $response = $this->getClient()->get(self::SBP_API_LIST_FILTERS, [
446
                'query' => $this->storeService->getDefaultQueryParameters($language, false),
447
                'headers' => $this->getHeaders(),
448
            ]);
449
        } catch (ClientException $e) {
450
            throw new StoreApiException($e);
451
        }
452
453
        return json_decode((string) $response->getBody(), true);
454
    }
455
456
    public function extensionDetail(int $id, Context $context): array
457
    {
458
        $language = $this->storeService->getLanguageByContext($context);
459
460
        try {
461
            $response = $this->getClient()->get(sprintf(self::SBP_API_DETAIL_EXTENSION, $id), [
462
                'query' => $this->storeService->getDefaultQueryParameters($language, false),
463
                'headers' => $this->getHeaders(),
464
            ]);
465
        } catch (ClientException $e) {
466
            throw new StoreApiException($e);
467
        }
468
469
        return json_decode((string) $response->getBody(), true);
470
    }
471
472
    public function extensionDetailReviews(int $id, ExtensionCriteria $criteria, Context $context): array
473
    {
474
        $language = $this->storeService->getLanguageByContext($context);
475
476
        try {
477
            $response = $this->getClient()->get(sprintf(self::SBP_API_DETAIL_EXTENSION_REVIEWS, $id), [
478
                'query' => array_merge($this->storeService->getDefaultQueryParameters($language, false), $criteria->getQueryParameter()),
479
                'headers' => $this->getHeaders(),
480
            ]);
481
        } catch (ClientException $e) {
482
            throw new StoreApiException($e);
483
        }
484
485
        return json_decode((string) $response->getBody(), true);
486
    }
487
488
    public function createCart(int $extensionId, int $variantId, Context $context): CartStruct
489
    {
490
        if ($this->authenticationProvider === null) {
491
            throw new \RuntimeException('App Store is not active');
492
        }
493
494
        $language = $this->storeService->getLanguageByContext($context);
495
496
        try {
497
            $response = $this->getClient()->post(self::SBP_API_CREATE_CART, [
498
                'query' => $this->storeService->getDefaultQueryParameters($language, false),
499
                'headers' => $this->getHeaders($this->authenticationProvider->getUserStoreToken($context)),
500
                'json' => [
501
                    'extensions' => [
502
                        [
503
                            'extensionId' => $extensionId,
504
                            'variantId' => $variantId,
505
                        ],
506
                    ],
507
                ],
508
            ]);
509
        } catch (ClientException $e) {
510
            throw new StoreApiException($e);
511
        }
512
513
        return CartStruct::fromArray(json_decode((string) $response->getBody(), true));
514
    }
515
516
    public function orderCart(CartStruct $cartStruct, Context $context): void
517
    {
518
        if ($this->authenticationProvider === null) {
519
            throw new \RuntimeException('App Store is not active');
520
        }
521
522
        try {
523
            $this->getClient()->post(self::SBP_API_ORDER_CART, [
524
                'query' => $this->storeService->getDefaultQueryParameters('en-GB', false),
525
                'headers' => $this->getHeaders($this->authenticationProvider->getUserStoreToken($context)),
526
                'json' => $cartStruct,
527
            ]);
528
        } catch (ClientException $e) {
529
            throw new StoreApiException($e);
530
        }
531
    }
532
533
    public function cancelSubscription(int $licenseId, Context $context): void
534
    {
535
        if ($this->authenticationProvider === null) {
536
            throw new \RuntimeException('App Store is not active');
537
        }
538
539
        try {
540
            $this->getClient()->post(sprintf(self::SBP_API_CANCEL_LICENSE, $licenseId), [
541
                'query' => $this->storeService->getDefaultQueryParameters('en-GB', false),
542
                'headers' => $this->getHeaders($this->authenticationProvider->getUserStoreToken($context)),
543
            ]);
544
        } catch (ClientException $e) {
545
            if ($e->hasResponse() && $e->getResponse() !== null) {
546
                $error = json_decode((string) $e->getResponse()->getBody(), true);
547
548
                // It's okay when its already canceled
549
                if (isset($error['type']) && $error['type'] === 'EXTENSION_LICENSE_IS_ALREADY_CANCELLED') {
550
                    return;
551
                }
552
            }
553
554
            throw new StoreApiException($e);
555
        }
556
    }
557
558
    public function createRating(ReviewStruct $rating, Context $context): void
0 ignored issues
show
Unused Code introduced by
The parameter $rating is not used and could be removed. ( Ignorable by Annotation )

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

558
    public function createRating(/** @scrutinizer ignore-unused */ ReviewStruct $rating, Context $context): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

558
    public function createRating(ReviewStruct $rating, /** @scrutinizer ignore-unused */ Context $context): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
559
    {
560
    }
561
562
    public function getLicenses(Context $context): array
563
    {
564
        if ($this->authenticationProvider === null) {
565
            throw new \RuntimeException('App Store is not active');
566
        }
567
568
        try {
569
            $response = $this->getClient()->get(
570
                self::SBP_API_URL_LICENSES,
571
                [
572
                    'query' => $this->storeService->getDefaultQueryParameters('en-GB'),
573
                    'headers' => $this->getHeaders($this->authenticationProvider->getUserStoreToken($context)),
574
                ]
575
            );
576
        } catch (ClientException $e) {
577
            throw new StoreApiException($e);
578
        }
579
580
        $body = json_decode($response->getBody()->getContents(), true);
581
582
        return [
583
            'headers' => $response->getHeaders(),
584
            'data' => $body,
585
        ];
586
    }
587
588
    private function getClient(): Client
589
    {
590
        if ($this->client === null) {
591
            $this->client = $this->storeService->createClient();
592
        }
593
594
        return $this->client;
595
    }
596
597
    /**
598
     * @return StoreLicenseViolationStruct[]
599
     */
600
    private function getViolations(array $violationsData): array
601
    {
602
        $violations = [];
603
        foreach ($violationsData as $violationData) {
604
            $violationData['actions'] = $this->getActions($violationData['actions'] ?? []);
605
            $violationData['type'] = (new StoreLicenseViolationTypeStruct())->assign($violationData['type']);
606
            $expired = new StoreLicenseViolationStruct();
607
            $expired->assign($violationData);
608
            $violations[] = $expired;
609
        }
610
611
        return $violations;
612
    }
613
614
    /**
615
     * @return StoreActionStruct[]
616
     */
617
    private function getActions(array $actionsData): array
618
    {
619
        $actions = [];
620
        foreach ($actionsData as $actionData) {
621
            $action = new StoreActionStruct();
622
            $action->assign($actionData);
623
            $actions[] = $action;
624
        }
625
626
        return $actions;
627
    }
628
629
    private function getHeaders(?string $storeToken = null): array
630
    {
631
        $headers = $this->getClient()->getConfig('headers');
632
633
        if ($storeToken) {
634
            $headers[self::SHOPWARE_PLATFORM_TOKEN_HEADER] = $storeToken;
635
        }
636
637
        $shopSecret = $this->configService->get('core.store.shopSecret');
638
        if ($shopSecret) {
639
            $headers[self::SHOPWARE_SHOP_SECRET_HEADER] = $shopSecret;
640
        }
641
642
        return $headers;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $headers could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
643
    }
644
}
645