Passed
Push — master ( ad9d2a...3a231c )
by Mario
02:53
created

Bootstrap::getOrderStatusById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Shopware
4
 * Copyright © 2015 shopware AG
5
 *
6
 * According to our dual licensing model, this program can be used either
7
 * under the terms of the GNU Affero General Public License, version 3,
8
 * or under a proprietary license.
9
 *
10
 * The texts of the GNU Affero General Public License with an additional
11
 * permission and of our proprietary license can be found at and
12
 * in the LICENSE file you have received along with this program.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * "Shopware" is a registered trademark of shopware AG.
20
 * The licensing of the program under the AGPLv3 does not imply a
21
 * trademark license. Therefore any rights, title and interest in
22
 * our trademarks remain entirely with us.
23
 */
24
25
use Doctrine\DBAL\Connection;
26
use Shopware\Components\StreetSplitService;
27
28
# Load dummy interface CSRFWhitelistAware for SW < 5.2
29
require_once __DIR__ . '/Components/CSRFWhitelistAware.php';
30
31
/**
32
 * Shopware Klarna Plugin
33
 */
34
class Shopware_Plugins_Frontend_SwagPaymentKlarna_Bootstrap extends Shopware_Components_Plugin_Bootstrap
35
{
36
    /**
37
     * Get cached countries
38
     * @var array
39
     */
40
    private $countries = array();
41
42
    /**
43
     * The klarna payment object.
44
     * @var \Shopware\Models\Payment\Payment
45
     */
46
    private $klarnaPayment = null;
47
    
48
    /**
49
     * Instance of API-Object
50
     * @var object
51
     */
52
    private $klarnaService = null;
53
54
    /**
55
     * Instance of klarna address object
56
     * @var object
57
     */
58
    private $klarnaAddr = null;
59
60
    /**
61
     * @return array
62
     */
63
    public function install($isUpdate = false)
64
    {
65
        $this->createMyEvents();
66
        if (!$isUpdate) {
67
            $this->createMyPayment();
68
        }
69
        $this->createMyForm();
70
        $this->createMyTranslations();
71
        $this->createMyAttributes();
72
73
        $aReturn = array(
74
            'success' => true,
75
            'invalidateCache' => array('backend')
76
        );
77
        
78
        return $aReturn;
79
    }
80
81
    /**
82
     * @param string $version
83
     * @return bool
84
     */
85
    public function update($version)
86
    {
87
        if ($version == '0.0.1') {
88
            return false;
89
        }
90
91
        if (version_compare($version, '2.0.0', '<')) {
92
            $em = $this->get('models');
93
            $form = $this->Form();
94
            if ($form->getElement('hideCheckoutSteps')) {
95
                $em->remove($form->getElement('hideCheckoutSteps'));
96
            }
97
            if ($form->getElement('expressButton')) {
98
                $em->remove($form->getElement('expressButton'));
99
            }
100
            if ($form->getElement('expressButtonLayer')) {
101
                $em->remove($form->getElement('expressButtonLayer'));
102
            }
103
            if ($form->getElement('noAccountCheckout')) {
104
                $em->remove($form->getElement('noAccountCheckout'));
105
            }
106
            $em->flush();
107
108
            $this->updatePayment();
109
        }
110
111
        return $this->install(true);
112
    }
113
114
    /**
115
     * @return bool
116
     */
117
    public function uninstall()
118
    {
119
        try {
120
            $this->get('models')->removeAttribute(
121
                's_order_attributes',
122
                'swag_klarna',
123
                'status'
124
            );
125
            $this->get('models')->removeAttribute(
126
                's_order_attributes',
127
                'swag_klarna',
128
                'invoice_number'
129
            );
130
            $this->get('models')->removeAttribute(
131
                's_order_details_attributes',
132
                'swag_klarna',
133
                'invoice_number'
134
            );
135
            $this->get('models')->generateAttributeModels(
136
                array(
137
                    's_order_attributes',
138
                    's_order_details_attributes'
139
                )
140
            );
141
        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
142
        }
143
144
        return true;
145
    }
146
147
    /**
148
     * @param string $name
149
     * @return mixed
150
     */
151
    public function get($name)
152
    {
153
        if (version_compare(Shopware::VERSION, '4.2.0', '<') && Shopware::VERSION != '___VERSION___') {
154
            $name = ucfirst($name);
155
            return $this->Application()->Bootstrap()->getResource($name);
156
        }
157
158
        return parent::get($name);
159
    }
160
161
    /**
162
     * Fetches and returns klarna payment row instance.
163
     *
164
     * @return \Shopware\Models\Payment\Payment
165
     */
166
    public function getPayment()
167
    {
168
        if ($this->klarnaPayment === null) {
169
            $this->klarnaPayment = $this->Payments()->findOneBy(
170
                array('name' => 'klarna_checkout')
171
            );
172
        }
173
174
        return $this->klarnaPayment;
175
    }
176
177
    /**
178
     * @return \Klarna_Checkout_Connector
179
     */
180
    public function getConnector()
181
    {
182
        return $this->Application()->KlarnaCheckoutConnector();
183
    }
184
185
    /**
186
     * @return \Klarna
187
     */
188
    public function getService()
189
    {
190
        /** @var Klarna $service */
191
        $service = $this->Application()->KlarnaService();
192
        $service->setActivateInfo('flags', KlarnaFlags::RSRV_SEND_BY_EMAIL);
193
        $service->setVersion($this->buildKlarnaVersion($service));
194
        $service->config(
195
            $this->Config()->get('merchantId'),
196
            $this->Config()->get('sharedSecret'),
197
            KlarnaCountry::DE,
198
            KlarnaLanguage::DE,
199
            KlarnaCurrency::EUR,
200
            $this->Config()->get('testDrive') ? Klarna::BETA : Klarna::LIVE,
201
            'pdo',
202
            array(
0 ignored issues
show
Documentation introduced by
array('table' => 's_klar...>Db()->getConnection()) is of type array<string,?,{"table":"string","pdo":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
203
                'table' => 's_klarna_pclasses',
204
                'pdo' => $this->Application()->Db()->getConnection()
205
            )
206
        );
207
208
        return $service;
209
    }
210
211
    /**
212
     * Activate the plugin klarna plugin.
213
     * Sets the active flag in the payment row.
214
     *
215
     * @return bool
216
     */
217
    public function enable()
218
    {
219
        $payment = $this->getPayment();
220
        if ($payment !== null) {
221
            $payment->setActive(true);
222
            $this->get('models')->flush($payment);
223
        }
224
225
        return array(
226
            'success' => true,
227
            'invalidateCache' => array('backend', 'frontend')
228
        );
229
    }
230
231
    /**
232
     * Disable plugin method and sets the active flag in the payment row
233
     *
234
     * @return bool
235
     */
236
    public function disable()
237
    {
238
        $payment = $this->getPayment();
239
        if ($payment !== null) {
240
            $payment->setActive(false);
241
            $this->get('models')->flush($payment);
242
        }
243
244
        return true;
245
    }
246
    
247
    /**
248
     * Returns an instance of klarna object
249
     * 
250
     * @param void
251
     * @return \Klarna
252
     */
253
    public function getKLarnaService() {
254
        if ($this->klarnaService === null) {
255
            require_once __DIR__ . '/Components/Klarna/Klarna.php';
256
            require_once __DIR__ . '/Components/Klarna/transport/xmlrpc-3.0.0.beta/lib/xmlrpc.inc';
257
            $this->klarnaService = new Klarna();
258
        }
259
260
        return $this->klarnaService;
261
    }
262
    
263
    /**
264
     * Returns an instance of klarna address object
265
     * 
266
     * @param void
267
     * @return object
268
     */
269
    public function getKlarnaAddr() {
270
        if ($this->klarnaAddr === null) {
271
            $this->klarnaAddr = new KlarnaAddr();
272
        }
273
        
274
        return $this->klarnaAddr;
275
    }
276
277
    /**
278
     * Creates and subscribe the events and hooks.
279
     */
280
    protected function createMyEvents()
281
    {
282
        // BACKEND
283
        $this->subscribeEvent(
284
            'Enlight_Controller_Action_PostDispatch_Backend_Order',
285
            'onLoadOrderBackendModule'
286
        );
287
        $this->subscribeEvent(
288
            'Enlight_Controller_Action_PostDispatch_Backend_Payment',
289
            'onLoadPaymentBackendModule'
290
        );
291
292
        $this->subscribeEvent(
293
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_PaymentKlarna',
294
            'onGetControllerPathBackend'
295
        );
296
297
        // FRONTEND
298
        $this->subscribeEvent(
299
            'Enlight_Controller_Dispatcher_ControllerPath_Frontend_PaymentKlarna',
300
            'onGetControllerPathFrontend'
301
        );
302
303
        $this->subscribeEvent(
304
            'Enlight_Controller_Action_PostDispatch_Frontend_Checkout',
305
            'onPostDispatchCheckout'
306
        );
307
308
        $this->subscribeEvent(
309
            'Enlight_Controller_Action_PreDispatch_Frontend_Checkout',
310
            'onPreDispatchCheckout'
311
        );
312
313
        $this->subscribeEvent(
314
            'Enlight_Controller_Action_Frontend_Checkout_Express',
315
            'onCheckoutExpress'
316
        );
317
318
        $this->subscribeEvent(
319
            'Enlight_Controller_Action_Frontend_Checkout_saveShippingKlarna',
320
            'onCheckoutSaveShippingKlarna'
321
        );
322
323
        $this->subscribeEvent(
324
            'Enlight_Controller_Action_PostDispatch',
325
            'onPostDispatch',
326
            110
327
        );
328
329
        // CONNECTOR
330
        $this->subscribeEvent(
331
            'Enlight_Bootstrap_InitResource_KlarnaCheckoutConnector',
332
            'onInitResourceKlarnaCheckoutConnector'
333
        );
334
335
        // SERVICES
336
        $this->subscribeEvent(
337
            'Enlight_Bootstrap_InitResource_KlarnaService',
338
            'onInitResourceKlarnaService'
339
        );
340
341
        $this->subscribeEvent(
342
            'Enlight_Bootstrap_InitResource_StreetSplitService',
343
            'onGetStreetSplitService'
344
        );
345
346
        $this->subscribeEvent(
347
            'Enlight_Controller_Action_PostDispatch_Frontend_Register',
348
            'onPostDispatchFrontendRegister'
349
        );
350
351
        $this->subscribeEvent(
352
            'Enlight_Controller_Action_PreDispatch_Frontend_Account',
353
            'onPreDispatchAccount'
354
        );
355
356
        $this->subscribeEvent(
357
            'Enlight_Controller_Action_PostDispatch_Frontend_Account',
358
            'onPostDispatchAccount'
359
        );
360
        $this->subscribeEvent(
361
            'Enlight_Controller_Action_PostDispatch_Frontend_Checkout',
362
            'onPostDispatchAccount'
363
        );
364
365
        $this->subscribeEvent(
366
            'Shopware\Models\Customer\Repository::getListQueryBuilder::after',
367
            'onAfterGetCustomerListQueryBuilder'
368
        );
369
370
        $this->subscribeEvent(
371
            'Theme_Compiler_Collect_Plugin_Javascript',
372
            'addJsFiles'
373
        );
374
375
        // LESS
376
        // Subscribe the needed event for less merge and compression
377
        $this->subscribeEvent(
378
            'Theme_Compiler_Collect_Plugin_Less',
379
            'addLessFiles'
380
        );
381
382
        #########
383
        # HOOKS   #
384
        #########
385
386
        if (version_compare(Shopware::VERSION, '5.2.0', '>=')) {
387
            $this->subscribeEvent(
388
                'sAdmin::saveRegisterAction::before',
389
                'onBeforeRegister'
390
            );
391
        }
392
        else {
393
            $this->subscribeEvent(
394
                'sAdmin::sSaveRegister::before',
395
                'onBeforeRegister'
396
            );
397
        }
398
399
        $this->subscribeEvent(
400
            'Shopware_Controllers_Backend_Payment::updatePaymentsAction::before',
401
            'onBeforeUpdatePayment'
402
        );
403
        
404
        $this->subscribeEvent(
405
            'Shopware_Controllers_Backend_Order::saveAction::after',
406
            'onBackendOrderSaveAfter'
407
        );    
408
        $this->subscribeEvent(
409
            'Shopware_Controllers_Backend_Order::deleteAction::after',
410
            'onBackendOrderDeleteAfter'
411
        );          
412
        
413
    }
414
415
    /**
416
     * Method will be triggered on clicking save on order details
417
     * 
418
     * @param Enlight_Hook_HookArgs $args
419
     * @return void
420
     */
421
    public function onBackendOrderSaveAfter(Enlight_Hook_HookArgs $args) {
422
        $orderDataRaw = $args->getSubject()->Request()->getPost();
423
        $orderId = $orderDataRaw['id'];
424
        $paymentName = $orderDataRaw['payment'][0]['name'];
425
        $orderStatus = $this->getOrderStatusById($orderId);
426
427
        $validUpdateDataToKlarna = (
428
            $orderStatus != 'activate' &&
429
            (
430
                $paymentName == 'klarna_checkout' ||
431
                $paymentName == 'klarna_account' ||
432
                $paymentName == 'klarna_invoice'
433
            )
434
        );
435
436
        if ($validUpdateDataToKlarna) {
437
            // require_once __DIR__ . '/Models/lightConnector.php';
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
438
            
439
            $klarnaService = $this->getService();
440
            
441
            $klarnaAddrBilling = $this->getKlarnaAddrByRawOrderData($orderDataRaw,'billing');
442
            $klarnaAddrShipping = $this->getKlarnaAddrByRawOrderData($orderDataRaw,'shipping');
443
            
444
            $transactionId = $orderDataRaw['transactionId'];
445
            $klarnaOrderId = $orderDataRaw['temporaryId'];
0 ignored issues
show
Unused Code introduced by
$klarnaOrderId is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
446
            
447
            $klarnaService->setAddress(KlarnaFlags::IS_BILLING, $klarnaAddrBilling);
0 ignored issues
show
Security Bug introduced by
It seems like $klarnaAddrBilling defined by $this->getKlarnaAddrByRa...rderDataRaw, 'billing') on line 441 can also be of type false; however, Klarna::setAddress() does only seem to accept object<KlarnaAddr>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
448
            $klarnaService->setAddress(KlarnaFlags::IS_SHIPPING, $klarnaAddrShipping);
0 ignored issues
show
Security Bug introduced by
It seems like $klarnaAddrShipping defined by $this->getKlarnaAddrByRa...derDataRaw, 'shipping') on line 442 can also be of type false; however, Klarna::setAddress() does only seem to accept object<KlarnaAddr>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
449
            try {
450
                $klarnaService->update($transactionId);
451
            } catch (Exception $e) {
452
                throw new Exception($e->getMessage());
453
            }
454
        }
455
    }
