mapProductAbstractEntitiesToProductAbstractTransfersWithoutRelations()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 0
loc 13
rs 10
c 0
b 0
f 0
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\Product\Persistence;
9
10
use ArrayObject;
11
use Generated\Shared\Transfer\FilterTransfer;
12
use Generated\Shared\Transfer\LocaleTransfer;
13
use Generated\Shared\Transfer\LocalizedAttributesTransfer;
14
use Generated\Shared\Transfer\PaginationTransfer;
15
use Generated\Shared\Transfer\ProductAbstractCollectionTransfer;
16
use Generated\Shared\Transfer\ProductAbstractCriteriaTransfer;
17
use Generated\Shared\Transfer\ProductAbstractSuggestionCollectionTransfer;
18
use Generated\Shared\Transfer\ProductAbstractTransfer;
19
use Generated\Shared\Transfer\ProductAttributeKeyCollectionTransfer;
20
use Generated\Shared\Transfer\ProductAttributeKeyCriteriaTransfer;
21
use Generated\Shared\Transfer\ProductConcreteCollectionTransfer;
22
use Generated\Shared\Transfer\ProductConcreteCriteriaTransfer;
23
use Generated\Shared\Transfer\ProductConcreteTransfer;
24
use Generated\Shared\Transfer\ProductCriteriaTransfer;
25
use Generated\Shared\Transfer\ProductUrlCriteriaFilterTransfer;
26
use Generated\Shared\Transfer\SpyProductEntityTransfer;
27
use Generated\Shared\Transfer\UrlTransfer;
28
use Orm\Zed\Product\Persistence\Map\SpyProductAbstractLocalizedAttributesTableMap;
29
use Orm\Zed\Product\Persistence\Map\SpyProductAbstractTableMap;
30
use Orm\Zed\Product\Persistence\Map\SpyProductLocalizedAttributesTableMap;
31
use Orm\Zed\Product\Persistence\Map\SpyProductTableMap;
32
use Orm\Zed\Product\Persistence\SpyProductAbstractQuery;
33
use Orm\Zed\Product\Persistence\SpyProductAttributeKeyQuery;
34
use Orm\Zed\Product\Persistence\SpyProductQuery;
35
use Orm\Zed\Url\Persistence\SpyUrlQuery;
36
use Propel\Runtime\ActiveQuery\ModelCriteria;
37
use Propel\Runtime\Collection\Collection;
38
use Propel\Runtime\Collection\ObjectCollection;
39
use Propel\Runtime\Util\PropelModelPager;
40
use Spryker\Zed\Kernel\Persistence\AbstractRepository;
41
use Spryker\Zed\PropelOrm\Business\Runtime\ActiveQuery\Criteria;
42
43
/**
44
 * @method \Spryker\Zed\Product\Persistence\ProductPersistenceFactory getFactory()
45
 */
