Passed
Branch development (62ef01)
by Theodoros
06:18
created

EcondaProductCollector   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 266
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 266
rs 10
c 0
b 0
f 0
wmc 21

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getPriceBySku() 0 3 1
A getDefaultImageSet() 0 7 3
A collectItem() 0 13 1
A getSmallPictureUrlFromDefaultImageSet() 0 9 2
A getProductCategoryMappings() 0 12 1
A getSmallImageUrl() 0 6 2
B generateProductConcreteImageSets() 0 27 3
A getImageUrlFromItemData() 0 8 1
A generateCategories() 0 16 3
A collectResourceType() 0 3 1
A __construct() 0 16 1
A collectData() 0 9 2
1
<?php
2
3
/**
4
 * MIT License
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerEco\Zed\Econda\Business\Collector\File;
9
10
use Generated\Shared\Transfer\LocaleTransfer;
11
use Generated\Shared\Transfer\StorageProductImageTransfer;
12
use Orm\Zed\Category\Persistence\Map\SpyCategoryTableMap;
13
use Propel\Runtime\ActiveQuery\Criteria;
14
use Propel\Runtime\Collection\Collection;
15
use Spryker\Shared\SqlCriteriaBuilder\CriteriaBuilder\CriteriaBuilderInterface;
16
use Spryker\Zed\ProductCategory\Persistence\ProductCategoryQueryContainerInterface;
17
use Spryker\Zed\ProductImage\Persistence\ProductImageQueryContainerInterface;
18
use SprykerEco\Zed\Econda\Business\Collector\AbstractDatabaseCollector;
19
use SprykerEco\Zed\Econda\Dependency\Facade\EcondaToPriceBridgeInterface;
20
use SprykerEco\Zed\Econda\EcondaConfig;
21
use SprykerEco\Zed\Econda\Persistence\Econda\AbstractPdoEcondaQuery;
22
23
class EcondaProductCollector extends AbstractDatabaseCollector
24
{
25
    // CSV File Columns
26
    const ID_COLUMN = 'ID';
27
    const NAME_COLUMN = 'Name';
28
    const DESCRIPTION_COLUMN = 'Description';
29
    const PRODUCTURL_COLUMN = 'ProductURL';
30
    const IMAGE_URL_COLUMN = 'ImageURL';
31
    const PRICE_COLUMN = 'Price';
32
    const STOCK_COLUMN = 'Stock';
33
    const PRODUCT_CATEGORY_COLUMN = 'ProductCategory';
34
35
    // Internal Query Fields
36
    const ID_PRODUCT_ABSTRACT = 'id_product_abstract';
37
    const SKU = 'sku';
38
    const URL = 'url';
39
    const NAME = 'name';
40
    const DESCRIPTION = 'description';
41
    const META_DESCRIPTION = 'meta_description';
42
    const QUANTITY = 'quantity';
43
    const ID_PRODUCT_CONCRETE = 'id_product';
44
    const DEFAULT_QUERY_FIELD = 'default';
45
    const EXTERNAL_URL_SMALL_QUERY_FIELD = 'externalUrlSmall';
46
47
    const RESOURCE_TYPE = 'products';
48
49
    /**
50
     * @var \SprykerEco\Zed\Econda\EcondaConfig
51
     */
52
    protected $config;
53
54
    /**
55
     * @var \Spryker\Zed\ProductCategory\Persistence\ProductCategoryQueryContainerInterface
56
     */
57
    protected $productCategoryQueryContainer;
58
59
    /**
60
     * @var \SprykerEco\Zed\Econda\Dependency\Facade\EcondaToPriceBridgeInterface
61
     */
62
    protected $priceFacade;
63
64
    /**
65
     * @var \Propel\Runtime\Collection\Collection
66
     */
67
    protected $categoryCacheCollection;
68
69
    /**
70
     * @var \Spryker\Zed\ProductImage\Persistence\ProductImageQueryContainerInterface
71
     */
72
    protected $productImageQueryContainer;