456
457
    /**
458
     * @param $orderId
459
     * @return string
460
     */
461
    protected function getOrderStatusById($orderId)
462
    {
463
        $klarnaOrderStatus = Shopware()->Db()->fetchOne('SELECT swag_klarna_status FROM s_order_attributes WHERE orderID = ?', [$orderId]);
464
465
        return $klarnaOrderStatus;
466
    }
467
468
    
469
    /**
470
     * Method will be triggered on clicking delete on order overview
471
     * 
472
     * @param Enlight_Hook_HookArgs $args
473
     * @return void
474
     */
475
    public function onBackendOrderDeleteAfter(Enlight_Hook_HookArgs $args) {
476
        $orderDataRaw = $args->getSubject()->Request()->getPost();
477
        $paymentName = $orderDataRaw['payment'][0]['name'];
478
        
479
        if ($paymentName == 'klarna_checkout') {
480
            
481
            $klarnaService = $this->getService();
482
            $transactionId = $orderDataRaw['transactionId'];
483
            try {
484
                $klarnaService->cancelReservation($transactionId);
485
            } catch (Exception $e) {
486
                throw new Exception($e->getMessage());
487
            }
488
        }
489
    }    
490
    
491
    
492
    /**
493
     * Hook to change the absolute media-path to a normalized virtual path.
494
     * @param Enlight_Hook_HookArgs $args
495
     */
496
    public function onBeforeUpdatePayment(Enlight_Hook_HookArgs $args)
497
    {
498
        if (!$this->assertMinimumVersion('5.1')) {
499
            return;
500
        }
501
502
        /** @var Zend_Controller_Request_Http $request */
503
        $request = $args->getSubject()->Request();
504
        $attributes = $request->getParam('attribute');
505
        $attribute = reset($attributes);
506
507
        if (empty($attribute['swagKlarnaKlarnaMedia'])) {
508
            return;
509
        }
510
511
        $mediaService = $this->get('shopware_media.media_service');
512
        $attribute['swagKlarnaKlarnaMedia'] = $mediaService->normalize($attribute['swagKlarnaKlarnaMedia']);
513
        $attributes[0] = $attribute;
514
        $request->setParam('attribute', $attributes);
515
    }
516
517
    /**
518
     * Needed to implement an additional "where"-condition to filter temporary klarna-customers, so they won't be shown
519
     * in the backend anymore.
520
     *
521
     * @param Enlight_Hook_HookArgs $args
522
     */
523
    public function onAfterGetCustomerListQueryBuilder(Enlight_Hook_HookArgs $args)
524
    {
525
        /** @var \Doctrine\DBAL\Query\QueryBuilder $builder */
526
        $builder = $args->getReturn();
527
528
        $builder->andWhere('billing.lastName != :lastName')->setParameter('lastName', 'Klarna Checkout');
529
530
        $args->setReturn($builder);
531
    }
532
533
    /**
534
     * Sets the default-payment to klarna checkout.
535
     */
536
    public function onBeforeRegister()
537
    {
538
        $register = $this->Application()->Session()->offsetGet('sRegister');
539
        if ($register["payment"]["object"]["id"] === $this->getPayment()->getId()) {
540
            unset($register["payment"]["object"]["id"]);
541
        }
542
    }
543
544
    /**
545
     * Only used in emotion-template.
546
     * Logs out the user when entering the
547
     * @param Enlight_Event_EventArgs $args
548
     */
549
    public function onPreDispatchAccount(Enlight_Event_EventArgs $args)
550
    {
551
        /** @var Shopware_Controllers_Frontend_Account $subject */
552
        $subject = $args->getSubject();
553
        $request = $subject->Request();
554
555
        if ($this->isKlarnaUser() && !$this->isTemplateResponsive() && $request->getActionName() != 'savePayment') {
556
            $subject->logoutAction();
557
        }
558
    }
559
560
    /**
561
     * Needed to delete temporary accounts, when the user changes the payment.
562
     *
563
     * @param Enlight_Controller_ActionEventArgs $args
564
     */
565
    public function onPostDispatchAccount(Enlight_Controller_ActionEventArgs $args)
566
    {
567
        $request = $args->getRequest();
568
        $response = $args->getResponse();
569 View Code Duplication
        if (!$this->isKlarnaUser() || !$request->isDispatched() || $response->isException() || $request->getActionName() == 'confirm') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
570
            return;
571
        }
572
        $session = Shopware()->Session();
573
        //Logout user
574
        $session->offsetUnset('sUserId');
575
        $session->offsetSet('sRegisterFinished', false);
576
        //Remove all temporary klarna-users older than 24 hours
577
        $this->removeKlarnaUsers();
578
    }
579
580
    public function onGetStreetSplitService()
581
    {
582
        $this->Application()->Loader()->registerNamespace(
583
            'Shopware\Components',
584
            __DIR__ . '/Components/'
585
        );
586
587
        return new StreetSplitService();
588
    }
589
    
590
    /**
591
     * Logs a message
592
     * 
593
     * @param string $message
594
     * @param int $logLevelMessage
595
     * @param mixed $mPrintableElement
596
     * @return void
597
     */
598 View Code Duplication
    public function klarnaLog($message, $logLevelMessage=1, $mPrintableElement=null) {
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...
599
        $configname = 'klarnaLogLevel';
600
        $elementId = Shopware()->Db()->fetchOne('SELECT id FROM s_core_config_elements WHERE name = ?', [$configname]);
601
        $logLevelConfigSetting = Shopware()->Db()->fetchOne('SELECT value FROM s_core_config_values WHERE element_id = ?', [$elementId]);
602
        $logLevelConfigSetting = unserialize($logLevelConfigSetting);
603
        $logLevelSetting = (is_numeric($logLevelConfigSetting) && $logLevelConfigSetting >=0 && $logLevelConfigSetting <=4) ? (int)$logLevelConfigSetting : 1;
604
        
605
        if ($logLevelMessage <= $logLevelSetting) {
606
            $prefix = "[".date('Y-m-d H:i:s')."] ";
607
            $debugBacktrace = '';
608
            if ($logLevelSetting >= 4) {
609
                $debugBacktrace = print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),true);
610
            }
611
            $sPrintableElementMessage = '';
612
            if ($mPrintableElement !== null) {
613
                $sPrintableElementMessage = print_r($mPrintableElement,true);
614
            }
615
            $fullMessage = $prefix.$message."\n".$sPrintableElementMessage.$debugBacktrace;
616
            $shopPath = Shopware()->DocPath();
617
            $logfilePath = $shopPath.'/var/log/klarnaTrace.log';
618
            $fileHandler = fopen($logfilePath,'a');
619
            fwrite($fileHandler, $fullMessage);
620
            fclose($fileHandler);
621
        }
622
    }
623
    
624
    /**
625
     * Method returns matching address parts by address type
626
     * 
627
     * @param array $orderDataRaw
628
     * @param string $type
629
     */
630
    protected function getKlarnaAddrByRawOrderData($orderDataRaw, $type) {
631
        $klarnaAddr = false;
632
        $baseData = (isset($orderDataRaw[$type][0])) ? $orderDataRaw[$type][0] : false;
633
        $baseData = $this->convertEncoding($baseData);
634
        
635
        if ($baseData) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $baseData 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...
636
            $addressParts = $this->fetchStreetAndHouseNumber($baseData);
637
638
            $manager = $this->get('models');
639
            $repository = 'Shopware\Models\Country\Country';
640
            $repository = $manager->getRepository($repository);
641
            $country = $repository->findOneBy(array('id' => $baseData['countryId']));
642
            $countryiso = $country->getIso();
643
644
            $klarnaAddr =  new KlarnaAddr();
645
            $klarnaAddr->setEmail($orderDataRaw['customerEmail']);
646
            $klarnaAddr->setFirstName($baseData['firstName']);
647
            $klarnaAddr->setLastName($baseData['lastName']);
648
            $klarnaAddr->setTelno($baseData['phone']);
649
            $klarnaAddr->setStreet($addressParts['street']);
650
            $klarnaAddr->setHouseNumber($addressParts['streetnr']);
651
            $klarnaAddr->setHouseExt($addressParts['streetnr_extension']);
652
            $klarnaAddr->setCompanyName($baseData['company']);
653
            $klarnaAddr->setCareof($baseData['department']);
654
            $klarnaAddr->setZipCode($baseData['zipCode']);
655
            $klarnaAddr->setCity($baseData['city']);
656
            $klarnaAddr->setCountry($countryiso);
657
        }
658
659
        $this->klarnaLog('Update order address from backend with following address data:',3,$klarnaAddr);
660
        return $klarnaAddr;
661
    }
662
663
664
    /**
665
     * Method splits street, streetnr and streetnr extension from basestring
666
     *
667
     * @param array $baseData
668
     * @return array
669
     */
670
    protected function fetchStreetAndHouseNumber($baseData) {
671
672
        $addressParts = explode(' ', $baseData['street']);
673
        $index = 0;
674
        $street = $streetnr = '';
675
        $houseNumberFound = false;
676
677
        foreach ($addressParts as $addressPart) {
678
            if (!$houseNumberFound) {
679
                // check if current addresspart is numeric
680
                $houseNumberFound = is_numeric($addressPart);
681
            }
682
683
            $index++;
684
            if ($index == count($addressParts) || $houseNumberFound) {
685
                // at least last element should be streetnr
686
                if (!empty($streetnr)) $streetnr .= ' ';
687
                $streetnr .= (string)$addressPart;
688
            }
689
            else  {
690
                $street .= (string)' '.$addressPart;
691
            }
692
        }
693
694
        $streetnr_extension = '';
695
        if (!empty($baseData['additionalAddressLine1'])) {
696
            $streetnr_extension .= $baseData['additionalAddressLine1'];
697
        }
698
        if (!empty($baseData['additionalAddressLine2'])) {
699
            $streetnr_extension .= "\n".$baseData['additionalAddressLine2'];
700
        }
701
702
        $return = array(
703
            'street' => $street,
704
            'streetnr' => $streetnr,
705
            'streetnr_extension' => $streetnr_extension,
706
        );
707
708
        return $return;
709
    }
710
    
711
712
    /**
713
     * Converts encoding in all string fields of an array
714
     * 
715
     * @param array $data
716
     * @return array
717
     */
718
    protected function convertEncoding($data) {
719
        $out = array();
720
        foreach ($data as $key=>$value) {
721
            if (is_string($value)) {
722
                $value = mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8');
723
                // $value = utf8_decode($value);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
724
            }
725
            
726
            $out[$key] = $value;
727
        }
728
        
729
        return $out;
730
    }
731
732
    /**
733
     * Creates and save the payment row.
734
     */
735
    protected function createMyPayment()
736
    {
737
        /** @var \Shopware\Components\Model\ModelManager $manager */
738
        $manager = $this->get('models');
739
        $repository = 'Shopware\Models\Country\Country';
740
        $repository = $manager->getRepository($repository);
741
        $countries = array(
742
            $repository->findOneBy(array('iso' => 'SE')),
743
            $repository->findOneBy(array('iso' => 'DE')),
744
            $repository->findOneBy(array('iso' => 'NO')),
745
            $repository->findOneBy(array('iso' => 'FI')),
746
            $repository->findOneBy(array('iso' => 'AT'))
747
        );
748
        $this->createPayment(
749
            array(
750
                'name' => 'klarna_checkout',
751
                'description' => $this->getLabel(),
752
                'action' => 'payment_klarna',
753
                'additionalDescription' => '',
754
                'countries' => $countries
755
            )
756
        );
757
    }
758
759
    /**
760
     * Creates and stores the payment config form.
761
     */
762
    protected function createMyForm()
