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

CronJob::exportDynamicStreams()   B

Complexity

Conditions 7
Paths 35

Size

Total Lines 60
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 33
nc 35
nop 1
dl 0
loc 60
rs 7.4661
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Subscribers;
9
10
use Enlight\Event\SubscriberInterface;
11
use Shopware\Connect\SDK;
12
use Shopware\CustomModels\Connect\Attribute;
13
use Shopware\Models\ProductStream\ProductStream;
14
use ShopwarePlugins\Connect\Components\Config;
15
use ShopwarePlugins\Connect\Components\ErrorHandler;
16
use ShopwarePlugins\Connect\Components\Helper;
17
use ShopwarePlugins\Connect\Components\ImageImport;
18
use ShopwarePlugins\Connect\Components\Logger;
19
use ShopwarePlugins\Connect\Components\ConnectExport;
20
use ShopwarePlugins\Connect\Components\ProductStream\ProductSearch;
21
use ShopwarePlugins\Connect\Components\ProductStream\ProductStreamService;
22
use Shopware\Components\DependencyInjection\Container;
23
24
/**
25
 * Cronjob callback
26
 *
27
 * Class CronJob
28
 * @package ShopwarePlugins\Connect\Subscribers
29
 */
30
class CronJob implements SubscriberInterface
31
{
32
    /**
33
     * @var \ShopwarePlugins\Connect\Components\Config
34
     */
35
    private $configComponent;
36
37
    /**
38
     * @var SDK
39
     */
40
    protected $sdk;
41
42
    /**
43
     * @var ProductStreamService
44
     */
45
    protected $streamService;
46
47
    /**
48
     * @var ConnectExport
49
     */
50
    protected $connectExport;
51
52
    /**
53
     * @var Helper
54
     */
55
    private $helper;
56
57
    /**
58
     * @var ProductSearch
59
     */
60
    private $productSearch;
61
62
    /**
63
     * @var Container
64
     */
65
    private $container;
66
67
    /**
68
     * @var ProductStreamService
69
     */
70
    private $productStreamService;
71
72
    /**
73
     * @param SDK $sdk
74
     * @param ConnectExport $connectExport
75
     * @param Config $configComponent
76
     * @param Helper $helper
77
     * @param Container $container
78
     * @param ProductStreamService $productStreamService
79
     */
80 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
        SDK $sdk,
82
        ConnectExport $connectExport,
83
        Config $configComponent,
84
        Helper $helper,
85
        Container $container,
86
        ProductStreamService $productStreamService
87
    ) {
88
        $this->connectExport = $connectExport;
89
        $this->sdk = $sdk;
90
        $this->configComponent = $configComponent;
91
        $this->helper = $helper;
92
        $this->container = $container;
93
        $this->productStreamService = $productStreamService;
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public static function getSubscribedEvents()
100
    {
101
        return [
102
            'Shopware_CronJob_ShopwareConnectImportImages' => 'importImages',
103
            'Shopware_CronJob_ShopwareConnectUpdateProducts' => 'updateProducts',
104
            'Shopware_CronJob_ConnectExportDynamicStreams' => 'exportDynamicStreams',
105
        ];
106
    }
107
108
    /**
109
     * @return ImageImport
110
     */
111
    public function getImageImport()
112
    {
113
        // do not use thumbnail_manager as a dependency!!!
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
114
        // MediaService::__construct uses Shop entity
115
        // this also could break the session in backend when it's used in subscriber
116
        return new ImageImport(
117
            Shopware()->Models(),
118
            $this->helper,
119
            $this->container->get('thumbnail_manager'),
120
            new Logger(Shopware()->Db())
121
        );
122
    }
123
124
    /**
125
     * Import images of new products
126
     *
127
     * @param \Shopware_Components_Cron_CronJob $job
128
     * @return bool
129
     */
130
    public function importImages(\Shopware_Components_Cron_CronJob $job)
131
    {
132
        $limit = $this->configComponent->getConfig('articleImagesLimitImport', 10);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $limit is correct as $this->configComponent->...ImagesLimitImport', 10) (which targets ShopwarePlugins\Connect\...nts\Config::getConfig()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
133
        $this->getImageImport()->import($limit);
134
135
        return true;
136
    }
137
138
    /**
139
     * Collect all own products and send them
140
     * to Connect system.
141
     *
142
     * Used to update products with many variants.
143
     *
144
     * @param \Shopware_Components_Cron_CronJob $job
145
     * @return bool
146
     */
147
    public function updateProducts(\Shopware_Components_Cron_CronJob $job)
148
    {
149
        $sourceIds = Shopware()->Db()->fetchCol(
150
            'SELECT source_id FROM s_plugin_connect_items WHERE shop_id IS NULL AND cron_update = 1 LIMIT 100'
151
        );
152
153
        if (empty($sourceIds)) {
154
            return true;
155
        }
156
157
        $this->connectExport->export($sourceIds);
158
159
        $quotedSourceIds = Shopware()->Db()->quote($sourceIds);
160
        Shopware()->Db()->query("
161
            UPDATE s_plugin_connect_items
162
            SET cron_update = false
163
            WHERE source_id IN ($quotedSourceIds)"
164
        )->execute();
165
166
        return true;
167
    }
168
169
    /**
170
     * @param \Shopware_Components_Cron_CronJob $job
171
     */
172
    public function exportDynamicStreams(\Shopware_Components_Cron_CronJob $job)
173
    {
174
        $streams = $this->productStreamService->getAllExportedStreams(ProductStreamService::DYNAMIC_STREAM);
175
176
        /** @var ProductStream $stream */
177
        foreach ($streams as $stream) {
178
            $streamId = $stream->getId();
179
            $productSearchResult = $this->getProductSearch()->getProductFromConditionStream($stream);
180
            $orderNumbers = array_keys($productSearchResult->getProducts());
181
182
            //no products found
183
            if (!$orderNumbers) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $orderNumbers 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...
184
                //removes all products from this stream
185
                $this->productStreamService->markProductsToBeRemovedFromStream($streamId);
186
            } else {
187
                $articleIds = $this->helper->getArticleIdsByNumber($orderNumbers);
188
189
                $this->productStreamService->markProductsToBeRemovedFromStream($streamId);
190
                $this->productStreamService->createStreamRelation($streamId, $articleIds);
191
            }
192
193
            try {
194
                $streamsAssignments = $this->productStreamService->prepareStreamsAssignments($streamId, false);
195
196
                //article ids must be taken from streamsAssignments
197
                $exportArticleIds = $streamsAssignments->getArticleIds();
198
199
                $removeArticleIds = $streamsAssignments->getArticleIdsWithoutStreams();
200
201
                if (!empty($removeArticleIds)) {
202
                    $this->removeArticlesFromStream($removeArticleIds);
203
204
                    //filter the $exportArticleIds
205
                    $exportArticleIds = array_diff($exportArticleIds, $removeArticleIds);
206
                }
207
208
                $sourceIds = $this->helper->getArticleSourceIds($exportArticleIds);
209
210
                $errorMessages = $this->connectExport->export($sourceIds, $streamsAssignments);
211
                $this->productStreamService->changeStatus($streamId, ProductStreamService::STATUS_EXPORT);
212
            } catch (\RuntimeException $e) {
213
                $this->productStreamService->changeStatus($streamId, ProductStreamService::STATUS_ERROR, $e->getMessage());
214
                continue;
215
            }
216
217
            if ($errorMessages) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $errorMessages 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...
218
                $errorMessagesText = '';
219
                $displayedErrorTypes = [
220
                    ErrorHandler::TYPE_DEFAULT_ERROR,
221
                    ErrorHandler::TYPE_PRICE_ERROR
222
                ];
223
224
                foreach ($displayedErrorTypes as $displayedErrorType) {
225
                    $errorMessagesText .= implode('\n', $errorMessages[$displayedErrorType]);
226
                }
227
228
                $this->productStreamService->changeStatus($streamId, ProductStreamService::STATUS_ERROR, $errorMessagesText);
229
            }
230
        }
231
    }
232
233
    /**
234
     * If article is not taking part of any shopware stream it will be removed
235
     * @param array $articleIds
236
     */
237
    private function removeArticlesFromStream(array $articleIds)
238
    {
239
        $sourceIds = $this->helper->getArticleSourceIds($articleIds);
240
        $items = $this->connectExport->fetchConnectItems($sourceIds, false);
241
242
        foreach ($items as $item) {
243
            $this->sdk->recordDelete($item['sourceId']);
244
        }
245
246
        $this->productStreamService->removeMarkedStreamRelations();
247
        $this->connectExport->updateConnectItemsStatus($sourceIds, Attribute::STATUS_DELETE);
248
    }
249
250
    /**
251
     * @return ProductSearch
252
     */
253
    private function getProductSearch()
254
    {
255
        if (!$this->productSearch) {
256
            // HACK
257
            // do not use as a dependency!!!
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
258
            // this class uses Shopware product search which depends on shop context
259
            // so if it's used as dependency of subscriber, plugin returns error on deactivate
260
            // see CON-4922
261
            $this->productSearch = $this->container->get('swagconnect.product_search');
262
        }
263
264
        return $this->productSearch;
265
    }
266
}
267