Completed
Push — master ( 159a25...a86692 )
by Stefan
03:09
created

collectRelatedStreamsAssignments()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 8.7972
c 0
b 0
f 0
cc 4
eloc 10
nc 4
nop 1
1
<?php
2
/**
3
 * (c) shopware AG <[email protected]>
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 */
7
8
namespace ShopwarePlugins\Connect\Components\ProductStream;
9
10
use Shopware\CustomModels\Connect\ProductStreamAttribute;
11
use Shopware\Models\ProductStream\ProductStream;
12
use Shopware\CustomModels\Connect\ProductStreamAttributeRepository;
13
use ShopwarePlugins\Connect\Components\Config;
14
15
class ProductStreamService
16
{
17
    const DYNAMIC_STREAM = 1;
18
    const STATIC_STREAM = 2;
19
    const STATUS_EXPORT = 'export';
20
    const STATUS_DELETE = 'delete';
21
    const STATUS_ERROR = 'error';
22
    const STATUS_SYNCED = 'synced';
23
    const STATUS_PENDING = 'pending';
24
    const PRODUCT_LIMIT = 100;
25
26
    //Available statuses for exported stream
27
    const EXPORTED_STATUSES = [
28
        self::STATUS_EXPORT,
29
        self::STATUS_SYNCED,
30
        self::STATUS_ERROR,
31
    ];
32
33
    /**
34
     * @var ProductStreamRepository
35
     */
36
    private $productStreamRepository;
37
38
    /**
39
     * @var ProductStreamAttributeRepository
40
     */
41
    private $streamAttrRepository;
42
43
    /** @var Config */
44
    private $config;
45
46
    /**
47
     * @param ProductStreamRepository $productStreamRepository
48
     * @param ProductStreamAttributeRepository $streamAttrRepository
49
     * @param Config $config
50
     */
51
    public function __construct(
52
        ProductStreamRepository $productStreamRepository,
53
        ProductStreamAttributeRepository $streamAttrRepository,
54
        Config $config
55
    ) {
56
        $this->productStreamRepository = $productStreamRepository;
57
        $this->streamAttrRepository = $streamAttrRepository;
58
        $this->config = $config;
59
    }
60
61
    /**
62
     * @param $streamId
63
     * @param bool $appendCurrent
64
     * @return ProductStreamsAssignments
65
     */
66
    public function prepareStreamsAssignments($streamId, $appendCurrent = true)
67
    {
68
        $stream = $this->findStream($streamId);
69
70
        $articleIds = $this->getArticlesIds($stream);
71
72
        $assignment = $this->collectRelatedStreamsAssignments($articleIds);
73
74
        if ($appendCurrent) {
75
            //merge prev with current streams
76
            foreach ($articleIds as $articleId) {
77
                $assignment[$articleId][$stream->getId()] = $stream->getName();
78
            }
79
        }
80
81
        return new ProductStreamsAssignments(
82
            ['assignments' => $assignment]
83
        );
84
    }
85
86
    /**
87
     * @param $streamId
88
     * @throws \Exception
89
     * @return ProductStreamsAssignments
90
     */
91
    public function getStreamAssignments($streamId)
92
    {
93
        //checks stream existence
94
        $stream = $this->findStream($streamId);
95
96
        $articleIds = $this->getArticlesIds($stream);
97
98
        $assignment = $this->collectRelatedStreamsAssignments($articleIds);
99
100
        return new ProductStreamsAssignments(
101
            ['assignments' => $assignment]
102
        );
103
    }
104
105
    /**
106
     * @param ProductStream $stream
107
     * @return bool
108
     */
109
    public function isConnectStream(ProductStream $stream)
110
    {
111
        $attribute = $stream->getAttribute();
112
113
        if (!$attribute) {
114
            return false;
115
        }
116
117
        return (bool) $attribute->getConnectIsRemote();
118
    }
119
120
    /**
121
     * @param ProductStream $stream
122
     * @return bool
123
     */
124
    public function activateConnectProductsByStream(ProductStream $stream)
125
    {
126
        return $this->productStreamRepository->activateConnectProductsByStream($stream);
127
    }
128
129
    /**
130
     * @param $streamId
131
     * @return mixed
132
     */
133
    public function findStream($streamId)
134
    {
135
        return $this->productStreamRepository->findById($streamId);
136
    }
137
138
    /**
139
     * @param array $streamIds
140
     * @return \Shopware\Models\ProductStream\ProductStream[]
141
     */
142
    public function findStreams(array $streamIds)
143
    {
144
        return $this->productStreamRepository->findByIds($streamIds);
145
    }
146
147
    /**
148
     * Filter the stream ids, it will return only the exported ones
149
     *
150
     * @param array $streamIds
151
     * @return array
152
     */
153
    public function filterExportedStreams(array $streamIds)
154
    {
155
        return $this->productStreamRepository->filterExportedStreams($streamIds);
156
    }
157
158
    /**
159
     * @param array $articleIds
160
     * @return array
161
     */
162
    public function collectRelatedStreamsAssignments(array $articleIds)
163
    {
164
        $assignment = [];
165
166
        $collection = $this->productStreamRepository->fetchAllPreviousExportedStreams($articleIds);
167
168
        //prepare previous related streams
169
        foreach ($collection as $item) {
170
            //does not append the streams which were marked deleted
171
            if ($item['deleted'] == ProductStreamAttribute::STREAM_RELATION_DELETED) {
172
                if (!isset($assignment[$item['articleId']])) {
173
                    //adds empty array if there is no other stream for this product
174
                    $assignment[$item['articleId']] = [];
175
                }
176
177
                continue;
178
            }
179
180
            $assignment[$item['articleId']][$item['streamId']] = $item['name'];
181
        }
182
183
        return $assignment;
184
    }
185
186
    /**
187
     * @param ProductStreamsAssignments $assignments
188
     * @param $streamId
189
     * @param $articleId
190
     * @return bool
191
     */
192
    public function allowToRemove(ProductStreamsAssignments $assignments, $streamId, $articleId)
193
    {
194
        $streamAssignments = $assignments->getStreamsByArticleId($articleId);
195
196
        if (!$streamAssignments || !isset($streamAssignments[$streamId])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $streamAssignments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
197
            return false;
198
        }
199
200
        if (count($streamAssignments) > 1) {
201
            return false;
202
        }
203
204
        return true;
205
    }
206
207
    /**
208
     * @param ProductStream $stream
209
     * @return array
210
     */
211
    public function getArticlesIds(ProductStream $stream)
212
    {
213
        if ($this->isStatic($stream)) {
214
            return $this->productStreamRepository->fetchArticleIdsFromStaticStream($stream);
215
        }
216
217
        return $this->productStreamRepository->fetchArticleIdsFromDynamicStream($stream);
218
    }
219
220
    /**
221
     * @param ProductStream $productStream
222
     * @return bool
223
     */
224
    public function isStatic(ProductStream $productStream)
225
    {
226
        if ($productStream->getType() == self::STATIC_STREAM) {
227
            return true;
228
        }
229
230
        return false;
231
    }
232
233
    /**
234
     * @param null $start
235
     * @param null $limit
236
     * @return array
237
     */
238
    public function getList($start = null, $limit = null)
239
    {
240
        $streamList = $this->productStreamRepository->fetchStreamList($start, $limit);
241
242
        $isCronActive = $this->config->isCronActive();
243
244
        $streams = $streamList['streams'];
245
        foreach ($streams as $index => $stream) {
246
            if ($stream['type'] == self::STATIC_STREAM) {
247
                $streams[$index]['productCount'] = $this->countProductsInStaticStream($stream['id']);
248
            } elseif ($stream['type'] == self::DYNAMIC_STREAM) {
249
                $streams[$index]['enableRow'] = $isCronActive;
250
            }
251
        }
252
253
        return [
254
            'data' => $streams,
255
            'total' => $streamList['total']
256
        ];
257
    }
258
259
    /**
260
     * @param $type
261
     * @return array
262
     */
263
    public function getAllExportedStreams($type)
264
    {
265
        return $this->productStreamRepository->fetchExportedStreams($type);
266
    }
267
268
    /**
269
     * @param ProductStream $stream
270
     * @return ProductStreamAttribute
271
     */
272
    public function createStreamAttribute(ProductStream $stream)
273
    {
274
        $streamAttribute = $this->streamAttrRepository->findOneBy(['streamId' => $stream->getId()]);
275
276
        if (!$streamAttribute) {
277
            $streamAttribute = $this->streamAttrRepository->create();
278
            $streamAttribute->setStreamId($stream->getId());
279
        }
280
281
        return $streamAttribute;
282
    }
283
284
    /**
285
     * @param $streamId
286
     * @return string
287
     */
288
    public function countProductsInStaticStream($streamId)
289
    {
290
        return $this->productStreamRepository->countProductsInStaticStream($streamId);
291
    }
292
293
    /**
294
     * @param $streamId
295
     * @return bool
296
     */
297
    public function isStreamExported($streamId)
298
    {
299
        return $this->streamAttrRepository->isStreamExported($streamId);
300
    }
301
302
    /**
303
     * @param $streamId
304
     * @return \Doctrine\DBAL\Driver\Statement|int
305
     */
306
    public function markProductsToBeRemovedFromStream($streamId)
307
    {
308
        return $this->productStreamRepository->markProductsToBeRemovedFromStream($streamId);
309
    }
310
311
    /**
312
     * @param $streamId
313
     * @param array $articleIds
314
     * @return array
315
     */
316
    public function createStreamRelation($streamId, array $articleIds)
317
    {
318
        return $this->productStreamRepository->createStreamRelation($streamId, $articleIds);
319
    }
320
321
    /**
322
     * @return \Doctrine\DBAL\Driver\Statement|int
323
     */
324
    public function removeMarkedStreamRelations()
325
    {
326
        return $this->productStreamRepository->removeMarkedStreamRelations();
327
    }
328
329
    /**
330
     * @return array
331
     */
332
    public function getConnectStreamIds()
333
    {
334
        return $this->productStreamRepository->fetchConnectStreamIds();
335
    }
336
337
    /**
338
     * @param int $streamId
339
     * @param string $status
340
     * @param string $exportMessage
0 ignored issues
show
Documentation introduced by
Should the type for parameter $exportMessage not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
341
     */
342
    public function changeStatus($streamId, $status, $exportMessage = null)
343
    {
344
        $streamAttr = $this->streamAttrRepository->findOneBy(['streamId' => (int) $streamId]);
345
346
        if (!$streamAttr) {
347
            $streamAttr = $this->streamAttrRepository->create();
348
            $streamAttr->setStreamId($streamId);
349
        }
350
351
        $streamAttr->setExportStatus($status);
352
        if ($exportMessage !== null) {
353
            $streamAttr->setExportMessage($exportMessage);
354
        }
355
        $this->streamAttrRepository->save($streamAttr);
356
    }
357
358
    /**
359
     * @param $streamId
360
     * @param $message
361
     * @deprecated Use changeStatus instead. Will be removed in version 1.2.0
362
     */
363
    public function log($streamId, $message)
364
    {
365
        /** @var ProductStreamAttribute $streamAttr */
366
        $streamAttr = $this->streamAttrRepository->findOneBy(['streamId' => $streamId]);
367
        $streamAttr->setExportMessage($message);
368
369
        $this->streamAttrRepository->save($streamAttr);
370
    }
371
}
372