763
    {
764
        $form = $this->Form();
765
766
        // API settings
767
        $form->setElement(
768
            'boolean',
769
            'testDrive',
770
            array(
771
                'label' => 'Testmodus aktvieren',
772
                'value' => false,
773
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
774
                'position' => 0
775
            )
776
        );
777
778
        $form->setElement(
779
            'text',
780
            'merchantId',
781
            array(
782
                'label' => 'API-HändlerID (EID)',
783
                'required' => true,
784
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
785
                'position' => 1
786
            )
787
        );
788
789
        $form->setElement(
790
            'text',
791
            'sharedSecret',
792
            array(
793
                'label' => 'API-Secret (sharedsecret)',
794
                'required' => true,
795
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
796
                'position' => 2
797
            )
798
        );
799
800
        $form->setElement(
801
            'number',
802
            'termSiteId',
803
            array(
804
                'label' => 'Shopseite mit den Geschäftsbedingungen',
805
                'value' => 4,
806
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
807
                'position' => 3
808
            )
809
        );
810
811
        $form->setElement(
812
            'boolean',
813
            'allowSeparateShippingAddress',
814
            array(
815
                'label' => 'Abweichende Lieferadresse erlauben',
816
                'value' => true,
817
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
818
                'position' => 4
819
            )
820
        );
821
822
        $form->setElement(
823
            'boolean',
824
            'supportPackstation',
825
            array(
826
                'label' => 'DHL Packstation unterstützen',
827
                'value' => false,
828
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
829
                'position' => 5,
830
                'helpText' => 'Die abweichende Lieferadresse muss erlaubt sein'
831
            )
832
        );
833
834
        $form->setElement(
835
            'text',
836
            'postnumberField',
837
            array(
838
                'label' => 'Alternatives Feld für die DHL-Postnummer',
839
                'value' => 'attribute1',
840
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
841
                'position' => 6
842
            )
843
        );
844
845
        $form->setElement(
846
            'boolean',
847
            'mandatoryPhone',
848
            array(
849
                'label' => 'Telefonummer als Pflichtfeld',
850
                'value' => false,
851
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
852
                'position' => 7
853
            )
854
        );
855
856
        $form->setElement(
857
            'boolean',
858
            'mandatoryBirthday',
859
            array(
860
                'label' => 'Geburtsdatum als Pflichtfeld',
861
                'value' => false,
862
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
863
                'position' => 8
864
            )
865
        );
866
867
        $form->setElement(
868
            'boolean',
869
            'disableAutofocus',
870
            array(
871
                'label' => 'Autofokus deaktivieren',
872
                'value' => false,
873
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
874
                'position' => 9
875
            )
876
        );
877
878
        $form->setElement(
879
            'boolean',
880
            'showKlarnaButton',
881
            array(
882
                'label' => 'Klarna Checkout-Button anzeigen',
883
                'value' => true,
884
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
885
                'position' => 10
886
            )
887
        );
888
889
        $form->setElement(
890
            'boolean',
891
            'preFillCheckout',
892
            array(
893
                'label' => 'Klarna Checkout für registrierte Kunden vorausfüllen',
894
                'value' => true,
895
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
896
                'position' => 11
897
            )
898
        );
899
900
        $form->setElement(
901
            'color',
902
            'checkoutButtonColor',
903
            array(
904
                'label' => 'Checkout Button Farbe',
905
                'value' => null,
906
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
907
                'position' => 12
908
            )
909
        );
910
911
        $form->setElement(
912
            'color',
913
            'checkoutButtonTextColor',
914
            array(
915
                'label' => 'Checkout Buttontext Farbe',
916
                'value' => null,
917
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
918
                'position' => 13
919
            )
920
        );
921
922
        $form->setElement(
923
            'color',
924
            'checkoutCheckboxColor',
925
            array(
926
                'label' => 'Checkout Checkbox Farbe',
927
                'value' => null,
928
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
929
                'position' => 14
930
            )
931
        );
932
933
        $form->setElement(
934
            'color',
935
            'checkoutCheckboxCheckmarkColor',
936
            array(
937
                'label' => 'Checkout Checkbox Häckchen Farbe',
938
                'value' => null,
939
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
940
                'position' => 15
941
            )
942
        );
943
944
        $form->setElement(
945
            'color',
946
            'checkoutHeaderColor',
947
            array(
948
                'label' => 'Checkout Header Farbe',
949
                'value' => null,
950
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
951
                'position' => 16
952
            )
953
        );
954
955
        $form->setElement(
956
            'color',
957
            'checkoutLinkColor',
958
            array(
959
                'label' => 'Checkout Link Farbe',
960
                'value' => null,
961
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
962
                'position' => 17
963
            )
964
        );
965
966
        $form->setElement(
967
            'boolean',
968
            'KlarnaExternalPayments',
969
            array(
970
                'label' => 'Externe Zahlungsarten im Klarna Checkout darstellen',
971
                'value' => null,
972
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
973
                'helpText' => 'Ihr Klarna-Konto muss für diese Funktion freigeschaltet werden',
974
                'position' => 18
975
            )
976
        );
977
978
        $form->setElement(
979
            'select',
980
            'displayType',
981
            array(
982
                'label' => 'Klarna Checkout Darstellungs-Art',
983
                'value' => 1,
984
                'store' => array(
985
                    array(1, 'Tab-Darstellung'),
986
                    array(2, 'Nur Klarna Checkout-Darstellung'),
987
                    array(3, 'Einseiten-Darstellung')
988
                ),
989
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
990
                'position' => 19
991
            )
992
        );
993
994
        $form->setElement(
995
            'boolean',
996
            'showB2bSelect',
997
            array(
998
                'label' => 'B2B-Auswahl anzeigen',
999
                'value' => true,
1000
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1001
                'helpText' => 'In dem Klarna Checkout wird eine Auswahl "Privatkunde / Firma" angezeigt',
1002
                'position' => 20
1003
            )
1004
        );
1005
1006
        $form->setElement(
1007
            'boolean',
1008
            'showLoginPanel',
1009
            array(
1010
                'label' => 'Login-Formular anzeigen',
1011
                'value' => true,
1012
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1013
                'helpText' => 'In dem Klarna Checkout wird ein Login-Formular angezeigt',
1014
                'position' => 21
1015
            )
1016
        );
1017
1018
        $form->setElement(
1019
            'boolean',
1020
            'showMiniBasket',
1021
            array(
1022
                'label' => 'Warenkorb anzeigen',
1023
                'value' => true,
1024
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1025
                'helpText' => 'In dem Klarna Checkout wird eine kleine Übersicht des Warenkorbs angezeigt',
1026
                'position' => 22
1027
            )
1028
        );
1029
1030
        $form->setElement(
1031
            'boolean',
1032
            'showDispatch',
1033
            array(
1034
                'label' => 'Lieferland & Versandarten anzeigen',
1035
                'value' => true,
1036
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1037
                'helpText' => 'In dem Klarna Checkout wird eine Lieferland- sowie Versandarten-Auswahl angezeigt',
1038
                'position' => 23
1039
            )
1040
        );
1041
1042
        $form->setElement(
1043
            'select',
1044
            'positionOrder',
1045
            array(
1046
                'label' => 'Reihenfolge der Elemente',
1047
                'value' => 1,
1048
                'store' => array(
1049
                    array(1, 'Login-Formular, Mini-Warenkorb, Versandauswahl, Zahlungsauswahl'),
1050
                    array(2, 'Login-Formular, Mini-Warenkorb, Zahlungsauswahl, Versandauswahl'),
1051
                    array(3, 'Versandauswahl, Zahlungsauswahl, Login-Formular, Mini-Warenkorb'),
1052
                    array(4, 'Zahlungsauswahl, Versandauswahl, Login-Formular, Mini-Warenkorb')
1053
                ),
1054
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1055
                'helpText' => 'Die \'Zahlungsauswahl\' wird nur in der \'Einseitig\'-Darstellung angezeigt.',
1056
                'position' => 24
1057
            )
1058
        );
1059
1060
        $form->setElement(
1061
            'boolean',
1062
            'partPaymentWidget',
1063
            array(
1064
                'label' => 'Teilzahlungs-Widget auf der Detailseite anzeigen',
1065
                'value' => true,
1066
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1067
                'position' => 25
1068
            )
1069
        );
1070
1071
        $form->setElement(
1072
            'boolean',
1073
            'convertShippingFee',
1074
            array(
1075
                'label' => 'Versandkosten in eine Bestellposition umwandeln',
1076
                'value' => true,
1077
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1078
                'position' => 26
1079
            )
1080
        );
1081
1082
        $form->setElement(
1083
            'select',
1084
            'statusId',
1085
            array(
1086
                'label' => 'Zahlstatus nach der Bestellung',
1087
                'value' => 18,
1088
                'store' => 'base.PaymentStatus',
1089
                'displayField' => 'description',
1090
                'valueField' => 'id',
1091
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1092
                'position' => 27
1093
            )
1094
        );
1095
1096
        $form->setElement(
1097
            'select',
1098
            'activateStatusId',
1099
            array(
1100
                'label' => 'Zahlungsstatus nach der Aktivierung',
1101
                'value' => 12,
1102
                'store' => 'base.PaymentStatus',
1103
                'displayField' => 'description',
1104
                'valueField' => 'id',
1105
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1106
                'position' => 28
1107
            )
1108
        );
1109
1110
        $form->setElement(
1111
            'select',
1112
            'cancelStatusId',
1113
            array(
1114
                'label' => 'Zahlungsstatus nach der Stornierung',
1115
                'value' => 17,
1116
                'store' => 'base.PaymentStatus',
1117
                'displayField' => 'description',
1118
                'valueField' => 'id',
1119
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1120
                'position' => 29
1121
            )
1122
        );
1123
        
1124
        $form->setElement(
1125
            'select',
1126
            'klarnaLogLevel',
1127
            array(
1128
                'label' => 'Detaillevel der Logeinträge zur Fehlerverfolgung',
1129
                'value' => 0,
1130
                'store' => array(
1131
                    array(0, 'Nichts protokollieren'),
1132
                    array(1, 'Nur Fehler protokollieren'),
1133
                    array(2, 'Fehler und Warnungen protokollieren'),
1134
                    array(3, 'Alle Meldungen protokollieren'),
1135
                    array(4, 'Alle Meldungen und zusätzlich Entwicklerinformationen protokollieren (Große Logdateien!)'),
1136
                ),
1137
                'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP,
1138
                'helpText' => 'Diese Einstellmöglichkeit dient vor allem der Nachverfolgung von Fehlern im Ablauf. Die Logdatei finden Sie unter var/log/klarnaTrace.log ihrer Shopware-Installation.',
1139
                'position' => 30
1140
            )
1141
        );
1142
    }
1143
1144
    /**
1145
     *
1146
     */
1147
    public function createMyTranslations()
1148
    {
1149
        $form = $this->Form();
1150
        $translations = $this->getTranslationArray();
1151
1152
        // In 4.2.2 we introduced a helper function for this, so we can skip the custom logic
1153
        if ($this->assertMinimumVersion('4.2.2')) {
1154
            $this->addFormTranslations($translations);
1155
            return true;
1156
        }
1157
1158
        $shopRepository = Shopware()->Models()->getRepository('\Shopware\Models\Shop\Locale');
1159
        foreach ($translations as $locale => $snippets) {
1160
            /** @var \Shopware\Models\Shop\Locale|null $localeModel */
1161
            $localeModel = $shopRepository->findOneBy(array('locale' => $locale));
1162
            if ($localeModel === null) {
1163
                continue;
1164
            }
1165
            foreach ($snippets as $element => $snippet) {
1166
                $translationModel = null;
1167
                //get the form element by name
1168
                $elementModel = $form->getElement($element);
1169
1170
                //not found? continue with next snippet
1171
                if ($elementModel === null) {
1172
                    continue;
1173
                }
1174
1175
                // Try to load existing translation
1176
                foreach ($elementModel->getTranslations() as $translation) {
1177
                    if ($translation->getLocale()->getLocale() == $locale) {
1178
                        $translationModel = $translation;
1179
                        break;
1180
                    }
1181
                }
1182
1183
                // If none found create a new one
1184
                if (!$translationModel) {
1185
                    $translationModel = new \Shopware\Models\Config\ElementTranslation();
1186
                    $translationModel->setLocale($localeModel);
1187
                    //add the translation to the form element
1188
                    $elementModel->addTranslation($translationModel);
1189
                }
1190
1191
                if ($snippet['label']) {
1192
                    $translationModel->setLabel($snippet['label']);
1193
                }
1194
1195
                if ($snippet['description']) {
1196
                    $translationModel->setDescription($snippet['description']);
1197
                }
1198
            }
1199
        }
1200
    }
1201
1202
    /**
1203
     *
1204
     */
1205
    public function createMyAttributes()
1206
    {
1207
        try {
1208
            $this->get('models')->addAttribute(
1209
                's_order_details_attributes',
1210
                'swag_klarna',
1211
                'invoice_number',
1212
                'VARCHAR(255)'
1213
            );
1214
        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1215
        }
1216
1217
        $this->get('models')->generateAttributeModels(
1218
            array(
1219
                's_order_details_attributes'
1220
            )
1221
        );
1222
1223
        try {
1224
            $this->get('models')->addAttribute(
1225
                's_order_attributes',
1226
                'swag_klarna',
1227
                'status',
1228
                'VARCHAR(255)'
1229
            );
1230
            $this->get('models')->addAttribute(
1231
                's_order_attributes',
1232
                'swag_klarna',
1233
                'invoice_number',
1234
                'VARCHAR(255)'
1235
            );
1236
1237
            $this->get('models')->addAttribute(
1238
                's_core_paymentmeans_attributes',
1239
                'swag_klarna',
1240
                'show_in_klarna_iframe',
1241
                'int(11)'
1242
            );
1243
            $this->get('models')->addAttribute(
1244
                's_core_paymentmeans_attributes',
1245
                'swag_klarna',
1246
                'allow_in_payment_container',
1247
                'int(11)'
1248
            );
1249
            $this->get('models')->addAttribute(
1250
                's_core_paymentmeans_attributes',
1251
                'swag_klarna',
1252
                'klarna_media',
1253
                'VARCHAR(255)'
1254
            );
1255
        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1256
        }
1257
1258
        $this->get('models')->generateAttributeModels(
1259
            array(
1260
                's_order_attributes',
1261
                's_core_paymentmeans_attributes'
1262
            )
1263
        );
1264
        
1265
        if ($this->assertMinimumVersion('5.2')) {
1266
            $this->get('shopware_attribute.crud_service')->update(
1267
                's_core_paymentmeans_attributes',
1268
                'swag_klarna_show_in_klarna_iframe',
1269
                'boolean',
1270
                [
1271
                    'label' => 'In Klarna Checkout einbinden',
1272
                    'helpText' => 'Bindet die Zahlungsart direkt in das Klarna iFrame ein',
1273
                    'displayInBackend' => true,
1274
                    'pluginId' => $this->getId()
1275
                ]
1276
            );
1277
            $this->get('shopware_attribute.crud_service')->update(
1278
                's_core_paymentmeans_attributes',
1279
                'swag_klarna_allow_in_payment_container',
1280
                'boolean',
1281
                [
1282
                    'label' => 'Nicht neben dem Klarna Checkout anzeigen',
1283
                    'helpText' => 'Versteckt die Zahlungsart in dem "Andere Zahlungsarten-Container" im Klarna Checkout',
1284
                    'displayInBackend' => true,
1285
                    'pluginId' => $this->getId()
1286
                ]
1287
            );    
1288
            $this->get('shopware_attribute.crud_service')->update(
1289
                's_core_paymentmeans_attributes',
1290
                'swag_klarna_klarna_media',
1291
                'string',
1292
                [
1293
                    'label' => 'Bild Name für Klarna Checkout',
1294
                    'helpText' => 'Zeigt die Zahlungsart zusätzlich mit einem Bild im iFrame an. Funktioniert nur, wenn SSL konfiguriert ist. Optimale Größe: 276x48px.'
1295
                    . 'Das Bild muss im Order /media/image gespeichert werden',
1296
                    'displayInBackend' => true,
1297
                    'pluginId' => $this->getId()
1298
                ]
1299
            );             
1300
            
1301
        }        
1302
    }
