Failed Conditions
Push — master ( ae631c...a04781 )
by
unknown
52:50 queued 12:37
created

ProductConcretePageSearchPublisher::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 11
dl 0
loc 13
rs 10
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\LocaleTransfer;
11
use Generated\Shared\Transfer\LocalizedAttributesTransfer;
12
use Generated\Shared\Transfer\ProductConcretePageSearchTransfer;
13
use Generated\Shared\Transfer\ProductConcreteTransfer;
14
use Generated\Shared\Transfer\StoreTransfer;
15
use Spryker\Shared\ProductPageSearch\ProductPageSearchConstants;
16
use Spryker\Zed\Kernel\Persistence\EntityManager\InstancePoolingTrait;
17
use Spryker\Zed\Kernel\Persistence\EntityManager\TransactionTrait;
18
use Spryker\Zed\ProductPageSearch\Business\DataMapper\AbstractProductSearchDataMapper;
19
use Spryker\Zed\ProductPageSearch\Business\Exception\ProductConcretePageSearchNotFoundException;
20
use Spryker\Zed\ProductPageSearch\Business\ProductConcretePageSearchReader\ProductConcretePageSearchReaderInterface;
21
use Spryker\Zed\ProductPageSearch\Business\ProductConcretePageSearchWriter\ProductConcretePageSearchWriterInterface;
22
use Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToProductInterface;
23
use Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToProductSearchInterface;
24
use Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToStoreFacadeInterface;
25
use Spryker\Zed\ProductPageSearch\Dependency\Service\ProductPageSearchToUtilEncodingInterface;
26
use Spryker\Zed\ProductPageSearch\Persistence\ProductPageSearchRepositoryInterface;
27
use Spryker\Zed\ProductPageSearch\ProductPageSearchConfig;
28
29
class ProductConcretePageSearchPublisher implements ProductConcretePageSearchPublisherInterface
30
{
31
    use TransactionTrait;
32
    use InstancePoolingTrait;
33
34
    /**
35
     * @var array<int>
36
     */
37
    protected static array $publishedProductConcreteIds = [];
38
39
    /**
40
     * @var array<int>
41
     */
42
    protected static array $unpublishedProductConcreteIds = [];
43
44
    /**
45
     * @var string
46
     */
47
    protected const IDENTIFIER_PRODUCT_CONCRETE_PAGE_SEARCH = 'id_product_concrete_page_search';
48
49
    /**
50
     * @var string
51
     */
52
    protected const IDENTIFIER_STRUCTURED_DATA = 'structured_data';
53
54
    /**
55
     * @var array<int, int>
56
     */
57
    protected array $productIdTimestampMapToSave = [];
58
59
    /**
60
     * @param \Spryker\Zed\ProductPageSearch\Persistence\ProductPageSearchRepositoryInterface $repository
61
     * @param \Spryker\Zed\ProductPageSearch\Business\ProductConcretePageSearchReader\ProductConcretePageSearchReaderInterface $productConcretePageSearchReader
62
     * @param \Spryker\Zed\ProductPageSearch\Business\ProductConcretePageSearchWriter\ProductConcretePageSearchWriterInterface $productConcretePageSearchWriter
63
     * @param \Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToProductInterface $productFacade
64
     * @param \Spryker\Zed\ProductPageSearch\Dependency\Service\ProductPageSearchToUtilEncodingInterface $utilEncoding
65
     * @param \Spryker\Zed\ProductPageSearch\Business\DataMapper\AbstractProductSearchDataMapper $productConcreteSearchDataMapper
66
     * @param \Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToStoreFacadeInterface $storeFacade
67
     * @param \Spryker\Zed\ProductPageSearch\Dependency\Facade\ProductPageSearchToProductSearchInterface $productPageSearchFacade
68
     * @param \Spryker\Zed\ProductPageSearch\ProductPageSearchConfig $productPageSearchConfig
69
     * @param array<\Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductConcretePageDataExpanderPluginInterface> $pageDataExpanderPlugins
70
     * @param array<\Spryker\Zed\ProductPageSearchExtension\Dependency\Plugin\ProductConcreteCollectionFilterPluginInterface> $productConcreteCollectionFilterPlugins
71
     */
72
    public function __construct(
73
        protected ProductPageSearchRepositoryInterface $repository,
74
        protected ProductConcretePageSearchReaderInterface $productConcretePageSearchReader,
75
        protected ProductConcretePageSearchWriterInterface $productConcretePageSearchWriter,
76
        protected ProductPageSearchToProductInterface $productFacade,
77
        protected ProductPageSearchToUtilEncodingInterface $utilEncoding,
78
        protected AbstractProductSearchDataMapper $productConcreteSearchDataMapper,
79
        protected ProductPageSearchToStoreFacadeInterface $storeFacade,
80
        protected ProductPageSearchToProductSearchInterface $productPageSearchFacade,
81
        protected ProductPageSearchConfig $productPageSearchConfig,
82
        protected array $pageDataExpanderPlugins,
83
        protected array $productConcreteCollectionFilterPlugins
84
    ) {
85
    }
86
87
    /**
88
     * @param array<int, int> $productIdTimestampMap
89
     *
90
     * @return void
91
     */
92
    public function publishWithTimestamp(array $productIdTimestampMap): void
93
    {
94
        // Filters IDs if it had been processed in the current process
95
        $productIds = array_values(array_unique(array_diff(array_keys($productIdTimestampMap), static::$publishedProductConcreteIds)));
96
        // Exclude IDs if they were processed in current process
97
        $productIdTimestampMap = array_intersect_key($productIdTimestampMap, array_flip($productIds));
98
        // Filters IDs if it had been processed in parallel processes
99
        $this->productIdTimestampMapToSave = $this->repository->getRelevantProductConcreteIdsToUpdate($productIdTimestampMap);
100
101
        if ($this->productIdTimestampMapToSave) {
102
            $this->publish(array_keys($this->productIdTimestampMapToSave));
103
        }
104
        static::$publishedProductConcreteIds = array_merge(static::$publishedProductConcreteIds, $productIds);
105
    }
106
107
    /**
108
     * @param array<int> $productIds
109
     *
110
     * @return void
111
     */
112
    public function publish(array $productIds): void
113
    {
114
        $isPoolingStateChanged = $this->disableInstancePooling();
115
116
        $productIds = array_unique(array_filter($productIds));
117
118
        if (!$productIds) {
119
            return;
120
        }
121
122
        $productConcreteIdsChunks = array_chunk(
123
            $productIds,
124
            $this->productPageSearchConfig->getProductConcretePagePublishChunkSize(),
125
        );
126
127
        foreach ($productConcreteIdsChunks as $productConcreteIdsChunk) {
128
            $productConcreteTransfers = $this->productFacade->getProductConcreteTransfersByProductIds($productConcreteIdsChunk);
129
            $productConcretePageSearchTransfers = $this->productConcretePageSearchReader
130
                ->getProductConcretePageSearchTransfersByProductIdsGrouppedByStoreAndLocale($productConcreteIdsChunk);
131
132
            $this->getTransactionHandler()->handleTransaction(function () use ($productConcreteTransfers, $productConcretePageSearchTransfers) {
133
                $this->executePublishTransaction($productConcreteTransfers, $productConcretePageSearchTransfers);
134
            });
135
        }
136
137
        if ($isPoolingStateChanged) {
138
            $this->enableInstancePooling();
139
        }
140
    }
141
142
    /**
143
     * @param array<int> $productAbstractIds
144
     *
145
     * @return void
146
     */
147
    public function publishProductConcretePageSearchesByProductAbstractIds(array $productAbstractIds): void
148
    {
149
        $productConcreteTransfers = $this->productFacade->getProductConcreteTransfersByProductAbstractIds($productAbstractIds);
150
        $productIds = $this->getProductIdsListFromProductConcreteTransfers($productConcreteTransfers);
151
        $productConcretePageSearchTransfers = $this->productConcretePageSearchReader->getProductConcretePageSearchTransfersByProductIdsGrouppedByStoreAndLocale($productIds);
152
153
        $this->getTransactionHandler()->handleTransaction(function () use ($productConcreteTransfers, $productConcretePageSearchTransfers) {
154
            $this->executePublishTransaction($productConcreteTransfers, $productConcretePageSearchTransfers);
155
        });
156
    }
157
158
    /**
159
     * @param array<int, int> $productIdTimestampMap
160
     *
161
     * @return void
162
     */
163
    public function unpublishWithTimestamp(array $productIdTimestampMap): void
164
    {
165
        $productIds = array_values(array_unique(array_diff(array_keys($productIdTimestampMap), static::$unpublishedProductConcreteIds)));
166
        if ($productIds) {
167
            $this->unpublish($productIds);
168
        }
169
170
        static::$unpublishedProductConcreteIds = array_merge(static::$unpublishedProductConcreteIds, $productIds);
171
    }
172
173
    /**
174
     * @param array<int> $productIds
175
     *
176
     * @return void
177
     */
178
    public function unpublish(array $productIds): void
179
    {
180
        $productConcretePageSearchTransfers = $this->productConcretePageSearchReader->getProductConcretePageSearchTransfersByProductIds($productIds);
181
182
        $this->getTransactionHandler()->handleTransaction(function () use ($productConcretePageSearchTransfers) {
183
            $this->executeUnpublishTransaction($productConcretePageSearchTransfers);
184
        });
185
    }
186
187
    /**
188
     * @param array<\Generated\Shared\Transfer\ProductConcreteTransfer> $productConcreteTransfers
189
     *
190
     * @return array
191
     */
192
    protected function getProductIdsListFromProductConcreteTransfers(array $productConcreteTransfers): array
193
    {
194
        $productIds = [];
195
        foreach ($productConcreteTransfers as $productConcreteTransfer) {
196
            $productIds[] = $productConcreteTransfer->getIdProductConcrete();
197
        }
198
199
        return $productIds;
200
    }
201
202
    /**
203
     * @param array<\Generated\Shared\Transfer\ProductConcreteTransfer> $productConcreteTransfers
204
     * @param array<\Generated\Shared\Transfer\ProductConcretePageSearchTransfer> $productConcretePageSearchTransfers
205
     *
206
     * @return void
207
     */
208
    protected function executePublishTransaction(array $productConcreteTransfers, array $productConcretePageSearchTransfers): void
209
    {
210
        $filteredProductConcreteTransfers = $this->executeProductConcreteCollectionFilterPlugins($productConcreteTransfers);
211
        $filteredProductIds = $this->getProductIdsListFromProductConcreteTransfers($filteredProductConcreteTransfers);
212
        $productConcreteTransfers = $this->productPageSearchFacade->expandProductConcreteTransfersWithIsSearchable(
213
            $productConcreteTransfers,
214
        );
215
216
        foreach ($productConcreteTransfers as $productConcreteTransfer) {
217
            foreach ($productConcreteTransfer->getStores() as $storeTransfer) {
218
                $this->syncProductConcretePageSearchPerStore(
219
                    $productConcreteTransfer,
220
                    $storeTransfer,
221
                    $productConcretePageSearchTransfers[$productConcreteTransfer->getIdProductConcrete()][$storeTransfer->getName()] ?? [],
222
                    $filteredProductIds,
223
                );
224
            }
225
        }
226
    }
227
228
    /**
229
     * @param array<\Generated\Shared\Transfer\ProductConcretePageSearchTransfer> $productConcretePageSearchTransfers
230
     *
231
     * @return void
232
     */
233
    protected function executeUnpublishTransaction(array $productConcretePageSearchTransfers): void
234
    {
235
        foreach ($productConcretePageSearchTransfers as $productConcretePageSearchTransfer) {
236
            $this->deleteProductConcretePageSearch($productConcretePageSearchTransfer);
237
        }
238
    }
239
240
    /**
241
     * @param \Generated\Shared\Transfer\ProductConcreteTransfer $productConcreteTransfer
242
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
243
     * @param array<\Generated\Shared\Transfer\ProductConcretePageSearchTransfer> $localizedProductConcretePageSearchTransfers
244
     * @param array<int> $filteredProductIds
245
     *
246
     * @return void
247
     */
248
    protected function syncProductConcretePageSearchPerStore(
249
        ProductConcreteTransfer $productConcreteTransfer,
250
        StoreTransfer $storeTransfer,
251
        array $localizedProductConcretePageSearchTransfers,
252
        array $filteredProductIds
253
    ): void {
254
        foreach ($productConcreteTransfer->getLocalizedAttributes() as $localizedAttributesTransfer) {
255
            $this->syncProductConcretePageSearchPerLocale(
256
                $productConcreteTransfer,
257
                $storeTransfer,
258
                $localizedProductConcretePageSearchTransfers[$localizedAttributesTransfer->getLocale()->getLocaleName()] ?? new ProductConcretePageSearchTransfer(),
259
                $localizedAttributesTransfer,
260
                $filteredProductIds,
261
            );
262
        }
263
    }
264
265
    /**
266
     * @param \Generated\Shared\Transfer\ProductConcreteTransfer $productConcreteTransfer
267
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
268
     * @param \Generated\Shared\Transfer\ProductConcretePageSearchTransfer $productConcretePageSearchTransfer
269
     * @param \Generated\Shared\Transfer\LocalizedAttributesTransfer $localizedAttributesTransfer
270
     * @param array<int> $filteredProductIds
271
     *
272
     * @return void
273
     */
274
    protected function syncProductConcretePageSearchPerLocale(
275
        ProductConcreteTransfer $productConcreteTransfer,
276
        StoreTransfer $storeTransfer,
277
        ProductConcretePageSearchTransfer $productConcretePageSearchTransfer,
278
        LocalizedAttributesTransfer $localizedAttributesTransfer,
279
        array $filteredProductIds
280
    ): void {
281
        if (!in_array($productConcreteTransfer->getIdProductConcrete(), $filteredProductIds)) {
282
            if ($productConcretePageSearchTransfer->getIdProductConcretePageSearch() !== null) {
283
                $this->deleteProductConcretePageSearch($productConcretePageSearchTransfer);
284
            }
285
286
            return;
287
        }
288
289
        if (!$productConcreteTransfer->getIsActive() && $productConcretePageSearchTransfer->getIdProductConcretePageSearch() !== null) {
290
            $this->deleteProductConcretePageSearch($productConcretePageSearchTransfer);
291
292
            return;
293
        }
294
295
        if (!$this->isValidStoreLocale($storeTransfer->getName(), $localizedAttributesTransfer->getLocale()->getLocaleName())) {
296
            if ($productConcretePageSearchTransfer->getIdProductConcretePageSearch() !== null) {
297
                $this->deleteProductConcretePageSearch($productConcretePageSearchTransfer);
298
            }
299
300
            return;
301
        }
302
303
        if ($localizedAttributesTransfer->getIsSearchable() === false) {
304
            if ($productConcretePageSearchTransfer->getIdProductConcretePageSearch() !== null) {
305
                $this->deleteProductConcretePageSearch($productConcretePageSearchTransfer);
306
            }
307
308
            return;
309
        }
310
311
        $this->mapProductConcretePageSearchTransfer(
312
            $productConcreteTransfer,
313
            $storeTransfer,
314
            $productConcretePageSearchTransfer,
315
            $localizedAttributesTransfer,
316
        );
317
318
        $this->productConcretePageSearchWriter->saveProductConcretePageSearch($productConcretePageSearchTransfer);
319
    }
320
321
    /**
322
     * @param \Generated\Shared\Transfer\ProductConcreteTransfer $productConcreteTransfer
323
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
324
     * @param \Generated\Shared\Transfer\ProductConcretePageSearchTransfer $productConcretePageSearchTransfer
325
     * @param \Generated\Shared\Transfer\LocalizedAttributesTransfer $localizedAttributesTransfer
326
     *
327
     * @return \Generated\Shared\Transfer\ProductConcretePageSearchTransfer
328
     */
329
    protected function mapProductConcretePageSearchTransfer(
330
        ProductConcreteTransfer $productConcreteTransfer,
331
        StoreTransfer $storeTransfer,
332
        ProductConcretePageSearchTransfer $productConcretePageSearchTransfer,
333
        LocalizedAttributesTransfer $localizedAttributesTransfer
334
    ): ProductConcretePageSearchTransfer {
335
        $productConcretePageSearchTransfer = $this->mapProductConcreteTransferToProductConcretePageSearchTransfer(
336
            $productConcreteTransfer,
337
            $productConcretePageSearchTransfer,
338
            $storeTransfer,
339
            $localizedAttributesTransfer,
340
        );
341
342
        if (!empty($this->productIdTimestampMapToSave[$productConcreteTransfer->getIdProductConcrete()])) {
343
            $productConcretePageSearchTransfer->setTimestamp($this->productIdTimestampMapToSave[$productConcreteTransfer->getIdProductConcrete()]);
344
        }
345
346
        $productConcretePageSearchTransfer = $this->expandProductConcretePageSearchTransferWithPlugins($productConcreteTransfer, $productConcretePageSearchTransfer);
347
348
        $productConcretePageSearchTransfer->setData(
349
            $this->mapTransferToProductConcretePageSearchDocument($productConcretePageSearchTransfer),
350
        );
351
352
        $productConcretePageSearchTransfer->setStructuredData(
353
            $this->getStructuredDataFromProductConcretePageSearchTransfer($productConcretePageSearchTransfer),
354
        );
355
356
        return $productConcretePageSearchTransfer;
357
    }
358
359
    /**
360
     * @param \Generated\Shared\Transfer\ProductConcreteTransfer $productConcreteTransfer
361
     * @param \Generated\Shared\Transfer\ProductConcretePageSearchTransfer $productConcretePageSearchTransfer
362
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
363
     * @param \Generated\Shared\Transfer\LocalizedAttributesTransfer $localizedAttributesTransfer
364
     *
365
     * @return \Generated\Shared\Transfer\ProductConcretePageSearchTransfer
366
     */
367
    protected function mapProductConcreteTransferToProductConcretePageSearchTransfer(
368
        ProductConcreteTransfer $productConcreteTransfer,
369
        ProductConcretePageSearchTransfer $productConcretePageSearchTransfer,
370
        StoreTransfer $storeTransfer,
371
        LocalizedAttributesTransfer $localizedAttributesTransfer
372
    ): ProductConcretePageSearchTransfer {
373
        $productConcretePageSearchTransfer->fromArray(
374
            $productConcreteTransfer->toArray(),
375
            true,
376
        );
377
378
        $productConcretePageSearchTransfer->setFkProduct($productConcreteTransfer->getIdProductConcrete())
379
            ->setFkProductAbstract($productConcreteTransfer->getFkProductAbstract())
380
            ->setType(ProductPageSearchConstants::PRODUCT_CONCRETE_RESOURCE_NAME)
381
            ->setStore($storeTransfer->getName())
382
            ->setLocale($localizedAttributesTransfer->getLocale()->getLocaleName())
383
            ->setName($localizedAttributesTransfer->getName());
384
385
        return $productConcretePageSearchTransfer;
386
    }
387
388
    /**
389
     * @param \Generated\Shared\Transfer\ProductConcretePageSearchTransfer $productConcretePageSearchTransfer
390
     *
391
     * @return array
392
     */
393
    protected function mapTransferToProductConcretePageSearchDocument(ProductConcretePageSearchTransfer $productConcretePageSearchTransfer): array
394
    {
395
        $productConcretePageSearchData = $productConcretePageSearchTransfer->toArray(true, true);
396
        $localeTransfer = (new LocaleTransfer())
397
            ->setLocaleName($productConcretePageSearchTransfer->getLocale());
398
399
        return $this->productConcreteSearchDataMapper->mapProductDataToSearchData($productConcretePageSearchData, $localeTransfer);
400
    }
401
402
    /**
403
     * @param \Generated\Shared\Transfer\ProductConcretePageSearchTransfer $productConcretePageSearchTransfer
404
     *
405
     * @throws \Spryker\Zed\ProductPageSearch\Business\Exception\ProductConcretePageSearchNotFoundException
406
     *
407
     * @return void
408
     */
409
    protected function deleteProductConcretePageSearch(ProductConcretePageSearchTransfer $productConcretePageSearchTransfer): void
410
    {
411
        if (!$this->productConcretePageSearchWriter->deleteProductConcretePageSearch($productConcretePageSearchTransfer)) {
412
            throw new ProductConcretePageSearchNotFoundException(sprintf('Target storage entry for product with id %s not found', $productConcretePageSearchTransfer->getFkProduct()));
413
        }
414
    }
415
416
    /**
417
     * @param \Generated\Shared\Transfer\ProductConcreteTransfer $productConcreteTransfer
418
     * @param \Generated\Shared\Transfer\ProductConcretePageSearchTransfer $productConcretePageSearchTransfer
419
     *
420
     * @return \Generated\Shared\Transfer\ProductConcretePageSearchTransfer
421
     */
422
    protected function expandProductConcretePageSearchTransferWithPlugins(
423
        ProductConcreteTransfer $productConcreteTransfer,
424
        ProductConcretePageSearchTransfer $productConcretePageSearchTransfer
425
    ): ProductConcretePageSearchTransfer {
426
        foreach ($this->pageDataExpanderPlugins as $pageDataExpanderPlugin) {
427
            $productConcretePageSearchTransfer = $pageDataExpanderPlugin->expand($productConcreteTransfer, $productConcretePageSearchTransfer);
428
        }
429
430
        return $productConcretePageSearchTransfer;
431
    }
432
433
    /**
434
     * @param \Generated\Shared\Transfer\ProductConcretePageSearchTransfer $productConcretePageSearchTransfer
435
     *
436
     * @return string
437
     */
438
    protected function getStructuredDataFromProductConcretePageSearchTransfer(ProductConcretePageSearchTransfer $productConcretePageSearchTransfer): string
439
    {
440
        $data = $productConcretePageSearchTransfer->toArray();
441
        unset($data[static::IDENTIFIER_PRODUCT_CONCRETE_PAGE_SEARCH]);
442
        // Avoiding data recursion when transfer was populated from DB already
443
        unset($data[static::IDENTIFIER_STRUCTURED_DATA]);
444
445
        return $this->utilEncoding->encodeJson($data);
446
    }
447
448
    /**
449
     * @param string $storeName
450
     * @param string $localeName
451
     *
452
     * @return bool
453
     */
454
    protected function isValidStoreLocale(string $storeName, string $localeName): bool
455
    {
456
        return in_array($localeName, $this->storeFacade->getStoreByName($storeName)->getAvailableLocaleIsoCodes());
457
    }
458
459
    /**
460
     * @param array<\Generated\Shared\Transfer\ProductConcreteTransfer> $productConcreteTransfers
461
     *
462
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
463
     */
464
    protected function executeProductConcreteCollectionFilterPlugins(array $productConcreteTransfers): array
465
    {
466
        foreach ($this->productConcreteCollectionFilterPlugins as $productConcreteCollectionFilterPlugin) {
467
            $productConcreteTransfers = $productConcreteCollectionFilterPlugin->filter($productConcreteTransfers);
468
        }
469
470
        return $productConcreteTransfers;
471
    }
472
}
473