73
74
    /**
75
     * @param \Spryker\Shared\SqlCriteriaBuilder\CriteriaBuilder\CriteriaBuilderInterface $criteria
76
     * @param \SprykerEco\Zed\Econda\Persistence\Econda\AbstractPdoEcondaQuery $pdoEcondaQuery
77
     * @param \Spryker\Zed\ProductCategory\Persistence\ProductCategoryQueryContainerInterface $productCategoryQueryContainer
78
     * @param \Spryker\Zed\ProductImage\Persistence\ProductImageQueryContainerInterface $productImageQueryContainer
79
     * @param \SprykerEco\Zed\Econda\Dependency\Facade\EcondaToPriceBridgeInterface $priceFacade
80
     * @param \SprykerEco\Zed\Econda\EcondaConfig $config
81
     */
82
    public function __construct(
83
        CriteriaBuilderInterface $criteria,
84
        AbstractPdoEcondaQuery $pdoEcondaQuery,
85
        ProductCategoryQueryContainerInterface $productCategoryQueryContainer,
86
        ProductImageQueryContainerInterface $productImageQueryContainer,
87
        EcondaToPriceBridgeInterface $priceFacade,
88
        EcondaConfig $config
89
    ) {
90
91
        parent::__construct($criteria, $pdoEcondaQuery);
92
93
        $this->productCategoryQueryContainer = $productCategoryQueryContainer;
94
        $this->productImageQueryContainer = $productImageQueryContainer;
95
        $this->priceFacade = $priceFacade;
96
        $this->categoryCacheCollection = new Collection([]);
97
        $this->config = $config;
98
    }
99
100
    /**
101
     * @param array $collectedSet
102
     * @param \Generated\Shared\Transfer\LocaleTransfer $localeTransfer
103
     *
104
     * @return array
105
     */
106
    protected function collectData(array $collectedSet, LocaleTransfer $localeTransfer)
107
    {
108
        $setToExport = [];
109
110
        foreach ($collectedSet as $index => $collectedItemData) {
111
            $setToExport[] = $this->collectItem($collectedItemData);
112
        }
113
114
        return $setToExport;
115
    }
116
117
    /**
118
     * @param array $collectItemData
119
     *
120
     * @return array
121
     */
122
    protected function collectItem(array $collectItemData)
123
    {
124
        $imageUrl = $this->getImageUrlFromItemData($collectItemData);
125
126
        return [
127
            static::ID_COLUMN => $collectItemData[static::SKU],
128
            static::NAME_COLUMN => $collectItemData[static::NAME],
129
            static::DESCRIPTION_COLUMN => $collectItemData[static::META_DESCRIPTION],
130
            static::PRODUCTURL_COLUMN => $this->config->getHostYves() . $collectItemData[static::URL],
131
            static::IMAGE_URL_COLUMN => $imageUrl,
132
            static::PRICE_COLUMN => $this->getPriceBySku($collectItemData[static::SKU]),
133
            static::STOCK_COLUMN => (int)$collectItemData[static::QUANTITY],
134
            static::PRODUCT_CATEGORY_COLUMN => implode(EcondaConfig::ECONDA_CSV_CATEGORY_DELIMITER, $this->generateCategories($collectItemData[static::ID_PRODUCT_ABSTRACT])),
135
        ];
136
    }
137
138
    /**
139
     * @return string
140
     */
141
    protected function collectResourceType()
142
    {
143
        return static::RESOURCE_TYPE;
144
    }
145
146
    /**
147
     * @param string $sku
148
     *
149
     * @return float
150
     */
151
    protected function getPriceBySku($sku)
152
    {
153
        return $this->priceFacade->getPriceBySku($sku) / 100;
154
    }
155
156
    /**
157
     * @param int $idProductAbstract
158
     *
159
     * @return array
160
     */
161
    protected function generateCategories($idProductAbstract)
162
    {
163
        if ($this->categoryCacheCollection->offsetExists($idProductAbstract)) {
164
            return $this->categoryCacheCollection->get($idProductAbstract);
165
        }
166
167
        $productCategoryMappings = $this->getProductCategoryMappings($idProductAbstract);
168
169
        $categories = [];
170
        foreach ($productCategoryMappings as $mapping) {
171
            $categories[] = $mapping->getSpyCategory()->getIdCategory();
172
        }
173
174
        $this->categoryCacheCollection->set($idProductAbstract, $categories);
175
176
        return $categories;
177
    }