1303
1304
    protected function registerMyTemplateDir($isBackend = false)
1305
    {
1306
        if ($isBackend) {
1307
            $this->get('template')->addTemplateDir(__DIR__ . '/Views/', 'klarna');
1308
        } elseif ($this->isTemplateResponsive()) {
1309
            $this->get('template')->addTemplateDir(__DIR__ . '/Views/responsive', 'klarna');
1310
        } else {
1311
            $this->get('template')->addTemplateDir(__DIR__ . '/Views/_emotion', 'klarna');
1312
        }
1313
    }
1314
1315
    /**
1316
     * Checks if the the current Template is responsive
1317
     *
1318
     * @return bool
1319
     */
1320
    private function isTemplateResponsive()
1321
    {
1322
        $template = $this->Application()->Shop()->getTemplate()->getVersion();
1323
        if ($template < 3) {
1324
            return false;
1325
        }
1326
1327
        return true;
1328
    }
1329
1330
    /**
1331
     * Returns the path to a frontend controller for an event.
1332
     *
1333
     * @return string
1334
     */
1335
    public function onGetControllerPathFrontend()
1336
    {
1337
        $this->registerMyTemplateDir();
1338
1339
        return __DIR__ . '/Controllers/Frontend/PaymentKlarna.php';
1340
    }
1341
1342
    /**
1343
     * Returns the path to a backend controller for an event.
1344
     *
1345
     * @return string
1346
     */
1347
    public function onGetControllerPathBackend()
1348
    {
1349
        $this->registerMyTemplateDir(true);
1350
        $this->Application()->Snippets()->addConfigDir(
1351
            __DIR__ . '/Snippets/'
1352
        );
1353
1354
        return __DIR__ . '/Controllers/Backend/PaymentKlarna.php';
1355
    }
1356
1357
    /**
1358
     * @param Enlight_Event_EventArgs $args
1359
     */
1360
    public function onPostDispatch(Enlight_Event_EventArgs $args)
1361
    {
1362
        /** @var $action Enlight_Controller_Action */
1363
        $action = $args->getSubject();
1364
        $request = $action->Request();
1365
        $response = $action->Response();
1366
        $view = $action->View();
1367
        
1368
        if ($request->getControllerName() == 'account' && $request->getActionName() == 'login'
1369
          && $request->get('klarnaPreFill') && $response->isRedirect()) {
1370
            $session = $this->get('session');
1371
            $session['klarnaPreFill'] = true;
1372
        }
1373
1374
        if (!$request->isDispatched()
1375
            || $response->isException()
1376
            || $request->getModuleName() != 'frontend'
1377
            || !$view->hasTemplate()
1378
        ) {
1379
            return;
1380
        }
1381
1382
        $postedCountry = $request->get('sCountry');
1383
        $controllerName = $request->getControllerName();
1384
        $actionName = $request->getActionName();
1385
        $fromScope = $request->get('fromScope');
1386
        $isFromKCO = (bool)($fromScope == 'klarna_checkout');
1387
        
1388
        $session = $this->get('session');
1389
        
1390
        if ($controllerName == 'payment_klarna' && $postedCountry !== null) {
1391
            $shopCountryId = $this->getCountryByShop(Shopware()->Shop());
1392
            $validKlarnaCountry = $this->checkValidKlarnaCountry($postedCountry);
1393
            if (!$validKlarnaCountry) {
1394
                $action->redirect(array('controller' => 'payment_klarna', 'action' => 'otherPayment'));
1395
                return;
1396
            }
1397
            if ($shopCountryId !== (int) $postedCountry){
1398
                if ($this->isKlarnaUser()){
1399
                    if ($postedCountry == '23'){
1400
                        $session['sCountry'] = '23';
1401
                        
1402
                    } else { 
1403
                    $action->redirect(array('controller' => 'payment_klarna', 'action' => 'otherPayment'));
1404
                    }
1405
                } else {
1406
                    $action->redirect(array('controller' => 'checkout', 'action' => 'shippingPayment'));
1407
                }
1408
                return;
1409
            }
1410
            
1411
        }
1412
              
1413
        $user = $view->getAssign('sUserData');
1414
1415
        if ($request->getControllerName() == 'checkout' || $request->getControllerName() == 'account') {
1416
            $this->registerMyTemplateDir();
1417
        }
1418
1419
        $config = $this->Config();
1420
1421
        if ($request->getControllerName() == 'checkout'
1422
            && ($request->getActionName() == 'cart' || $request->getActionName() == 'ajaxCart')
1423
        ) {
1424
            $view->assign('KlarnaEnableButton', (bool)$config->get('showKlarnaButton'));
1425
            $view->assign('KlarnaShowCheckoutButton', $this->getShowCheckoutButton($user));
1426
            $view->assign('klarnaKcoPaymentActive', $this->isKlarnaKcoPaymentActive($user));
1427
            $view->assign('KlarnaPaymentDescription', $this->getPayment()->getDescription());
1428
            if (!$this->isTemplateResponsive()) {
1429
                $view->extendsTemplate('frontend/payment_klarna_checkout/cart.tpl');
1430
            }
1431
        }
1432
1433
        if (!empty($config->partPaymentWidget)
1434
            && $request->getControllerName() == 'detail' && $request->getActionName() == 'index'
1435
        ) {
1436
            $this->registerMyTemplateDir();
1437
            //Do not shot the logo on the detail page if the kpm-plugin is active
1438
            $view->KlarnaShowLogo = !$this->isKpmActive();
1439
            $view->KlarnaLocale = $this->getLocale();
1440
            $view->KlarnaMerchantId = $config->get('merchantId');
1441
            if (!$this->isTemplateResponsive()) {
1442
                $view->extendsTemplate('frontend/payment_klarna_part/detail.tpl');
1443
            }
1444
        }
1445
1446
        if (!empty($config->noAccountCheckout)
1447
            && $request->getControllerName() == 'register'
1448
            && $request->getActionName() == 'index'
1449
        ) {
1450
            if ($request->getParam('skipLogin') !== null || $this->isTemplateResponsive()) {
1451
                $payments = $view->register->payment->payment_means;
1452
                foreach ($payments as $payment) {
1453
                    if ($payment['name'] == 'klarna_checkout' && !empty($session['sBasketQuantity'])) {
1454
                        if (empty($session['sPaymentID']) || $payment['id'] == $session['sPaymentID']) {
1455
                            $session['sPaymentID'] = $payment['id'];
1456
                            $action->redirect(array('controller' => 'payment_klarna', 'action' => 'express'));
1457
                            return;
1458
                        }
1459
                    }
1460
                }
1461
            }
1462
        }
1463
1464
        if ($request->getControllerName() == 'register' && $request->getActionName() == 'index') {
1465
            $this->registerMyTemplateDir();
1466
            $view->assign('KlarnaLocale', $this->getLocale());
1467
            $view->assign('KlarnaMerchantId', $config->get('merchantId'));
1468
            $view->assign('KlarnaHideCheckoutSteps', true);
1469
            if (version_compare(Shopware::VERSION, '5.2.0', '<')){
1470
                $view->assign('KlarnaSkipLoginFix', true);
1471
            }
1472
            if (!$this->isTemplateResponsive()) {
1473
                $view->extendsTemplate('frontend/payment_klarna_checkout/register.tpl');
1474
            }
1475
        }
1476
1477
        if ($request->getControllerName() == 'account' && $request->getActionName() == 'ajax_login') {
1478
            $this->registerMyTemplateDir();
1479
            $view->assign('KlarnaLocale', $this->getLocale());
1480
            $view->assign('KlarnaMerchantId', $config->get('merchantId'));
1481
            if (!$this->isTemplateResponsive()) {
1482
                $view->extendsTemplate('frontend/payment_klarna_checkout/ajax_login.tpl');
1483
            }
1484
        }
1485
1486
        if ($request->getControllerName() == 'checkout' && $request->getActionName() == 'shippingPayment') {
1487
            $this->registerMyTemplateDir();
1488
            $view->assign('KlarnaMerchantId', $config->get('merchantId'));
1489
            $view->assign('KlarnaLocale', $this->getLocale(true));
1490
        }
1491
        
1492
        if (isset($postedCountry) && isset($validKlarnaCountry) && $validKlarnaCountry) {
1493
            $session['sChangedCountry'] = $postedCountry;
1494
        }
1495
        
1496
        if ($controllerName == 'checkout' && $actionName == 'changeQuantity' && $this->isKlarnaKcoPaymentActive($user) && $isFromKCO) {
1497
            $action->redirect(array('controller' => 'payment_klarna', 'action' => 'express'));
1498
        }
1499
        
1500
    }
1501
    
1502
    /**
1503
     * @param Enlight_Event_EventArgs $args
1504
     * @throws Exception
1505
     */
1506
    public function onPostDispatchCheckout($args)
1507
    {
1508
        /** @var $action Enlight_Controller_Action */
1509
        $action = $args->getSubject();
1510
        $request = $action->Request();
1511
        $response = $action->Response();
1512
        $view = $action->View();
1513
1514 View Code Duplication
        if (!$request->isDispatched()
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1515
            || $response->isException()
1516
            || $response->isRedirect()
1517
            || $request->getActionName() != 'confirm'
1518
        ) {
1519
            return;
1520
        }
1521
1522
        $connector = $this->getConnector();
1523
        $session = $this->Application()->Session();
1524
        $user = $view->sUserData;
1525
        $basket = $view->sBasket;
1526
        $payment = $view->sPayment;
1527
        /** @var \Shopware\Models\Shop\Shop $shop */
1528
        $shop = $this->Application()->Shop();
1529
        $config = $this->Config();
1530
1531
        $this->registerMyTemplateDir();
1532
        if (!$this->isTemplateResponsive()) {
1533
            $view->extendsTemplate('frontend/payment_klarna_checkout/confirm.tpl');
1534
        }
1535
1536
        if (empty($payment) || $payment['name'] != 'klarna_checkout') {
1537
            return;
1538
        }
1539
1540
        // SwagDhl fix
1541
        $allowPackstation = true;
1542
        if (!empty($view->dhlDispatchIds)) {
1543
            $allowPackstation = false;
1544
            if (in_array($session->sDispatch, $view->dhlDispatchIds)) {
1545
                $allowPackstation = true;
1546
            }
1547
            unset($view->dhlDispatchIds);
1548
        }
1549
1550
        $this->getViewConfig($view, $config);
1551
        
1552
        $preFill = $request->get('klarnaPreFill') || !empty($session['klarnaPreFill']) || $config->get('preFillCheckout');
1553
1554
        try {
1555
            if (isset($session['KlarnaOrder']) && $preFill) {
1556
                $order = new Klarna_Checkout_Order($connector, $session['KlarnaOrder']);
0 ignored issues
show
Documentation introduced by
$connector is of type object<Klarna_Checkout_Connector>, but the function expects a object<Klarna_Checkout_ConnectorInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1557
                $order->fetch();
1558
1559
                if ($order['status'] == "checkout_incomplete") {
1560
                    $update = array();
1561
                    $update['cart']['items'] = $this->getCheckoutCart($basket);
1562
                    $update['options'] = $this->getCheckoutOptions($allowPackstation, $view->sDispatch);
1563
                    if ($request->get('klarnaPreFill') == "on"){
1564
                        $update['customer'] = $this->getCheckoutCustomer($user);
1565
                        if  ( !isset($user['billingaddress']['phone'])) {
1566
                                $user['billingaddress']['phone'] = " ";
1567
                        }  
1568
                        if  ( !isset($user['shippinggaddress']['phone'])) {
1569
                                $user['shippingaddress']['phone'] = " ";
1570
                        }                        
1571 View Code Duplication
                        if ($user['additional']['countryShipping']['id'] == $user['additional']['country']['id']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1572
                            $update['shipping_address'] = $this->getCheckoutAddress($user, 'billing');
1573
                        } else {
1574
                            $update['shipping_address'] = $this->getCheckoutAddress($user, 'shipping');
1575
                        }                          
1576
                    }
1577
                    $order->update($update);
1578
                } else {
1579
                    unset($session['KlarnaOrder']);
1580
                }
1581
            } else {
1582
                $create = array();
1583
                $create['cart']['items'] = $this->getCheckoutCart($basket);
1584
                $create['merchant'] = $this->getCheckoutMerchant();
1585
1586
                if (isset($session['sChangedCountry'])) {
1587
                    $session['sCountry'] = $session['sChangedCountry'];
1588
                } else {
1589
                    $session['sCountry'] = $this->getCountryByShop($shop);
1590
                }                
1591
                
1592
                $create['purchase_country'] = $this->getCountryIsoById($session['sCountry']);
1593
                $create['purchase_currency'] = $shop->getCurrency()->toString();
1594
                $create['locale'] = $this->getLocale(false, $create['purchase_country']);
1595
                $create['options'] = $this->getCheckoutOptions($allowPackstation, $view->sDispatch);
1596
1597
                if ($config->get('KlarnaExternalPayments')) {
1598
                    list($create['external_payment_methods'], $create['external_checkouts']) = $this->getExternalPaymentMethods($basket);
1599
                }
1600
1601
                if ($config->get('disableAutofocus')) {
1602
                    $create['gui']['options'] = array('disable_autofocus');
1603
                }
1604
1605
                if (Shopware::VERSION === '___VERSION___' || version_compare(Shopware::VERSION, '5.2.0', '>=')) {
1606
                   if  ( isset($user['additional']['user']['birthday']) && $user['additional']['user']['birthday'] !== "0000-00-00") {
1607
                       $user['billingaddress']['birthday'] = $user['additional']['user']['birthday'];
1608
                       $user['birthday'] = $user['additional']['user']['birthday'];
1609
                   }
1610
                }              
1611
                if  ( !isset($user['billingaddress']['phone'])) {
1612
                        $user['billingaddress']['phone'] = " ";
1613
                }        
1614
1615
                if ($preFill) {
1616
                    $session['klarnaPreFill'] = true;
1617
                    if (empty($session['sCountry'])) {
1618
                        $countryId = $this->getCountryByShop($shop);
1619
                    }
1620
                    else {
1621
                        $countryId = $session['sCountry'];
1622
                    }
1623
                    if ($user['additional']['countryShipping']['id'] == $countryId
1624
                        && $user['billingaddress']['zipcode'] != '00000'
1625
                    ) {
1626
                        $create['customer'] = $this->getCheckoutCustomer($user);
1627 View Code Duplication
                        if ($user['additional']['countryShipping']['id'] == $user['additional']['country']['id']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1628
                            $create['shipping_address'] = $this->getCheckoutAddress($user, 'billing');
1629
                        } else {
1630
                            $create['shipping_address'] = $this->getCheckoutAddress($user, 'shipping');
1631
                        }
1632
                    }                    
1633
                } else {
1634
                    $session['klarnaPreFill'] = false;
1635
                }
1636
                $order = new Klarna_Checkout_Order($connector);
0 ignored issues
show
Documentation introduced by
$connector is of type object<Klarna_Checkout_Connector>, but the function expects a object<Klarna_Checkout_ConnectorInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1637
                if ($create['purchase_country'] == 'AT') {
1638
                    $locale = 'de-at';
1639
                } elseif ($create['purchase_country'] == 'DE')
1640
                    {
1641
                     $locale = 'de-de';
1642
                } else {
1643
                    $locale = $this->getLocale(false, $create['purchase_country']);
1644
                }
1645
                $create['locale'] = $locale;
1646
                $order->create($create);
1647
                $order->fetch();
1648
1649
                $session['KlarnaOrder'] = $order->getLocation();
1650
            }
1651
        } catch (Exception $e) {
1652
            unset($session['KlarnaOrder']);
1653
            /** @var Shopware\Components\Logger $logger */
1654
            $logger = $this->get('corelogger');
1655
            $logger->error($e->getMessage());
1656
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
1657
            echo "Entschuldigung, Ein Verbindungsfehler ist aufgetreten, bitte aktualisieren Sie die Seite";
1658
        }
1659
1660
        if (isset($session['klarnaSavedRegister'])) {
1661
            try {
1662
                $update = $this->klarnaMapping($session['klarnaSavedRegister']);
1663
                if ($update) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $update 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...
1664
                    $order->update($update);
0 ignored issues
show
Bug introduced by
The variable $order does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1665
                }
1666
            } catch (Exception $e) {
1667
                Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
1668
                echo "Entschuldigung, Ein Verbindungsfehler ist aufgetreten, bitte aktualisieren Sie die Seite";
1669
            }
1670
            unset($session['klarnaSavedRegister']);
1671
        }