46
class ProductRepository extends AbstractRepository implements ProductRepositoryInterface
47
{
48
    /**
49
     * @var string
50
     */
51
    public const KEY_FILTERED_PRODUCTS_RESULT = 'result';
52
53
    /**
54
     * @var string
55
     */
56
    public const KEY_FILTERED_PRODUCTS_PRODUCT_NAME = 'name';
57
58
    /**
59
     * @param string $productConcreteSku
60
     *
61
     * @return \Generated\Shared\Transfer\SpyProductEntityTransfer|null
62
     */
63
    public function findProductConcreteBySku(string $productConcreteSku): ?SpyProductEntityTransfer
64
    {
65
        $productQuery = $this->getFactory()
66
            ->createProductQuery()
67
            ->joinWithSpyProductAbstract()
68
            ->filterBySku($productConcreteSku);
69
70
        return $this->buildQueryFromCriteria($productQuery)->findOne();
71
    }
72
73
    /**
74
     * @param int $idProductConcrete
75
     *
76
     * @return \Generated\Shared\Transfer\SpyProductEntityTransfer|null
77
     */
78
    public function findProductConcreteById(int $idProductConcrete): ?SpyProductEntityTransfer
79
    {
80
        $productQuery = $this->getFactory()
81
            ->createProductQuery()
82
            ->joinWithSpyProductAbstract()
83
            ->filterByIdProduct($idProductConcrete);
84
85
        return $this->buildQueryFromCriteria($productQuery)->findOne();
86
    }
87
88
    /**
89
     * @param array<int> $productIds
90
     *
91
     * @return array<\Generated\Shared\Transfer\SpyProductEntityTransfer>
92
     */
93
    public function findProductConcreteByIds(array $productIds): array
94
    {
95
        $productQuery = $this->getFactory()
96
            ->createProductQuery()
97
            ->joinWithSpyProductAbstract()
98
            ->filterByIdProduct_In($productIds);
99
100
        return $this->buildQueryFromCriteria($productQuery)->find();
101
    }
102
103
    /**
104
     * @param string $search
105
     * @param \Generated\Shared\Transfer\LocaleTransfer $localeTransfer
106
     * @param int $limit
107
     *
108
     * @return array
109
     */
110
    public function findProductAbstractDataBySkuOrLocalizedName(string $search, LocaleTransfer $localeTransfer, int $limit): array
111
    {
112
        $criteria = new Criteria();
113
        $skuLikeCriteria = $criteria->getNewCriterion(
114
            SpyProductAbstractTableMap::COL_SKU,
115
            '%' . $search . '%',
116
            Criteria::LIKE,
117
        );
118
119
        $productAbstractQuery = $this->getFactory()
120
            ->createProductAbstractQuery();
121
        $productAbstractQuery->leftJoinSpyProductAbstractLocalizedAttributes()
122
            ->addJoinCondition(
123
                'SpyProductAbstractLocalizedAttributes',
124
                sprintf('SpyProductAbstractLocalizedAttributes.fk_locale = %d', $localeTransfer->getIdLocale()),
125
            )
126
            ->withColumn(SpyProductAbstractLocalizedAttributesTableMap::COL_NAME, static::KEY_FILTERED_PRODUCTS_PRODUCT_NAME)
127
            ->withColumn(SpyProductAbstractTableMap::COL_SKU, static::KEY_FILTERED_PRODUCTS_RESULT)
128
            ->where('lower(' . SpyProductAbstractLocalizedAttributesTableMap::COL_NAME . ') like ?', '%' . mb_strtolower($search) . '%')
129
            ->addOr($skuLikeCriteria);
130
        $productAbstractQuery->limit($limit)
131
            ->select([
132
                static::KEY_FILTERED_PRODUCTS_RESULT,
133
                static::KEY_FILTERED_PRODUCTS_PRODUCT_NAME,
134
            ])->addAscendingOrderByColumn(SpyProductAbstractLocalizedAttributesTableMap::COL_NAME);
135
136
        /** @var \Propel\Runtime\Collection\ObjectCollection $abstractProducts */
137
        $abstractProducts = $productAbstractQuery->find();
138
139
        return $this->collectFilteredResults(
140
            $abstractProducts->toArray(),
141
        );
142
    }
143
144
    /**
145
     * @param string $search
146
     * @param \Generated\Shared\Transfer\LocaleTransfer $localeTransfer
147
     * @param int $limit
148
     *
149
     * @return array
150
     */
151
    public function findProductConcreteDataBySkuOrLocalizedName(string $search, LocaleTransfer $localeTransfer, int $limit): array
152
    {
153
        $criteria = new Criteria();
154
        $skuLikeCriteria = $criteria->getNewCriterion(
155
            SpyProductTableMap::COL_SKU,
156
            '%' . $search . '%',
157
            Criteria::LIKE,
158
        );
159
160
        $productConcreteQuery = $this->getFactory()
161
            ->createProductQuery();
162
        $productConcreteQuery->leftJoinSpyProductLocalizedAttributes()
163
            ->addJoinCondition(
164
                'SpyProductLocalizedAttributes',
165
                sprintf('SpyProductLocalizedAttributes.fk_locale = %d', $localeTransfer->getIdLocale()),
166
            )
167
            ->withColumn(SpyProductLocalizedAttributesTableMap::COL_NAME, static::KEY_FILTERED_PRODUCTS_PRODUCT_NAME)
168
            ->withColumn(SpyProductTableMap::COL_SKU, static::KEY_FILTERED_PRODUCTS_RESULT)
169
            ->where('lower(' . SpyProductLocalizedAttributesTableMap::COL_NAME . ') like ?', '%' . mb_strtolower($search) . '%')
170
            ->addOr($skuLikeCriteria);
171
        $productConcreteQuery->limit($limit)
172
            ->select([
173
                static::KEY_FILTERED_PRODUCTS_RESULT,
174
                static::KEY_FILTERED_PRODUCTS_PRODUCT_NAME,
175
            ]);
176
177
        /** @var \Propel\Runtime\Collection\ObjectCollection $concreteProducts */
178
        $concreteProducts = $productConcreteQuery->find();
179
180
        return $this->collectFilteredResults(
181
            $concreteProducts->toArray(),
182
        );
183
    }
184
185
    /**
186
     * @param int $idProductConcrete
187
     *
188
     * @return int|null
189
     */
190
    public function findProductAbstractIdByConcreteId(int $idProductConcrete): ?int
191
    {
192
        $productConcrete = $this->getFactory()
193
            ->createProductQuery()
194
            ->filterByIdProduct($idProductConcrete)
195
            ->findOne();
196
197
        if (!$productConcrete) {
198
            return null;
199
        }
200
201
        return $productConcrete->getFkProductAbstract();
202
    }
203
204
    /**
205
     * @param array<int> $productConcreteIds
206
     *
207
     * @return array<int>
208
     */
209
    public function getProductAbstractIdsByProductConcreteIds(array $productConcreteIds): array
210
    {
211
        /** @var \Orm\Zed\Product\Persistence\SpyProductQuery $productQuery */
212
        $productQuery = $this->getFactory()
213
            ->createProductQuery()
214
            ->select([SpyProductTableMap::COL_FK_PRODUCT_ABSTRACT, SpyProductTableMap::COL_ID_PRODUCT]);
215
216
        /** @var \Propel\Runtime\Collection\ObjectCollection $products */
217
        $products = $productQuery
218
            ->filterByIdProduct_In($productConcreteIds)
219
            ->find();
220
221
        return $products->toKeyValue(SpyProductTableMap::COL_ID_PRODUCT, SpyProductTableMap::COL_FK_PRODUCT_ABSTRACT);
222
    }
223
224
    /**
225
     * @param int $idProductAbstract
226
     *
227
     * @return array<int>
228
     */
229
    public function findProductConcreteIdsByAbstractProductId(int $idProductAbstract): array
230
    {
231
        $productConcreteQuery = $this->getFactory()
232
            ->createProductQuery();
233
        /** @var \Propel\Runtime\Collection\ObjectCollection|null $productConcreteIds */
234
        $productConcreteIds = $productConcreteQuery
235
            ->filterByFkProductAbstract($idProductAbstract)
236
            ->select([SpyProductTableMap::COL_ID_PRODUCT])
237
            ->find();
238
239
        if (!$productConcreteIds) {
240
            return [];
241
        }
242
243
        return $productConcreteIds->getData();
244
    }
245
246
    /**
247
     * @param array<int> $productAbstractIds
248
     *
249
     * @return array<int>
250
     */
251
    public function findProductConcreteIdsByProductAbstractIds(array $productAbstractIds): array
252
    {
253
        /** @var \Propel\Runtime\Collection\ArrayCollection $productConcreteIds */
254
        $productConcreteIds = $this->getFactory()
255
            ->createProductQuery()
256
            ->filterByFkProductAbstract_In($productAbstractIds)
257
            ->select([SpyProductTableMap::COL_ID_PRODUCT])
258
            ->find();
259
260
        return $productConcreteIds->toArray();
261
    }
262
263
    /**
264
     * @param \Generated\Shared\Transfer\ProductConcreteTransfer $productConcreteTransfer
265
     *
266
     * @return bool
267
     */
268
    public function isProductConcreteActive(ProductConcreteTransfer $productConcreteTransfer): bool
269
    {
270
        return $this->getFactory()
271
            ->createProductQuery()
272
            ->findOneBySku($productConcreteTransfer->getSku())
273
            ->getIsActive();
274
    }
275
276
    /**
277
     * @param array $products
278
     *
279
     * @return array
280
     */
281
    protected function collectFilteredResults(array $products): array
282
    {
283
        $results = [];
284
285
        foreach ($products as $product) {
286
            $results[$product[static::KEY_FILTERED_PRODUCTS_RESULT]] = $product[static::KEY_FILTERED_PRODUCTS_PRODUCT_NAME];
287
        }
288
289
        return $results;
290
    }
291
292
    /**
293
     * @param array<string> $skus
294
     *
295
     * @return array<int>
296
     */
297
    public function getProductConcreteIdsByConcreteSkus(array $skus): array
298
    {
299
        $results = $this->getFactory()
300
            ->createProductQuery()
301
            ->filterBySku_In($skus)
302
            ->select([
303
                SpyProductTableMap::COL_ID_PRODUCT,
304
                SpyProductTableMap::COL_SKU,
305
            ])
306
            ->find()
307
            ->getData();
308
309
        $formattedResults = [];
310
        foreach ($results as $result) {
311
            $formattedResults[$result[SpyProductTableMap::COL_SKU]] = $result[SpyProductTableMap::COL_ID_PRODUCT];
312
        }
313
314
        return $formattedResults;
315
    }
316
317
    /**
318
     * @param array<int> $productIds
319
     *
320
     * @return array
321
     */
322
    public function getProductConcreteSkusByConcreteIds(array $productIds): array
323
    {
324
        $results = $this->getFactory()
325
            ->createProductQuery()
326
            ->filterByIdProduct_In($productIds)
327
            ->select([
328
                SpyProductTableMap::COL_ID_PRODUCT,
329
                SpyProductTableMap::COL_SKU,
330
            ])
331
            ->find()
332
            ->getData();
333
334
        $formattedResults = [];
335
        foreach ($results as $result) {
336
            $formattedResults[$result[SpyProductTableMap::COL_SKU]] = $result[SpyProductTableMap::COL_ID_PRODUCT];
337
        }
338
339
        return $formattedResults;
340
    }
341
342
    /**
343
     * @module Locale
344
     * @module Store
345
     *
346
     * @param array<int> $productIds
347
     *
348
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
349
     */
350
    public function getProductConcreteTransfersByProductIds(array $productIds): array
351
    {
352
        if (!$productIds) {
353
            return [];
354
        }
355
356
        /** @var \Orm\Zed\Product\Persistence\SpyProductQuery $query */
357
        $query = $this->getFactory()
358
            ->createProductQuery()
359
            ->filterByIdProduct_In($productIds)
360
            ->joinWithSpyProductAbstract()
361
            ->joinWithSpyProductLocalizedAttributes()
362
            ->useSpyProductLocalizedAttributesQuery()
363
                ->joinWithLocale()
364
            ->endUse();
365
366
        /** @var \Orm\Zed\Product\Persistence\SpyProductQuery $query */
367
        $query = $query
368
            ->useSpyProductAbstractQuery()
369
                ->joinSpyProductAbstractStore()
370
                ->useSpyProductAbstractStoreQuery()
371
                    ->joinWithSpyStore()
372
                ->endUse()
373
            ->endUse();
374
375
        $productConcreteEntities = $query->find();
376
377
        return $this->getProductConcreteTransfersMappedFromProductConcreteEntities($productConcreteEntities);
378
    }
379
380
    /**
381
     * @param array<int> $productAbstractIds
382
     *
383
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
384
     */
385
    public function getProductConcreteTransfersByProductAbstractIds(array $productAbstractIds): array
386
    {
387
        if (!$productAbstractIds) {
388
            return [];
389
        }
390
391
        $query = $this->getFactory()
392
            ->createProductQuery()
393
            ->filterByFkProductAbstract_In($productAbstractIds);
394
395
        $productConcreteEntities = $query->find();
396
397
        return $this->getProductConcreteTransfersMappedFromProductConcreteEntities($productConcreteEntities);
398
    }
399
400
    /**
401
     * @param string $search
402
     * @param \Generated\Shared\Transfer\PaginationTransfer $paginationTransfer
403
     * @param \Generated\Shared\Transfer\LocaleTransfer $localeTransfer
404
     *
405
     * @return \Generated\Shared\Transfer\ProductAbstractSuggestionCollectionTransfer
406
     */
407
    public function getProductAbstractSuggestionCollectionBySkuOrLocalizedName(
408
        string $search,
409
        PaginationTransfer $paginationTransfer,
410
        LocaleTransfer $localeTransfer
411
    ): ProductAbstractSuggestionCollectionTransfer {
412
        $criteria = new Criteria();
413
        $skuLikeCriteria = $criteria->getNewCriterion(
414
            SpyProductAbstractTableMap::COL_SKU,
415
            '%' . $search . '%',
416
            Criteria::LIKE,
417
        );
418
419
        $productAbstractQuery = $this->getFactory()
420
            ->createProductAbstractQuery();
421
        $productAbstractQuery->leftJoinSpyProductAbstractLocalizedAttributes()
422
            ->useSpyProductAbstractLocalizedAttributesQuery()
423
                ->filterByFkLocale($localeTransfer->getIdLocale())
424
            ->endUse()
425
            ->withColumn(SpyProductAbstractLocalizedAttributesTableMap::COL_NAME, static::KEY_FILTERED_PRODUCTS_PRODUCT_NAME)
426
            ->where('lower(' . SpyProductAbstractLocalizedAttributesTableMap::COL_NAME . ') like ?', '%' . mb_strtolower($search) . '%')
427
            ->addOr($skuLikeCriteria)
428
            ->addAscendingOrderByColumn(SpyProductAbstractTableMap::COL_SKU);
429
430
        $paginationModel = $this->getPaginationModelFromQuery($productAbstractQuery, $paginationTransfer);
431
        $paginationTransfer->setLastPage($paginationModel->getLastPage());
432
        $productAbstractQuery = $paginationModel->getQuery();
433
434
        $productAbstractEntities = $productAbstractQuery->find();
435
436
        return (new ProductAbstractSuggestionCollectionTransfer())
437
            ->setPagination($paginationTransfer)
438
            ->setProductAbstracts(
439
                $this->getProductAbstractTransfersMappedFromProductAbstractEntities($productAbstractEntities),
440
            );
441
    }
442
443
    /**
444
     * @param \Generated\Shared\Transfer\FilterTransfer $filterTransfer
445
     *
446
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
447
     */
448
    public function getProductConcretesByFilter(FilterTransfer $filterTransfer): array
449
    {
450
        $productConcreteEntities = $this->buildQueryFromCriteria(
451
            $this->getFactory()->createProductQuery(),
452
            $filterTransfer,
453
        )->setFormatter(ModelCriteria::FORMAT_OBJECT)->find();
454
455
        return $this->getProductConcreteTransfersMappedFromProductConcreteEntities($productConcreteEntities);
456
    }
457
458
    /**
459
     * @param \Orm\Zed\Product\Persistence\SpyProductAbstractQuery $productAbstractQuery
460
     * @param \Generated\Shared\Transfer\PaginationTransfer $paginationTransfer
461
     *
462
     * @return \Propel\Runtime\Util\PropelModelPager
463
     */
464
    protected function getPaginationModelFromQuery(
465
        SpyProductAbstractQuery $productAbstractQuery,
466
        PaginationTransfer $paginationTransfer
467
    ): PropelModelPager {
468
        $page = $paginationTransfer
469
            ->requirePage()
470
            ->getPage();
471
472
        $maxPerPage = $paginationTransfer
473
            ->requireMaxPerPage()
474
            ->getMaxPerPage();
475
476
        return $productAbstractQuery->paginate($page, $maxPerPage);
477
    }
478
479
    /**
480
     * @param \Propel\Runtime\Collection\Collection $productConcreteEntities
481
     *
482
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
483
     */
484
    protected function getProductConcreteTransfersMappedFromProductConcreteEntities(Collection $productConcreteEntities): array
485
    {
486
        $productConcreteTransfers = [];
487
        $productMapper = $this->getFactory()->createProductMapper();
488
489
        foreach ($productConcreteEntities as $productConcreteEntity) {
490
            $productConcreteTransfers[] = $productMapper->mapProductConcreteEntityToTransfer(
491
                $productConcreteEntity,
492
                new ProductConcreteTransfer(),
493
            );
494
        }
495
496
        return $productConcreteTransfers;
497
    }
498
499
    /**
500
     * @param array<string> $productConcreteSkus
501
     *
502
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
503
     */
504
    public function getProductConcretesByConcreteSkus(array $productConcreteSkus): array
505
    {
506
        $productConcreteEntities = $this->getFactory()
507
            ->createProductQuery()
508
            ->joinWithSpyProductAbstract()
509
            ->joinWithSpyProductLocalizedAttributes()
510
            ->filterBySku_In($productConcreteSkus)
511
            ->useSpyProductLocalizedAttributesQuery()
512
                ->joinWithLocale()
513
            ->endUse()
514
            ->find();
515
516
        if ($productConcreteEntities->count() === 0) {
517
            return [];
518
        }
519
520
        return $this->mapProductEntitiesToProductConcreteTransfersWithoutStores($productConcreteEntities);
521
    }
522
523
    /**
524
     * @param \Propel\Runtime\Collection\Collection $productEntities
525
     *
526
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
527
     */
528
    protected function mapProductEntitiesToProductConcreteTransfersWithoutStores(Collection $productEntities): array
529
    {
530
        $productConcreteTransfers = [];
531
        $productMapper = $this->getFactory()->createProductMapper();
532
533
        foreach ($productEntities as $productEntity) {
534
            $productConcreteTransfers[] = $productMapper
535
                ->mapProductEntityToProductConcreteTransferWithoutStores($productEntity, new ProductConcreteTransfer());
536
        }
537
538
        return $productConcreteTransfers;
539
    }
540
541
    /**
542
     * @param \Propel\Runtime\Collection\ObjectCollection $productAbstractEntities
543
     *
544
     * @return \ArrayObject<int, \Generated\Shared\Transfer\ProductAbstractTransfer>
545
     */
546
    protected function getProductAbstractTransfersMappedFromProductAbstractEntities(ObjectCollection $productAbstractEntities): ArrayObject
547
    {
548
        /** @var \ArrayObject<int, \Generated\Shared\Transfer\ProductAbstractTransfer> $productAbstractTransfers */
549
        $productAbstractTransfers = new ArrayObject();
550
        $productMapper = $this->getFactory()->createProductMapper();
551
552
        foreach ($productAbstractEntities as $productAbstractEntity) {
553
            $productAbstractTransfers[] = $productMapper->mapProductAbstractEntityToProductAbstractTransferForSuggestion(
554
                $productAbstractEntity,
555
                new ProductAbstractTransfer(),
556
            );
557
        }
558
559
        return $productAbstractTransfers;
560
    }
561
562
    /**
563
     * @param \Generated\Shared\Transfer\FilterTransfer $filterTransfer
564
     *
565
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
566
     */
567
    public function getRawProductConcreteTransfersByFilter(FilterTransfer $filterTransfer): array
568
    {
569
        $productQuery = $this->getFactory()->createProductQuery();
570
        $productConcreteEntities = $this->buildQueryFromCriteria($productQuery, $filterTransfer)
571
            ->setFormatter(ModelCriteria::FORMAT_OBJECT)
572
            ->find();
573
574
        return $this->mapProductConcreteEntitiesToProductConcreteTransfersWithoutRelations($productConcreteEntities);
575
    }
576
577
    /**
578
     * @param \Propel\Runtime\Collection\ObjectCollection<\Orm\Zed\Product\Persistence\SpyProduct>|\Propel\Runtime\Collection\Collection $productConcreteEntities
579
     *
580
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
581
     */
582
    protected function mapProductConcreteEntitiesToProductConcreteTransfersWithoutRelations(
583
        ObjectCollection|Collection $productConcreteEntities
584
    ): array {
585
        $productConcreteTransfers = [];
586
        $productMapper = $this->getFactory()->createProductMapper();
587
588
        foreach ($productConcreteEntities as $productConcreteEntity) {
589
            $productConcreteTransfers[] = $productMapper->mapProductConcreteEntityToProductConcreteTransferWithoutRelations(
590
                $productConcreteEntity,
591
                new ProductConcreteTransfer(),
592
            );
593
        }
594
595
        return $productConcreteTransfers;
596
    }
597
598
    /**
599
     * @param \Generated\Shared\Transfer\ProductUrlCriteriaFilterTransfer $productUrlCriteriaFilterTransfer
600
     *
601
     * @return array<\Generated\Shared\Transfer\UrlTransfer>
602
     */
603
    public function getProductUrls(ProductUrlCriteriaFilterTransfer $productUrlCriteriaFilterTransfer): array
604
    {
605
        $urlQuery = $this->getFactory()
606
            ->getUrlQueryContainer()
607
            ->queryUrls();
608
609
        $urlQuery = $this->setUrlFilters($urlQuery, $productUrlCriteriaFilterTransfer);
610
        $urlEntities = $urlQuery->find();
611
612
        $urlTransfers = [];
613
614
        foreach ($urlEntities as $urlEntity) {
615
            $urlTransfers[] = (new UrlTransfer())->fromArray($urlEntity->toArray(), true);
616
        }
617
618
        return $urlTransfers;
619
    }
620
621
    /**
622
     * @param \Orm\Zed\Url\Persistence\SpyUrlQuery $urlQuery
623
     * @param \Generated\Shared\Transfer\ProductUrlCriteriaFilterTransfer $productUrlCriteriaFilterTransfer
624
     *
625
     * @return \Orm\Zed\Url\Persistence\SpyUrlQuery
626
     */
627
    protected function setUrlFilters(
628
        SpyUrlQuery $urlQuery,
629
        ProductUrlCriteriaFilterTransfer $productUrlCriteriaFilterTransfer
630
    ): SpyUrlQuery {
631
        if (count($productUrlCriteriaFilterTransfer->getProductAbstractIds())) {
632
            $urlQuery->filterByFkResourceProductAbstract_In($productUrlCriteriaFilterTransfer->getProductAbstractIds());
633
        }
634
635
        if ($productUrlCriteriaFilterTransfer->getIdLocale()) {
636
            $urlQuery->filterByFkLocale($productUrlCriteriaFilterTransfer->getIdLocale());
637
        }
638
639
        return $urlQuery;
640
    }
641
642
    /**
643
     * @param array<string> $productAbstractSkus
644
     *
645
     * @return array<\Generated\Shared\Transfer\ProductAbstractTransfer>
646
     */
647
    public function getRawProductAbstractTransfersByAbstractSkus(array $productAbstractSkus): array
648
    {
649
        $productAbstractEntities = $this->getFactory()->createProductAbstractQuery()
650
            ->filterBySku_In($productAbstractSkus)
651
            ->find();
652
653
        return $this->mapProductAbstractEntitiesToProductAbstractTransfersWithoutRelations($productAbstractEntities);
654
    }
655
656
    /**
657
     * @param array<int> $productAbstractIds
658
     *
659
     * @return array<\Generated\Shared\Transfer\ProductAbstractTransfer>
660
     */
661
    public function getActiveProductAbstractsByProductAbstractIds(array $productAbstractIds): array
662
    {
663
        /** @var \Propel\Runtime\Collection\ObjectCollection<\Orm\Zed\Product\Persistence\SpyProductAbstract> $productAbstractEntities */
664
        $productAbstractEntities = $this->getFactory()
665
            ->createProductAbstractQuery()
666
            ->filterByIdProductAbstract_In($productAbstractIds)
667
            ->joinWithSpyProduct()
668
            ->useSpyProductQuery()
669
                ->filterByIsActive(true)
670
            ->endUse()
671
            ->find();
672
673
        return $this->mapProductAbstractEntitiesToProductAbstractTransfersWithoutRelations($productAbstractEntities);
674
    }
675
676
    /**
677
     * @param array<int> $productAbstractIds
678
     *
679
     * @return array<\Generated\Shared\Transfer\ProductAbstractTransfer>
680
     */
681
    public function getRawProductAbstractsByProductAbstractIds(array $productAbstractIds): array
682
    {
683
        $productAbstractEntities = $this->getFactory()->createProductAbstractQuery()
684
            ->filterByIdProductAbstract_In($productAbstractIds)
685
            ->find();
686
687
        return $this->mapProductAbstractEntitiesToProductAbstractTransfersWithoutRelations($productAbstractEntities);
688
    }
689
690
    /**
691
     * @param array<int> $productAbstractIds
692
     *
693
     * @return array<int, string>
694
     */
695
    public function getProductAbstractLocalizedAttributeNamesIndexedByIdProductAbstract(array $productAbstractIds): array
696
    {
697
        if (!$productAbstractIds) {
698
            return [];
699
        }
700
701
        $productAbstractLocalizedAttributesDataCollection = $this->getFactory()
702
            ->createProductAbstractLocalizedAttributesQuery()
703
            ->select([SpyProductAbstractLocalizedAttributesTableMap::COL_FK_PRODUCT_ABSTRACT, SpyProductAbstractLocalizedAttributesTableMap::COL_NAME])
704
            ->filterByName(null, Criteria::ISNOTNULL)
705
            ->filterByName('', Criteria::NOT_EQUAL)
706
            ->filterByFkProductAbstract_In($productAbstractIds)
707
            ->find();
708
709
        $productAbstractLocalizedAttributeNames = [];
710
        foreach ($productAbstractLocalizedAttributesDataCollection as $productAbstractLocalizedAttributesData) {
711
            /** @var int $idProductAbstract */
712
            $idProductAbstract = $productAbstractLocalizedAttributesData[SpyProductAbstractLocalizedAttributesTableMap::COL_FK_PRODUCT_ABSTRACT];
713
            $name = $productAbstractLocalizedAttributesData[SpyProductAbstractLocalizedAttributesTableMap::COL_NAME];
714
715
            if (!isset($productAbstractLocalizedAttributeNames[$idProductAbstract])) {
716
                $productAbstractLocalizedAttributeNames[$idProductAbstract] = $name;
717
            }
718
        }
719
720
        return $productAbstractLocalizedAttributeNames;
721
    }
722
723
    /**
724
     * @param \Generated\Shared\Transfer\ProductCriteriaTransfer $productCriteriaTransfer
725
     *
726
     * @return array<\Generated\Shared\Transfer\ProductConcreteTransfer>
727
     */
728
    public function getProductConcretesByCriteria(ProductCriteriaTransfer $productCriteriaTransfer): array
729
    {
730
        $productQuery = $this->getFactory()
731
            ->createProductQuery();
732
        if ($productCriteriaTransfer->getWithoutAdditionalProductData() !== true) {
733
            $productQuery
734
                ->joinWithSpyProductAbstract()
735
                ->joinWithSpyProductLocalizedAttributes();
736
        }
737
738
        $productQuery = $this->applyCriteriaFilter($productQuery, $productCriteriaTransfer);
739
        $productConcreteEntities = $productQuery->find();
740
741
        if ($productCriteriaTransfer->getWithoutAdditionalProductData() !== true) {
742
            return $this->mapProductEntitiesToProductConcreteTransfersWithoutStores($productConcreteEntities);
743
        }
744
745
        return $this->mapProductConcreteEntitiesToProductConcreteTransfersWithoutRelations($productConcreteEntities);
746
    }
747
748
    /**
749
     * @module Store
750
     *
751
     * @param \Orm\Zed\Product\Persistence\SpyProductQuery $productQuery
752
     * @param \Generated\Shared\Transfer\ProductCriteriaTransfer $productCriteriaTransfer
753
     *
754
     * @return \Orm\Zed\Product\Persistence\SpyProductQuery
755
     */
756
    protected function applyCriteriaFilter(SpyProductQuery $productQuery, ProductCriteriaTransfer $productCriteriaTransfer): SpyProductQuery
757
    {
758
        if ($productCriteriaTransfer->getSkus()) {
759
            $productQuery->filterBySku_In($productCriteriaTransfer->getSkus());
760
        }
761
762
        if ($productCriteriaTransfer->getIsActive() !== null) {
763
            $productQuery->filterByIsActive($productCriteriaTransfer->getIsActive());
764
        }
765
766
        if ($productCriteriaTransfer->getIdStore()) {
767
            $productQuery->useSpyProductAbstractQuery()
768
                ->useSpyProductAbstractStoreQuery()
769
                    ->filterByFkStore($productCriteriaTransfer->getIdStore())
770
                ->endUse()
771
            ->endUse();
772
        }
773
774
        if ($productCriteriaTransfer->getIdProductAbstract()) {
775
            $productQuery->filterByFkProductAbstract($productCriteriaTransfer->getIdProductAbstract());
776
        }
777
778
        if (count($productCriteriaTransfer->getAttributes()) > 0) {
779
            $criteria = new Criteria();
780
            foreach ($productCriteriaTransfer->getAttributes() as $key => $value) {
781
                $attributesLikeCriteria = $criteria->getNewCriterion(
782
                    SpyProductTableMap::COL_ATTRIBUTES,
783
                    sprintf('%%"%s":"%s"%%', $key, $value),
784
                    Criteria::LIKE,
785
                );
786
                $productQuery->addAnd($attributesLikeCriteria);
787
            }
788
        }
789
790
        return $productQuery;
791
    }
792
793
    /**
794
     * @param \Propel\Runtime\Collection\Collection<\Orm\Zed\Product\Persistence\SpyProductAbstract> $productAbstractEntities
795
     *
796
     * @return array<\Generated\Shared\Transfer\ProductAbstractTransfer>
797
     */
798
    protected function mapProductAbstractEntitiesToProductAbstractTransfersWithoutRelations(Collection $productAbstractEntities): array
799
    {
800
        $productAbstractTransfers = [];
801
        $mapper = $this->getFactory()->createProductMapper();
802
803
        foreach ($productAbstractEntities as $productAbstractEntity) {
804
            $productAbstractTransfers[] = $mapper->mapProductAbstractEntityToProductAbstractTransferWithoutRelations(
805
                $productAbstractEntity,
806
                new ProductAbstractTransfer(),
807
            );
808
        }
809
810
        return $productAbstractTransfers;
811
    }
812
813
    /**
814
     * Result format:
815
     * [
816
     *     $idProduct => [LocalizedAttributesTransfer, ...],
817
     *     ...
818
     * ]
819
     *
820
     * @param array<int> $productIds
821
     *
822
     * @return array<int, array<int, \Generated\Shared\Transfer\LocalizedAttributesTransfer>>
823
     */
824
    public function getLocalizedAttributesGroupedByIdProduct(array $productIds): array
825
    {
826
        $productLocalizedAttributesCollection = $this->getFactory()->createProductLocalizedAttributesQuery()
827
            ->filterByFkProduct_In($productIds)
828
            ->joinWithLocale()
829
            ->find();
830
831
        $result = [];
832
833
        $localizedAttributesMapper = $this->getFactory()->createLocalizedAttributesMapper();
834
835
        /** @var \Orm\Zed\Product\Persistence\SpyProductLocalizedAttributes $productLocalizedAttributesEntity */
836
        foreach ($productLocalizedAttributesCollection as $productLocalizedAttributesEntity) {
837
            $result[$productLocalizedAttributesEntity->getFkProduct()][] = $localizedAttributesMapper->mapProductLocalizedAttributesEntityToTransfer(
838
                $productLocalizedAttributesEntity,
839
                new LocalizedAttributesTransfer(),
840
            );
841
        }
842
843
        return $result;
844
    }
845
846
    /**
847
     * @param int $productExportPublishChunkSize
848
     * @param int $lastProductId
849
     * @param int|null $idStore Deprecated: Will be removed without replacement.
850
     *
851
     * @return array<int>
852
     */
853
    public function getAllProductConcreteIdsWithLimit(
854
        int $productExportPublishChunkSize,
855
        int $lastProductId,
856
        ?int $idStore = null
857
    ): array {
858
        $productQuery = $this->getFactory()->createProductQuery()
859
            ->select(SpyProductTableMap::COL_ID_PRODUCT)
860
            ->where(SpyProductTableMap::COL_ID_PRODUCT . ' > ?', $lastProductId)
861
            ->limit($productExportPublishChunkSize)
862
            ->orderBy(SpyProductTableMap::COL_ID_PRODUCT);
863
864
        if ($idStore) {
865
            $productQuery->useSpyProductAbstractQuery()
866
                ->useSpyProductAbstractStoreQuery()
867
                    ->filterByFkStore($idStore)
868
                ->endUse()
869
            ->endUse();
870
        }
871
872
        /** @var \Propel\Runtime\Collection\ArrayCollection $products */
873
        $products = $productQuery->find();
874
875
        return $products->toArray();
876
    }
877
878
    /**
879
     * @param \Generated\Shared\Transfer\ProductAbstractCriteriaTransfer $productAbstractCriteriaTransfer
880
     *
881
     * @return \Generated\Shared\Transfer\ProductAbstractCollectionTransfer
882
     */
883
    public function getProductAbstractCollection(ProductAbstractCriteriaTransfer $productAbstractCriteriaTransfer): ProductAbstractCollectionTransfer
884
    {
885
        $productAbstractQuery = $this->getFactory()->createProductAbstractQuery();
886
887
        $productAbstractQuery = $this->applyProductAbstractCriteria($productAbstractCriteriaTransfer, $productAbstractQuery);
888
        $productAbstractQuery = $this->applyProductAbstractSortings($productAbstractCriteriaTransfer, $productAbstractQuery);
889
        $productAbstractQuery = $this->applyProductAbstractPagination($productAbstractCriteriaTransfer, $productAbstractQuery);
890
891
        $productAbstractCollectionTransfer = (new ProductAbstractCollectionTransfer())
892
            ->setPagination($productAbstractCriteriaTransfer->getPagination());
893
894
        $productAbstractCollection = $productAbstractQuery->find();
895
896
        return $this->getFactory()->createProductMapper()
897
            ->mapProductAbstractEntitiesToProductAbstractCollectionTransfer(
898
                $productAbstractCollection,
899
                $productAbstractCollectionTransfer,
900
            );
901
    }
902
903
    /**
904
     * @param array<int, int> $productAbstractIds
905
     *
906
     * @return array<int, \Generated\Shared\Transfer\StoreRelationTransfer>
907
     */
908
    public function getProductAbstractStoreRelations(array $productAbstractIds): array
909
    {
910
        $productAbstractStoreQuery = $this->getFactory()
911
            ->createProductAbstractStoreQuery();
912
        $productAbstractStoreEntities = $productAbstractStoreQuery
913
            ->filterByFkProductAbstract_In($productAbstractIds)
914
            ->leftJoinWithSpyStore()
915
            ->find();
916
917
        return $this->getFactory()
918
            ->createProductAbstractStoreMapper()
919
            ->mapProductAbstractStoreEntitiesToStoreRelationTransfers($productAbstractStoreEntities);
920
    }
921
922
    /**
923
     * @param array<int, int> $productAbstractIds
924
     *
925
     * @return array<int, array<\Generated\Shared\Transfer\LocalizedAttributesTransfer>>
926
     */
927
    public function getProductAbstractLocalizedAttributes(array $productAbstractIds): array
928
    {
929
        $productAbstractLocalizedAttributesEntities = $this->getFactory()->createProductAbstractLocalizedAttributesQuery()
930
            ->joinWithLocale()
931
            ->filterByFkProductAbstract_In($productAbstractIds)
932
            ->find();
933
934
        return $this->getFactory()->createLocalizedAttributesMapper()
935
            ->mapProductLocalizedAttributesEntitiesToLocalizedAttributesTransfers($productAbstractLocalizedAttributesEntities);
936
    }
937
938
    /**
939
     * @param \Generated\Shared\Transfer\ProductAbstractCriteriaTransfer $productAbstractCriteriaTransfer
940
     * @param \Orm\Zed\Product\Persistence\SpyProductAbstractQuery $productAbstractQuery
941
     *
942
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstractQuery
943
     */
944
    public function applyProductAbstractCriteria(
945
        ProductAbstractCriteriaTransfer $productAbstractCriteriaTransfer,
946
        SpyProductAbstractQuery $productAbstractQuery
947
    ): SpyProductAbstractQuery {
948
        if ($productAbstractCriteriaTransfer->getProductAbstractConditions()) {
949
            if ($productAbstractCriteriaTransfer->getProductAbstractConditions()->getSkus()) {
950
                $productAbstractQuery->filterBySku_In($productAbstractCriteriaTransfer->getProductAbstractConditions()->getSkus());
951
            }
952
            if ($productAbstractCriteriaTransfer->getProductAbstractConditions()->getIds()) {
953
                $productAbstractQuery->filterByIdProductAbstract_In($productAbstractCriteriaTransfer->getProductAbstractConditions()->getIds());
954
            }
955
        }
956
957
        return $productAbstractQuery;
958
    }
959
960
    /**
961
     * @param \Generated\Shared\Transfer\ProductAbstractCriteriaTransfer $productAbstractCriteriaTransfer
962
     * @param \Orm\Zed\Product\Persistence\SpyProductAbstractQuery $productAbstractQuery
963
     *
964
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstractQuery
965
     */
966
    public function applyProductAbstractSortings(
967
        ProductAbstractCriteriaTransfer $productAbstractCriteriaTransfer,
968
        SpyProductAbstractQuery $productAbstractQuery
969
    ): SpyProductAbstractQuery {
970
        foreach ($productAbstractCriteriaTransfer->getSortCollection() as $sortTransfer) {
971
            $productAbstractQuery->orderBy(
972
                $sortTransfer->getField(),
973
                $sortTransfer->getIsAscending() ? Criteria::ASC : Criteria::DESC,
974
            );
975
        }
976
977
        return $productAbstractQuery;
978
    }
979
980
    /**
981
     * @param \Generated\Shared\Transfer\ProductAbstractCriteriaTransfer $productAbstractCriteriaTransfer
982
     * @param \Orm\Zed\Product\Persistence\SpyProductAbstractQuery $productAbstractQuery
983
     *
984
     * @return \Orm\Zed\Product\Persistence\SpyProductAbstractQuery
985
     */
986
    public function applyProductAbstractPagination(
987
        ProductAbstractCriteriaTransfer $productAbstractCriteriaTransfer,
988
        SpyProductAbstractQuery $productAbstractQuery
989
    ): SpyProductAbstractQuery {
990
        if ($productAbstractCriteriaTransfer->getPagination()) {
991
            $productAbstractCriteriaTransfer->getPagination()->setNbResults($productAbstractQuery->count());
992
993
            $productAbstractQuery
994
                ->setLimit($productAbstractCriteriaTransfer->getPagination()->getLimit())
995
                ->setOffset($productAbstractCriteriaTransfer->getPagination()->getOffset());
996
        }
997
998
        return $productAbstractQuery;
999
    }
1000
1001
    /**
1002
     * @param \Generated\Shared\Transfer\ProductConcreteCriteriaTransfer $productConcreteCriteriaTransfer
1003
     *
1004
     * @return \Generated\Shared\Transfer\ProductConcreteCollectionTransfer
1005
     */
1006
    public function getProductConcreteCollection(
1007
        ProductConcreteCriteriaTransfer $productConcreteCriteriaTransfer
1008
    ): ProductConcreteCollectionTransfer {
1009
        $productConcreteCollectionTransfer = new ProductConcreteCollectionTransfer();
1010
1011
        $productConcreteQuery = $this->getFactory()->createProductQuery();
1012
        $productConcreteQuery = $this->applyProductConcreteFilters($productConcreteQuery, $productConcreteCriteriaTransfer);
1013
1014
        $paginationTransfer = $productConcreteCriteriaTransfer->getPagination();
1015
        if ($paginationTransfer !== null) {
1016
            /** @var \Orm\Zed\Product\Persistence\SpyProductQuery $productConcreteQuery */
1017
            $productConcreteQuery = $this->applyPaginationToQuery($productConcreteQuery, $paginationTransfer);
1018
            $productConcreteCollectionTransfer->setPagination($paginationTransfer);
1019
        }
1020
1021
        $productConcreteQuery = $this->expandProductConcreteQueryWithProductLocalizedAttributes($productConcreteQuery, $productConcreteCriteriaTransfer);
1022
        /** @var \Orm\Zed\Product\Persistence\SpyProductQuery $productConcreteQuery */
1023
        $productConcreteQuery = $this->applySortingToQuery(
1024
            $productConcreteQuery,
1025
            $productConcreteCriteriaTransfer->getSortCollection(),
1026
        );
1027
1028
        return $this->getFactory()
1029
            ->createProductMapper()
1030
            ->mapProductEntitiesToProductConcreteCollection(
1031
                $productConcreteQuery->find(),
1032
                $productConcreteCollectionTransfer,
1033
            );
1034
    }
1035
1036
    /**
1037
     * @param \Generated\Shared\Transfer\ProductAttributeKeyCriteriaTransfer $productAttributeKeyCriteriaTransfer
1038
     *
1039
     * @return \Generated\Shared\Transfer\ProductAttributeKeyCollectionTransfer
1040
     */
1041
    public function getProductAttributeKeyCollection(
1042
        ProductAttributeKeyCriteriaTransfer $productAttributeKeyCriteriaTransfer
1043
    ): ProductAttributeKeyCollectionTransfer {
1044
        $productAttributeKeyCollectionTransfer = new ProductAttributeKeyCollectionTransfer();
1045
1046
        $productAttributeKeyQuery = $this->getFactory()->createProductAttributeKeyQuery();
1047
        $productAttributeKeyQuery = $this->applyProductAttributeKeyFilters($productAttributeKeyQuery, $productAttributeKeyCriteriaTransfer);
1048
1049
        $paginationTransfer = $productAttributeKeyCriteriaTransfer->getPagination();
1050
        if ($paginationTransfer !== null) {
1051
            /** @var \Orm\Zed\Product\Persistence\SpyProductAttributeKeyQuery $productAttributeKeyQuery */
1052
            $productAttributeKeyQuery = $this->applyPaginationToQuery($productAttributeKeyQuery, $paginationTransfer);
1053
            $productAttributeKeyCollectionTransfer->setPagination($paginationTransfer);
1054
        }
1055
1056
        /** @var \Orm\Zed\Product\Persistence\SpyProductAttributeKeyQuery $productAttributeKeyQuery */
1057
        $productAttributeKeyQuery = $this->applySortingToQuery(
1058
            $productAttributeKeyQuery,
1059
            $productAttributeKeyCriteriaTransfer->getSortCollection(),
1060
        );
1061
1062
        return $this->getFactory()
1063
            ->createProductAttributeKeyMapper()
1064
            ->mapProductAttributeKeyEntitiesToProductAttributeKeyCollection(
1065
                $productAttributeKeyQuery->find(),
1066
                $productAttributeKeyCollectionTransfer,
1067
            );
1068
    }
1069
1070
    /**
1071
     * @param array<int> $productAbstractIds
1072
     * @param callable $indexGenerator
1073
     *
1074
     * @return array<string, \Generated\Shared\Transfer\UrlTransfer>
1075
     */
1076
    public function getUrlsByProductAbstractIds(array $productAbstractIds, callable $indexGenerator): array
1077
    {
1078
        $urlEntities = $this->getFactory()
1079
            ->createUrlQuery()
1080
            ->filterByFkResourceProductAbstract_In($productAbstractIds)
1081
            ->find();
1082
1083
        $indexedTransfers = [];
1084
1085
        foreach ($urlEntities as $urlEntity) {
1086
            $urlTransfer = (new UrlTransfer())->fromArray($urlEntity->toArray(), true);
1087
            /** @var string $index */
1088
            $index = $indexGenerator($urlTransfer->getFkResourceProductAbstract(), $urlTransfer->getFkLocale());
1089
            $indexedTransfers[$index] = $urlTransfer;
1090
        }
1091
1092
        return $indexedTransfers;
1093
    }
1094
1095
    /**
1096
     * @module Locale
1097
     *
1098
     * @param \Orm\Zed\Product\Persistence\SpyProductQuery $productConcreteQuery
1099
     * @param \Generated\Shared\Transfer\ProductConcreteCriteriaTransfer $productConcreteCriteriaTransfer
1100
     *
1101
     * @return \Orm\Zed\Product\Persistence\SpyProductQuery
1102
     */
1103
    protected function expandProductConcreteQueryWithProductLocalizedAttributes(
1104
        SpyProductQuery $productConcreteQuery,
1105
        ProductConcreteCriteriaTransfer $productConcreteCriteriaTransfer
1106
    ): SpyProductQuery {
1107
        if (!$productConcreteQuery->count()) {
1108
            return $productConcreteQuery;
1109
        }
1110
1111
        /** @var \Propel\Runtime\Collection\ArrayCollection $productConcreteIds */
1112
        $productConcreteIds = $productConcreteQuery
1113
            ->groupByIdProduct()
1114
            ->select([SpyProductTableMap::COL_ID_PRODUCT])
1115
            ->find();
1116
1117
        /** @var \Orm\Zed\Product\Persistence\SpyProductQuery $productConcreteQuery */
1118
        $productConcreteQuery = $this->getFactory()
1119
            ->createProductQuery()
1120
            ->filterByIdProduct_In($productConcreteIds->toArray())
1121
            ->joinWithSpyProductAbstract()
1122
            ->joinWithSpyProductLocalizedAttributes()
1123
            ->useSpyProductLocalizedAttributesQuery()
1124
                ->joinWithLocale()
1125
            ->endUse();
1126
1127
        $productConcreteConditionsTransfer = $productConcreteCriteriaTransfer->getProductConcreteConditions();
1128
1129
        if ($productConcreteConditionsTransfer && $productConcreteConditionsTransfer->getLocaleNames()) {
1130
            $productConcreteQuery = $productConcreteQuery
1131
                ->useSpyProductLocalizedAttributesQuery()
1132
                    ->useLocaleQuery()
1133
                        ->filterByLocaleName_In($productConcreteConditionsTransfer->getLocaleNames())
1134
                    ->endUse()
1135
                ->endUse();
1136
        }
1137
1138
        /** @phpstan-var \Orm\Zed\Product\Persistence\SpyProductQuery */
1139
        return $productConcreteQuery;
1140
    }
1141
1142
    /**
1143
     * @param \Orm\Zed\Product\Persistence\SpyProductQuery $productConcreteQuery
1144
     * @param \Generated\Shared\Transfer\ProductConcreteCriteriaTransfer $productConcreteCriteriaTransfer
1145
     *
1146
     * @return \Orm\Zed\Product\Persistence\SpyProductQuery
1147
     */
1148
    protected function applyProductConcreteFilters(
1149
        SpyProductQuery $productConcreteQuery,
1150
        ProductConcreteCriteriaTransfer $productConcreteCriteriaTransfer
1151
    ): SpyProductQuery {
1152
        $productConcreteConditionsTransfer = $productConcreteCriteriaTransfer->getProductConcreteConditions();
1153
        if ($productConcreteConditionsTransfer === null) {
1154
            return $productConcreteQuery;
1155
        }
1156
1157
        if ($productConcreteConditionsTransfer->getSkus()) {
1158
            $productConcreteQuery->filterBySku_In($productConcreteConditionsTransfer->getSkus());
1159
        }
1160
1161
        if ($productConcreteConditionsTransfer->getLocaleNames()) {
1162
            $productConcreteQuery = $this->filterProductConcretesByLocaleName(
1163
                $productConcreteQuery,
1164
                $productConcreteConditionsTransfer->getLocaleNames(),
1165
            );
1166
        }
1167
1168
        return $productConcreteQuery;
1169
    }
1170
1171
    /**
1172
     * @param \Propel\Runtime\ActiveQuery\ModelCriteria $query
1173
     * @param \Generated\Shared\Transfer\PaginationTransfer $paginationTransfer
1174
     *
1175
     * @return \Propel\Runtime\ActiveQuery\ModelCriteria
1176
     */
1177
    protected function applyPaginationToQuery(
1178
        ModelCriteria $query,
1179
        PaginationTransfer $paginationTransfer
1180
    ): ModelCriteria {
1181
        if ($paginationTransfer->getOffset() !== null && $paginationTransfer->getLimit() !== null) {
1182
            $paginationTransfer->setNbResults($query->count());
1183
1184
            $query->offset($paginationTransfer->getOffsetOrFail())
1185
                ->setLimit($paginationTransfer->getLimitOrFail());
1186
1187
            return $query;
1188
        }
1189
1190
        if ($paginationTransfer->getPage() !== null && $paginationTransfer->getMaxPerPage()) {
1191
            $paginationModel = $query->paginate(
1192
                $paginationTransfer->getPage(),
1193
                $paginationTransfer->getMaxPerPage(),
1194
            );
1195
1196
            $paginationTransfer->setNbResults($paginationModel->getNbResults())
1197
                ->setFirstIndex($paginationModel->getFirstIndex())
1198
                ->setLastIndex($paginationModel->getLastIndex())
1199
                ->setFirstPage($paginationModel->getFirstPage())
1200
                ->setLastPage($paginationModel->getLastPage())
1201
                ->setNextPage($paginationModel->getNextPage())
1202
                ->setPreviousPage($paginationModel->getPreviousPage());
1203
1204
            return $paginationModel->getQuery();
1205
        }
1206
1207
        return $query;
1208
    }
1209
1210
    /**
1211
     * @param \Propel\Runtime\ActiveQuery\ModelCriteria $query
1212
     * @param \ArrayObject<array-key, \Generated\Shared\Transfer\SortTransfer> $sortCollection
1213
     *
1214
     * @return \Propel\Runtime\ActiveQuery\ModelCriteria
1215
     */
1216
    protected function applySortingToQuery(
1217
        ModelCriteria $query,
1218
        ArrayObject $sortCollection
1219
    ): ModelCriteria {
1220
        foreach ($sortCollection as $sortTransfer) {
1221
            $query->orderBy(
1222
                $sortTransfer->getFieldOrFail(),
1223
                $sortTransfer->getIsAscending() ? Criteria::ASC : Criteria::DESC,
1224
            );
1225
        }
1226
1227
        return $query;
1228
    }
1229
1230
    /**
1231
     * @param \Orm\Zed\Product\Persistence\SpyProductAttributeKeyQuery $productAttributeKeyQuery
1232
     * @param \Generated\Shared\Transfer\ProductAttributeKeyCriteriaTransfer $productAttributeKeyCriteriaTransfer
1233
     *
1234
     * @return \Orm\Zed\Product\Persistence\SpyProductAttributeKeyQuery
1235
     */
1236
    protected function applyProductAttributeKeyFilters(
1237
        SpyProductAttributeKeyQuery $productAttributeKeyQuery,
1238
        ProductAttributeKeyCriteriaTransfer $productAttributeKeyCriteriaTransfer
1239
    ): SpyProductAttributeKeyQuery {
1240
        $productAttributeKeyConditionsTransfer = $productAttributeKeyCriteriaTransfer->getProductAttributeKeyConditions();
1241
        if ($productAttributeKeyConditionsTransfer === null) {
1242
            return $productAttributeKeyQuery;
1243
        }
1244
1245
        if ($productAttributeKeyConditionsTransfer->getKeys() !== []) {
1246
            $productAttributeKeyQuery->filterByKey_In($productAttributeKeyConditionsTransfer->getKeys());
1247
        }
1248
1249
        if ($productAttributeKeyConditionsTransfer->getIsSuper() !== null) {
1250
            $productAttributeKeyQuery->filterByIsSuper($productAttributeKeyConditionsTransfer->getIsSuperOrFail());
1251
        }
1252
1253
        return $productAttributeKeyQuery;
1254
    }
1255
1256
    /**
1257
     * Provided query can not contain group by, offset, or limit directives otherwise it will alter the results.
1258
     *
1259
     * @param \Orm\Zed\Product\Persistence\SpyProductQuery $productConcreteQuery
1260
     * @param list<string> $localeNames
1261
     *
1262
     * @return \Orm\Zed\Product\Persistence\SpyProductQuery
1263
     */
1264
    protected function filterProductConcretesByLocaleName(SpyProductQuery $productConcreteQuery, array $localeNames): SpyProductQuery
1265
    {
1266
        $localizedProductConcreteQuery = clone $productConcreteQuery;
1267
1268
        /** @var \Propel\Runtime\Collection\ArrayCollection $hiddenProductConcreteIds */
1269
        $hiddenProductConcreteIds = $localizedProductConcreteQuery
1270
            ->groupByIdProduct()
1271
            ->joinWithSpyProductLocalizedAttributes()
1272
            ->useSpyProductLocalizedAttributesQuery()
1273
                ->joinWithLocale()
1274
                ->useLocaleQuery()
1275
                    ->filterByLocaleName_In($localeNames)
1276
                ->endUse()
1277
            ->endUse()
1278
            ->select([SpyProductTableMap::COL_ID_PRODUCT])
1279
            ->find();
1280
1281
        if (!$hiddenProductConcreteIds->toArray()) {
1282
            return $productConcreteQuery->filterByIdProduct();
1283
        }
1284
1285
        return $productConcreteQuery->filterByIdProduct_In($hiddenProductConcreteIds->toArray());
1286
    }
1287
}
1288