178
179
    /**
180
     * @param int $idProductAbstract
181
     *
182
     * @return \Orm\Zed\ProductCategory\Persistence\SpyProductCategory[]|\Propel\Runtime\Collection\ObjectCollection
183
     */
184
    protected function getProductCategoryMappings($idProductAbstract)
185
    {
186
        return $this->productCategoryQueryContainer
187
            ->queryLocalizedProductCategoryMappingByIdProduct($idProductAbstract)
188
            ->innerJoinSpyCategory()
189
            ->addAnd(
190
                SpyCategoryTableMap::COL_IS_ACTIVE,
191
                true,
192
                Criteria::EQUAL
193
            )
194
            ->orderByProductOrder()
195
            ->find();
196
    }
197
198
    /**
199
     * @param int $idProductAbstract
200
     * @param int $idProductConcrete
201
     *
202
     * @return array
203
     */
204
    protected function generateProductConcreteImageSets($idProductAbstract, $idProductConcrete)
205
    {
206
        $imageSets = $this->productImageQueryContainer
207
            ->queryProductImageSet()
208
            ->filterByFkProductAbstract($idProductAbstract)
209
            ->_or()
210
            ->filterByFkProduct($idProductConcrete)
211
            ->find();
212
213
        $result = [];
214
        foreach ($imageSets as $imageSetEntity) {
215
            $result[$imageSetEntity->getName()] = [];
216
            $productsToImages = $imageSetEntity->getSpyProductImageSetToProductImages(
217
                $this->productImageQueryContainer->queryProductImageSetToProductImage()
218
                    ->orderBySortOrder(Criteria::DESC)
219
            );
220
            foreach ($productsToImages as $productToImageEntity) {
221
                $imageEntity = $productToImageEntity->getSpyProductImage();
222
                $result[$imageSetEntity->getName()][] = [
223
                    StorageProductImageTransfer::ID_PRODUCT_IMAGE => $imageEntity->getIdProductImage(),
224
                    StorageProductImageTransfer::EXTERNAL_URL_LARGE => $imageEntity->getExternalUrlLarge(),
225
                    StorageProductImageTransfer::EXTERNAL_URL_SMALL => $imageEntity->getExternalUrlSmall(),
226
                ];
227
            }
228
        }
229
230
        return $result;
231
    }
232
233
    /**
234
     * @param array $collectItemData
235
     *
236
     * @return string
237
     */
238
    protected function getImageUrlFromItemData(array $collectItemData)
239
    {
240
        $imageSet = $this->generateProductConcreteImageSets(
241
            $collectItemData[static::ID_PRODUCT_ABSTRACT],
242
            $collectItemData[static::ID_PRODUCT_CONCRETE]
243
        );
244
245
        return $this->getSmallPictureUrlFromDefaultImageSet($imageSet);
246
    }
247
248
    /**
249
     * @param array $imageSet
250
     *
251
     * @return null|string
252
     */
253
    protected function getSmallPictureUrlFromDefaultImageSet($imageSet)
254
    {
255
        $defaultImageSet = $this->getDefaultImageSet($imageSet);
256
257
        if (is_array($defaultImageSet[0])) {
258
            return $this->getSmallImageUrl($defaultImageSet[0]);
259
        }
260
261
        return null;
262
    }
263
264
    /**
265
     * @param array $imageSet
266
     *
267
     * @return array
268
     */
269
    protected function getDefaultImageSet($imageSet)
270
    {
271
        if (array_key_exists(static::DEFAULT_QUERY_FIELD, $imageSet) && is_array($imageSet[static::DEFAULT_QUERY_FIELD])) {
272
            return $imageSet[static::DEFAULT_QUERY_FIELD];
273
        }
274
275
        return [];
276
    }
277
278
    /**
279
     * @param array $imageArray
280
     *
281
     * @return string
282
     */
283
    protected function getSmallImageUrl($imageArray)
284
    {
285
        if (array_key_exists(static::EXTERNAL_URL_SMALL_QUERY_FIELD, $imageArray)) {
286
            return $imageArray[static::EXTERNAL_URL_SMALL_QUERY_FIELD];
287
        }
288
        return '';
289
    }
290
}
291