Completed
Pull Request — master (#324)
by Simon
04:20
created

SubscriberRegistration::registerSubscribers()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 31
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 31
rs 8.5806
c 1
b 0
f 0
cc 4
eloc 16
nc 8
nop 1
1
<?php
2
3
namespace ShopwarePlugins\Connect\Bootstrap;
4
5
use Enlight_Components_Db_Adapter_Pdo_Mysql;
6
use Shopware\Components\Model\ModelManager;
7
use Shopware\Connect\Gateway\PDO;
8
use Shopware\Connect\SDK;
9
use ShopwarePlugins\Connect\Components\Config;
10
use ShopwarePlugins\Connect\Components\ConnectExport;
11
use ShopwarePlugins\Connect\Components\ConnectFactory;
12
use ShopwarePlugins\Connect\Components\ErrorHandler;
13
use ShopwarePlugins\Connect\Components\Helper;
14
use ShopwarePlugins\Connect\Components\Validator\ProductAttributesValidator\ProductsAttributesValidator;
15
use ShopwarePlugins\Connect\Subscribers\Checkout;
16
use ShopwarePlugins\Connect\Subscribers\Lifecycle;
17
18
class SubscriberRegistration
19
{
20
    /**
21
     * @var ModelManager
22
     */
23
    private $modelManager;
24
25
    /**
26
     * @var Config
27
     */
28
    private $config;
29
30
    /**
31
     * @var Enlight_Components_Db_Adapter_Pdo_Mysql
32
     */
33
    private $db;
34
35
    /**
36
     * @TODO: Subscribers should not depend on the Bootstrap class. If you see a possible solution refactor it please.
37
     *
38
     * @var \Shopware_Plugins_Backend_SwagConnect_Bootstrap
39
     */
40
    private $pluginBootstrap;
41
42
    /**
43
     * @var \Enlight_Event_EventManager
44
     */
45
    private $eventManager;
46
47
    /**
48
     * @var SDK
49
     */
50
    private $SDK;
51
52
    /**
53
     * @var ConnectFactory
54
     */
55
    private $connectFactory;
56
57
    /**
58
     * @var Helper
59
     */
60
    private $helper;
61
62
    /**
63
     * This property saves all product updates and will be inserted back later
64
     *
65
     * @var array
66
     */
67
    private $productUpdates = [];
68
69
    /**
70
     * @var Lifecycle
71
     */
72
    private $lifecycle;
73
74
    /**
75
     * @param Config $config
76
     * @param ModelManager $modelManager
77
     * @param Enlight_Components_Db_Adapter_Pdo_Mysql $db
78
     * @param \Shopware_Plugins_Backend_SwagConnect_Bootstrap $pluginBootstrap
79
     * @param \Enlight_Event_EventManager $eventManager
80
     * @param SDK $SDK
81
     * @param ConnectFactory $connectFactory
82
     * @param Helper $helper
83
     */
84 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...
Coding Style Naming introduced by
The parameter $SDK is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
85
        Config $config,
86
        ModelManager $modelManager,
87
        Enlight_Components_Db_Adapter_Pdo_Mysql $db,
88
        \Shopware_Plugins_Backend_SwagConnect_Bootstrap $pluginBootstrap,
89
        \Enlight_Event_EventManager $eventManager,
90
        SDK $SDK,
91
        ConnectFactory $connectFactory,
92
        Helper $helper
93
    ) {
94
        $this->config = $config;
95
        $this->modelManager = $modelManager;
96
        $this->db = $db;
97
        $this->pluginBootstrap = $pluginBootstrap;
98
        $this->eventManager = $eventManager;
99
        $this->SDK = $SDK;
100
        $this->connectFactory = $connectFactory;
101
        $this->helper = $helper;
102
    }
103
104
    /**
105
     * @param boolean $isShopware52
106
     */
107
    public function registerSubscribers($isShopware52)
108
    {
109
        try {
110
            $verified = $this->config->getConfig('apiKeyVerified', false);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $verified is correct as $this->config->getConfig('apiKeyVerified', false) (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...
111
        } catch (\Exception $e) {
112
            // if the config table is not available, just assume, that the update
113
            // still needs to be installed
114
            $verified = false;
115
        }
116
117
        $subscribers = $this->getDefaultSubscribers($isShopware52);
118
119
        // Some subscribers may only be used, if the SDK is verified
120
        if ($verified) {
121
            $subscribers = array_merge($subscribers, $this->getSubscribersForVerifiedKeys());
122
            // These subscribers are used if the api key is not valid
123
        } else {
124
            $subscribers = array_merge($subscribers, $this->getSubscribersForUnverifiedKeys());
125
        }
126
127
        /** @var $subscriber \ShopwarePlugins\Connect\Subscribers\BaseSubscriber */
128
        foreach ($subscribers as $subscriber) {
129
            $subscriber->setBootstrap($this->pluginBootstrap);
130
            $this->eventManager->registerSubscriber($subscriber);
131
        }
132
133
        $this->modelManager->getEventManager()->addEventListener(
134
            [\Doctrine\ORM\Events::onFlush, \Doctrine\ORM\Events::postFlush],
135
            $this
136
        );
137
    }
138
139
140
    /**
141
     * Default subscribers can safely be used, even if the api key wasn't verified, yet
142
     *
143
     * @param bool $isShopware52
144
     * @return array
145
     */
146
    private function getDefaultSubscribers($isShopware52)
147
    {
148
        return [
149
            new \ShopwarePlugins\Connect\Subscribers\OrderDocument(),
150
            new \ShopwarePlugins\Connect\Subscribers\ControllerPath($isShopware52),
151
            new \ShopwarePlugins\Connect\Subscribers\CustomerGroup(),
152
            new \ShopwarePlugins\Connect\Subscribers\CronJob(
153
                $this->SDK,
154
                $this->connectFactory->getConnectExport()
155
            ),
156
            new \ShopwarePlugins\Connect\Subscribers\ArticleList(),
157
            new \ShopwarePlugins\Connect\Subscribers\Article(
158
                new PDO($this->db->getConnection()),
159
                $this->modelManager,
160
                new ConnectExport(
161
                    $this->helper,
162
                    $this->SDK,
163
                    $this->modelManager,
164
                    new ProductsAttributesValidator(),
165
                    $this->config,
166
                    new ErrorHandler(),
167
                    $this->eventManager
168
                )
169
            ),
170
            new \ShopwarePlugins\Connect\Subscribers\Category(
171
                $this->modelManager
172
            ),
173
            new \ShopwarePlugins\Connect\Subscribers\Connect(),
174
            new \ShopwarePlugins\Connect\Subscribers\Payment(),
175
            new \ShopwarePlugins\Connect\Subscribers\ServiceContainer(
176
                $this->modelManager,
177
                $this->db,
178
                Shopware()->Container()
179
            ),
180
            new \ShopwarePlugins\Connect\Subscribers\Supplier(),
181
            new \ShopwarePlugins\Connect\Subscribers\ProductStreams(
182
                $this->connectFactory->getConnectExport(),
183
                new Config($this->modelManager),
184
                $this->connectFactory->getHelper()
185
            ),
186
            new \ShopwarePlugins\Connect\Subscribers\Property(
187
                $this->modelManager
188
            ),
189
            new \ShopwarePlugins\Connect\Subscribers\Search(
190
                $this->modelManager
191
            ),
192
        ];
193
    }
194
195
    private function getSubscribersForUnverifiedKeys()
196
    {
197
        return array(
198
            new \ShopwarePlugins\Connect\Subscribers\DisableConnectInFrontend(),
199
            $this->getLifecycleSubscriber()
200
        );
201
    }
202
203
204
    /**
205
     * These subscribers will only be used, once the user has verified his api key
206
     * This will prevent the users from having shopware Connect extensions in their frontend
207
     * even if they cannot use shopware Connect due to the missing / wrong api key
208
     *
209
     * @return array
210
     */
211
    private function getSubscribersForVerifiedKeys()
212
    {
213
        $subscribers = array(
214
            new \ShopwarePlugins\Connect\Subscribers\TemplateExtension(),
215
            $this->createCheckoutSubscriber(),
216
            new \ShopwarePlugins\Connect\Subscribers\Voucher(),
217
            new \ShopwarePlugins\Connect\Subscribers\BasketWidget(),
218
            new \ShopwarePlugins\Connect\Subscribers\Dispatches(),
219
            new \ShopwarePlugins\Connect\Subscribers\Javascript(),
220
            new \ShopwarePlugins\Connect\Subscribers\Less(),
221
            $this->getLifecycleSubscriber()
222
223
        );
224
225
        return $subscribers;
226
    }
227
228
229
    /**
230
     * Creates checkout subscriber
231
     *
232
     * @return Checkout
233
     */
234
    private function createCheckoutSubscriber()
235
    {
236
        $checkoutSubscriber = new Checkout(
237
            $this->modelManager,
238
            $this->eventManager
239
        );
240
        foreach ($checkoutSubscriber->getListeners() as $listener) {
241
            if ($listener->getName() === 'Enlight_Controller_Action_PostDispatch_Frontend_Checkout') {
242
                $listener->setPosition(-1);
243
            }
244
        }
245
246
        return $checkoutSubscriber;
247
    }
248
249
    /**
250
     * Generate changes for updated Articles and Details.
251
     * On postFlush all related entities are updated and product can
252
     * be fetched from DB correctly.
253
     *
254
     * @param \Doctrine\ORM\Event\PostFlushEventArgs $eventArgs
255
     */
256
    public function postFlush(\Doctrine\ORM\Event\PostFlushEventArgs $eventArgs)
0 ignored issues
show
Unused Code introduced by
The parameter $eventArgs is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
257
    {
258
        foreach ($this->productUpdates as $entity) {
259
            $this->getLifecycleSubscriber()->handleChange($entity);
260
        }
261
262
        $this->productUpdates = [];
263
    }
264
265
    /**
266
     * @return Lifecycle
267
     */
268
    private function getLifecycleSubscriber()
269
    {
270
        if (!$this->lifecycle) {
271
            $this->lifecycle = new Lifecycle(
272
                Shopware()->Models(),
273
                $this->config->getConfig('autoUpdateProducts', 1)
274
            );
275
        }
276
277
        return $this->lifecycle;
278
    }
279
280
281
    /**
282
     * Collect updated Articles and Details
283
     * Lifecycle events don't work correctly, because products will be fetched via query builder,
284
     * but related entities like price are not updated yet.
285
     *
286
     * @param \Doctrine\ORM\Event\OnFlushEventArgs $eventArgs
287
     */
288
    public function onFlush(\Doctrine\ORM\Event\OnFlushEventArgs $eventArgs)
289
    {
290
        /** @var $em ModelManager */
291
        $em  = $eventArgs->getEntityManager();
292
        $uow = $em->getUnitOfWork();
293
294
        // Entity updates
295
        foreach ($uow->getScheduledEntityUpdates() as $entity) {
296
            if (!$entity instanceof \Shopware\Models\Article\Article
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Article does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
297
                && !$entity instanceof \Shopware\Models\Article\Detail
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Detail does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
298
            ) {
299
                continue;
300
            }
301
302
            $this->productUpdates[] = $entity;
303
        }
304
    }
305
}