1672
        
1673
        if (isset($session['sChangedCountry'])) {
1674
            $sCountryId = $session['sChangedCountry'];
1675
        } else {
1676
            $sCountryId = $this->getCountryByShop($shop);
1677
        }
1678
              
1679
        $view->assign('sCountryId', $sCountryId);
1680
        $view->assign('KlarnaMerchantId', $config->get('merchantId'));
1681
        $view->assign('KlarnaPreFillSelect', !$this->isKlarnaUser() && empty($session['klarnaPreFill']));
1682
        $view->assign('KlarnaLocale', $this->getLocale(true));
1683
        $view->assign('KlarnaOrder', $order->marshal());
1684
    }
1685
1686
    /**
1687
     * Populate register form with saved data on changing klarna and register tabs
1688
     *
1689
     * @param Enlight_Event_EventArgs $args
1690
     */
1691
    public function onPostDispatchFrontendRegister($args)
1692
    {
1693
        /** @var $action Enlight_Controller_Action */
1694
        $action = $args->getSubject();
1695
        $view = $action->View();
1696
        $request = $action->Request();
1697
        /** @var Enlight_Components_Session_Namespace $session */
1698
        $session = $this->Application()->Session();
1699
        $connector = $this->getConnector();
1700
        $controllerName = $request->getControllerName();
0 ignored issues
show
Unused Code introduced by
$controllerName is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1701
        
1702
        if (isset($session['KlarnaOrder'])) {
1703
            $order = new Klarna_Checkout_Order($connector, $session['KlarnaOrder']);
0 ignored issues
show
Documentation introduced by
$connector is of type object<Klarna_Checkout_Connector>, but the function expects a object<Klarna_Checkout_ConnectorInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1704
            
1705
            try {
1706
                $order->fetch();
1707
            } catch (Exception $e) {
1708
                Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
1709
                echo "Entschuldigung, Ein Verbindungsfehler ist aufgetreten, bitte aktualisieren Sie die Seite";
1710
            }
1711
1712
            $registerData = $this->getKlarnaCustomerData($order);
1713 View Code Duplication
            foreach ($registerData['personal'] as $key => $val) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1714
                if (empty($view->register->personal->form_data->$key)) {
1715
                    $view->register->personal->form_data->$key = trim($val);
1716
                }
1717
            }
1718
1719 View Code Duplication
            foreach ($registerData['billing'] as $key => $val) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1720
                if (empty($view->register->billing->form_data->$key)) {
1721
                    $view->register->billing->form_data->$key = trim($val);
1722
                }
1723
            }
1724
1725 View Code Duplication
            foreach ($registerData['shipping'] as $key => $val) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1726
                if (empty($view->register->shipping->form_data->$key)) {
1727
                    $view->register->shipping->form_data->$key = trim($val);
1728
                }
1729
            }
1730
        }
1731
1732
        $view->assign('klarnaRedirect', $request->has('klarnaRedirect') && $request->getParam('klarnaRedirect') == 1);
1733
    }
1734
1735
    public function addJsFiles()
1736
    {
1737
        $jsPath = array(
1738
            __DIR__ . '/Views/responsive/frontend/_public/src/js/jquery.klarna_checkout.js'
1739
        );
1740
1741
        return new Doctrine\Common\Collections\ArrayCollection($jsPath);
1742
    }
1743
1744
    /**
1745
     * @param Enlight_Event_EventArgs $args
1746
     */
1747
    public function onPreDispatchCheckout($args)
1748
    {
1749
        /** @var $action Enlight_Controller_Action */
1750
        $action = $args->getSubject();
1751
        $request = $action->Request();
1752
        $response = $action->Response();
1753
        $view = $action->View();
1754
        $session = $this->Application()->Session();
1755
1756
        if (!$request->isDispatched()
1757
            || $response->isException()
1758
            || $request->getModuleName() != 'frontend'
1759
        ) {
1760
            return;
1761
        }
1762
1763
        if (!isset($session['sCountry'])) {
1764
            $shop = $this->Application()->Shop();
1765
            $session['sCountry'] = $this->getCountryByShop($shop);
1766
        }
1767
1768
        if ($request->getActionName() != 'finish' || !isset($session['KlarnaOrder'])) {
1769
            return;
1770
        }
1771
1772
        $connector = $this->getConnector();
1773
        $order = new Klarna_Checkout_Order($connector, $session['KlarnaOrder']);
0 ignored issues
show
Documentation introduced by
$connector is of type object<Klarna_Checkout_Connector>, but the function expects a object<Klarna_Checkout_ConnectorInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1774
        try {
1775
            $order->fetch();
1776
        } catch (Exception $e) {
1777
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
1778
            echo "Entschuldigung, Ein Verbindungsfehler ist aufgetreten, bitte aktualisieren Sie die Seite";
1779
            $this->klarnaLog("Verbindungsfehler in onPreDispatchCheckout\nCode:".$e->getCode()."Nachricht:\n".$e->getMessage(),1);
1780
        }
1781
        
1782
        if ($order['status'] != 'created' && $order['status'] != 'checkout_complete') {
1783
            return;
1784
        }
1785
1786
        $this->registerMyTemplateDir();
1787
        if (!$this->isTemplateResponsive()) {
1788
            $view->extendsTemplate('frontend/payment_klarna_checkout/finish.tpl');
1789
        }
1790
        $view->assign('KlarnaOrder', $order->marshal());
1791
        
1792
        try {
1793
            $data['status'] = 'created';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1794
            $this->klarnaLog("onPreDispatchCheckout: Trying to update order to klarna with state created with following data:",4, $data);
1795
            $order->update($data);
1796
        } catch (Klarna_Checkout_ConnectionErrorException $e) {
1797
            $view->assign('KlarnaConnectionError', json_decode($e->getMessage(), true));
1798
        }       
1799
        unset($session['KlarnaOrder']);
1800
        
1801
        
1802
        $postedCountry = $request->getParam('sCountry');
1803
        if ($postedCountry && !isset($session['sCountry'])) {
1804
            $session['sCountry'] = $postedCountry;   
1805
        }
1806
    }
1807
    
1808
    /**
1809
     * @param Enlight_Event_EventArgs $args
1810
     */
1811 View Code Duplication
    public function onLoadOrderBackendModule(Enlight_Event_EventArgs $args)
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...
1812
    {
1813
        /** @var $subject Enlight_Controller_Action */
1814
        $subject = $args->getSubject();
1815
        $request = $subject->Request();
1816
        $view = $subject->View();
1817
1818
        switch ($request->getActionName()) {
1819
            case 'load':
1820
                $this->registerMyTemplateDir(true);
1821
                $view->extendsTemplate('backend/order/payment_klarna.js');
1822
                break;
1823
            default:
1824
                break;
1825
        }
1826
    }
1827
1828
    /**
1829
     * @param Enlight_Event_EventArgs $args
1830
     */
1831 View Code Duplication
    public function onLoadPaymentBackendModule(Enlight_Event_EventArgs $args)
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...
1832
    {
1833
        /** @var $subject Enlight_Controller_Action */
1834
        $subject = $args->getSubject();
1835
        $request = $subject->Request();
1836
        $view = $subject->View();
1837
1838
        switch ($request->getActionName()) {
1839
            case 'load':
1840
                $this->registerMyTemplateDir(true);
1841
                $view->extendsTemplate('backend/payment/payment_klarna.js');
1842
                break;
1843
            default:
1844
                break;
1845
        }
1846
    }
1847
1848
    public function updateOrderVariables()
1849
    {
1850
        $session = Shopware()->Session();
1851
        $admin = Shopware()->Modules()->Admin();
1852
        /** @var ArrayObject $orderVariables */
1853
        $orderVariables = $session['sOrderVariables'];
1854
        $userData = $admin->sGetUserData();
1855
        $userData['payment'] = $orderVariables['sUserData']['payment'];
1856
        $userData['additional'] = array_merge(
1857
            $orderVariables['sUserData']['additional'],
1858
            $userData['additional']
1859
        );
1860
        
1861
        if (isset($session['sChangedCountry'])){
1862
            
1863
            /** @var \Shopware\Components\Model\ModelManager $em */
1864
            $em = $this->get('models');
1865
1866
            /** @var \Shopware\Models\Customer\Customer $customer */
1867
            $country = $em->getRepository('Shopware\Models\Country\Country')->findOneBy(array('id' => $session['sChangedCountry']));            
1868
            $userData['shippingaddress']['country'] =$country;     
1869
            $userData['billingaddress']['country'] =$country;   
1870
            $userData['shippingaddress']['countryID'] = $session['sChangedCountry'];
1871
            $userData['billingaddress']['countryID'] = $session['sChangedCountry'];
1872
         }
1873
        
1874
        $orderVariables['sUserData'] = $userData;
1875
    }
1876
1877
    /**
1878
     * @param $shop Shopware\Models\Shop\Shop
1879
     * @return int|null
1880
     */
1881
    public function getCountryByShop($shop)
1882
    {
1883
        $locale = $shop->getLocale()->getLocale();
1884
        $this->klarnaLog("Entering Bootstrap::getCountryByShop", 3);
1885
        $locale = explode('_', $locale);
1886
        $locale = isset($locale[1]) ? $locale[1] : $locale[0];
1887
        $this->klarnaLog("Bootstrap::getCountryByShop locale to request for:".$locale,3);
1888
        $sql = 'SELECT id FROM s_core_countries WHERE countryiso=?';
1889
        $countryId = Shopware()->Db()->fetchOne($sql, array($locale));
1890
        $countryId = ($countryId) ? (int)$countryId : null;
1891
                
1892
        return $countryId;
1893
    }
1894
1895
    /**
1896
     * Get user country by country id
1897
     *
1898
     * @param $id
1899
     * @return string
1900
     */
1901
    public function getCountryIsoById($id)
1902
    {
1903
        $sql = 'SELECT countryiso FROM s_core_countries WHERE id = ?';
1904
        $countryIso = Shopware()->Db()->fetchOne($sql, array($id));
1905
1906
        return $countryIso;
1907
    }
1908
1909
    public function getLocale($underscore = false, $countryIso = null)
