ProductAbstractPagePublisher::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 9
dl 0
loc 20
rs 9.9666
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace Spryker\Zed\ProductPageSearch\Business\Publisher;
9
10
use Generated\Shared\Transfer\ProductPageLoadTransfer;
11
use Generated\Shared\Transfer\ProductPageSearchTransfer;
12
use Generated\Shared\Transfer\ProductPayloadTransfer;
13
use Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch;
14
use Spryker\Shared\ProductPageSearch\ProductPageSearchConfig as SharedProductPageSearchConfig;
15
use Spryker\Zed\Kernel\Persistence\EntityManager\InstancePoolingTrait;
16
use Spryker\Zed\ProductPageSearch\Business\Exception\PluginNotFoundException;
17
use Spryker\Zed\ProductPageSearch\Business\Mapper\ProductPageSearchMapperInterface;
18
use Spryker\Zed\ProductPageSearch\Business\Model\ProductPageSearchWriterInterface;
19
use Spryker\Zed\ProductPageSearch\Business\Reader\AddToCartSkuReaderInterface;
20
use Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToStoreFacadeInterface;
21
use Spryker\Zed\ProductPageSearch\Persistence\ProductPageSearchQueryContainerInterface;
22
use Spryker\Zed\ProductPageSearch\ProductPageSearchConfig;
23
24
class ProductAbstractPagePublisher implements ProductAbstractPagePublisherInterface
25
{
26
    use InstancePoolingTrait;
27
28
    /**
29
     * @var string
30
     */
31
    public const PRODUCT_ABSTRACT_LOCALIZED_ENTITY = 'PRODUCT_ABSTRACT_LOCALIZED_ENTITY';
32
33
    /**
34
     * @var string
35
     */
36
    public const PRODUCT_ABSTRACT_PAGE_SEARCH_ENTITY = 'PRODUCT_ABSTRACT_PAGE_SEARCH_ENTITY';
37
38
    /**
39
     * @var string
40
     */
41
    public const STORE_NAME = 'STORE_NAME';
42
43
    /**
44
     * @var string
45
     */
46
    public const LOCALE_NAME = 'LOCALE_NAME';
47
48
    /**
49
     * @var \Spryker\Zed\ProductPageSearch\Persistence\ProductPageSearchQueryContainerInterface
50
     */
51
    protected $queryContainer;
52
53
    /**
54
     * @var array<\Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductPageDataLoaderPluginInterface>
55
     */
56
    protected $productPageDataLoaderPlugins = [];
57
58
    /**
59
     * @var array<\Spryker\Zed\ProductPageSearch\Dependency\Plugin\ProductPageDataExpanderInterface>
60
     */
61
    protected $pageDataExpanderPlugins = [];
62
63
    /**
64
     * @var array<\Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductPageSearchCollectionFilterPluginInterface>
65
     */
66
    protected $productPageSearchCollectionFilterPlugins = [];
67
68
    /**
69
     * @var \Spryker\Zed\ProductPageSearch\Business\Mapper\ProductPageSearchMapperInterface
70
     */
71
    protected $productPageSearchMapper;
72
73
    /**
74
     * @var \Spryker\Zed\ProductPageSearch\Business\Model\ProductPageSearchWriterInterface
75
     */
76
    protected $productPageSearchWriter;
77
78
    /**
79
     * @var \Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToStoreFacadeInterface
80
     */
81
    protected $storeFacade;
82
83
    /**
84
     * @var \Spryker\Zed\ProductPageSearch\ProductPageSearchConfig
85
     */
86
    protected $productPageSearchConfig;
87
88
    /**
89
     * @var \Spryker\Zed\ProductPageSearch\Business\Reader\AddToCartSkuReaderInterface
90
     */
91
    protected $addToCartSkuReader;
92
93
    /**
94
     * @param \Spryker\Zed\ProductPageSearch\Persistence\ProductPageSearchQueryContainerInterface $queryContainer
95
     * @param array<\Spryker\Zed\ProductPageSearch\Dependency\Plugin\ProductPageDataExpanderInterface> $pageDataExpanderPlugins
96
     * @param array<\Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductPageDataLoaderPluginInterface> $productPageDataLoaderPlugins
97
     * @param array<\Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductPageSearchCollectionFilterPluginInterface> $productPageSearchCollectionFilterPlugins
98
     * @param \Spryker\Zed\ProductPageSearch\Business\Mapper\ProductPageSearchMapperInterface $productPageSearchMapper
99
     * @param \Spryker\Zed\ProductPageSearch\Business\Model\ProductPageSearchWriterInterface $productPageSearchWriter
100
     * @param \Spryker\Zed\ProductPageSearch\ProductPageSearchConfig $productPageSearchConfig
101
     * @param \Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToStoreFacadeInterface $storeFacade
102
     * @param \Spryker\Zed\ProductPageSearch\Business\Reader\AddToCartSkuReaderInterface $addToCartSkuReader
103
     */
104
    public function __construct(
105
        ProductPageSearchQueryContainerInterface $queryContainer,
106
        array $pageDataExpanderPlugins,
107
        array $productPageDataLoaderPlugins,
108
        array $productPageSearchCollectionFilterPlugins,
109
        ProductPageSearchMapperInterface $productPageSearchMapper,
110
        ProductPageSearchWriterInterface $productPageSearchWriter,
111
        ProductPageSearchConfig $productPageSearchConfig,
112
        ProductPageSearchToStoreFacadeInterface $storeFacade,
113
        AddToCartSkuReaderInterface $addToCartSkuReader
114
    ) {
115
        $this->queryContainer = $queryContainer;
116
        $this->pageDataExpanderPlugins = $pageDataExpanderPlugins;
117
        $this->productPageDataLoaderPlugins = $productPageDataLoaderPlugins;
118
        $this->productPageSearchCollectionFilterPlugins = $productPageSearchCollectionFilterPlugins;
119
        $this->productPageSearchMapper = $productPageSearchMapper;
120
        $this->productPageSearchWriter = $productPageSearchWriter;
121
        $this->productPageSearchConfig = $productPageSearchConfig;
122
        $this->storeFacade = $storeFacade;
123
        $this->addToCartSkuReader = $addToCartSkuReader;
124
    }
125
126
    /**
127
     * @param array<int> $productAbstractIds
128
     *
129
     * @return void
130
     */
131
    public function publish(array $productAbstractIds)
132
    {
133
        $productAbstractIdsChunks = array_chunk(
134
            $productAbstractIds,
135
            $this->productPageSearchConfig->getProductAbstractPagePublishChunkSize(),
136
        );
137
138
        foreach ($productAbstractIdsChunks as $productAbstractIdsChunk) {
139
            $this->publishEntities($productAbstractIdsChunk, [], false);
140
        }
141
    }
142
143
    /**
144
     * @param array<int> $productAbstractIds
145
     * @param array<string> $pageDataExpanderPluginNames
146
     *
147
     * @return void
148
     */
149
    public function refresh(array $productAbstractIds, array $pageDataExpanderPluginNames = [])
150
    {
151
        $isPoolingStateChanged = $this->disableInstancePooling();
152
153
        $productAbstractIdsChunks = array_chunk(
154
            array_unique($productAbstractIds),
155
            $this->productPageSearchConfig->getProductAbstractPagePublishChunkSize(),
156
        );
157
158
        foreach ($productAbstractIdsChunks as $productAbstractIdsChunk) {
159
            $this->publishEntities($productAbstractIdsChunk, $pageDataExpanderPluginNames, true);
160
        }
161
162
        if ($isPoolingStateChanged) {
163
            $this->enableInstancePooling();
164
        }
165
    }
166
167
    /**
168
     * @param array<int> $productAbstractIds
169
     *
170
     * @return void
171
     */
172
    public function unpublish(array $productAbstractIds)
173
    {
174
        $productAbstractPageSearchEntities = $this->findProductAbstractPageSearchEntities($productAbstractIds);
175
176
        $this->deleteProductAbstractPageSearchEntities($productAbstractPageSearchEntities);
177
    }
178
179
    /**
180
     * @param array<\Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch> $productAbstractPageSearchEntities
181
     *
182
     * @return void
183
     */
184
    protected function deleteProductAbstractPageSearchEntities(array $productAbstractPageSearchEntities)
185
    {
186
        foreach ($productAbstractPageSearchEntities as $productAbstractPageSearchEntity) {
187
            $productAbstractPageSearchEntity->delete();
188
        }
189
    }
190
191
    /**
192
     * @param array<int> $productAbstractIds
193
     * @param array<string> $pageDataExpanderPluginNames
194
     * @param bool $isRefresh
195
     *
196
     * @return void
197
     */
198
    protected function publishEntities(array $productAbstractIds, array $pageDataExpanderPluginNames, $isRefresh = false)
199
    {
200
        $pageDataExpanderPlugins = $this->getPageDataExpanderPlugins($pageDataExpanderPluginNames);
201
202
        $payloadTransfers = [];
203
        foreach ($productAbstractIds as $productAbstractId) {
204
            $payloadTransfers[$productAbstractId] = (new ProductPayloadTransfer())->setIdProductAbstract($productAbstractId);
205
        }
206
207
        $productPageLoadTransfer = (new ProductPageLoadTransfer())
208
            ->setProductAbstractIds($productAbstractIds)
209
            ->setPayloadTransfers($payloadTransfers);
210
211
        foreach ($this->productPageDataLoaderPlugins as $productPageDataLoaderPlugin) {
212
            $productPageLoadTransfer = $productPageDataLoaderPlugin->expandProductPageDataTransfer($productPageLoadTransfer);
213
        }
214
215
        $productAbstractLocalizedEntities = $this->findProductAbstractLocalizedEntities($productAbstractIds);
216
        $productCategories = $this->getProductCategoriesByProductAbstractIds($productAbstractIds);
217
        $productAbstractLocalizedEntities = $this->hydrateProductAbstractLocalizedEntitiesWithProductCategories($productCategories, $productAbstractLocalizedEntities);
218
219
        $productAbstractPageSearchEntities = $this->findProductAbstractPageSearchEntities($productAbstractIds);
220
        if (!$productAbstractLocalizedEntities) {
221
            $this->deleteProductAbstractPageSearchEntities($productAbstractPageSearchEntities);
222
223
            return;
224
        }
225
226
        if ($this->productPageSearchConfig->isProductAbstractAddToCartEnabled()) {
227
            $productAbstractLocalizedEntities = $this->hydrateProductAbstractLocalizedEntitiesWithProductAbstractAddToCartSku(
228
                $productAbstractLocalizedEntities,
229
                $productAbstractIds,
230
            );
231
        }
232
233
        $this->storeData(
234
            $productAbstractLocalizedEntities,
235
            $productAbstractPageSearchEntities,
236
            $pageDataExpanderPlugins,
237
            $productPageLoadTransfer,
238
            $isRefresh,
239
        );
240
    }
241
242
    /**
243
     * @param array<array<string, mixed>> $productAbstractLocalizedEntities
244
     * @param array<\Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch> $productAbstractPageSearchEntities
245
     * @param array<\Spryker\Zed\ProductPageSearch\Dependency\Plugin\ProductPageDataExpanderInterface> $pageDataExpanderPlugins
246
     * @param \Generated\Shared\Transfer\ProductPageLoadTransfer $productPageLoadTransfer
247
     * @param bool $isRefresh
248
     *
249
     * @return void
250
     */
251
    protected function storeData(
252
        array $productAbstractLocalizedEntities,
253
        array $productAbstractPageSearchEntities,
254
        array $pageDataExpanderPlugins,
255
        ProductPageLoadTransfer $productPageLoadTransfer,
256
        $isRefresh = false
257
    ) {
258
        $pairedEntities = $this->pairProductAbstractLocalizedEntitiesWithProductAbstractPageSearchEntities(
259
            $productAbstractLocalizedEntities,
260
            $productAbstractPageSearchEntities,
261
            $productPageLoadTransfer,
262
        );
263
264
        $productPageSearchTransfers = $this->mapPairedEntitiesToProductPageSearchTransfers(
265
            $pairedEntities,
266
            $isRefresh,
267
        );
268
        $productPageSearchTransfers = $this->executeProductPageSearchCollectionFilterPlugins($productPageSearchTransfers);
269
        $productPageSearchTransfersIndexedByLocaleAndIdProductAbstract = $this->getProductPageSearchTransfersIndexedByLocaleAndIdProductAbstract(
270
            $productPageSearchTransfers,
271
        );
272
273
        foreach ($pairedEntities as $pairedEntity) {
274
            /** @var array|null $productAbstractLocalizedEntity */
275
            $productAbstractLocalizedEntity = $pairedEntity[static::PRODUCT_ABSTRACT_LOCALIZED_ENTITY];
276
            /** @var \Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch $productAbstractPageSearchEntity */
277
            $productAbstractPageSearchEntity = $pairedEntity[static::PRODUCT_ABSTRACT_PAGE_SEARCH_ENTITY];
278
            $store = $pairedEntity[static::STORE_NAME];
279
            $locale = $pairedEntity[static::LOCALE_NAME];
280
281
            if ($productAbstractLocalizedEntity === null || !$this->isActual($productAbstractLocalizedEntity)) {
282
                $this->deleteProductAbstractPageSearchEntity($productAbstractPageSearchEntity);
283
284
                continue;
285
            }
286
287
            $idProductAbstract = $productAbstractLocalizedEntity['fk_product_abstract'];
288
            $productPageSearchTransfer = $this->findProductPageSearchTransferFromIndexedList(
289
                $productPageSearchTransfersIndexedByLocaleAndIdProductAbstract,
290
                $idProductAbstract,
291
                $locale,
292
                $store,
293
            );
294
295
            if ($productPageSearchTransfer === null) {
296
                $this->deleteProductAbstractPageSearchEntity($productAbstractPageSearchEntity);
297
298
                continue;
299
            }
300
301
            $this->storeProductAbstractPageSearchEntity(
302
                $productAbstractLocalizedEntity,
303
                $productAbstractPageSearchEntity,
304
                $productPageSearchTransfer,
305
                $store,
306
                $locale,
307
                $pageDataExpanderPlugins,
308
            );
309
        }
310
    }
311
312
    /**
313
     * @param \Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch $productAbstractPageSearchEntity
314
     *
315
     * @return void
316
     */
317
    protected function deleteProductAbstractPageSearchEntity(SpyProductAbstractPageSearch $productAbstractPageSearchEntity)
318
    {
319
        if (!$productAbstractPageSearchEntity->isNew()) {
320
            $productAbstractPageSearchEntity->delete();
321
        }
322
    }
323
324
    /**
325
     * @param array $productAbstractLocalizedEntity
326
     * @param \Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch $productAbstractPageSearchEntity
327
     * @param \Generated\Shared\Transfer\ProductPageSearchTransfer $productPageSearchTransfer
328
     * @param string $storeName
329
     * @param string $localeName
330
     * @param array<\Spryker\Zed\ProductPageSearch\Dependency\Plugin\ProductPageDataExpanderInterface> $pageDataExpanderPlugins
331
     *
332
     * @return void
333
     */
334
    protected function storeProductAbstractPageSearchEntity(
335
        array $productAbstractLocalizedEntity,
336
        SpyProductAbstractPageSearch $productAbstractPageSearchEntity,
337
        ProductPageSearchTransfer $productPageSearchTransfer,
338
        string $storeName,
339
        string $localeName,
340
        array $pageDataExpanderPlugins
341
    ) {
342
        $productPageSearchTransfer->setStore($storeName);
343
        $productPageSearchTransfer->setLocale($localeName);
344
345
        $this->expandPageSearchTransferWithPlugins($pageDataExpanderPlugins, $productAbstractLocalizedEntity, $productPageSearchTransfer);
346
347
        $searchDocument = $this->productPageSearchMapper->mapToSearchData($productPageSearchTransfer);
348
349
        $this->productPageSearchWriter->save($productPageSearchTransfer, $searchDocument, $productAbstractPageSearchEntity);
350
    }
351
352
    /**
353
     * @param array $productAbstractLocalizedEntity
354
     *
355
     * @return bool
356
     */
357
    protected function isActual(array $productAbstractLocalizedEntity): bool
358
    {
359
        foreach ($productAbstractLocalizedEntity['SpyProductAbstract']['SpyProducts'] as $spyProduct) {
360
            if ($spyProduct['is_active'] && $this->isSearchable($spyProduct, $productAbstractLocalizedEntity['fk_locale'])) {
361
                return true;
362
            }
363
        }
364
365
        return false;
366
    }
367
368
    /**
369
     * @param array $spyProduct
370
     * @param int $idLocale
371
     *
372
     * @return bool
373
     */
374
    protected function isSearchable(array $spyProduct, int $idLocale): bool
375
    {
376
        foreach ($spyProduct['SpyProductSearches'] as $spyProductSearch) {
377
            if ($spyProductSearch['fk_locale'] === $idLocale && $spyProductSearch['is_searchable'] === true) {
378
                return true;
379
            }
380
        }
381
382
        return false;
383
    }
384
385
    /**
386
     * Retrieves the ProductPageSearchTransfer from the storage entity (if it existed already) or populates it from the localized entity.
387
     *
388
     * @param array $productAbstractLocalizedEntity
389
     * @param \Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch $productAbstractPageSearchEntity
390
     * @param bool $isRefresh
391
     *
392
     * @return \Generated\Shared\Transfer\ProductPageSearchTransfer
393
     */
394
    protected function getProductPageSearchTransfer(
395
        array $productAbstractLocalizedEntity,
396
        SpyProductAbstractPageSearch $productAbstractPageSearchEntity,
397
        $isRefresh = false
398
    ): ProductPageSearchTransfer {
399
        if ($isRefresh && !$productAbstractPageSearchEntity->isNew()) {
400
            return $this->refreshProductPageSearchTransfer($productAbstractPageSearchEntity);
401
        }
402
403
        return $this->productPageSearchMapper->mapToProductPageSearchTransfer($productAbstractLocalizedEntity);
404
    }
405
406
    /**
407
     * @param \Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch $productAbstractPageSearchEntity
408
     *
409
     * @return \Generated\Shared\Transfer\ProductPageSearchTransfer
410
     */
411
    protected function refreshProductPageSearchTransfer(
412
        SpyProductAbstractPageSearch $productAbstractPageSearchEntity
413
    ): ProductPageSearchTransfer {
414
        return $this->productPageSearchMapper->mapToProductPageSearchTransferFromJson($productAbstractPageSearchEntity->getStructuredData());
415
    }
416
417
    /**
418
     * @param array<string> $pageDataExpanderPluginNames
419
     *
420
     * @return array<\Spryker\Zed\ProductPageSearch\Dependency\Plugin\ProductPageDataExpanderInterface>
421
     */
422
    protected function getPageDataExpanderPlugins(array $pageDataExpanderPluginNames)
423
    {
424
        if (!$pageDataExpanderPluginNames) {
425
            return $this->pageDataExpanderPlugins;
426
        }
427
428
        $selectedExpanderPlugins = [];
429
        foreach ($pageDataExpanderPluginNames as $pageDataExpanderPluginName) {
430
            $this->assertPageDataExpanderPluginName($pageDataExpanderPluginName);
431
432
            $selectedExpanderPlugins[] = $this->pageDataExpanderPlugins[$pageDataExpanderPluginName];
433
        }
434
435
        return $selectedExpanderPlugins;
436
    }
437
438
    /**
439
     * @param string $pageDataExpanderPluginName
440
     *
441
     * @throws \Spryker\Zed\ProductPageSearch\Business\Exception\PluginNotFoundException
442
     *
443
     * @return void
444
     */
445
    protected function assertPageDataExpanderPluginName($pageDataExpanderPluginName)
446
    {
447
        if (!isset($this->pageDataExpanderPlugins[$pageDataExpanderPluginName])) {
448
            throw new PluginNotFoundException(sprintf('The plugin with this name: %s is not found', $pageDataExpanderPluginName));
449
        }
450
    }
451
452
    /**
453
     * @param array<\Spryker\Zed\ProductPageSearch\Dependency\Plugin\ProductPageDataExpanderInterface> $pageDataExpanderPlugins
454
     * @param array<string, mixed> $productAbstractLocalizedEntity
455
     * @param \Generated\Shared\Transfer\ProductPageSearchTransfer $productPageSearchTransfer
456
     *
457
     * @return void
458
     */
459
    protected function expandPageSearchTransferWithPlugins(
460
        array $pageDataExpanderPlugins,
461
        array $productAbstractLocalizedEntity,
462
        ProductPageSearchTransfer $productPageSearchTransfer
463
    ) {
464
        foreach ($pageDataExpanderPlugins as $pageDataExpanderPlugin) {
465
            $pageDataExpanderPlugin->expandProductPageData($productAbstractLocalizedEntity, $productPageSearchTransfer);
466
        }
467
    }
468
469
    /**
470
     * - Returns a paired array with all provided entities.
471
     * - ProductAbstractLocalizedEntities without ProductAbstractPageSearchEntity are paired with a newly created ProductAbstractPageSearchEntity.
472
     * - ProductAbstractPageSearchEntity without ProductAbstractLocalizedEntities (left outs) are paired with NULL.
473
     * - ProductAbstractLocalizedEntities are paired multiple times per store.
474
     *
475
     * @param array<array<string, mixed>> $productAbstractLocalizedEntities
476
     * @param array<\Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch> $productAbstractPageSearchEntities
477
     * @param \Generated\Shared\Transfer\ProductPageLoadTransfer $productPageLoadTransfer
478
     *
479
     * @return array
480
     */
481
    protected function pairProductAbstractLocalizedEntitiesWithProductAbstractPageSearchEntities(
482
        array $productAbstractLocalizedEntities,
483
        array $productAbstractPageSearchEntities,
484
        ProductPageLoadTransfer $productPageLoadTransfer
485
    ) {
486
        $mappedProductAbstractPageSearchEntities = $this->mapProductAbstractPageSearchEntities($productAbstractPageSearchEntities);
487
488
        $pairs = [];
489
        $productPayloadTransfers = $productPageLoadTransfer->getPayloadTransfers();
490
        foreach ($productAbstractLocalizedEntities as $productAbstractLocalizedEntity) {
491
            [$pairs, $mappedProductAbstractPageSearchEntities] = $this->pairProductAbstractLocalizedEntityWithProductAbstractPageSearchEntityByStoresAndLocale(
492
                $productAbstractLocalizedEntity['fk_product_abstract'],
493
                $productAbstractLocalizedEntity['Locale']['locale_name'],
494
                $productPayloadTransfers[$productAbstractLocalizedEntity['fk_product_abstract']],
495
                $productAbstractLocalizedEntity['SpyProductAbstract']['SpyProductAbstractStores'],
496
                $productAbstractLocalizedEntity,
497
                $mappedProductAbstractPageSearchEntities,
498
                $pairs,
499
            );
500
        }
501
502
        $pairs = $this->pairRemainingProductAbstractPageSearchEntities($mappedProductAbstractPageSearchEntities, $pairs);
503
504
        return $pairs;
505
    }
506
507
    /**
508
     * @param array<int> $productAbstractIds
509
     *
510
     * @return array
511
     */
512
    protected function findProductAbstractLocalizedEntities(array $productAbstractIds)
513
    {
514
        $allProductAbstractLocalizedEntities = [];
515
        $localesByStore = [];
516
        foreach ($this->storeFacade->getAllStores() as $storeTransfer) {
517
            $productAbstractLocalizedEntities = $this
518
                ->queryContainer
519
                ->queryProductAbstractLocalizedEntitiesByProductAbstractIdsAndStore($productAbstractIds, $storeTransfer)
520
                ->find()
521
                ->getData();
522
523
            if (!isset($localesByStore[$storeTransfer->getName()])) {
524
                $localesByStore[$storeTransfer->getName()] = $storeTransfer->getAvailableLocaleIsoCodes();
525
            }
526
            $productConcreteEntities = $this->getProductConcreteEntitiesWithProductSearchEntities($productAbstractIds, $localesByStore[$storeTransfer->getName()]);
527
            $allProductAbstractLocalizedEntities[] = $this->hydrateProductAbstractLocalizedEntitiesWithProductConcreteEntities($productConcreteEntities, $productAbstractLocalizedEntities);
528
        }
529
530
        return array_merge(...$allProductAbstractLocalizedEntities);
531
    }
532
533
    /**
534
     * @param array<int> $productAbstractIds
535
     * @param array<string> $localeIsoCodes
536
     *
537
     * @return array
538
     */
539
    protected function getProductConcreteEntitiesWithProductSearchEntities(array $productAbstractIds, array $localeIsoCodes): array
540
    {
541
        $productConcreteEntities = $this->getProductConcreteEntitiesByProductAbstractIdsAndLocaleIsoCodes($productAbstractIds, $localeIsoCodes);
542
        $productSearchEntities = $this->getProductSearchEntitiesByProductConcreteIdsAndLocaleIsoCodes(array_column($productConcreteEntities, 'id_product'), $localeIsoCodes);
543
        $productConcreteEntities = $this->hydrateProductConcreteEntitiesWithProductSearchEntities($productSearchEntities, $productConcreteEntities);
544
545
        return $productConcreteEntities;
546
    }
547
548
    /**
549
     * @param array<int> $productAbstractIds
550
     * @param array<string> $localeIsoCodes
551
     *
552
     * @return array
553
     */
554
    protected function getProductConcreteEntitiesByProductAbstractIdsAndLocaleIsoCodes(array $productAbstractIds, array $localeIsoCodes): array
555
    {
556
        return $this->queryContainer
557
            ->queryProductConcretesByAbstractProductIdsAndLocaleIsoCodes($productAbstractIds, $localeIsoCodes)
558
            ->find()
559
            ->getData();
560
    }
561
562
    /**
563
     * @param array<int> $productConcreteIds
564
     * @param array<string> $localeIsoCodes
565
     *
566
     * @return array
567
     */
568
    protected function getProductSearchEntitiesByProductConcreteIdsAndLocaleIsoCodes(array $productConcreteIds, array $localeIsoCodes): array
569
    {
570
        return $this->queryContainer
571
            ->queryProductSearchByProductConcreteIdsAndLocaleIsoCodes($productConcreteIds, $localeIsoCodes)
572
            ->find()
573
            ->getData();
574
    }
575
576
    /**
577
     * @param array $productSearchEntities
578
     * @param array $productConcreteEntities
579
     *
580
     * @return array
581
     */
582
    protected function hydrateProductConcreteEntitiesWithProductSearchEntities(array $productSearchEntities, array $productConcreteEntities): array
583
    {
584
        $productSearchByProductConcreteId = [];
585
586
        foreach ($productSearchEntities as $productSearch) {
587
            $productSearchByProductConcreteId[$productSearch['fk_product']][] = $productSearch;
588
        }
589
590
        foreach ($productConcreteEntities as $key => $productConcreteEntity) {
591
            $productConcreteId = (int)$productConcreteEntity['id_product'];
592
            $productConcreteEntities[$key]['SpyProductSearches'] = $productSearchByProductConcreteId[$productConcreteId] ?? [];
593
        }
594
595
        return $productConcreteEntities;
596
    }
597
598
    /**
599
     * @param array $productCategories
600
     * @param array $productAbstractLocalizedEntities
601
     *
602
     * @return array
603
     */
604
    protected function hydrateProductAbstractLocalizedEntitiesWithProductCategories(array $productCategories, array $productAbstractLocalizedEntities)
605
    {
606
        $productCategoriesByProductAbstractId = [];
607
608
        foreach ($productCategories as $productCategory) {
609
            $productCategoriesByProductAbstractId[$productCategory['fk_product_abstract']][] = $productCategory;
610
        }
611
612
        foreach ($productAbstractLocalizedEntities as $key => $productAbstractLocalizedEntity) {
613
            $productAbstractId = (int)$productAbstractLocalizedEntity['fk_product_abstract'];
614
            $productAbstractLocalizedEntities[$key]['SpyProductAbstract']['SpyProductCategories']
615
                = $productCategoriesByProductAbstractId[$productAbstractId] ?? [];
616
        }
617
618
        return $productAbstractLocalizedEntities;
619
    }
620
621
    /**
622
     * @param array $productConcreteData
623
     * @param array $productAbstractLocalizedEntities
624
     *
625
     * @return array
626
     */
627
    protected function hydrateProductAbstractLocalizedEntitiesWithProductConcreteEntities(
628
        array $productConcreteData,
629
        array $productAbstractLocalizedEntities
630
    ): array {
631
        $productConcretesByProductAbstractId = [];
632
        foreach ($productConcreteData as $productConcrete) {
633
            $productConcretesByProductAbstractId[$productConcrete['fk_product_abstract']][] = $productConcrete;
634
        }
635
636
        foreach ($productAbstractLocalizedEntities as $key => $productAbstractLocalizedEntity) {
637
            $productAbstractId = (int)$productAbstractLocalizedEntity['fk_product_abstract'];
638
            $productAbstractLocalizedEntities[$key]['SpyProductAbstract']['SpyProducts'] = $productConcretesByProductAbstractId[$productAbstractId] ?? [];
639
        }
640
641
        return $productAbstractLocalizedEntities;
642
    }
643
644
    /**
645
     * @param array<int> $productAbstractIds
646
     *
647
     * @return array
648
     */
649
    protected function getProductCategoriesByProductAbstractIds(array $productAbstractIds)
650
    {
651
        return $this->queryContainer->queryAllProductCategories($productAbstractIds)->find()->getData();
652
    }
653
654
    /**
655
     * @param array<int> $productAbstractIds
656
     *
657
     * @return array<\Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch>
658
     */
659
    protected function findProductAbstractPageSearchEntities(array $productAbstractIds)
660
    {
661
        return $this->queryContainer->queryProductAbstractSearchPageByIds($productAbstractIds)->find()->getArrayCopy();
662
    }
663
664
    /**
665
     * @param array<\Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch> $productAbstractPageSearchEntities
666
     *
667
     * @return array
668
     */
669
    protected function mapProductAbstractPageSearchEntities(array $productAbstractPageSearchEntities)
670
    {
671
        $mappedProductAbstractPageSearchEntities = [];
672
        foreach ($productAbstractPageSearchEntities as $entity) {
673
            $mappedProductAbstractPageSearchEntities[$entity->getFkProductAbstract()][$entity->getStore()][$entity->getLocale()] = $entity;
674
        }
675
676
        return $mappedProductAbstractPageSearchEntities;
677
    }
678
679
    /**
680
     * @param array $mappedProductAbstractPageSearchEntities
681
     * @param array $pairs
682
     *
683
     * @return array
684
     */
685
    protected function pairRemainingProductAbstractPageSearchEntities(array $mappedProductAbstractPageSearchEntities, array $pairs)
686
    {
687
        array_walk_recursive($mappedProductAbstractPageSearchEntities, function (SpyProductAbstractPageSearch $productAbstractPageSearchEntity) use (&$pairs) {
688
            $pairs[] = [
689
                static::PRODUCT_ABSTRACT_LOCALIZED_ENTITY => null,
690
                static::PRODUCT_ABSTRACT_PAGE_SEARCH_ENTITY => $productAbstractPageSearchEntity,
691
                static::LOCALE_NAME => $productAbstractPageSearchEntity->getLocale(),
692
                static::STORE_NAME => $productAbstractPageSearchEntity->getStore(),
693
            ];
694
        });
695
696
        return $pairs;
697
    }
698
699
    /**
700
     * @param int $idProductAbstract
701
     * @param string $localeName
702
     * @param \Generated\Shared\Transfer\ProductPayloadTransfer $productPayloadTransfer
703
     * @param array $productAbstractStores
704
     * @param array $productAbstractLocalizedEntity
705
     * @param array $mappedProductAbstractPageSearchEntities
706
     * @param array $pairs
707
     *
708
     * @return array
709
     */
710
    protected function pairProductAbstractLocalizedEntityWithProductAbstractPageSearchEntityByStoresAndLocale(
711
        $idProductAbstract,
712
        $localeName,
713
        ProductPayloadTransfer $productPayloadTransfer,
714
        array $productAbstractStores,
715
        array $productAbstractLocalizedEntity,
716
        array $mappedProductAbstractPageSearchEntities,
717
        array $pairs
718
    ) {
719
        foreach ($productAbstractStores as $productAbstractStore) {
720
            $storeName = $productAbstractStore['SpyStore']['name'];
721
            $productAbstractLocalizedEntity[SharedProductPageSearchConfig::PRODUCT_ABSTRACT_PAGE_LOAD_DATA] = $productPayloadTransfer;
722
723
            $searchEntity = $mappedProductAbstractPageSearchEntities[$idProductAbstract][$storeName][$localeName] ??
724
                new SpyProductAbstractPageSearch();
725
726
            unset($mappedProductAbstractPageSearchEntities[$idProductAbstract][$storeName][$localeName]);
727
728
            $pairs[] = [
729
                static::PRODUCT_ABSTRACT_LOCALIZED_ENTITY => $productAbstractLocalizedEntity,
730
                static::PRODUCT_ABSTRACT_PAGE_SEARCH_ENTITY => $searchEntity,
731
                static::LOCALE_NAME => $localeName,
732
                static::STORE_NAME => $storeName,
733
            ];
734
        }
735
736
        return [$pairs, $mappedProductAbstractPageSearchEntities];
737
    }
738
739
    /**
740
     * @param array $productAbstractLocalizedEntities
741
     * @param array<int> $productAbstractIds
742
     *
743
     * @return array
744
     */
745
    protected function hydrateProductAbstractLocalizedEntitiesWithProductAbstractAddToCartSku(
746
        array $productAbstractLocalizedEntities,
747
        array $productAbstractIds
748
    ): array {
749
        $productAbstractStoreIds = [];
750
        foreach ($productAbstractLocalizedEntities as $productAbstractLocalizedEntity) {
751
            $productAbstractId = (int)$productAbstractLocalizedEntity['fk_product_abstract'];
752
            foreach ($productAbstractLocalizedEntity['SpyProductAbstract']['SpyProductAbstractStores'] as $productAbstractStoreData) {
753
                $storeId = (int)$productAbstractStoreData['SpyStore']['id_store'];
754
                $productAbstractStoreIds[$productAbstractId][] = $storeId;
755
            }
756
        }
757
758
        $productConcreteSkuMapByIdProductAbstract = $this->addToCartSkuReader->getProductAbstractAddToCartSkus($productAbstractIds, $productAbstractStoreIds);
759
760
        foreach ($productAbstractLocalizedEntities as &$productAbstractLocalizedEntity) {
761
            $productAbstractId = (int)$productAbstractLocalizedEntity['fk_product_abstract'];
762
            $productAbstractLocalizedEntity[ProductPageSearchTransfer::ADD_TO_CART_SKU] = $productConcreteSkuMapByIdProductAbstract[$productAbstractId] ?? null;
763
        }
764
765
        return $productAbstractLocalizedEntities;
766
    }
767
768
    /**
769
     * @param array $pairedEntities
770
     * @param bool $isRefresh
771
     *
772
     * @return array
773
     */
774
    protected function mapPairedEntitiesToProductPageSearchTransfers(
775
        array $pairedEntities,
776
        bool $isRefresh
777
    ): array {
778
        $productAbstractPageSearchTransfers = [];
779
780
        foreach ($pairedEntities as $pairedEntity) {
781
            /** @var array|null $productAbstractLocalizedEntity */
782
            $productAbstractLocalizedEntity = $pairedEntity[static::PRODUCT_ABSTRACT_LOCALIZED_ENTITY] ?? null;
783
            /** @var \Orm\Zed\ProductPageSearch\Persistence\SpyProductAbstractPageSearch $productAbstractPageSearchEntity */
784
            $productAbstractPageSearchEntity = $pairedEntity[static::PRODUCT_ABSTRACT_PAGE_SEARCH_ENTITY];
785
786
            if (!$productAbstractLocalizedEntity) {
787
                continue;
788
            }
789
790
            $productAbstractPageSearchTransfers[] = $this->getProductPageSearchTransfer(
791
                $productAbstractLocalizedEntity,
792
                $productAbstractPageSearchEntity,
793
                $isRefresh,
794
            );
795
        }
796
797
        return $productAbstractPageSearchTransfers;
798
    }
799
800
    /**
801
     * @param array<\Generated\Shared\Transfer\ProductPageSearchTransfer> $productPageSearchTransfers
802
     *
803
     * @return array<\Generated\Shared\Transfer\ProductPageSearchTransfer>
804
     */
805
    protected function executeProductPageSearchCollectionFilterPlugins(array $productPageSearchTransfers): array
806
    {
807
        foreach ($this->productPageSearchCollectionFilterPlugins as $productPageSearchCollectionFilterPlugin) {
808
            $productPageSearchTransfers = $productPageSearchCollectionFilterPlugin->filter($productPageSearchTransfers);
809
        }
810
811
        return $productPageSearchTransfers;
812
    }
813
814
    /**
815
     * @param array<\Generated\Shared\Transfer\ProductPageSearchTransfer> $productPageSearchTransfers
816
     *
817
     * @return array<string, array<int, list<\Generated\Shared\Transfer\ProductPageSearchTransfer>>>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, array<int,...ctPageSearchTransfer>>> at position 8 could not be parsed: Expected '>' at position 8, but found 'list'.
Loading history...
818
     */
819
    protected function getProductPageSearchTransfersIndexedByLocaleAndIdProductAbstract(array $productPageSearchTransfers): array
820
    {
821
        $productPageSearchTransfersIndexedByLocaleAndIdProductAbstract = [];
822
        foreach ($productPageSearchTransfers as $productPageSearchTransfer) {
823
            $idProductAbstract = $productPageSearchTransfer->getIdProductAbstractOrFail();
824
            $locale = $productPageSearchTransfer->getLocaleOrFail();
825
            $productPageSearchTransfersIndexedByLocaleAndIdProductAbstract[$locale][$idProductAbstract][] = $productPageSearchTransfer;
826
        }
827
828
        return $productPageSearchTransfersIndexedByLocaleAndIdProductAbstract;
829
    }
830
831
    /**
832
     * @param array<string, array<int, list<\Generated\Shared\Transfer\ProductPageSearchTransfer>>> $productPageSearchTransfersIndexedByLocaleAndIdProductAbstract
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, array<int,...ctPageSearchTransfer>>> at position 8 could not be parsed: Expected '>' at position 8, but found 'list'.
Loading history...
833
     * @param int $idProductAbstract
834
     * @param string $locale
835
     * @param string $storeName
836
     *
837
     * @return \Generated\Shared\Transfer\ProductPageSearchTransfer|null
838
     */
839
    protected function findProductPageSearchTransferFromIndexedList(
840
        array $productPageSearchTransfersIndexedByLocaleAndIdProductAbstract,
841
        int $idProductAbstract,
842
        string $locale,
843
        string $storeName
844
    ): ?ProductPageSearchTransfer {
845
        if (!isset($productPageSearchTransfersIndexedByLocaleAndIdProductAbstract[$locale][$idProductAbstract])) {
846
            return null;
847
        }
848
849
        $productPageSearchTransfers = $productPageSearchTransfersIndexedByLocaleAndIdProductAbstract[$locale][$idProductAbstract];
850
        foreach ($productPageSearchTransfers as $productPageSearchTransfer) {
851
            if ($productPageSearchTransfer->getStore() === $storeName) {
852
                return $productPageSearchTransfer;
853
            }
854
        }
855
856
        return $productPageSearchTransfers[0] ?? null;
857
    }
858
}
859