Issues (258)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Bootstrap/Setup.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Bootstrap;
9
10
use Shopware\Bundle\AttributeBundle\Service\CrudService;
11
use Shopware\Models\Attribute\Configuration;
12
use Shopware\Models\Customer\Group;
13
use Shopware\Components\Model\ModelManager;
14
use Enlight_Components_Db_Adapter_Pdo_Mysql as Pdo;
15
use ShopwarePlugins\Connect\Components\Config;
16
use Shopware\Models\Order\Status;
17
use ShopwarePlugins\Connect\Components\Utils\ConnectOrderUtil;
18
19
/**
20
 * The setup class does the basic setup of the shopware Connect plugin. All operations should be implemented in a way
21
 * that they can also be run on update of the plugin
22
 *
23
 * Class Setup
24
 * @package ShopwarePlugins\Connect\Bootstrap
25
 */
26
class Setup
27
{
28
    /**
29
     * @var \Shopware_Plugins_Backend_SwagConnect_Bootstrap
30
     */
31
    protected $bootstrap;
32
33
    /**
34
     * @var Pdo
35
     */
36
    protected $db;
37
38
    /**
39
     * @var ModelManager
40
     */
41
    protected $modelManager;
42
43
    private $menu;
44
45
    /**
46
     * Setup constructor.
47
     * @param \Shopware_Plugins_Backend_SwagConnect_Bootstrap $bootstrap
48
     * @param ModelManager $modelManager
49
     * @param Pdo $db
50
     * @param Menu
51
     */
52 View Code Duplication
    public function __construct(
0 ignored issues
show
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...
53
        \Shopware_Plugins_Backend_SwagConnect_Bootstrap $bootstrap,
54
        ModelManager $modelManager,
55
        Pdo $db,
56
        Menu $menu
57
58
    ) {
59
        $this->bootstrap = $bootstrap;
60
        $this->modelManager = $modelManager;
61
        $this->db = $db;
62
        $this->menu = $menu;
63
    }
64
65
    public function run($fullSetup)
66
    {
67
        $this->createMyEvents();
68
        $this->createMyTables();
69
        $this->createConfig();
70
        $this->createMyAttributes();
71
        $this->populateConfigTable();
72
        $this->importSnippets();
73
        $this->generateConnectPaymentAttribute();
74
        $this->populateDispatchAttributes();
75
        $this->populateConnectPaymentAttribute();
76
        $this->createConnectCustomerGroup();
77
78
        if ($fullSetup) {
79
            $this->createMyMenu();
80
            $this->populatePaymentStates();
81
            $this->populateOrderStates();
82
        }
83
    }
84
85
    private function createConfig()
86
    {
87
        $form = $this->bootstrap->Form();
88
89
        $form->setElement(
90
            'text',
91
            'connectDebugHost',
92
            [
93
                'label' => 'Shopware Connect Host',
94
                'required' => false,
95
                'value'    => Config::MARKETPLACE_URL
96
            ]
97
        );
98
    }
99
100
    /**
101
     * Creates the plugin menu item
102
     */
103
    private function createMyMenu()
104
    {
105
        $this->menu->create();
106
107
        $sql = "INSERT IGNORE INTO `s_core_snippets` (`namespace`, `shopID`, `localeID`, `name`, `value`, `created`, `updated`) VALUES
108
            ('backend/index/view/main', 1, 1, 'Connect', 'Connect', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
109
            ('backend/index/view/main', 1, 2, 'Connect', 'Connect', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
110
            ('backend/index/view/main', 1, 1, 'Connect/Export', 'Produkte zu Connect', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
111
            ('backend/index/view/main', 1, 2, 'Connect/Export', 'Export', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
112
            ('backend/index/view/main', 1, 1, 'Connect/Settings', 'Einstellungen', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
113
            ('backend/index/view/main', 1, 2, 'Connect/Settings', 'Settings', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
114
            ('backend/index/view/main', 1, 1, 'Connect/Register', 'Einrichtung', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
115
            ('backend/index/view/main', 1, 2, 'Connect/Register', 'Register', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
116
            ('backend/index/view/main', 1, 1, 'Connect/Import', 'Produkte von Connect', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
117
            ('backend/index/view/main', 1, 2, 'Connect/Import', 'Import', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
118
            ('backend/index/view/main', 1, 1, 'Connect/OpenConnect', 'Login', '2016-03-17 18:32:48', '2016-03-17 18:32:48'),
119
            ('backend/index/view/main', 1, 2, 'Connect/OpenConnect', 'Login', '2016-03-17 18:32:48', '2016-03-17 18:32:48')
120
121
            ON DUPLICATE KEY UPDATE
122
              `namespace` = VALUES(`namespace`),
123
              `shopID` = VALUES(`shopID`),
124
              `name` = VALUES(`name`),
125
              `localeID` = VALUES(`localeID`),
126
              `value` = VALUES(`value`)
127
              ;";
128
        $this->db->exec($sql);
129
    }
130
131
    /**
132
     * Registers the shopware Connect events. As we register all events on the fly, only the early
133
     * Enlight_Controller_Front_StartDispatch-Event is needed.
134
     */
135
    public function createMyEvents()
136
    {
137
        $this->bootstrap->subscribeEvent(
138
            'Enlight_Bootstrap_InitResource_ConnectSDK',
139
            'onInitResourceSDK'
140
        );
141
142
        $this->bootstrap->subscribeEvent(
143
          'Enlight_Controller_Action_PreDispatch',
144
          'registerTemplateDir'
145
        );
146
147
        $this->bootstrap->subscribeEvent(
148
            'Enlight_Controller_Front_DispatchLoopStartup',
149
            'onStartDispatch'
150
        );
151
152
        $this->bootstrap->subscribeEvent(
153
            'Shopware_Console_Add_Command',
154
            'onConsoleAddCommand'
155
        );
156
157
        $connectImportImages = $this->db->fetchOne(
158
            'SELECT id FROM s_crontab WHERE `action` LIKE :action',
159
            ['action' => '%ShopwareConnectImportImages']
160
        );
161
162
        if (!$connectImportImages) {
163
            $this->bootstrap->createCronJob(
164
                'SwagConnect Import images',
165
                'ShopwareConnectImportImages',
166
                60 * 30,
167
                false
168
            );
169
        }
170
171
        $connectUpdateProducts = $this->db->fetchOne(
172
            'SELECT id FROM s_crontab WHERE `action` LIKE :action',
173
            ['action' => '%ShopwareConnectUpdateProducts']
174
        );
175
176
        if (!$connectUpdateProducts) {
177
            $this->bootstrap->createCronJob(
178
                'SwagConnect Update Products',
179
                'ShopwareConnectUpdateProducts',
180
                60 * 2,
181
                false
182
            );
183
        }
184
185
        $connectExportDynamicStreams = $this->db->fetchOne(
186
            'SELECT id FROM s_crontab WHERE `action` LIKE :action',
187
            ['action' => '%ConnectExportDynamicStreams']
188
        );
189
190
        if (!$connectExportDynamicStreams) {
191
            $this->bootstrap->createCronJob(
192
                'SwagConnect Export Dynamic Streams',
193
                'Shopware_CronJob_ConnectExportDynamicStreams',
194
                12 * 3600, //12hours
195
                true
196
            );
197
        }
198
    }
199
200
    /**
201
     * Create necessary tables
202
     */
203
    private function createMyTables()
204
    {
205
        $queries = ['
206
            CREATE TABLE IF NOT EXISTS `sw_connect_change` (
207
              `c_entity_id` varchar(64) NOT NULL,
208
              `c_operation` char(8) NOT NULL,
209
              `c_revision` decimal(20,10) NOT NULL,
210
              `c_payload` longblob,
211
              `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
212
              UNIQUE KEY `c_revision` (`c_revision`),
213
              KEY `c_entity_id` (`c_entity_id`),
214
              INDEX `c_operation` (`c_operation`)
215
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', '
216
           CREATE TABLE IF NOT EXISTS `sw_connect_data` (
217
              `d_key` varchar(32) NOT NULL,
218
              `d_value` varchar(256) NOT NULL,
219
              `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
220
              PRIMARY KEY (`d_key`)
221
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', '
222
            CREATE TABLE IF NOT EXISTS `sw_connect_product` (
223
              `p_source_id` varchar(64) NOT NULL,
224
              `p_hash` varchar(64) NOT NULL,
225
              `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
226
              PRIMARY KEY (`p_source_id`)
227
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', '
228
            CREATE TABLE IF NOT EXISTS `sw_connect_reservations` (
229
              `r_id` varchar(32) NOT NULL,
230
              `r_state` varchar(12) NOT NULL,
231
              `r_order` longblob NOT NULL,
232
              `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
233
              PRIMARY KEY (`r_id`)
234
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', '
235
            CREATE TABLE IF NOT EXISTS `sw_connect_shop_config` (
236
              `s_shop` varchar(32) NOT NULL,
237
              `s_config` LONGBLOB NOT NULL,
238
              `changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
239
              PRIMARY KEY (`s_shop`)
240
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', '
241
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_config` (
242
              `id` int(11) NOT NULL AUTO_INCREMENT,
243
              `name` varchar(255) NOT NULL,
244
              `value` TEXT NOT NULL,
245
              `shopId` int(11) NULL,
246
              `groupName` varchar(255) NULL,
247
              PRIMARY KEY (`id`)
248
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', '
249
            CREATE TABLE IF NOT EXISTS `sw_connect_shipping_costs` (
250
              `sc_from_shop` VARCHAR(32) NOT NULL,
251
              `sc_to_shop` VARCHAR(32) NOT NULL,
252
              `sc_revision` VARCHAR(32) NOT NULL,
253
              `sc_shipping_costs` LONGBLOB NOT NULL,
254
              `sc_customer_costs` LONGBLOB NOT NULL,
255
              `changed` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
256
              PRIMARY KEY (`sc_from_shop`, `sc_to_shop`),
257
              INDEX (`sc_revision`)
258
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', '
259
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_log` (
260
              `id` int(11) NOT NULL AUTO_INCREMENT,
261
              `isError` int(1) NOT NULL,
262
              `service` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
263
              `command` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
264
              `request` text COLLATE utf8_unicode_ci DEFAULT NULL,
265
              `response` text COLLATE utf8_unicode_ci DEFAULT NULL,
266
              `time` datetime NOT NULL,
267
              PRIMARY KEY (`id`)
268
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', '
269
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_marketplace_attr` (
270
              `id` int(11) NOT NULL AUTO_INCREMENT,
271
              `marketplace_attribute` varchar(255) NOT NULL UNIQUE,
272
              `local_attribute` varchar(255) NOT NULL UNIQUE,
273
              PRIMARY KEY (`id`)
274
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;', "
275
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_items` (
276
             `id` int(11) NOT NULL AUTO_INCREMENT,
277
             `article_id` int(11) unsigned DEFAULT NULL,
278
             `article_detail_id` int(11) unsigned DEFAULT NULL,
279
             `shop_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
280
             `source_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
281
             `export_status` varchar(255) COLLATE utf8_unicode_ci,
282
             `export_message` text COLLATE utf8_unicode_ci,
283
             `exported` TINYINT(1) DEFAULT 0,
284
             `category` text COLLATE utf8_unicode_ci,
285
             `purchase_price` double DEFAULT NULL,
286
             `fixed_price` int(1) DEFAULT NULL,
287
             `free_delivery` int(1) DEFAULT NULL,
288
             `update_price` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'inherit',
289
             `update_image` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'inherit',
290
             `update_main_image` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'inherit',
291
             `update_long_description` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'inherit',
292
             `update_short_description` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'inherit',
293
             `update_additional_description` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'inherit',
294
             `update_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'inherit',
295
             `last_update` longtext COLLATE utf8_unicode_ci,
296
             `last_update_flag` int(11) DEFAULT NULL,
297
             `group_id` VARCHAR (64) NULL DEFAULT NULL,
298
             `is_main_variant` TINYINT(1) NULL DEFAULT NULL,
299
             `purchase_price_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
300
             `offer_valid_until` int(10) NOT NULL,
301
             `stream` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
302
             `cron_update` TINYINT(1) NULL DEFAULT NULL,
303
             `revision` decimal(20,10) DEFAULT NULL,
304
             PRIMARY KEY (`id`),
305
             UNIQUE KEY `article_detail_id` (`article_detail_id`),
306
             KEY `article_id` (`article_id`),
307
             CONSTRAINT s_plugin_connect_items_relations_fk_article_detail_id FOREIGN KEY (`article_detail_id`) REFERENCES s_articles_details (id) ON DELETE SET NULL,
308
             INDEX source_id (source_id, shop_id),
309
             INDEX group_id (group_id, shop_id),
310
             INDEX IDX_revision (revision),
311
             INDEX IDX_status (export_status)
312
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;", '
313
            CREATE TABLE IF NOT EXISTS `sw_connect_shipping_rules` (
314
             `sr_id` int(11) NOT NULL AUTO_INCREMENT,
315
             `sr_group_id` int(11) unsigned DEFAULT NULL,
316
             `sr_country` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
317
             `sr_delivery_days` int(5) DEFAULT NULL,
318
             `sr_price` double DEFAULT NULL,
319
             `sr_zip_prefix` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
320
             PRIMARY KEY (`sr_id`),
321
             KEY `sr_group_id` (`sr_group_id`)
322
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci','
323
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_categories` (
324
              `id` int(11) NOT NULL AUTO_INCREMENT,
325
              `category_key` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
326
              `label` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
327
              `local_category_id` int(11) DEFAULT NULL,
328
              `shop_id` int(11) NULL,
329
              PRIMARY KEY (`id`),
330
              INDEX (`category_key`),
331
              UNIQUE KEY `scuk_connect_category_for_shop_id` (`category_key`,`shop_id`)
332
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;', '
333
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_product_to_categories` (
334
              `id` int(11) NOT NULL AUTO_INCREMENT,
335
              `connect_category_id` int(11) NOT NULL,
336
              `articleID` int(11) NOT NULL,
337
              PRIMARY KEY (`id`),
338
              INDEX article_id (articleID),
339
              UNIQUE KEY `scuk_connect_category_id` (`connect_category_id`,`articleID`)
340
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;', '
341
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_streams` (
342
              `id` int(11) NOT NULL AUTO_INCREMENT,
343
              `stream_id` int(11) NOT NULL,
344
              `export_status` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
345
              `export_message` text COLLATE utf8_unicode_ci DEFAULT NULL,
346
              PRIMARY KEY (`id`)
347
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;',"
348
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_streams_relation` (
349
                `stream_id` int(11) unsigned NOT NULL,
350
                `article_id` int(11) unsigned NOT NULL,
351
                `deleted` int(1) NOT NULL DEFAULT '0',
352
                UNIQUE KEY `stream_id` (`stream_id`,`article_id`),
353
                CONSTRAINT s_plugin_connect_streams_selection_fk_stream_id FOREIGN KEY (stream_id) REFERENCES s_product_streams (id) ON DELETE CASCADE,
354
                CONSTRAINT s_plugin_connect_streams_selection_fk_article_id FOREIGN KEY (article_id) REFERENCES s_articles (id) ON DELETE CASCADE
355
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;", '
356
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_categories_to_local_categories` (
357
                `id` int(11) NOT NULL AUTO_INCREMENT,
358
                `remote_category_id` int(11) NOT NULL,
359
                `local_category_id` int(11) unsigned NOT NULL,
360
                `stream` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
361
                PRIMARY KEY (`id`),
362
                UNIQUE KEY `scuk_connect_category_to_local_category` (`remote_category_id`, `local_category_id`, `stream`),
363
                CONSTRAINT s_plugin_connect_remote_categories_fk_remote_category_id FOREIGN KEY (remote_category_id) REFERENCES s_plugin_connect_categories (id) ON DELETE CASCADE,
364
                CONSTRAINT s_plugin_connect_remote_categories_fk_local_category_id FOREIGN KEY (local_category_id) REFERENCES s_categories (id) ON DELETE CASCADE
365
            ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
366
            ', '
367
            CREATE TABLE IF NOT EXISTS `s_plugin_connect_article_relations` (
368
                `id` int(11) NOT NULL AUTO_INCREMENT,
369
                `article_id` int(11) unsigned NOT NULL,
370
                `shop_id` int(11) NOT NULL,
371
                `related_article_local_id` int(11) NOT NULL,
372
                `relationship_type` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
373
                PRIMARY KEY (`id`),
374
                UNIQUE KEY `relations` (`article_id`, `shop_id`, `related_article_local_id`, `relationship_type`),
375
                CONSTRAINT s_plugin_connect_article_relations_fk_article_id FOREIGN KEY (article_id) REFERENCES s_articles (id) ON DELETE CASCADE
376
            ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
377
            '];
378
379
        foreach ($queries as $query) {
380
            $this->db->exec($query);
381
        }
382
    }
383
384
    public function getCrudService()
385
    {
386
        return $this->bootstrap->Application()->Container()->get('shopware_attribute.crud_service');
387
    }
388
389
    /**
390
     * Creates product, order and category attributes
391
     */
392
    private function createMyAttributes()
393
    {
394
        /** @var CrudService $crudService */
395
        $crudService = $this->getCrudService();
396
397
        $crudService->update(
398
            's_order_attributes',
399
            'connect_shop_id',
400
            'integer'
401
        );
402
403
        $crudService->update(
404
            's_order_attributes',
405
            'connect_order_id',
406
            'integer'
407
        );
408
409
        $crudService->update(
410
            's_categories_attributes',
411
            'connect_import_mapping',
412
            'text'
413
        );
414
415
        $crudService->update(
416
            's_categories_attributes',
417
            'connect_export_mapping',
418
            'text'
419
        );
420
421
        $crudService->update(
422
            's_categories_attributes',
423
            'connect_imported',
424
            'text'
425
        );
426
427
        $crudService->update(
428
            's_media_attributes',
429
            'connect_hash',
430
            'string'
431
        );
432
433
        $crudService->update(
434
            's_premium_dispatch_attributes',
435
            'connect_allowed',
436
            'boolean',
437
            [],
438
            null,
439
            false,
440
            1
441
        );
442
443
        $crudService->update(
444
            's_articles_attributes',
445
            'connect_product_description',
446
            'html',
447
            [
448
                'translatable' => 1,
449
                'displayInBackend' => 1,
450
                'label' => 'Connect Beschreibung'
451
            ]
452
        );
453
454
        $crudService->update(
455
            's_articles_prices_attributes',
456
            'connect_price',
457
            'float',
458
            [],
459
            null,
460
            false,
461
            0
462
        );
463
464
        $crudService->update(
465
            's_core_customergroups_attributes',
466
            'connect_group',
467
            'boolean'
468
        );
469
470
        $crudService->update(
471
            's_articles_attributes',
472
            'connect_article_shipping',
473
            'text'
474
        );
475
476
        $crudService->update(
477
            's_articles_attributes',
478
            'connect_reference',
479
            'string'
480
        );
481
482
        $crudService->update(
483
            's_articles_attributes',
484
            'connect_property_group',
485
            'string'
486
        );
487
488
        $crudService->update(
489
            's_categories_attributes',
490
            'connect_imported_category',
491
            'boolean'
492
        );
493
494
        $crudService->update(
495
            's_articles_attributes',
496
            'connect_mapped_category',
497
            'boolean'
498
        );
499
500
        $crudService->update(
501
            's_articles_attributes',
502
            'connect_remote_unit',
503
            'string'
504
        );
505
506
        $crudService->update(
507
            's_articles_supplier_attributes',
508
            'connect_is_remote',
509
            'boolean',
510
            [],
511
            null,
512
            false,
513
            0
514
        );
515
516
        $crudService->update(
517
            's_articles_img_attributes',
518
            'connect_detail_mapping_id',
519
            'integer'
520
        );
521
522
        $crudService->update(
523
            's_filter_attributes',
524
            'connect_is_remote',
525
            'boolean',
526
            [],
527
            null,
528
            false,
529
            0
530
        );
531
532
        $crudService->update(
533
            's_filter_options_attributes',
534
            'connect_is_remote',
535
            'boolean',
536
            [],
537
            null,
538
            false,
539
            0
540
        );
541
542
        $crudService->update(
543
            's_filter_values_attributes',
544
            'connect_is_remote',
545
            'boolean',
546
            [],
547
            null,
548
            false,
549
            0
550
        );
551
552
        $crudService->update(
553
            's_product_streams_attributes',
554
            'connect_is_remote',
555
            'boolean',
556
            [],
557
            null,
558
            false,
559
            0
560
        );
561
562
        $this->modelManager->generateAttributeModels([
563
            's_articles_attributes',
564
            's_articles_supplier_attributes',
565
            's_order_attributes',
566
            's_core_customergroups_attributes',
567
            's_articles_prices_attributes',
568
            's_premium_dispatch_attributes',
569
            's_categories_attributes',
570
            's_order_details_attributes',
571
            's_order_basket_attributes',
572
            's_articles_img_attributes',
573
            's_media_attributes',
574
            's_filter_attributes',
575
            's_filter_options_attributes',
576
            's_filter_values_attributes',
577
            's_product_streams_attributes',
578
        ]);
579
    }
580
581
    /**
582
     * Creates the configuration table. Existing configs will not be overwritten
583
     */
584
    public function populateConfigTable()
585
    {
586
        $this->registerCustomModels();
587
588
        $this->bootstrap->registerMyLibrary();
589
        $configComponent = $this->bootstrap->getConfigComponents();
590
        // when add/remove item in $configs array
591
        // open ConnectConfigTest.php and change tearDown function
592
        // for some reason shopware runs test during plugin installation
593
        $configs = [
594
            'priceGroupForPriceExport' => ['', null, 'export'],
595
            'priceGroupForPurchasePriceExport' => ['', null, 'export'],
596
            'priceFieldForPriceExport' => ['', null, 'export'],
597
            'priceFieldForPurchasePriceExport' => ['', null, 'export'],
598
            'excludeInactiveProducts' => ['1', null, 'export'],
599
            'detailProductNoIndex' => ['1', null, 'general'],
600
            'detailShopInfo' => ['1', null, 'import'],
601
            'checkoutShopInfo' => ['1', null, 'import'],
602
            'longDescriptionField' => ['1', null, 'export'],
603
            'useTriggers' => ['0', null, 'export'],
604
            'importImagesOnFirstImport' => ['1', null, 'import'],
605
            'autoUpdateProducts' => ['1', null, 'export'],
606
            'overwriteProductName' => ['1', null, 'import'],
607
            'overwriteProductPrice' => ['1', null, 'import'],
608
            'overwriteProductImage' => ['1', null, 'import'],
609
            'overwriteProductMainImage' => ['1', null, 'import'],
610
            'overwriteProductShortDescription' => ['1', null, 'import'],
611
            'overwriteProductLongDescription' => ['1', null, 'import'],
612
            'overwriteProductAdditionalDescription' => ['1', null, 'import'],
613
            'logRequest' => ['1', null, 'general'],
614
            'showShippingCostsSeparately' => ['0', null, 'import'],
615
            'articleImagesLimitImport' => [5, null, 'import'],
616
            'updateOrderStatus' => ['0', null, 'import'],
617
            'removeBasketAdditions' => ['1', null, 'import'],
618
        ];
619
620
        foreach ($configs as $name => $values) {
621
            list($value, $shopId, $group) = $values;
622
623
            try {
624
                $configComponent->setConfig(
625
                    $name,
626
                    $configComponent->getConfig($name, $value, $shopId),
627
                    $shopId,
628
                    $group
629
                );
630
            } catch (\Exception $e) {
631
                // This may fail if the config table was not updated, yet.
632
                // The Updater will take care of this
633
            }
634
        }
635
    }
636
637
    /**
638
     * Import frontend snippets
639
     */
640
    public function importSnippets()
641
    {
642
        $sql = file_get_contents($this->bootstrap->Path() . 'Snippets/frontend.sql');
643
        $this->db->exec($sql);
644
    }
645
646
    /**
647
     * Creates a shopware Connect customer group - this can be used by the shop owner to manage the Connect product prices
648
     *
649
     * Logic is very simple here - if a group with the key 'SC' already exists, no new group is created
650
     */
651
    public function createConnectCustomerGroup()
652
    {
653
        $connectGroupAttributeId = $this->getConnectCustomerGroupId();
654
        if (!$this->connectCustomerGroupExists($connectGroupAttributeId)) {
655
656
            // Create Customer Group
657
            $this->db->insert(
658
                's_core_customergroups',
659
                [
660
                    'groupkey' => $this->getAvailableCustomerGroupName(),
661
                    'description' => 'SC export',
662
                    'tax' => 0,
663
                    'taxinput' => 0,
664
                    'mode' => 0
665
                ]
666
            );
667
668
            $customerGroupID = $this->db->fetchOne('SELECT MAX(id) FROM s_core_customergroups');
669
670
            // Create Customer Group Attributes
671
            $this->db->insert(
672
                's_core_customergroups_attributes',
673
                [
674
                  'customerGroupID' => $customerGroupID,
675
                  'connect_group' => 1
676
                ]
677
            );
678
        }
679
    }
680
681
    private function getConnectCustomerGroupId()
682
    {
683
        return $this->db->fetchOne(
684
            'SELECT customerGroupID
685
            FROM `s_core_customergroups_attributes`
686
            WHERE connect_group = 1'
687
        );
688
    }
689
690
    private function connectCustomerGroupExists($attributeId)
691
    {
692
        $result = $this->db->fetchOne(
693
            'SELECT COUNT(*)
694
            FROM `s_core_customergroups`
695
            WHERE id = :id',
696
            [
697
                'id' => $attributeId
698
            ]
699
        );
700
701
        return !empty($result);
702
    }
703
704
    /**
705
     * Return a free customer group name. It will only check 5 groups - if all are used, probably the detection
706
     * of existing connectCustomerGroups is broken. Throw an exception then
707
     *
708
     * @throws \RuntimeException
709
     * @return mixed
710
     */
711
    private function getAvailableCustomerGroupName()
712
    {
713
        $names = ['SC', 'SWC', 'SWCONN', 'SC-1'];
714
715
        $repo = $this->modelManager->getRepository('Shopware\Models\Customer\Group');
716
        foreach ($names as $name) {
717
            $model = $repo->findOneBy(['key' => $name]);
718
            if (is_null($model)) {
719
                return $name;
720
            }
721
        }
722
723
        throw new \RuntimeException(
724
            'Could not find a free group name for the Shopware Connect customer group.Probably you need to delete an existing customer group created by Shopware Connect (SC, SWC, SWCONN, SC-1). Make sure, you really don\'t need it any more!'
725
        );
726
    }
727
728
    public function registerCustomModels()
729
    {
730
        Shopware()->Loader()->registerNamespace(
731
            'Shopware\CustomModels',
732
            $this->bootstrap->Path() . 'Models/'
733
        );
734
        Shopware()->ModelAnnotations()->addPaths([
735
            $this->bootstrap->Path() . 'Models/'
736
        ]);
737
    }
738
739
    /**
740
     * Populates the dispatch attributes with entries for each dispatch type, so that
741
     * the connect attribute can be used
742
     */
743
    public function populateDispatchAttributes()
744
    {
745
        $this->db->exec(
746
            'INSERT IGNORE INTO `s_premium_dispatch_attributes` (`dispatchID`)
747
            SELECT `id` FROM `s_premium_dispatch`'
748
        );
749
    }
750
751
    /**
752
     * Generates connect payment attribute
753
     */
754
    public function generateConnectPaymentAttribute()
755
    {
756
        /** @var CrudService $crudService */
757
        $crudService = $this->getCrudService();
758
759
        $crudService->update(
760
            's_core_paymentmeans_attributes',
761
            'connect_is_allowed',
762
            'boolean',
763
            [],
764
            null,
765
            false,
766
            1
767
        );
768
769
        $this->modelManager->generateAttributeModels([
770
            's_core_paymentmeans_attributes'
771
        ]);
772
773
        $this->modelManager->regenerateProxies();
774
    }
775
776
    public function populateConnectPaymentAttribute()
777
    {
778
        $this->db->exec(
779
            'INSERT IGNORE INTO `s_core_paymentmeans_attributes` (`paymentmeanID`)
780
            SELECT `id` FROM `s_core_paymentmeans`'
781
        );
782
    }
783
784
    public function populatePaymentStates()
785
    {
786
        $states = [
787
            'sc_received' => ' SC received',
788
            'sc_requested' => 'SC requested',
789
            'sc_initiated' => 'SC initiated',
790
            'sc_instructed' => 'SC instructed',
791
            'sc_aborted' => 'SC aborted',
792
            'sc_timeout' => 'SC timeout',
793
            'sc_pending' => 'SC pending',
794
            'sc_refunded' => 'SC refunded',
795
            'sc_verify' => 'SC verify',
796
            'sc_loss' => 'SC loss',
797
            'sc_error' => 'SC error',
798
        ];
799
800
        $this->populateStates($states, Status::GROUP_PAYMENT);
801
    }
802
803
    public function populateOrderStates()
804
    {
805
        $states = [
806
            ConnectOrderUtil::ORDER_STATUS_ERROR => 'SC error'
807
        ];
808
809
        $this->populateStates($states, Status::GROUP_STATE);
810
    }
811
812
    public function populateStates(array $states, $group)
813
    {
814
        $currentId = $this->getMaxStateId();
815
816
        foreach ($states as $name => $description) {
817
            $isExists = $this->db->query(
818
                'SELECT `id` FROM `s_core_states`
819
                WHERE `name` = ? AND `group` = ?',
820
                [$name, $group]
821
            )->fetch();
822
823
            if ($isExists) {
824
                continue;
825
            }
826
827
            ++$currentId;
828
            $this->db->query(
829
                'INSERT INTO `s_core_states`
830
                (`id`, `name`, `description`, `position`, `group`, `mail`)
831
                VALUES (?, ?, ?, ?, ?, ?)',
832
                [$currentId, $name, $description, $currentId, $group, 0]
833
            );
834
        }
835
    }
836
837
    /**
838
     * @return int
839
     */
840
    private function getMaxStateId()
841
    {
842
        $query = $this->modelManager->getRepository('Shopware\Models\Order\Status')->createQueryBuilder('s');
843
        $query->select('MAX(s.id)');
844
        $result = $query->getQuery()->getOneOrNullResult();
845
846
        if (count($result) > 0) {
847
            return (int) reset($result);
848
        }
849
850
        return 0;
851
    }
852
}
853