1910
    {
1911
        /** @var \Shopware\Models\Shop\Shop $shop */
1912
        $shop = $this->Application()->Shop();
1913
        $locale = $shop->getLocale()->getLocale();
1914
        $locale = strtolower($locale);
1915
        if (!$underscore) {
1916
            $locale = str_replace('_', '-', $locale);
1917
        }
1918
        $locale = $locale == 'nn-no' ? 'nb-no' : $locale;
1919
1920
        if ($locale == 'de-de') {
1921
            if($countryIso == 'CH') {
1922
                $locale = 'de-ch';
1923
            } elseif ($countryIso == 'AT') {
1924
                $locale = 'de-at';
1925
            }
1926
        }
1927
1928
        return $locale;
1929
    }
1930
1931
    protected function getCheckoutOptions($allowPackstation = true, $dispatch = array())
1932
    {
1933
        $config = $this->Config();
1934
        $options = $this->getColorConfigOptions($config);
1935
1936
        $options['allow_separate_shipping_address'] = (bool)$config->get('allowSeparateShippingAddress');
1937
        $options['packstation_enabled'] = (bool)$config->get('supportPackstation') && $allowPackstation;
1938
        $options['phone_mandatory'] = (bool)$config->get('mandatoryPhone');
1939
        $options['date_of_birth_mandatory'] = (bool)$config->get('mandatoryBirthday');
1940
1941
        if (!empty($dispatch)) {
1942
            $options['shipping_details'] = $dispatch['description'];
1943
        }
1944
1945
        return $options;
1946
    }
1947
1948
    protected function getCheckoutCart($basket)
1949
    {
1950
        $cart = array();
1951
        foreach ($basket['content'] as $index=>$basketItem) {
1952
            // compatibility to shopware plugin custom products
1953
            if (isset($basketItem['custom_product_prices'])) {
1954
                $basketItemPrice = (double)$basketItem['custom_product_prices']['total'];
1955
            }
1956
            else {
1957
                $basketItemPrice = (double)str_replace(',', '.', $basketItem['price']);
1958
            }
1959
            $unitPrice = round($basketItemPrice * 100);
1960
            $cart[] = array(
1961
                'type' => $unitPrice >= 0 ? 'physical' : 'discount',
1962
                'reference' => $basketItem['ordernumber'],
1963
                'name' => $basketItem['articlename'],
1964
                'quantity' => (int)$basketItem['quantity'],
1965
                'unit_price' => (int)$unitPrice,
1966
                'tax_rate' => (int)round($basketItem['tax_rate'] * 100)
1967
            );
1968
        }
1969
        if (!empty($basket['sShippingcosts'])) {
1970
            $shippingCostsWithTax = $basket['sShippingcostsWithTax'];
1971
            $shippingAmount = !empty($shippingCostsWithTax) ? $shippingCostsWithTax : $basket['sShippingcosts'];
1972
            $cart[] = array(
1973
                'type' => 'shipping_fee',
1974
                'reference' => 'SHIPPING',
1975
                'name' => 'Shipping Fee',
1976
                'quantity' => 1,
1977
                'unit_price' => (int)round($shippingAmount * 100),
1978
                'tax_rate' => (int)round($basket['sShippingcostsTax'] * 100),
1979
            );
1980
        }
1981
1982
        return $cart;
1983
    }
1984
1985
    protected function getCheckoutMerchant()
1986
    {
1987
        /** @var \Shopware\Components\Routing\RouterInterface $router */
1988
        $router = $this->Application()->Front()->Router();
1989
        $merchant = array();
1990
        $merchant['id'] = $this->Config()->get('merchantId');
1991
        $merchant['terms_uri'] = $router->assemble(
1992
            array(
1993
                'controller' => 'custom',
1994
                'sCustom' => $this->Config()->get('termSiteId', 4),
1995
                'forceSecure' => true
1996
            )
1997
        );
1998
        $merchant['checkout_uri'] = $router->assemble(
1999
            array(
2000
                'action' => 'confirm'
2001
            )
2002
        );
2003
        $merchant['confirmation_uri'] = $router->assemble(
2004
            array(
2005
                'controller' => 'payment_klarna',
2006
                'action' => 'return',
2007
                'forceSecure' => true
2008
            )
2009
        ) . "?transactionId={checkout.order.uri}";
2010
        $merchant['push_uri'] = $router->assemble(
2011
            array(
2012
                'controller' => 'payment_klarna',
2013
                'action' => 'push',
2014
                'forceSecure' => true,
2015
                'appendSession' => true
2016
            )
2017
        ) . "&transactionId={checkout.order.uri}";
2018
        $merchant['back_to_store_uri'] = $router->assemble(
2019
            array(
2020
                'controller' => 'index',
2021
                'action' => 'index'
2022
            )
2023
        );
2024
2025
        return $merchant;
2026
    }
2027
2028
    public function getCheckoutAddress($user, $type = 'billing')
2029
    {
2030
        if (empty($user[$type . 'address']['zipcode']) || $user[$type . 'address']['zipcode'] == '00000') {
2031
            return array();
2032
        }
2033
2034
        $address = array(
2035
            'given_name' => $user[$type . 'address']['firstname'],
2036
            'family_name' => $user[$type . 'address']['lastname'],
2037
            'postal_code' => $user[$type . 'address']['zipcode'],
2038
            'city' => $user[$type . 'address']['city'],
2039
            'country' => $user['additional'][$type == 'billing' ? 'country' : 'countryShipping']['countryiso'],
2040
            'email' => $user['additional']['user']['email'],
2041
            'phone' => $user['billingaddress']['phone'],
2042
        );
2043
        $address['country'] = strtolower($address['country']);
2044
        if ($address['country'] == 'de' || $address['country'] == 'nl') {
2045
            $address['title'] = $user[$type . 'address']['salutation'] == 'ms' ? 'Frau' : 'Herr';
2046
            if ($this->assertMinimumVersion('5.0.0')) {
2047
                /** @var StreetSplitService $streetSplitService */
2048
                $streetSplitService = Shopware()->StreetSplitService();
2049
                $streetAndNumber = $streetSplitService->split($user[$type . 'address']['street']);
2050
2051
                $address['street_name'] = $streetAndNumber['streetName'];
2052
                $address['street_number'] = $streetAndNumber['streetNumber'];
2053 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
2054
                $address['street_name'] = $user[$type . 'address']['street'];
2055
                $address['street_number'] = $user[$type . 'address']['streetnumber'];
2056
            }
2057 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
2058
            $address['street_address'] = trim(
2059
                $user[$type . 'address']['street'] . ' ' . $user[$type . 'address']['streetnumber']
2060
            );
2061
        }
2062
2063
        return $address;
2064
    }
2065
2066
    public function getCheckoutCustomer($user)
2067
    {
2068
        $customer = array(
2069
            'type' => 'person'
2070
        );
2071
        if (!empty($user['billingaddress']['birthday']) && $user['billingaddress']['birthday'] != '0000-00-00') {
2072
            $customer['date_of_birth'] = $user['billingaddress']['birthday'];
2073
        }
2074
        // SW 5.2 and newer
2075
        if (!empty($user['birthday']) && $user['birthday'] != '0000-00-00') {
2076
            $customer['date_of_birth'] = $user['birthday'];
2077
        }
2078
2079
        return $customer;
2080
    }
2081
2082
    /**
2083
     *
2084
     * @return array
2085
     */
2086
    public function getLabel()
2087
    {
2088
        return 'Klarna Checkout';
2089
    }
2090
2091
    /**
2092
     * @return string
2093
     * @throws Exception
2094
     */
2095
    public function getVersion()
2096
    {
2097
        $info = json_decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'plugin.json'), true);
2098
2099
        if ($info) {
2100
            return $info['currentVersion'];
2101
        } else {
2102
            throw new Exception('The plugin has an invalid version file.');
2103
        }
2104
    }
2105
2106
    /**
2107
     * @return array
2108
     */
2109
    public function getInfo()
2110
    {
2111
        return array(
2112
            'version' => $this->getVersion(),
2113
            'label' => $this->getLabel(),
2114
            'description' => file_get_contents(__DIR__ . '/info.txt')
2115
        );
2116
    }
2117
2118
    /**
2119
     * Creates and returns the klarna client for an event.
2120
     *
2121
     * @return \Klarna_Checkout_Connector
2122
     */
2123
    public function onInitResourceKlarnaCheckoutConnector()
2124
    {
2125
        require_once __DIR__ . '/Components/KlarnaCheckout/Checkout.php';
2126
        if ($this->Config()->get('testDrive')) {
2127
            Klarna_Checkout_Order::$baseUri = 'https://checkout.testdrive.klarna.com/checkout/orders';
2128
        } else {
2129
            Klarna_Checkout_Order::$baseUri = 'https://checkout.klarna.com/checkout/orders';
2130
        }
2131
        Klarna_Checkout_Order::$contentType = "application/vnd.klarna.checkout.aggregated-order-v2+json";
2132
        $sharedSecret = $this->Config()->get('sharedSecret');
2133
        $connector = Klarna_Checkout_Connector::create($sharedSecret);
2134
        $this->klarnaLog("Created Klarna Connector:", 4, $connector);
2135
2136
        return $connector;
2137
    }
2138
2139
    /**
2140
     * @return Klarna
2141
     */
2142
    public function onInitResourceKlarnaService()
2143
    {
2144
        require_once __DIR__ . '/Components/Klarna/Klarna.php';
2145
        require_once __DIR__ . '/Components/Klarna/transport/xmlrpc-3.0.0.beta/lib/xmlrpc.inc';
2146
2147
        $k = new Klarna();
2148
        return $k;
2149
    }
2150
2151
    /**
2152
     * Provide the file collection for less
2153
     *
2154
     * @return \Doctrine\Common\Collections\ArrayCollection
2155
     */
2156
    public function addLessFiles()
2157
    {
2158
        $less = new \Shopware\Components\Theme\LessDefinition(
2159
            //configuration
2160
            array(),
2161
            //less files to compile
2162
            array(
2163
                __DIR__ . '/Views/responsive/frontend/_public/src/less/all.less'
2164
            ),
2165
            //import directory
2166
            __DIR__
2167
        );
2168
2169
        return new Doctrine\Common\Collections\ArrayCollection(array($less));
2170
    }
2171
2172
    /**
2173
     * @param string $requiredVersion
2174
     * @return bool|mixed
2175
     */
2176
    protected function assertMinimumVersion($requiredVersion)
2177
    {
2178
        if (Shopware::VERSION === '___VERSION___') {
2179
            return true;
2180
        }
2181
2182
        return version_compare(Shopware::VERSION, $requiredVersion, '>=');
2183
    }
2184
2185
    /**
2186
     * @param Enlight_Event_EventArgs $args
2187
     * @return bool
2188
     */
2189
    public function onCheckoutSaveShippingKlarna(Enlight_Event_EventArgs $args)
2190
    {
2191
        /** @var Shopware_Controllers_Frontend_Checkout $controller */
2192
        $controller = $args->getSubject();
2193
        if (!$controller->Request()->isPost()) {
2194
            $controller->forward('shippingPayment');
2195
            return true;
2196
        }
2197
2198
        // Save payment and shipping method data.
2199
        $controller->setDispatch($controller->Request()->getPost('sDispatch'));
2200
        $controller->redirect(array('controller' => 'payment_klarna', 'action' => 'express'));
2201
        return true;
2202
    }
2203
2204
    /**
2205
     * This event is executed when the expressAction of the checkout-controller should be executed.
2206
     * It is needed to redirect the user back to the klarna checkout after deleting an article in the klarna checkout.
2207
     *
2208
     * @param Enlight_Event_EventArgs $args
2209
     * @return bool
2210
     */
2211
    public function onCheckoutExpress(Enlight_Event_EventArgs $args)
2212
    {
2213
        /** @var $action Enlight_Controller_Action */
2214
        $action = $args->getSubject();
2215
2216
        $action->redirect(array('controller' => 'payment_klarna', 'action' => 'express'));
2217
        return true;
2218
    }
2219
2220
    /**
2221
     * Mapping to populate klarna checkout with saved information from register page
2222
     *
2223
     * @param $form
2224
     * @return mixed
2225
     */
2226
    private function klarnaMapping($form)
2227
    {
2228
        $fields = array(
2229
            'email' => 'email',
2230
            'zipcode' => 'postal_code',
2231
            'firstname' => 'given_name',
2232
            'lastname' => 'family_name',
2233
        );
2234
2235
        $create = array();
2236
        foreach ($fields as $formField => $klarnaField) {
2237 View Code Duplication
            if (!empty($form['register']['personal'][$formField])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
2238
                $create['shipping_address'][$klarnaField] = $form['register']['personal'][$formField];
2239
            }
2240 View Code Duplication
            if (!empty($form['register']['billing'][$formField])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
2241
                $create['shipping_address'][$klarnaField] = $form['register']['billing'][$formField];
2242
            }
2243
        }
2244
2245
        $countryIso = $this->getCountryIsoById($form['register']['billing']['country']);
2246
2247
        $salutation = $form['register']['personal']['salutation'];
2248
        if (!empty($salutation) && ($countryIso == 'DE' || $countryIso == 'NL')) {
2249
            $create['shipping_address']['title'] = ($salutation == 'ms' ? 'Frau' : 'Herr');//German names
2250
        }
2251
2252
        $billingStreet = $form['register']['billing']['street'];
2253
        $billingStreetNumber = $form['register']['billing']['streetnumber'];
2254
        if (!empty($billingStreet)) {
2255
            if ($countryIso == 'DE' || $countryIso == 'NL') {
2256
                if ($this->assertMinimumVersion('5.0.0')) {
2257
                    preg_match('(^(?P<street>.+)\\s+(?P<number>\\d+\\S*)$)', $billingStreet, $matches);
2258
2259
                    $create['shipping_address']['street_name'] = $matches['street'];
2260
                    $create['shipping_address']['street_number'] = $matches['number'];
2261
                } else {
2262
                    $create['shipping_address']['street_name'] = $form['register']['billing']['street'];
2263
                    $create['shipping_address']['street_number'] = $billingStreetNumber;
2264
                }
2265
            } else {
2266
                $create['shipping_address']['street_address'] = $billingStreet . ' ' . $billingStreetNumber;
2267
            }
2268
        }
2269
2270
        return $create;
2271
    }
2272
2273
    /**
2274
     * Helper method to read the color-config options properly.
2275
     *
2276
     * @param $config Enlight_Config
2277
     * @return mixed
2278
     */
2279
    private function getColorConfigOptions($config)
2280
    {
2281
        $options = array();
2282
        $checkoutButtonColor = $config->get('checkoutButtonColor');
2283
        $checkoutButtonTextColor = $config->get('checkoutButtonTextColor');
2284
        $checkoutCheckboxColor = $config->get('checkoutCheckboxColor');
2285
        $checkoutCheckboxCheckMarkColor = $config->get('checkoutCheckboxCheckmarkColor');
2286
        $checkoutHeaderColor = $config->get('checkoutHeaderColor');
2287
        $checkoutLinkColor = $config->get('checkoutLinkColor');
2288
2289
        if (!empty($checkoutButtonColor) && $checkoutButtonColor !== "#") {
2290
            $options['color_button'] = $checkoutButtonColor;
2291
        }
2292
        if (!empty($checkoutButtonTextColor) && $checkoutButtonTextColor !== "#") {
2293
            $options['color_button_text'] = $checkoutButtonTextColor;
2294
        }
2295
        if (!empty($checkoutCheckboxColor) && $checkoutCheckboxColor !== "#") {
2296
            $options['color_checkbox'] = $checkoutCheckboxColor;
2297
        }
2298
        if (!empty($checkoutCheckboxCheckMarkColor) && $checkoutCheckboxCheckMarkColor !== "#") {
2299
            $options['color_checkbox_checkmark'] = $checkoutCheckboxCheckMarkColor;
2300
        }
2301
        if (!empty($checkoutHeaderColor) && $checkoutHeaderColor !== "#") {
2302
            $options['color_header'] = $checkoutHeaderColor;
2303
        }
2304
        if (!empty($checkoutLinkColor) && $checkoutLinkColor !== "#") {
2305
            $options['color_link'] = $checkoutLinkColor;
2306
        }
2307
2308
        return $options;
2309
    }
2310
2311
    /**
2312
     * @param $view Enlight_View_Default
2313
     * @param $config Enlight_Config
2314
     */
2315
    private function getViewConfig($view, $config)
2316
    {
2317
        /** @var sAdmin $adminModule */
2318
        $adminModule = $this->get('modules')->Admin();
2319
        $session = $this->get('session');
2320
        $sCountry = $session['sCountry'];
0 ignored issues
show
Unused Code introduced by
$sCountry is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2321
        $view->assign('sCountryId', $session['sCountry']);
2322
        $view->assign('sPayments', $this->filterPayments($adminModule->sGetPaymentMeans()));
2323
        $view->assign('sCountryList', $adminModule->sGetCountryList());
2324
        $view->assign('KlarnaHideCheckoutSteps', true);
2325
        $view->assign('KlarnaShowB2bSelect', (bool)$config->get('showB2bSelect'));
2326
        $view->assign('KlarnaShowBasket', (bool)$config->get('showMiniBasket'));
2327
        $view->assign('KlarnaShowDispatch', (bool)$config->get('showDispatch'));
2328
        $view->assign(
2329
            'KlarnaCDNLink',
2330
            $this->buildCDNLink()
2331
        );
2332
        $view->assign(
2333
            'KlarnaLoggedInUser',
2334
            $view->sUserData['billingaddress']['lastname'] == 'Klarna Checkout'
2335
        );
2336
        $view->assign(
2337
            'KlarnaShowLogin',
2338
            $this->getShowLoginConfig($config, $view->sUserData['billingaddress']['lastname'])
2339
        );
2340
        $view->assign(
2341
            'KlarnaDisplayType',
2342
            $this->getKlarnaDisplayType($config)
2343
        );
2344
        $view->assign(
2345
            'KlarnaPositionOrder',
2346
            $this->getPositionOrder($config)
2347
        );
2348
    }
2349
2350
    /**
2351
     * Helper method to get the config whether or not to show the login-panel in the klarna-checkout.
2352
     *
2353
     * @param $config Enlight_Config
2354
     * @param $lastName string
2355
     * @return bool
2356
     */
2357
    private function getShowLoginConfig($config, $lastName)
2358
    {
2359
        return (bool)$config->get('showLoginPanel') && $lastName == 'Klarna Checkout';
2360
    }
2361
2362
    /**
2363
     * Helper method to read all countries.
2364
     * Reads all countries connected to a locale by the iso.
2365
     * Additionally reads out if that country is configured for the klarna-payment method.
2366
     * @example array(
2367
         array(
2368
             'id' => 1,
2369
             'localeId' => 17,
2370
             'countryname' => 'Germany',
2371
             'configured' => 0
2372
         ),
2373
         array(
2374
             'id' => 4,
2375
             'localeId' => 22,
2376
             'countryname' => 'Austria',
2377
             'configured' => 1
2378
         )
2379
     );
2380
     * @return array
2381
     */
2382
    private function getAllCountries()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
2383
    {
2384
        if (empty($this->countries)) {
2385
            $sql = "SELECT cl.id, cc.id as countryId, cl.territory, cc.countryname, IF(pmc.countryID IS NULL, IF(pmc2.countryID IS NULL, 1, 0), 1) as configured
2386
                FROM s_core_countries cc
2387
                INNER JOIN s_core_locales cl
2388
                    ON cl.locale LIKE CONCAT('%_', cc.countryiso)
2389
                LEFT JOIN s_core_paymentmeans_countries pmc
2390
                    ON cc.id = pmc.countryID
2391
                    AND pmc.paymentID = (SELECT id FROM s_core_paymentmeans WHERE action='payment_klarna')
2392
                LEFT JOIN s_core_paymentmeans_countries pmc2
2393
                    ON pmc2.paymentID = (SELECT id FROM s_core_paymentmeans WHERE action='payment_klarna')
2394
                WHERE cc.active = 1
2395
                GROUP BY cc.countryname
2396
                ORDER BY cc.position, cc.countryname";
2397
2398
            $result = Shopware()->Db()->fetchAssoc($sql, array());
2399
2400
            // Load translations if available
2401
            $this->countries = array_map(function ($country) {
2402
                $country['id'] = $country['countryId'];
2403
                return Shopware()->Modules()->Admin()->sGetCountryTranslation($country);
2404
            }, $result);
2405
        }
2406
2407
        return $this->countries;
2408
    }
2409
2410
    /**
2411
     * Helper method to find the correct display-type for the frontend.
2412
     * Will return the value configured in the plugin-config, if there is at least one more payment-mean besides klarna.
2413
     * @param $config Enlight_Config
2414
     * @return int
2415
     */
2416
    private function getKlarnaDisplayType($config)
2417
    {
2418
        if (!$this->getOtherPayments()) {
2419
            return 2;
2420
        }
2421
        return $config->get('displayType');
2422
    }
2423
2424
    /**
2425
     * Helper method to find other payment-means besides klarna.
2426
     * @return bool
2427
     */
2428
    private function getOtherPayments()
2429
    {
2430
        $payments = $this->Application()->Modules()->Admin()->sGetPaymentMeans();
2431
2432
        foreach ($payments as $payment) {
2433
            if ($payment['action'] != 'payment_klarna') {
2434
                return true;
2435
            }
2436
        }
2437
2438
        return false;
2439
    }
2440
2441
    /**
2442
     * Helper method to figure out whether or not to show the extra klarna checkout button.
2443
     * @return bool
2444
     */
2445
    private function getShowCheckoutButton($user)
2446
    {
2447
        if (!empty($user['additional']['payment']['id']) && $user['additional']['payment']['id'] != $this->getPayment()->getId()) {
2448
            return true;
2449
        }
2450
2451
        return false;
2452
    }
2453
2454
    /**
2455
     * Helper method to get the correct order for the elements
2456
     *
2457
     * @param $config Enlight_Config
2458
     * @return array Array with the order of the elements
2459
     */
2460
    private function getPositionOrder($config)
2461
    {
2462
        $loginPanel = 'login_panel';
2463
        $miniBasket = 'mini_basket';
2464
        $dispatch = 'dispatch';
2465
        $payments = 'payments';
2466
        switch ($config->get('positionOrder')) {
2467
            case 1:
2468
                return array($loginPanel, $miniBasket, $dispatch, $payments);
2469
            case 2:
2470
                return array($loginPanel, $miniBasket, $payments, $dispatch);
2471
            case 3:
2472
                return array($dispatch, $payments, $loginPanel, $miniBasket);
2473
            case 4:
2474
            default:
2475
                return array($payments, $dispatch, $loginPanel, $miniBasket);
2476
        }
2477
    }
2478
2479
    /**
2480
     * Helper method to build the proper cdn-link for the image in the tabs-layout.
2481
     * @return string
2482
     */
2483
    private function buildCDNLink()
2484
    {
2485
        $validLocales = array(
2486
            'de_de',
2487
            'de_at',
2488
            'en_us',
2489
            'en_gb',
2490
            'fi_fi',
2491
            'sv_se',
2492
            'nb_no',
2493
        );
2494
        $locale = str_replace('-', '_', $this->getLocale());
2495
2496
        if (!in_array($locale, $validLocales)) {
2497
            $locale = 'en_gb';
2498
        }
2499
        return "https://cdn.klarna.com/1.0/shared/image/generic/badge/{$locale}/checkout/long-no-klarna-logo.png";
2500
    }
2501
2502
    /**
2503
     * Helper method to read the customer-data from the klarna order-object.
2504
     * @param Klarna_Checkout_Order $order
2505
     * @return array
2506
     */
2507
    private function getKlarnaCustomerData($order)
2508
    {
2509
        $billingAddress = $order['billing_address'];
2510
2511
        return array(
2512
            'personal' => array(
2513
                'customer_type' => 'private',
2514
                'salutation' => $billingAddress['title'],
2515
                'firstname' => $billingAddress['given_name'],
2516
                'lastname' => $billingAddress['family_name'],
2517
                'email' => $billingAddress['email'],
2518
                'birthday' => $order['customer']['date_of_birth'],
2519
                'phone' => $billingAddress['phone']
2520
            ),
2521
            'billing' => array(
2522
                'street' => $billingAddress['street_name'] . ' ' . $billingAddress['street_number'],
2523
                'zipcode' => $billingAddress['postal_code'],
2524
                'city' => $billingAddress['city']
2525
            )
2526
        );
2527
    }
2528
2529
    /**
2530
     * Returns an array with all translations
2531
     * @return array
2532
     */
2533
    private function getTranslationArray()
2534
    {
2535
        return array(
2536
            'en_GB' => array(
2537
                'testDrive' => array(
2538
                    'label' => 'Activate test-modus'
2539
                ),
2540
                'merchantId' => array(
2541
                    'label' => 'API merchant ID (EID)'
2542
                ),
2543
                'sharedSecret' => array(
2544
                    'label' => 'API-Secret (sharedsecret)'
2545
                ),
2546
                'termSiteId' => array(
2547
                    'label' => 'Shopsite including the terms and conditions'
2548
                ),
2549
                'allowSeparateShippingAddress' => array(
2550
                    'label' => 'Enable differing shipping address'
2551
                ),
2552
                'supportPackstation' => array(
2553
                    'label' => 'Support DHL-packstation',
2554
                    'helpText' => 'The differing shipping address must be enabled'
2555
                ),
2556
                'postnumberField' => array(
2557
                    'label' => 'Alternative field for the DHL-postnumber'
2558
                ),
2559
                'mandatoryPhone' => array(
2560
                    'label' => 'Phone mandatory field'
2561
                ),
2562
                'mandatoryBirthday' => array(
2563
                    'label' => 'Birthday mandatory field'
2564
                ),
2565
                'disableAutofocus' => array(
2566
                    'label' => 'Disable auto-focus'
2567
                ),
2568
                'showKlarnaButton' => array(
2569
                    'label' => 'Show klarna-checkout button'
2570
                ),
2571
                'checkoutButtonColor' => array(
2572
                    'label' => 'Checkout Button Color'
2573
                ),
2574
                'checkoutButtonTextColor' => array(
2575
                    'label' => 'Checkout Buttontext Color'
2576
                ),
2577
                'checkoutCheckboxColor' => array(
2578
                    'label' => 'Checkout Checkbox Color'
2579
                ),
2580
                'checkoutCheckboxCheckmarkColor' => array(
2581
                    'label' => 'Checkout Checkbox Tick Color'
2582
                ),
2583
                'checkoutHeaderColor' => array(
2584
                    'label' => 'Checkout Header Color'
2585
                ),
2586
                'checkoutLinkColor' => array(
2587
                    'label' => 'Checkout Link Color'
2588
                ),
2589
                'KlarnaExternalPayments' => array(
2590
                    'label' => 'Display external payment-methods in klarna checkout',
2591
                    'helpText' => 'Your klarna-account has to be unlocked for this feature',
2592
                ),
2593
                'displayType' => array(
2594
                    'label' => 'Klarna Checkout display-type',
2595
                    'store' => array(
2596
                        array(1, 'Display tabs'),
2597
                        array(2, 'Display only klarna checkout'),
2598
                        array(3, 'One-page display')
2599
                    ),
2600
                ),
2601
                'showB2bSelect' => array(
2602
                    'label' => 'Show B2B-select',
2603
                    'helpText' => 'Displays a new select-box containing "Private customer" and "Company" in the klarna checkout'
2604
                ),
2605
                'showLoginPanel' => array(
2606
                    'label' => 'Show login-panel',
2607
                    'helpText' => 'Displays a login-panel in the klarna-checkout',
2608
                ),
2609
                'showMiniBasket' => array(
2610
                    'label' => 'Show mini-basket',
2611
                    'helpText' => 'Displays a small overview of the basket in the klarna-checkout',
2612
                ),
2613
                'showDispatch' => array(
2614
                    'label' => 'Show shipping-country and -method',
2615
                    'helpText' => 'Shows a shipping-country and shipping-method select in the klarna-checkout'
2616
                ),
2617
                'partPaymentWidget' => array(
2618
                    'label' => 'Show partial-payment-widget on detail-page'
2619
                ),
2620
                'convertShippingFee' => array(
2621
                    'label' => 'Convert shipping-costs to an order-position'
2622
                ),
2623
                'statusId' => array(
2624
                    'label' => 'Payment status after order'
2625
                ),
2626
                'activateStatusId' => array(
2627
                    'label' => 'Payment status after activation'
2628
                ),
2629
                'cancelStatusId' => array(
2630
                    'label' => 'Payment status after cancellation'
2631
                )
2632
            )
2633
        );
2634
    }
2635
2636
    /**
2637
     * Helper method to update the klarna-payment when updating from any version to >= 2.0 of klarna.
2638
     * It adds "austria" to the valid countries.
2639
     */
2640
    private function updatePayment()
2641
    {
2642
        /** @var \Shopware\Components\Model\ModelManager $manager */
2643
        $manager = $this->get('models');
2644
        $payment = $manager->getRepository('Shopware\Models\Payment\Payment')->findOneBy(array(
2645
            'name' => 'klarna_checkout'
2646
        ));
2647
2648
        if (empty($payment)) {
2649
            return;
2650
        }
2651
2652
        $updateNeeded = true;
2653
        $countries = $payment->getCountries();
2654
        /** @var Shopware\Models\Country\Country $country */
2655
        foreach ($countries as $country) {
2656
            if ($country->getIso() == 'AT') {
2657
                $updateNeeded = false;
2658
            }
2659
        }
2660
2661
        if ($updateNeeded) {
2662
            $countries->add($manager->getRepository('Shopware\Models\Country\Country')->findOneBy(array('iso' => 'AT')));
2663
            $payment->setCountries($countries);
2664
2665
            $manager->persist($payment);
2666
            $manager->flush();
2667
        }
2668
    }
2669
2670
    /**
2671
     * @return bool
2672
     */
2673
    public function isKlarnaUser()
2674
    {
2675
        $session = $this->get('session');
2676
        if (!$session->offsetGet('sUserId')) {
2677
            return false;
2678
        }
2679
        $email = $session->offsetGet('sUserMail');
2680
        $sessionId = $session->offsetGet('sessionId');
2681
        if (!preg_match('#.{' . strlen($sessionId) . '}@klarna.com#', $email)) {
2682
            return false;
2683
        }
2684
2685
        return true;
2686
    }
2687
2688
    /**
2689
     * Helper method to find and remove all klarna-users older than 24 hours
2690
     */
2691
    public function removeKlarnaUsers()
2692
    {
2693
        $connection = Shopware()->Models()->getConnection();
2694
2695
        $builder = $connection->createQueryBuilder();
2696
        $builder->select('user.id')
2697
            ->from('s_user', 'user')
2698
            ->innerJoin(
2699
                'user',
2700
                's_user_billingaddress',
2701
                'billing',
2702
                'billing.userID = user.id'
2703
            )
2704
            ->where('billing.lastname = :lastName')
2705
            ->andWhere('DATE_SUB(NOW(), INTERVAL 1 DAY) >= user.lastlogin')
2706
            ->setParameter(':lastName', 'Klarna Checkout');
2707
2708
        $ids = array_column($builder->execute()->fetchAll(), 'id');
2709
2710
        if (empty($ids)) {
2711
            return;
2712
        }
2713
2714
        $builder = $connection->createQueryBuilder();
2715
        $builder->delete('s_user')->where('id IN (:ids)')->setParameter(
2716
            'ids',
2717
            $ids,
2718
            Connection::PARAM_INT_ARRAY
2719
        )->execute();
2720
2721
        $builder->delete('s_user_billingaddress')->where('userID IN (:ids)')->setParameter(
2722
            'ids',
2723
            $ids,
2724
            Connection::PARAM_INT_ARRAY
2725
        )->execute();
2726
2727
        $builder->delete('s_user_shippingaddress')->where('userID IN (:ids)')->setParameter(
2728
            'ids',
2729
            $ids,
2730
            Connection::PARAM_INT_ARRAY
2731
        )->execute();
2732
    }
2733
    
2734
    /**
2735
     * Method checks if selected country is valid for use with klarna
2736
     * 
2737
     * @param string $countryId
2738
     * @return boolean
2739
     */
2740
    protected function checkValidKlarnaCountry($countryId) {
2741
        $countries = $this->getPayment()->getCountries();
2742
        foreach ($countries as $country) {
2743
            $allowedCountries[] = $country->getId();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$allowedCountries was never initialized. Although not strictly required by PHP, it is generally a good practice to add $allowedCountries = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2744
        }
2745
2746
        return in_array($countryId, $allowedCountries);
0 ignored issues
show
Bug introduced by
The variable $allowedCountries does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2747
    }
2748
    
2749
2750
    /**
2751
     * Helper method to read all payments, that should be displayed in the klarna checkout.
2752
     * @param $basket
2753
     * @return array
2754
     */
2755
    private function getExternalPaymentMethods($basket)
2756
    {
2757
        $payments = Shopware()->Models()->getRepository('Shopware\Models\Attribute\Payment')->findBy(array(
2758
            'swagKlarnaShowInKlarnaIframe' => 1,
2759
            'swagKlarnaAllowInPaymentContainer' => 0
2760
        ));
2761
2762
        $externalPayments = array();
2763
        $externalCheckouts = array();
2764
        /** @var Shopware\Models\Attribute\Payment $payment */
2765
        foreach ($payments as $payment) {
2766
            $paymentObj = $payment->getPayment();
2767
            if (is_null($paymentObj)){
2768
                $paymentName = false;
2769
            } else {
2770
                $paymentName = $paymentObj->getName();
2771
            }
2772
            
2773
            if(!$paymentName){
2774
                continue;
2775
            }            
2776
            
2777
            if ($paymentName && $paymentName == 'klarna_checkout') {
2778
                continue;
2779
            }
2780
            $paymentArray = array(
2781
                'name' => $payment->getPayment()->getDescription(),
2782
                'redirect_uri' => $this->getRedirectUri() . '/paymentId/' . $payment->getPaymentId()
2783
            );
2784
2785
            if ($fee = $this->getFee($payment->getPayment(), $basket)) {
2786
                $paymentArray['fee'] = $fee;
2787
            }
2788
2789
            if ($description = $payment->getPayment()->getAdditionalDescription()) {
2790
                //Shorten the description to max. 500 characters
2791
                $description = strip_tags($description);
2792
                $description = preg_replace('#<!--.*-->#ms', '', $description);
2793
                $paymentArray['description'] = substr($description, 0, 497) . '...';
2794
            }
2795
2796
            //Only add to external checkouts if an image is set and if the shop supports SSL
2797
            if (Shopware()->Shop()->getSecure() && $image = $this->getImageForKlarna($payment)) {
2798
                $paymentArray['image_uri'] = $image;
2799
                $externalCheckouts[] = $paymentArray;
2800
            }
2801
2802
            $externalPayments[] = $paymentArray;
2803
        }
2804
2805
        return array($externalPayments, $externalCheckouts);
2806
    }
2807
2808
    /**
2809
     * @param Shopware\Models\Payment\Payment $payment
2810
     * @param $basket
2811
     * @return bool
2812
     */
2813
    private function getFee($payment, $basket)
2814
    {
2815
        $fee = 0;
2816
        $amount = str_replace(',', '.', $basket['Amount']);
2817
2818
        if ($surcharge = $payment->getSurcharge()) {
2819
            $fee += $surcharge;
2820
            $amount += $surcharge;
2821
        }
2822
2823
        if ($percent = $payment->getDebitPercent()) {
2824
            $fee += round($amount / 100 * $percent, 3);
2825
        }
2826
2827
        return round($fee * 100);
2828
    }
2829
2830
    /**
2831
     * Helper method to get the redirect-uri
2832
     * @return string
2833
     */
2834
    private function getRedirectUri()
2835
    {
2836
        return Shopware()->Front()->Router()->assemble(array(
2837
            'controller' => 'PaymentKlarna',
2838
            'action' => 'setPayment'
2839
        ));
2840
    }
2841
2842
    /**
2843
     * Helper method to read the image for the klarna-checkout if set
2844
     * @param Shopware\Models\Attribute\Payment $payment
2845
     * @return null|string
2846
     */
2847
    private function getImageForKlarna($payment)
2848
    {
2849
        $media = $payment->getSwagKlarnaKlarnaMedia();
2850
        if (!$payment->getSwagKlarnaShowInKlarnaIframe() || !empty($media)) {
2851
            if ($this->assertMinimumVersion('5.1') && version_compare(Shopware::VERSION, '5.2.0', '<=') ) {
2852
                $media = $this->get('shopware_media.media_service')->getUrl($media);
2853
            } else {
2854
                /** @var Enlight_Controller_Front $front */
2855
                $front = $this->get('front');
2856
                $request = $front->Request();
2857
                if ($request && $request->getHttpHost()) {
2858
                    $url = ($request->isSecure() ? 'https' : 'http') . '://' . $request->getHttpHost() . $request->getBasePath() . "/";
2859
                } else {
2860
                    $url = $front->Router()->assemble(array('controller' => 'index', 'module' => 'frontend'));
2861
                }
2862
		if (version_compare(Shopware::VERSION, '5.2.0', '>=')) {
2863
            		# make sure me get only the image name, path is set in case of upgarde from SW.5.1 to 5.2
2864
		        $end = end((explode('/', $media)));
0 ignored issues
show
Bug introduced by
explode('/', $media) cannot be passed to end() as the parameter $array expects a reference.
Loading history...
2865
			$media = $url . 'media/image/' . $end;
2866
		} else {
2867
	                $media = $url . $media;
2868
		}
2869
            }
2870
2871
            return $media;
2872
        }
2873
        return null;
2874
    }
2875
2876
    /**
2877
     * Helper method to filter the available payment-means.
2878
     * @param $sGetPaymentMeans
2879
     * @return array
2880
     */
2881
    private function filterPayments($sGetPaymentMeans)
2882
    {
2883
        $paymentArray = array();
2884
        foreach ($sGetPaymentMeans as $paymentMean) {
2885
            if (!$this->isPaymentAllowed($paymentMean)) {
2886
                continue;
2887
            }
2888
2889
            $paymentArray[] = $paymentMean;
2890
        }
2891
        return $paymentArray;
2892
    }
2893
2894
    /**
2895
     * Helper method to check if a payment is allowed to be
2896
     * @param $payment
2897
     * @return bool
2898
     */
2899
    private function isPaymentAllowed($payment)
2900
    {
2901
        if ($payment['name'] == 'klarna_checkout') {
2902
            return false;
2903
        }
2904
        $connection = Shopware()->Models()->getConnection();
2905
2906
        $builder = $connection->createQueryBuilder();
2907
        $builder->select('swag_klarna_allow_in_payment_container', 'swag_klarna_show_in_klarna_iframe')
2908
            ->from('s_core_paymentmeans_attributes')
2909
            ->where('paymentmeanID = :id')
2910
            ->setParameter(':id', $payment['id']);
2911
2912
        $result = reset($builder->execute()->fetchAll());
0 ignored issues
show
Bug introduced by
$builder->execute()->fetchAll() cannot be passed to reset() as the parameter $array expects a reference.
Loading history...
2913
        return !$result['swag_klarna_allow_in_payment_container'] && !$result['swag_klarna_show_in_klarna_iframe'];
2914
    }
2915
2916
    /**
2917
     * Builds the new klarna version-string.
2918
     *
2919
     * @param Klarna $klarna
2920
     * @return string
2921
     */
2922
    private function buildKlarnaVersion(Klarna $klarna)
2923
    {
2924
        $versionInfo = array(
2925
            'Shopware',
2926
            $this->Application()->Config()->version,
2927
            'KCO-Plugin',
2928
            $this->getVersion(),
2929
            $klarna->getVersion()
2930
        );
2931
2932
        return implode(':', $versionInfo);
2933
    }
2934
2935
    /**
2936
     * Helper method to find out if the kpm plugin is active
2937
     */
2938
    public function isKpmActive()
2939
    {
2940
        /** @var Doctrine\DBAL\Query\QueryBuilder $queryBuilder */
2941
        $queryBuilder = Shopware()->Models()->getConnection()->createQueryBuilder();
2942
2943
        $result = $queryBuilder->select('plugin.id')
2944
            ->from('s_core_plugins', 'plugin')
2945
            ->where('plugin.name = :name')
2946
            ->andWhere('plugin.active = 1')
2947
            ->setParameter('name', 'SwagPaymentKlarnaKpm')
2948
            ->execute()
2949
            ->fetchColumn();
2950
2951
        return !empty($result);
2952
    }
2953
2954
    /**
2955
     * Helper method to find out if the klarna kco payment is active.
2956
     * Necessary to disable the checkout-button.
2957
     * @param array $user
2958
     * @return bool
2959
     */
2960
    public function isKlarnaKcoPaymentActive($user)
2961
    {
2962
        $payment = $this->getPayment();
2963
        if (!$payment) {
2964
            return false;
2965
        }
2966
        $data = $this->get('modules')->Admin()->sGetPaymentMeanById($payment->getId(), $user);
2967
        if (empty($data) || $data['id'] != $payment->getId()) {
2968
            return false;
2969
        }
2970
        return true;
2971
    }
2972
}
2973