getUserIdByReference()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 13
rs 9.4285
1
<?php
2
3
use Shopware\Components\CSRFWhitelistAware;
4
5
/**
6
 * Klarna payment controller
7
 */
8
class Shopware_Controllers_Frontend_PaymentKlarna extends Shopware_Controllers_Frontend_Payment implements CSRFWhitelistAware
9
{
10
    /**
11
     * @var Shopware_Plugins_Frontend_SwagPaymentKlarna_Bootstrap
12
     */
13
    private $plugin;
14
15
    /**
16
     * @var Enlight_Config
17
     */
18
    private $config;
19
20
    private $basket;
21
22
    private $admin;
23
24
    private $session;
25
26
    /**
27
     * Init method that get called automatically
28
     *
29
     * Set class properties
30
     */
31
    public function init()
32
    {
33
        $this->admin = Shopware()->Modules()->Admin();
34
        $this->session = Shopware()->Session();
35
        $this->plugin = Shopware()->Container()->get('plugins')->Frontend()->SwagPaymentKlarna();
36
        $this->config = $this->plugin->Config();
37
    }
38
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function preDispatch()
44
    {
45
46
        if (in_array($this->Request()->getActionName(), ['push', 'saveFormData'])) {
47
            $this->Front()->Plugins()->ViewRenderer()->setNoRender();
48
        }
49
    }
50
    
51
    /**
52
     * whitelists indexAction for SW 5.2 compatibility
53
     */
54
    public function getWhitelistedCSRFActions()
55
    {
56
        return [
57
            'index',
58
            'express',
59
            'push',
60
            'login',
61
            'return',
62
            'showIframe',
63
            'calculateShippingCosts',
64
            'savePayment',
65
            'addVoucher',
66
            'deleteArticle',
67
            'saveFormData',
68
            'setPayment',
69
            'otherPayment',
70
        ];
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 View Code Duplication
    public function get($name)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
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...
77
    {
78
        if (version_compare(Shopware::VERSION, '4.2.0', '<') && Shopware::VERSION != '___VERSION___') {
79
            if ($name == 'pluginlogger') {
80
                $name = 'log';
81
            }
82
            $name = ucfirst($name);
83
            return Shopware()->Bootstrap()->getResource($name);
84
        }
85
        return parent::get($name);
86
    }
87
    
88
    /**
89
     * Index action method.
90
     *
91
     * Forwards to correct the action.
92
     */
93
    public function indexAction()
94
    {
95
        $this->redirect(['controller' => 'payment_klarna', 'action' => 'showIframe']);
96
    }
97
98
    /**
99
     * Express payment action method.
100
     */
101
    public function expressAction()
102
    {
103
        if (!empty($this->session->PaypalResponse)) {
104
            $this->plugin->klarnaLog("Paypal Payment in Progress detected Redirecting To Index Page", 3);
105
            $this->redirect(
106
                [
107
                    'controller' => 'index',
108
                    'action' => 'index',
109
                ]
110
            );
111
            return;
112
        }
113
        
114
        if ($this->Request()->getPost('sCountry')) {
115
            $this->session['sCountry'] = (int)$this->Request()->getPost('sCountry');
116
            $this->session["sState"] = 0;
117
            $this->session["sArea"] = Shopware()->Db()->fetchOne("
118
                SELECT areaID FROM s_core_countries WHERE id = ?
119
            ", [$this->session['sCountry']]);
120
            unset($this->session->KlarnaOrder);
121
            $this->session['sChangedCountry'] = (int)$this->Request()->getPost('sCountry');
122
        }
123
        $this->forward('index');
124
    }
125
126
127
    /**
128
     * Express Iframe Test
129
     */
130
    public function showIframeAction()
131
    {
132
        $this->basket = $this->get('modules')->Basket()->sGetBasket();
133
         $preFill = $this->config['preFillCheckout'];
134
        if ($this->isUserLoggedIn()) {
135
            $user = Shopware()->Modules()->Admin()->sGetUserData();
136
        }
137
138
        $paymentIdDebug = $this->plugin->getPayment()->getId();
139
140
        // set payment to klarna checkout
141
        $this->session['sPaymentID'] = $this->plugin->getPayment()->getId();
142
143
        $postedCountry = null;
144
        // Register Custom Template
145
        $this->View()->loadTemplate("frontend/checkout/confirm.tpl");
146
        // update dispatch or delivery country in case form was submitted
147
        if ($this->Request()->isPost()) {
148
            // set klarnaPrefill, in case User ovverides Setting with checkbox
149
            if ($this->Request()->getParam('klarnaPreFill') == "on") {
150
                $this->session['klarnaUserPreFill'] = true;
151
            }
152
153
            $this->setDispatch($this->Request()->getPost('sDispatch'));
154
            $postedCountry = $this->Request()->getPost('sCountry');
155
            if (!empty($postedCountry)) {
156
                $shopCountryId = $this->session['sCountry'];
157
                $validKlarnaCountry = $this->plugin->checkValidKlarnaCountry($postedCountry);
158
                if (!$validKlarnaCountry) {
159
                    $this->redirect(['controller' => 'payment_klarna', 'action' => 'otherPayment']);
160
                    return;
161
                }
162
                $shopCountryId = (string)$shopCountryId;
163
                if ($shopCountryId != $postedCountry) {
164
                    $this->session['sCountry'] = $postedCountry;
165
                    // unset klarnaOrder so it will be created with new countryID
166
                    unset($this->session['KlarnaOrder']);
167
                }
168
            }
169
            //$this->redirect(array('controller' => 'payment_klarna', 'action' => 'showIframe'));
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% 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...
170
        } else {
171
            $this->setDispatch($this->session->sDispatch, $paymentIdDebug);
172
        }
173
        // set shipping costs (Overwrites $session->sCountry!)
174
        $debugShipping = $this->getShippingCosts();
175
        if ($postedCountry) {
176
            $this->session['sCountry'] = $postedCountry;
177
        } else {
178
            // set Default Country
179
            $bootstrap = $this->get('plugins')->get('Frontend')->get('SwagPaymentKlarna');
180
            $this->session['sCountry'] = $bootstrap->getCountryByShop(Shopware()->Shop());
181
        }
182
183
        $this->basket['sShippingcosts'] = $debugShipping['brutto'];
184
        $this->basket['sShippingcostsWithTax'] = $debugShipping['brutto'];
185
        $this->basket['sShippingcostsNet'] = $debugShipping['netto'];
186
        $this->basket['sShippingcostsTax'] = $debugShipping['tax'];
187
188
        // set missing basket vars for use in view
189
        $this->basket['AmountWithTaxNumeric'] = floatval(
190
            str_replace(',', '.', $this->basket['Amount'])
191
        ) + floatval(
192
            str_replace(',', '.', $debugShipping['brutto'])
193
        );
194
        $this->basket['AmountNetNumeric'] = floatval(str_replace(',', '.', $this->basket['AmountNet']));
195
196
        $klarnaConnector = $this->plugin->getConnector();
197
        $shop = $this->plugin->Application()->Shop();
198
199
        $create = [];
200
        $create['cart']['items'] = $this->plugin->getCheckoutCart($this->basket);
201
        $create['merchant'] = $this->plugin->getCheckoutMerchant();
202
203
        $create['purchase_country'] = $this->plugin->getCountryIsoById($this->session['sCountry']);
204
        $create['purchase_currency'] = $shop->getCurrency()->toString();
205
        $create['locale'] = $this->plugin->getLocale(false, $create['purchase_country']);
206
        $create['options'] = $this->plugin->getCheckoutOptions();
207
208
        if ($this->config->get('KlarnaExternalPayments')) {
209
            list($create['external_payment_methods'], $create['external_checkouts']) = $this->plugin
210
                ->getExternalPaymentMethods($this->basket);
211
        }
212
213
        if ($this->config->get('disableAutofocus')) {
214
            $create['gui']['options'] = ['disable_autofocus'];
215
        }
216
217
        // set Prefill Information
218
219
        if (($preFill == true) || ($this->session['klarnaUserPreFill'] == true)) {
220
            $this->session['klarnaPreFill'] = true;
221
            if (empty($session['sCountry'])) {
0 ignored issues
show
Bug introduced by
The variable $session seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
222
                $bootstrap = $this->get('plugins')->get('Frontend')->get('SwagPaymentKlarna');
223
                $countryId = $bootstrap->getCountryByShop($shop);
224
            } else {
225
                $countryId = $session['sCountry'];
226
            }
227
            if ($user['additional']['countryShipping']['id'] == $countryId
228
                && $user['billingaddress']['zipcode'] != '00000'
229
            ) {
230
                $create['customer'] = $this->plugin->getCheckoutCustomer($user);
0 ignored issues
show
Bug introduced by
The variable $user 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...
231
                if ($user['additional']['countryShipping']['id'] == $user['additional']['country']['id']) {
232
                    $create['shipping_address'] = $this->plugin->getCheckoutAddress($user, 'billing');
233
                } else {
234
                    $create['shipping_address'] = $this->plugin->getCheckoutAddress($user, 'shipping');
235
                }
236
            }
237
        } else {
238
            $this->session['klarnaPreFill'] = false;
239
        }
240
241
        // In case Customer fills Iframe and then logs in do not update existing klarnaOrder
242
        if (!empty($this->session['KlarnaOrder']) && !$this->isUserLoggedIn()) {
243
            $klarnaOrder = new Klarna_Checkout_Order($klarnaConnector, $this->session['KlarnaOrder']);
0 ignored issues
show
Documentation introduced by
$klarnaConnector 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...
244
            $update = [];
245
            $update['cart']['items'] = $this->plugin->getCheckoutCart($this->basket);
246
            $update['purchase_country'] = $this->plugin->getCountryIsoById($this->session['sCountry']);
247
248
            $klarnaOrder->fetch();
249
            // update basket and delivery country in case it changed
250
            $klarnaOrder->update($update);
251
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
252
        } else {
253
            $klarnaOrder = new Klarna_Checkout_Order($klarnaConnector);
0 ignored issues
show
Documentation introduced by
$klarnaConnector 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...
254
            $klarnaOrder->create($create);
255
        }
256
257
258
        try {
259
            $klarnaOrder->fetch();
260
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
261
        } catch (Exception $e) {
262
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
263
            echo "Entschuldigung! Ein Verbindungsfehler ist aufgetreten. Bitte aktualisieren Sie die Seite.\n";
264
            $this->plugin->klarnaLog(
265
                "Verbindungsfehler in onPreDispatchCheckout\nCode:" . $e->getCode() . "Nachricht:\n" . $e->getMessage(),
266
                1
267
            );
268
        }
269
270
        $this->session->KlarnaOrder = $klarnaOrder->getLocation();
271
272
        // Delete old perhaps cancelled Klarna Order
273
274
        if ($klarnaOrder['status'] !== "checkout_incomplete") {
275
            unset($this->session->KlarnaOrder);
276
        }
277
278
        $userAdditionalArray = [];
279
        $userAdditionalArray['additional']['charge_vat'] = 1;
280
281
        $userPayment = [];
282
        $userPayment['id'] = $this->plugin->getPayment()->getId();
283
284
        // persist basket changes
285
        Shopware()->Session()->sOrderVariables['sBasket'] = $this->basket;
286
287
        // Klarna Iframe Information
288
        $this->View()->assign('KlarnaOrder', $klarnaOrder->marshal());
289
290
        // Klarna Prefill checkBox
291
        if ($this->isUserLoggedIn()) {
292
               $this->View()->assign('KlarnaPreFillSelect', !$this->session['klarnaPreFill']);
293
        }
294
295
        // Iframe Backend Config
296
        $this->plugin->getViewConfig($this->View(), $this->config);
297
        $this->View()->sBasket = $this->basket;
298
        $this->View()->sDispatches = $this->getDispatches($paymentIdDebug);
299
        if ($postedCountry) {
300
            $this->session['sCountry'] = $postedCountry;
301
        }
302
        $this->View()->sDispatch = $this->getSelectedDispatch();
303
304
        // Neccessary if user is not logged in
305
        $this->View()->sPayment = $userPayment;
306
307
        $this->basket['sShippingcosts'] = $debugShipping['brutto'];
308
        $this->basket['sShippingcostsWithTax'] = $debugShipping['brutto'];
309
        $this->basket['sShippingcostsNet'] = $debugShipping['netto'];
310
        $this->basket['sShippingcostsTax'] = $debugShipping['tax'];
311
312
        $this->basket['sAmount'] = floatval($this->basket['Amount']) + floatval($this->basket['sShippingcosts']);
313
        $this->basket['sAmountNet'] = floatval($this->basket['AmountNetNumeric']) + floatval($debugShipping['netto']);
314
315
        $this->basket['sAmountTax'] = 1.9;
316
        $this->View()->sShippingcosts = $debugShipping['brutto'];
317
        $this->View()->sShippingcostsWithTax =  $debugShipping['brutto'];
318
        $this->View()->sShippingcostsNet = $debugShipping['netto'];
319
        $this->View()->sShippingcostsTax = $debugShipping['tax'];
320
        $this->View()->sAmount = $this->basket['AmountWithTaxNumeric'] ;
321
322
        $this->View()->sAmountNet = $this->basket['sAmountNet'];
323
        $this->View()->sAmountTax = $this->basket['sAmountTax'];
324
        $this->View()->assign('sUserData', $userAdditionalArray);
325
        $this->View()->sPayments = $this->plugin->filterPayments($this->admin->sGetPaymentMeans());
326
        $this->View()->sUserLoggedIn = $this->isUserLoggedIn();
327
    }
328
329
    /**
330
     * Add voucher to cart
331
     *
332
     * At failure view variable sVoucherError will give further information
333
     * At success return to cart / confirm view
334
     */
335
    public function addVoucherAction()
336
    {
337
        $basketObj = $this->get('modules')->Basket();
338
        if ($this->Request()->isPost()) {
339
            $voucher = $basketObj->sAddVoucher($this->Request()->getParam('sVoucher'));
340
            if (!empty($voucher['sErrorMessages'])) {
341
                $this->View()->assign('sVoucherError', $voucher['sErrorMessages'], null, Smarty::SCOPE_ROOT);
342
            }
343
        }
344
        $this->forward('showIframe');
345
    }
346
347
348
349
    /**
350
     * Get shipping costs as an array (brutto / netto) depending on selected country / payment
351
     *
352
     * @return array
353
     */
354
    public function getShippingCosts()
355
    {
356
        $country = $this->getSelectedCountry();
357
        $payment = $this->plugin->getPayment()->getId();
358
        if (empty($country) || empty($payment)) {
359
            return ['brutto' =>0, 'netto' =>0];
360
        }
361
        $shippingcosts = $this->admin->sGetPremiumShippingcosts($country);
362
        return empty($shippingcosts) ? ['brutto' =>0, 'netto' =>0] : $shippingcosts;
363
    }
364
365
    /**
366
     * Express Iframe Test
367
     */
368
    public function finishAction()
369
    {
370
        $connector = $this->plugin->getConnector();
371
        $klarnaOrder = new Klarna_Checkout_Order($connector, $this->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...
372
        $klarnaOrder->fetch();
373
        $this->View()->loadTemplate("frontend/checkout/finish.tpl");
374
        $this->View()->assign('KlarnaOrder', $klarnaOrder->marshal());
375
        // reset basket
376
        unset($this->session['KlarnaOrder']);
377
        unset($this->session['sBasketQuantity']);
378
        unset($this->session['sBasketAmount']);
379
    }
380
381
    /**
382
     * Change quantity of a certain product
383
     * @param sArticle = The article to update
384
     * @param sQuantity = new quantity
385
     * Forward to cart / confirm view after success
386
     */
387
    public function changeQuantityAction()
388
    {
389
        $basketObj = $this->get('modules')->Basket();
390
391
        if ($this->Request()->getParam('sArticle') && $this->Request()->getParam('sQuantity')) {
392
            $this->View()->sBasketInfo = $basketObj->sUpdateArticle(
393
                $this->Request()->getParam('sArticle'),
394
                $this->Request()->getParam('sQuantity')
395
            );
396
        }
397
        $this->redirect(['action' => $this->Request()->getParam('sTargetAction', 'showIframe')]);
398
    }
399
400
    /**
401
     * Delete an article from cart -
402
     * @param sDelete = id from s_basket identifying the product to delete
403
     * Forward to cart / confirmation page after success
404
     */
405
    public function deleteArticleAction()
406
    {
407
        $basketObj = $this->get('modules')->Basket();
408
409
        if ($this->Request()->getParam('sDelete')) {
410
            $basketObj->sDeleteArticle($this->Request()->getParam('sDelete'));
411
        }
412
        $this->forward($this->Request()->getParam('sTargetAction', 'index'));
413
    }
414
415
    /**
416
     * Get all dispatches available in selected country from sAdmin object
417
     *
418
     * @param null $paymentId
419
     * @return array|boolean list of dispatches
420
     */
421
    public function getDispatches($paymentId = null)
422
    {
423
        $country = $this->getSelectedCountry();
424
        $state = $this->getSelectedState();
425
        if (empty($country)) {
426
            return false;
427
        }
428
        $stateId = !empty($state['id']) ? $state['id'] : null;
429
        return $this->admin->sGetPremiumDispatches($country['id'], $paymentId, $stateId);
430
    }
431
432
    /**
433
     * Set the provided dispatch method
434
     *
435
     * @param int $dispatchId ID of the dispatch method to set
436
     * @param int|null $paymentId Payment id to validate
437
     * @return int set dispatch method id
438
     */
439
    public function setDispatch($dispatchId, $paymentId = null)
440
    {
441
        $supportedDispatches = $this->getDispatches($paymentId);
442
443
        // Iterate over supported dispatches, look for the provided one
444
        foreach ($supportedDispatches as $dispatch) {
0 ignored issues
show
Bug introduced by
The expression $supportedDispatches of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
445
            if ($dispatch['id'] == $dispatchId) {
446
                $this->session['sDispatch'] = $dispatchId;
447
                return $dispatchId;
448
            }
449
        }
450
451
        // If it was not found, we fallback to the default (head of supported)
452
        $defaultDispatch = array_shift($supportedDispatches);
453
        $this->session['sDispatch'] = $defaultDispatch['id'];
454
        return $this->session['sDispatch'];
455
    }
456
457
    /**
458
     * Get selected dispatch or select a default dispatch
459
     *
460
     * @return boolean|array
461
     */
462
    public function getSelectedDispatch()
463
    {
464
        if (empty($this->session['sCountry'])) {
465
            return false;
466
        }
467
468
        $dispatches = $this->admin->sGetPremiumDispatches($this->session['sCountry'], null, $this->session['sState']);
469
        if (empty($dispatches)) {
470
            unset($this->session['sDispatch']);
471
            return false;
472
        }
473
474
        foreach ($dispatches as $dispatch) {
475
            if ($dispatch['id'] == $this->session['sDispatch']) {
476
                return $dispatch;
477
            }
478
        }
479
        $dispatch = reset($dispatches);
480
        $this->session['sDispatch'] = (int) $dispatch['id'];
481
        return $dispatch;
482
    }
483
484
    /**
485
     * On any change on country, payment or dispatch recalculate shipping costs
486
     * and forward to cart / confirm view
487
     */
488
    public function calculateShippingCostsAction()
489
    {
490
        if ($this->Request()->getPost('sCountry')) {
491
            $this->session['sCountry'] = (int) $this->Request()->getPost('sCountry');
492
            $this->session["sState"] = 0;
493
            $this->session["sArea"] = Shopware()->Db()->fetchOne("
494
            SELECT areaID FROM s_core_countries WHERE id = ?
495
            ", [$this->session['sCountry']]);
496
        }
497
498
        if ($this->Request()->getPost('sPayment')) {
499
            $this->session['sPaymentID'] = (int) $this->Request()->getPost('sPayment');
500
        }
501
502
        if ($this->Request()->getPost('sDispatch')) {
503
            $this->session['sDispatch'] = (int) $this->Request()->getPost('sDispatch');
504
        }
505
506
        if ($this->Request()->getPost('sState')) {
507
            $this->session['sState'] = (int) $this->Request()->getPost('sState');
508
        }
509
510
        // We might change the shop context here so we need to initialize it again
511
        $this->get('shopware_storefront.context_service')->initializeShopContext();
512
513
        // We need an indicator in the view to expand the shipping costs pre-calculation on page load
514
        $this->View()->assign('calculateShippingCosts', true);
515
516
        $this->forward('showIframe');
517
    }
518
519
    /**
520
     * Get current selected country - if no country is selected, choose first one from list
521
     * of available countries
522
     *
523
     * @return array with country information
524
     */
525
    public function getSelectedCountry()
526
    {
527
        if (!empty($this->View()->sUserData['additional']['countryShipping'])) {
528
            $this->session['sCountry'] = (int) $this->View()->sUserData['additional']['countryShipping']['id'];
529
            $this->session['sArea'] = (int) $this->View()->sUserData['additional']['countryShipping']['areaID'];
530
531
            return $this->View()->sUserData['additional']['countryShipping'];
532
        }
533
        $countries = $this->getCountryList();
534
        if (empty($countries)) {
535
            unset($this->session['sCountry']);
536
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by Shopware_Controllers_Fro...rna::getSelectedCountry of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
537
        }
538
        $country = reset($countries);
539
        $this->session['sCountry'] = (int) $country['id'];
540
        $this->session['sArea'] = (int) $country['areaID'];
541
        $this->View()->sUserData['additional']['countryShipping'] = $country;
542
        return $country;
543
    }
544
545
    /**
546
     * Get all countries from database via sAdmin object
547
     *
548
     * @return array list of countries
549
     */
550
    public function getCountryList()
551
    {
552
        return $this->admin->sGetCountryList();
553
    }
554
555
    /**
556
     * Get current selected country - if no country is selected, choose first one from list
557
     * of available countries
558
     *
559
     * @return array with country information
560
     */
561
    public function getSelectedState()
562
    {
563
        if (!empty($this->View()->sUserData['additional']['stateShipping'])) {
564
            $this->session['sState'] = (int) $this->View()->sUserData['additional']['stateShipping']['id'];
565
            return $this->View()->sUserData['additional']['stateShipping'];
566
        }
567
        return ["id" => $this->session['sState']];
568
    }
569
570
    /**
571
     * @param Klarna_Checkout_Order $order
0 ignored issues
show
Documentation introduced by
Should the type for parameter $order not be Klarna_Checkout_Order|null?

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

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

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

Loading history...
572
     * @param bool $checkLoginState
573
     */
574
    public function createAccount($order = null, $checkLoginState = true)
575
    {
576
        $this->plugin->klarnaLog('Entering Shopware_Controllers_Frontend_PaymentKlarna::createAccount', 3);
577
        $module = Shopware()->Modules()->Admin();
578
        $session = Shopware()->Session();
579
        $version = Shopware()->Config()->version;
580
581
        if ($version == '___VERSION___' || version_compare($version, '4.1.0', '>=')) {
582
            $encoder = Shopware()->PasswordEncoder()->getDefaultPasswordEncoderName();
583
        }
584
        
585
        $data = [];
586
587
        if ($order !== null && !empty($order['billing_address']['email'])) {
588
            $data['auth']['email'] = $order['billing_address']['email'];
589
            $data['auth']['password'] = $order['reference'];
590
        } else {
591
            $sessionId = Shopware()->SessionID();
592
            // email is only varchar(70) so we cut the sessionid
593
            //$sessionId = substr($sessionId, 0,49);
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
594
            $data['auth']['email'] = substr($sessionId, 0, 49) . '@klarna.com';
595
            $data['auth']['password'] = $sessionId;
596
        }
597
        $data['auth']['accountmode'] = '1';
598
        $data['phone'] = !empty($order['billing_address']['phone']) ?
599
            $order['billing_address']['phone'] : ' ';
600
601
        if (!empty($order['customer']['date_of_birth'])) {
602
            list($data['billing']['birthyear'], $data['billing']['birthmonth'], $data['billing']['birthday']) = explode(
603
                '-',
604
                $order['customer']['date_of_birth']
605
            );
606
        }
607
608
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->order:", 4, $order);
609
        
610
        foreach (['billing', 'shipping'] as $type) {
611
            if (isset($order[$type . '_address'])) {
612
                $orderAddress = $order[$type . '_address'];
613
                if (isset($orderAddress['title'])) {
614
                    $data[$type]['salutation'] = $orderAddress['title'] == 'Frau' ? 'ms' : 'mr';
615
                } else {
616
                    $data[$type]['salutation'] = 'mr';
617
                }
618
                $data[$type]['firstname'] = $orderAddress['given_name'];
619
                $data[$type]['lastname'] = $orderAddress['family_name'];
620
                if (isset($orderAddress['street_name']) && $orderAddress['street_number']) {
621
                    if (version_compare(Shopware::VERSION, '5.0.0', '>=')) {
622
                        $data[$type]['street'] = $orderAddress['street_name'] . ' ' . $orderAddress['street_number'];
623 View Code Duplication
                    } else {
624
                        $data[$type]['street'] = $orderAddress['street_name'];
625
                        $data[$type]['streetnumber'] = $orderAddress['street_number'];
626
                    }
627
                } else {
628
                    $data[$type]['street'] = $orderAddress['street_address'];
629
                    $data[$type]['streetnumber'] = ' ';
630
                }
631
                $data[$type]['zipcode'] = $orderAddress['postal_code'];
632
                $data[$type]['city'] = $orderAddress['city'];
633
                if (!empty($orderAddress['care_of'])) {
634
                    if ($orderAddress['street_name'] == 'Packstation') {
635
                        $data[$type]['postnumber'] = $orderAddress['care_of'];
636
                        $data[$type]['swagDhlPostnumber'] = $data[$type]['postnumber'];
637
                    } else {
638
                        $data[$type]['company'] = $orderAddress['care_of'];
639
                    }
640
                }
641
                $data[$type]['phone'] = !empty($orderAddress['phone']) ? $orderAddress['phone'] : ' ';
642
            }
643
644
            if (!isset($data[$type]['company'])) {
645
                $data[$type]['company'] = '';
646
            }
647
            $data[$type]['department'] = '';
648
649
            if (!empty($order[$type . '_address']['country'])) {
650
                $sql = 'SELECT id FROM s_core_countries WHERE countryiso=?';
651
                $countryId = Shopware()->Db()->fetchOne($sql, [$order[$type . '_address']['country']]);
652
            } else {
653
                $countryId = $session['sCountry'];
654
            }
655
            // make sure country is set in case of lost sessions defualt to germany
656
            if (empty($countryId)) {
657
                $countryId = 2;
658
            }
659
660
            $data[$type]['country'] = $countryId;
661
        }
662
663
        $this->plugin->klarnaLog(
664
            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->data AFTER ADDRESSES:",
665
            4,
666
            $data
667
        );
668
        $sql = 'SELECT id FROM s_core_paymentmeans WHERE name=?';
669
        $paymentId = Shopware()->Db()->fetchOne($sql, ['klarna_checkout']);
670
671
        if ($order !== null && !empty($order['billing_address']['email'])) {
672
            $shop = $this->get('shop');
673
            $shop = $shop->getMain() ?: $shop;
674
            $sql = 'SELECT id, email, `password` FROM `s_user` WHERE `email` LIKE ? AND `active` = 1 ';
675
            if ($shop->getCustomerScope()) {
676
                $sql .= "AND `subshopID` = {$shop->getId()} ";
677
            }
678
            $sql .= 'ORDER BY `accountmode`';
679
            $user = Shopware()->Db()->fetchRow($sql, [$data['auth']['email']]);
680
            // First try login
681
            if (!empty($user)) {
682
                $session->offsetSet('sUserMail', $user['email']);
683
                $session->offsetSet('sUserPassword', $user['password']);
684
                $session->offsetSet('sUserId', $user['id']);
685
            } else {
686
                $this->plugin->klarnaLog(
687
                    "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->user Not Found in DB SQL was:" . $sql,
688
                    1
689
                );
690
            }
691
        }
692
693
        if ($checkLoginState) {
694
            // Check login status
695
            if (!empty($session->sUserId)) {
696
                if ($order !== null) {
697
                    $module->sSYSTEM->_POST = $data['shipping'];
698 View Code Duplication
                    if ($this->plugin->isShopwareVersionNew()) {
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...
699
                        $userId = $session->offsetGet('sUserId');
700
                        $this->plugin->klarnaLog(
701
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->updateShipping:",
702
                            3,
703
                            $data['shipping']
704
                        );
705
                        $this->updateShipping($userId, $data['shipping']);
706
                    } else {
707
                        $this->plugin->klarnaLog(
708
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->sUpdateShipping:",
709
                            3,
710
                            $this->front->Request()->getPost()
711
                        );
712
                        $module->sUpdateShipping();
713
                    }
714
                    $module->sSYSTEM->_POST = $data['billing'];
715 View Code Duplication
                    if ($this->plugin->isShopwareVersionNew()) {
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...
716
                        $userId = $session->offsetGet('sUserId');
717
                        $this->plugin->klarnaLog(
718
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->updateBilling:",
719
                            3,
720
                            $data['billing']
721
                        );
722
                        $this->updateBilling($userId, $data['billing']);
723
                    } else {
724
                        $this->plugin->klarnaLog(
725
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->sUpdateBilling:",
726
                            3,
727
                            $this->front->Request()->getPost()
728
                        );
729
                        $module->sUpdateBilling();
730
                    }
731
                    unset($data['auth']['password']);
732
                    $module->sSYSTEM->_POST = $data['auth'];
733 View Code Duplication
                    if ($this->plugin->isShopwareVersionNew()) {
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...
734
                        $userId = $session->offsetGet('sUserId');
735
                        $this->plugin->klarnaLog(
736
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->updateCustomer:",
737
                            3,
738
                            $data
739
                        );
740
                        $this->updateCustomer($data, $userId);
741
                    } else {
742
                        $this->plugin->klarnaLog(
743
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->sUpdateAccount:",
744
                            3,
745
                            $this->front->Request()->getPost()
746
                        );
747
                        $module->sUpdateAccount();
748
                    }
749
                } else {
750
                    /** @var Enlight_Controller_Front $front */
751
                    $front = $this->get('front');
752
                    $front->Request()->setPost([]);
753
                    $module->sSYSTEM->_POST = ['country' => $data['shipping']['country']];
754
                    $shippingId = $this->get('db')->fetchOne(
755
                        'SELECT id FROM s_user_shippingaddress WHERE userID = ?',
756
                        [$session->offsetGet('sUserId')]
757
                    );
758
                    if (!empty($shippingId)) {
759
                        if ($this->plugin->isShopwareVersionNew()) {
760
                            $userId = $session->offsetGet('sUserId');
761
                            $this->updateShipping($userId, $data['shipping']);
762
                        } else {
763
                            $module->sUpdateShipping();
764
                        }
765
                    } else {
766
                        $module->sUpdateBilling();
767
                    }
768
                }
769
                $module->sSYSTEM->_POST = ['sPayment' => $paymentId];
770
                $module->sUpdatePayment();
771
            } else {
772
                $data['payment']['object'] = $module->sGetPaymentMeanById($paymentId);
773
                if (isset($encoder)) {
774
                    $data["auth"]["encoderName"] = $encoder;
775
                    $data["auth"]["password"] = Shopware()->PasswordEncoder()
776
                        ->encodePassword($data["auth"]["password"], $encoder);
777
                } else {
778
                    $data['auth']['password'] = md5($data['auth']['password']);
779
                }
780
                $session->sRegisterFinished = false;
781
                if (version_compare(Shopware::VERSION, '4.3.0', '>=') &&
782
                    version_compare(Shopware::VERSION, '5.2.0', '<')
783
                ) {
784
                    $session->sRegister = $data;
785
                } elseif (version_compare(Shopware::VERSION, '4.3.0', '<')) {
786
                    $session->sRegister = new ArrayObject($data, ArrayObject::ARRAY_AS_PROPS);
787
                }
788
                try {
789
                    if ($this->plugin->isShopwareVersionNew()) {
790
                        $this->plugin->klarnaLog(
791
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser->Before:",
792
                            3,
793
                            print_r($data, true)
794
                        );
795
                        $newdata = $this->saveUser($data);
796
                        $this->plugin->klarnaLog(
797
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser->After:",
798
                            3,
799
                            print_r($newdata, true)
800
                        );
801
                        $module->sSYSTEM->_POST = $newdata['auth'];
802
                        $errors = $module->sLogin(true);
803
                        if (is_array($errors)) {
804
                            $this->plugin->klarnaLog(
805
                                "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->sLogin->Errors: \n",
806
                                3,
807
                                implode(",\n", $errors)
808
                            );
809
                        }
810
                    } else {
811
                        $this->plugin->klarnaLog(
812
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser->Register:",
813
                            3,
814
                            $session->sRegister
815
                        );
816
                        $module->sSaveRegister();
817
                        $this->plugin->klarnaLog(
818
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser->RegisterFinished:",
819
                            3,
820
                            $session->offsetGet('sRegisterFinished')
821
                        );
822
                    }
823
                } catch (\Exception $ex) {
824
                    $this->plugin->klarnaLog(
825
                        "ERROR while creating User. Exception information: ". $ex->getMessage(),
826
                        1
827
                    );
828
                    $this->plugin->klarnaLog(
829
                        "ERROR while creating User. Exception backtrace: \n". $ex->getTraceAsString(),
830
                        1
831
                    );
832
                    if ($ex instanceof \Shopware\Components\Api\Exception\ValidationException) {
0 ignored issues
show
Bug introduced by
The class Shopware\Components\Api\...ion\ValidationException does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

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

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

2. Missing use statement

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

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

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

Loading history...
833
                        /** @var Shopware\Components\Api\Exception\ValidationException $ex */
834
                        $violations = $ex->getViolations();
835
                        $details = [];
836
                        for ($i = 0; $i < $violations->count(); $i++) {
837
                            /** @var \Symfony\Component\Validator\ConstraintViolation $violation */
838
                            $violation = $violations->get($i);
839
                            $details[] = $violation->__toString();
840
                        }
841
                        $this->plugin->klarnaLog(
842
                            "ERROR while creating User. Validation exception details: \n". implode("\n", $details),
843
                            1
844
                        );
845
                    }
846
                }
847
            }
848
        }
849
        
850
        $this->plugin->klarnaLog(
851
            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->data END OF METHOD:",
852
            4,
853
            $data
854
        );
855
    }
856
    
857
    /**
858
     * Saves a new user to the system.
859
     *
860
     * @param array $data
861
     * @return array $data
862
     */
863
    private function saveUser($data)
864
    {
865
866
        $plainbilling = array_merge($data['auth'], $data['billing']);
867
        $plainshipping = array_merge($data['auth'], $data['shipping']);
868
869
        if (empty($plainbilling['birthyear']) ||
870
            empty($plainbilling['birthmonth']) ||
871
            empty($plainbilling['birthday'])
872
        ) {
873
            $plainbilling['birthday'] = null;
874
        } else {
875
            $plainbilling['birthday'] = new \DateTime(
876
               $plainbilling['birthyear'] . '-' .
877
                    $plainbilling['birthmonth'] . '-' .
878
                    $plainbilling['birthday']);
879
        }
880
881
        //Create forms and validate the input
882
        $customer = new Shopware\Models\Customer\Customer();
883
884
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\PersonalFormType', $customer);
885
        $form->submit($plainbilling);
886
887
        $billingaddress = new Shopware\Models\Customer\Address();
888
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\AddressFormType', $billingaddress);
889
        $form->submit($plainbilling);
890
891
        $shippingaddress = new Shopware\Models\Customer\Address();
892
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\AddressFormType', $shippingaddress);
893
        $form->submit($plainshipping);
894
895
        /** @var Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface $context */
896
        $context = $this->get('shopware_storefront.context_service')->getShopContext();
897
898
        /** @var Shopware\Bundle\StoreFrontBundle\Struct\Shop $shop */
899
        $shop = $context->getShop();
900
901
        /** @var Shopware\Bundle\AccountBundle\Service\RegisterServiceInterface $registerService */
902
        $registerService = $this->get('shopware_account.register_service');
903
        $registerService->register($shop, $customer, $billingaddress, $shippingaddress);
904
905
        // get updated password; it is md5 randomized after register
906
        $getUser = Shopware()->Models()->getRepository('Shopware\Models\Customer\Customer')->findOneBy(
907
            ['email' =>  $data['auth']['email']]
908
        );
909
910
        $data['auth']['password'] = $getUser->getPassword();
911
        $data['auth']['passwordMD5'] = $getUser->getPassword();
912
        $data['auth']['encoderName'] = 'md5';
913
914
        return $data;
915
    }
916
917
918
    /**
919
     * Endpoint for changing the main profile data
920
     */
921
    public function updateCustomer($data, $userId)
922
    {
923
        if (empty($data['billing']['birthyear']) ||
924
            empty($data['billing']['birthmonth']) ||
925
            empty($data['billing']['birthday'])
926
        ) {
927
            $data['birthdate'] = "0000-00-00";
928
        } else {
929
            $data['birthdate'] = $data['billing']['birthyear'] . '-' .
930
                $data['billing']['birthmonth'] . '-' . $data['billing']['birthday'];
931
            $data['birthday'] = $data['birthdate'];
932
        }
933
        $data['email'] = $data['auth']['email'];
934
        $data['firstname'] = $data['billing']['firstname'];
935
        $data['lastname'] = $data['billing']['lastname'];
936
        unset($data['shipping']);
937
        unset($data['billing']);
938
939
        $customer = Shopware()->Models()->getRepository('Shopware\Models\Customer\Customer')->findOneBy(
940
            ['id' =>  $userId]
941
        );
942
        $customer->fromArray($data);
943
        Shopware()->Container()->get('shopware_account.customer_service')->update($customer);
944
    }
945
946
947
     /**
948
     * Updates the shipping address
949
     *
950
     * @param int $userId
951
     * @param array $shippingData
952
     */
953
    private function updateShipping($userId, $shippingData)
954
    {
955
        /** @var \Shopware\Components\Model\ModelManager $em */
956
        $em = $this->get('models');
957
958
        /** @var \Shopware\Models\Customer\Customer $customer */
959
        $customer = $em->getRepository('Shopware\Models\Customer\Customer')->findOneBy(['id' => $userId]);
960
961
        /** @var \Shopware\Models\Customer\Address $address */
962
        $addressBefore = $customer->getDefaultShippingAddress();
963
        $address = new \Shopware\Models\Customer\Address();
964
        
965
         /** @var \Shopware\Models\Country\Country $country */
966
        $country = $addressBefore->getCountry();
967
        $shippingData['country'] = $country;
968
        if ($shippingData['phone'] === null) {
969
            $shippingData['phone'] = ' ';
970
        }
971
        $address->fromArray($shippingData);
972
        $compareData = [];
973
        /**
974
         * @var integer $key
975
         * @var \Shopware\Models\Customer\Address $data
976
         */
977
        foreach ([$addressBefore, $address] as $key => $data) {
978
            $compareData[$key] = implode("|", [
979
                $data->getCompany(),
980
                $data->getDepartment(),
981
                $data->getSalutation(),
982
                $data->getFirstname(),
983
                $data->getTitle(),
984
                $data->getLastname(),
985
                $data->getStreet(),
986
                $data->getZipcode(),
987
                $data->getCity(),
988
                $data->getPhone(),
989
            ]);
990
        }
991
        if ($compareData[0] === $compareData[1]) {
992
            $this->plugin->klarnaLog(
993
                "Shopware_Controllers_Frontend_PaymentKlarna::updateShipping: " .
994
                "Shipping address doesn't need to be updated.",
995
                3
996
            );
997
            return;
998
        }
999
1000
        try {
1001
            $addressService = $this->get('shopware_account.address_service');
1002
            $addressService->create($address, $customer);
1003
            $addressService->setDefaultShippingAddress($address);
1004
        } catch (Exception $ex) {
1005
            $this->plugin->klarnaLog(
1006
                "ERROR while creating address via address service. Exception information:" . $ex->getMessage(),
1007
                1
1008
            );
1009
        }
1010
    }
1011
1012
    /**
1013
     * Updates the billing address
1014
     *
1015
     * @param int $userId
1016
     * @param array $billingData
1017
     */
1018
    private function updateBilling($userId, $billingData)
1019
    {
1020
        /** @var \Shopware\Components\Model\ModelManager $em */
1021
        $em = $this->get('models');
1022
1023
        /** @var \Shopware\Models\Customer\Customer $customer */
1024
        $customer = $em->getRepository('Shopware\Models\Customer\Customer')->findOneBy(['id' => $userId]);
1025
1026
        /** @var \Shopware\Models\Customer\Address $address */
1027
        $address = $customer->getDefaultBillingAddress();
1028
        
1029
         /** @var \Shopware\Models\Country\Country $country */
1030
        $country = $address->getCountry();
1031
        $billingData['country'] = $country;
1032
        $address->fromArray($billingData);
1033
1034
        $this->get('shopware_account.address_service')->update($address);
1035
    }
1036
1037
1038
    /**
1039
     * Needed to reset the session when the user logs in
1040
     */
1041
    public function loginAction()
1042
    {
1043
        // Shopware()->Session()->offsetSet('KlarnaOrder', null);
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% 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...
1044
        $this->redirect(['controller' => 'payment_klarna', 'action' => 'showIframe']);
1045
    }
1046
1047
    /**
1048
     * Return action method
1049
     *
1050
     * Reads the transactionResult and represents it for the customer.
1051
     */
1052
    public function returnAction()
1053
    {
1054
        $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction", 3);
1055
        $transactionId = $this->Request()->getParam('transactionId');
1056
        $connector = $this->plugin->getConnector();
1057
1058
        $order = new Klarna_Checkout_Order($connector, $transactionId);
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...
1059
        $this->plugin->klarnaLog(
1060
            "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction->transactionId:\n" . $transactionId,
1061
            3
1062
        );
1063
        $this->plugin->klarnaLog(
1064
            "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction->order:",
1065
            4,
1066
            $order
1067
        );
1068
        $orderNumber = '';
1069
        $session = Shopware()->Session();
1070
1071
        // set payment to Klarna Checkout Dangerous??
1072
        $session['sPaymentID'] = $this->plugin->getPayment()->getId();
1073
1074
        try {
1075
            $order->fetch();
1076
1077
            // if already created by pushaction just redirect
1078
1079
            if ($order['status'] === 'created') {
1080
                $this->plugin->klarnaLog(
1081
                    "Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1082
                    "OrderStatus is already created... nothing to do: " . $orderNumber,
1083
                    1
1084
                );
1085
                $this->redirect([
1086
                    'controller' => 'payment_klarna',
1087
                    'action' => 'finish',
1088
                    'sUniqueID' => $order['reference'],
1089
                ]);
1090
                //return;
1091
            }
1092
1093
            $this->createAccount($order);
1094
            // After createAccount update PaymentId to Klarna, could be defaultpayment
1095
            $this->plugin->savePayment($this->plugin->getPayment()->getId());
1096
            Shopware()->Session()->sOrderVariables['sUserData'] = $this->getUserData();
1097
1098 View Code Duplication
            if ($order['status'] === 'checkout_complete') {
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...
1099
                $this->plugin->klarnaLog(
1100
                    "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1101
                    "checkout_complete. Save oder if session values match.",
1102
                    3
1103
                );
1104
                if (Shopware()->Session()->offsetGet('KlarnaTransactionId') == null) {
1105
                    $this->plugin->klarnaLog(
1106
                        "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1107
                        "Session matches. Order will be saved",
1108
                        3
1109
                    );
1110
                    Shopware()->Session()->offsetSet('KlarnaTransactionId', $transactionId);
1111
                    $orderNumber = $this->saveOrder(
1112
                        $order['reservation'],
1113
                        $order['reference']
1114
                    );
1115
                    Shopware()->Session()->offsetSet('KlarnaTransactionId', null);
1116
                }
1117
            }
1118
1119
1120 View Code Duplication
            if (empty($orderNumber) && !empty($order['merchant_reference']['orderid1'])) {
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...
1121
                $orderNumber = $order['merchant_reference']['orderid1'];
1122
            }
1123
1124 View Code Duplication
            if (!empty($orderNumber)) {
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...
1125
                $update = [];
1126
1127
                $update['status'] = 'created';
1128
                $update['merchant_reference'] = [
1129
                    'orderid1' => (string)$orderNumber,
1130
                    'orderid2' => (string)$order['reference'],
1131
                ];
1132
                $order->update($update);
1133
            }
1134
           
1135
            // Saves postnumber for dhl packstation
1136
            if (!empty($orderNumber)
1137
                && !empty($order['shipping_address']['care_of'])
1138
                && $order['shipping_address']['street_name'] == 'Packstation'
1139
                && $this->config->get('postnumberField')
1140
            ) {
1141
                $field = $this->config->get('postnumberField');
1142
                $value = $order['shipping_address']['care_of'];
1143
                $this->saveOrderAttribute($orderNumber, $field, $value);
1144
            }
1145
1146
            $session['KlarnaOrder'] = $order->getLocation();
1147
1148
            if ($order['status'] == 'created' || $order['status'] == 'checkout_complete') {
1149
                $this->saveOrderAttribute($orderNumber, 'swag_klarna_status', 'created');
1150
                $this->savePaymentStatus(
1151
                    $order['reservation'],
1152
                    $order['reference'],
1153
                    $this->config->get('statusId')
1154
                );
1155
                $this->redirect([
1156
                    'controller' => 'payment_klarna',
1157
                    'action' => 'finish',
1158
                    'sUniqueID' => $order['reference'],
1159
                ]);
1160
            } else {
1161
                $this->redirect(['controller' => 'checkout', 'action' => 'confirm']);
1162
            }
1163
        } catch (Exception $e) {
1164
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
1165
            $this->plugin->klarnaLog(
1166
                "Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1167
                "Catch. Searching for Order:",
1168
                3
1169
            );
1170
            $this->checkKlarnaOrderExistsByReservation($order['reservation']);
1171
            $this->checkKlarnaOrderExistsByReference($order['reference']);
1172
            $this->checkKlarnaOrderExistsBySession(Shopware()->Session()->sUserId);
1173
            $this->checkKlarnaOrderDetailsBySession(Shopware()->Session()->sUserId);
1174
            echo "Entschuldigung! Ein Verbindungsfehler ist aufgetreten. Bitte aktualisieren Sie die Seite.\n";
1175
            echo $e->getMessage();
1176
        }
1177
    }
1178
    
1179
    /**
1180
     * Method checks if certain klarna order exists or not
1181
     *
1182
     * @param string $sessionID
1183
     * @return bool
1184
     */
1185 View Code Duplication
    protected function checkKlarnaOrderExistsBySession($sessionID)
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...
1186
    {
1187
        $sql = '
1188
            SELECT * FROM s_order
1189
            WHERE userID=?
1190
        ';
1191
        
1192
        $order = Shopware()->Db()->fetchAll($sql, [
1193
                $sessionID,
1194
        ]);
1195
        
1196
        $orderExists = (empty($order)) ? false : true;
1197
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsBySession:", 3);
1198
        if ($orderExists) {
1199
            $this->plugin->klarnaLog(
1200
                "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsBySession: Order Found: ",
1201
                3,
1202
                $order
1203
            );
1204
        }
1205
        return $orderExists;
1206
    }
1207
1208
    /**
1209
     * Method checks if certain klarna order exists or not
1210
     *
1211
     * @param string $paymentUniqueId
1212
     * @return bool
1213
     * @internal param string $transactionId
1214
     */
1215 View Code Duplication
    protected function checkKlarnaOrderExistsByReference($paymentUniqueId)
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...
1216
    {
1217
        $sql = '
1218
            SELECT * FROM s_order
1219
            WHERE temporaryID=?
1220
        ';
1221
        
1222
        $order = Shopware()->Db()->fetchAll($sql, [
1223
                $paymentUniqueId,
1224
        ]);
1225
        
1226
        $orderExists = (empty($order)) ? false : true;
1227
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReference:", 3);
1228
        if ($orderExists) {
1229
            $this->plugin->klarnaLog(
1230
                "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReference: Order Found: ",
1231
                3,
1232
                $order
1233
            );
1234
        }
1235
        return $orderExists;
1236
    }
1237
1238
    /**
1239
     * Method checks if certain klarna order exists or not
1240
     *
1241
     * @param string $transactionId
1242
     * @return bool
1243
     * @internal param string $paymentUniqueId
1244
     */
1245 View Code Duplication
    protected function checkKlarnaOrderExistsByReservation($transactionId)
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...
1246
    {
1247
        $sql = '
1248
            SELECT * FROM s_order
1249
            WHERE transactionID=?
1250
        ';
1251
        
1252
        $order = Shopware()->Db()->fetchAll($sql, [
1253
                $transactionId,
1254
        ]);
1255
        
1256
        $orderExists = (empty($order)) ? false : true;
1257
        $this->plugin->klarnaLog(
1258
            "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReservation:",
1259
            3
1260
        );
1261
        if ($orderExists) {
1262
            $this->plugin->klarnaLog(
1263
                "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReservation: Order Found: ",
1264
                3,
1265
                $order
1266
            );
1267
        }
1268
        return $orderExists;
1269
    }
1270
    
1271
    /**
1272
     * Method checks if certain klarna order exists or not
1273
     *
1274
     * @param string $transactionId
1275
     * @param string $paymentUniqueId
1276
     * @param string $userId
1277
     * @return bool
1278
     */
1279
    protected function checkKlarnaOrderExists($transactionId, $paymentUniqueId, $userId)
1280
    {
1281
        $sql = '
1282
            SELECT ordernumber FROM s_order
1283
            WHERE transactionID=? AND temporaryID=?
1284
            AND status!=-1 AND userID=?
1285
        ';
1286
        
1287
        $orderNumber = Shopware()->Db()->fetchOne($sql, [
1288
                $transactionId,
1289
                $paymentUniqueId,
1290
                $userId,
1291
        ]);
1292
        
1293
        $orderExists = (empty($orderNumber)) ? false : true;
1294
        
1295
        return $orderExists;
1296
    }
1297
    
1298
    /**
1299
     * Method checks if certain klarna order exists or not
1300
     *
1301
     * @param string $sessionID
1302
     * @return bool
1303
     */
1304 View Code Duplication
    protected function checkKlarnaOrderDetailsBySession($sessionID)
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...
1305
    {
1306
        $sql = '
1307
            SELECT * FROM s_order
1308
            LEFT JOIN s_order_details ON s_order.id = s_order_details.orderID
1309
            WHERE userID=?
1310
        ';
1311
        
1312
        $orderDetails = Shopware()->Db()->fetchAll($sql, [
1313
                $sessionID,
1314
        ]);
1315
        
1316
        $orderExists = (empty($orderDetails)) ? false : true;
1317
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderDetailsBySession:", 3);
1318
        if ($orderExists) {
1319
            $this->plugin->klarnaLog(
1320
                "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderDetailsBySession: OrderDetails Found: ",
1321
                3,
1322
                $orderDetails
1323
            );
1324
        }
1325
        return $orderExists;
1326
    }
1327
    
1328
    /**
1329
     * Method checks if certain klarna order exists or not
1330
     *
1331
     * @param string $paymentUniqueId
1332
     * @return string
1333
     */
1334
    protected function getUserIdByReference($paymentUniqueId)
1335
    {
1336
        $sql = '
1337
            SELECT userID FROM s_order
1338
            WHERE temporaryID=?
1339
        ';
1340
        
1341
        $userId = Shopware()->Db()->fetchOne($sql, [
1342
                $paymentUniqueId,
1343
        ]);
1344
1345
        return $userId;
1346
    }
1347
    
1348
    /**
1349
     *
1350
     *
1351
     * @param string $transactionId
1352
     * @param string $paymentUniqueId
1353
     * @param string $userId
1354
     * @return string $orderNumber
1355
     */
1356 View Code Duplication
    protected function getKlarnaOrderNumber($transactionId, $paymentUniqueId, $userId)
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...
1357
    {
1358
        $sql = '
1359
            SELECT ordernumber FROM s_order
1360
            WHERE transactionID=? AND temporaryID=?
1361
            AND status!=-1 AND userID=?
1362
        ';
1363
1364
        $orderNumber = Shopware()->Db()->fetchOne($sql, [
1365
            $transactionId,
1366
            $paymentUniqueId,
1367
            $userId,
1368
        ]);
1369
1370
        return $orderNumber;
1371
    }
1372
1373
    /**
1374
     *
1375
     *
1376
     * @param string $transactionId
1377
     * @param string $paymentUniqueId
1378
     * @param string $userId
1379
     * @return string $orderId
1380
     */
1381 View Code Duplication
    protected function getKlarnaOrderId($transactionId, $paymentUniqueId, $userId)
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...
1382
    {
1383
        $sql = '
1384
            SELECT id FROM s_order
1385
            WHERE transactionID=? AND temporaryID=?
1386
            AND status!=-1 AND userID=?
1387
        ';
1388
1389
        $orderId = Shopware()->Db()->fetchOne($sql, [
1390
            $transactionId,
1391
            $paymentUniqueId,
1392
            $userId,
1393
        ]);
1394
1395
        return $orderId;
1396
    }
1397
1398
1399
    /**
1400
     * Notify action method
1401
     */
1402
    public function pushAction()
1403
    {
1404
        $transactionId = $this->Request()->getParam('transactionId');
1405
1406
        $this->plugin->klarnaLog(
1407
            "Shopware_Controllers_Frontend_PaymentKlarna::pushAction->transactionId:\n" . $transactionId,
1408
            3
1409
        );
1410
        $connector = $this->plugin->getConnector();
1411
        $order = new Klarna_Checkout_Order($connector, $transactionId);
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...
1412
1413
        $order->fetch();
1414
1415
        if ($order['status'] === 'created') {
1416
            $this->plugin->klarnaLog(
1417
                "Shopware_Controllers_Frontend_PaymentKlarna::pushAction: " .
1418
                "OrderStatus is already created... nothing to do: ",
1419
                1
1420
            );
1421
            return;
1422
        }
1423
1424
        $this->createAccount($order);
1425
        // After createAccount update PaymentId to Klarna, could be defaultpayment
1426
        $this->plugin->savePayment($this->plugin->getPayment()->getId());
1427
        Shopware()->Session()->sOrderVariables['sUserData'] = $this->getUserData();
1428
1429 View Code Duplication
        if ($order['status'] == 'checkout_complete') {
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...
1430
            $this->plugin->klarnaLog(
1431
                "Entering Shopware_Controllers_Frontend_PaymentKlarna::pushAction: " .
1432
                "checkout_complete. Save oder if session values match.",
1433
                3
1434
            );
1435
            if (Shopware()->Session()->offsetGet('KlarnaTransactionId') == null) {
1436
                $this->plugin->klarnaLog(
1437
                    "Entering Shopware_Controllers_Frontend_PaymentKlarna::pushAction: " .
1438
                    "Session matches. Order will be saved",
1439
                    3
1440
                );
1441
                Shopware()->Session()->offsetSet('KlarnaTransactionId', $transactionId);
1442
                $orderNumber = $this->saveOrder(
1443
                    $order['reservation'],
1444
                    $order['reference']
1445
                );
1446
                Shopware()->Session()->offsetSet('KlarnaTransactionId', null);
1447
            }
1448
        }
1449
1450 View Code Duplication
        if (empty($orderNumber) && !empty($order['merchant_reference']['orderid1'])) {
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...
1451
            $orderNumber = $order['merchant_reference']['orderid1'];
1452
        }
1453
1454 View Code Duplication
        if (!empty($orderNumber)) {
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...
1455
            $update = [];
1456
1457
            $update['status'] = 'created';
1458
            $update['merchant_reference'] = [
1459
                'orderid1' => (string)$orderNumber,
1460
                'orderid2' => (string)$order['reference'],
1461
            ];
1462
            $order->update($update);
1463
        }
1464
1465
        $this->savePaymentStatus(
1466
            $order['reservation'],
1467
            $order['reference'],
1468
            $this->config->get('statusId')
1469
        );
1470
    }
1471
1472
    private function saveOrderAttribute($orderNumber, $field, $value)
1473
    {
1474
        try {
1475
            $sql = "
1476
                INSERT INTO s_order_attributes (orderID, `$field`)
1477
                SELECT id, ? FROM s_order WHERE ordernumber = ?
1478
                ON DUPLICATE KEY UPDATE `$field` = VALUES(`$field`)
1479
            ";
1480
            $this->get('db')->query($sql, [
1481
                $value,
1482
                $orderNumber,
1483
            ]);
1484
        } catch (Exception $e) {
1485
            $this->plugin->klarnaLog("PROBLEM SAVING ORDER ATTRIBUTES AFTER KLARNA PUSH!:\n" . $e->getMessage(), 1);
1486
        }
1487
    }
1488
1489
    /**
1490
     * Save register form so we can use it if user change between klarna and register tab
1491
     */
1492
    public function saveFormDataAction()
1493
    {
1494
        $form = $this->Request()->getPost();
1495
1496
        //unset password from passed post
1497
        unset($form['register']['personal']['password']);
1498
1499
        if (!empty($form)) {
1500
            Shopware()->Session()->klarnaSavedRegister = $form;
1501
        }
1502
    }
1503
1504
    /**
1505
     * Helper method to redirect the request to the proper page to set the payment into the customer account
1506
     */
1507
    public function setPaymentAction()
1508
    {
1509
        if ($this->Request()->isPost()) {
1510
            $values = $this->Request()->getPost('register');
1511
            $payment = $values['payment'];
1512
        } else {
1513
            $payment = $this->Request()->getParam('paymentId');
1514
        }
1515
1516
        if (empty($payment)) {
1517
            return;
1518
        }
1519
        $session = Shopware()->Session();
1520
        $session['KlarnaExternalPaymentId'] = $payment;
1521
1522
        $paymentName = $this->getPaymentNameById($session['KlarnaExternalPaymentId']);
1523
        $user = Shopware()->Modules()->Admin()->sGetUserData();
1524
        $userID = $user['additional']['user']['id'];
1525
1526
        // If user is not already registered and has selected external payment method
1527
        // PayPal redirect to PayPal Express checkout to prevent user registration
1528
        if ($paymentName === 'paypal' && empty($userID)) {
1529
            $this->redirect(
1530
                [
1531
                    'controller' => 'payment_paypal',
1532
                    'action'     => 'express',
1533
                ]
1534
            );
1535
        } elseif (empty($userID)) {
1536
            $session->offsetSet('sPaymentID', $payment);
0 ignored issues
show
Bug introduced by
The method offsetSet cannot be called on $session (of type array<string,?,{"KlarnaExternalPaymentId":"?"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1537
            $session->offsetUnset('sUserId');
0 ignored issues
show
Bug introduced by
The method offsetUnset cannot be called on $session (of type array<string,?,{"KlarnaExternalPaymentId":"?"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1538
            $session->offsetSet('sRegisterFinished', false);
0 ignored issues
show
Bug introduced by
The method offsetSet cannot be called on $session (of type array<string,?,{"KlarnaExternalPaymentId":"?"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1539
1540
            $this->redirect(
1541
                [
1542
                    'controller'    => 'register',
1543
                    'action'        => 'index',
1544
                    'sTarget'       => 'checkout',
1545
                    'sTargetAction' => 'confirm',
1546
                ]
1547
            );
1548
        } else {
1549
            $session->offsetSet('sPaymentID', $payment);
0 ignored issues
show
Bug introduced by
The method offsetSet cannot be called on $session (of type array<string,?,{"KlarnaExternalPaymentId":"?"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1550
            $this->plugin->savePayment($payment);
1551
            $this->redirect(
1552
                [
1553
                    'controller' => 'checkout',
1554
                    'action'     => 'confirm',
1555
                ]
1556
            );
1557
        }
1558
    }
1559
1560
    /**
1561
     * This action is called when the user is not logged in and tries to change
1562
     * the payment from klarna to another payment. Only used in responsive theme.
1563
     */
1564
    public function otherPaymentAction()
1565
    {
1566
        $userData = Shopware()->Modules()->Admin()->sGetUserData();
1567
        $session = Shopware()->Session();
1568
1569
        // reset country
1570
        $session['sCountry'] = $userData['additional']['country']['id'];
1571
        unset($session['sChangedCountry']);
1572
1573
        //Register-controller redirects to checkout by default when the user is logged in already.
1574
        /*        $this->redirect(array(
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
1575
                    'controller' => 'checkout',
1576
                    'action' => 'shippingPayment',
1577
                    'klarnaRedirect' => 1
1578
                    //'sTarget' => 'checkout',
1579
                    //'sTargetAction' => 'shippingPayment'
1580
                ));
1581
        */
1582
        if ($this->isUserLoggedIn()) {
1583
            $this->redirect([
1584
                'controller' => 'checkout',
1585
                'klarnaRedirect' => 1,
1586
                'action' => 'shippingPayment',
1587
                'sTarget' => 'checkout',
1588
            ]);
1589
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
1590
        } else {
1591
            $this->redirect([
1592
                'controller' => 'register',
1593
                'klarnaRedirect' => 1,
1594
                'sTarget' => 'checkout',
1595
                'sTargetAction' => 'shippingPayment',
1596
            ]);
1597
        }
1598
    }
1599
1600
    /**
1601
     * @return bool
1602
     */
1603
    protected function isUserLoggedIn()
1604
    {
1605
         return (isset($this->session->sUserId) && !empty($this->session->sUserId));
1606
    }
1607
1608
    /**
1609
     * Get complete user-data as an array to use in view
1610
     *
1611
     * @return array
1612
     */
1613
    public function getUserData()
1614
    {
1615
        $system = Shopware()->System();
1616
        $admin = Shopware()->Modules()->Admin();
1617
        $userData = $admin->sGetUserData();
1618
        if (!empty($userData['additional']['countryShipping'])) {
1619
            $system->sUSERGROUPDATA = Shopware()->Db()->fetchRow("
1620
                SELECT * FROM s_core_customergroups
1621
                WHERE groupkey = ?
1622
            ", [$system->sUSERGROUP]);
1623
1624
            if ($this->isTaxFreeDelivery($userData)) {
1625
                $system->sUSERGROUPDATA['tax'] = 0;
1626
                $system->sCONFIG['sARTICLESOUTPUTNETTO'] = 1; //Old template
1627
                Shopware()->Session()->sUserGroupData = $system->sUSERGROUPDATA;
1628
                $userData['additional']['charge_vat'] = false;
1629
                $userData['additional']['show_net'] = false;
1630
                Shopware()->Session()->sOutputNet = true;
1631
            } else {
1632
                $userData['additional']['charge_vat'] = true;
1633
                $userData['additional']['show_net'] = !empty($system->sUSERGROUPDATA['tax']);
1634
                Shopware()->Session()->sOutputNet = empty($system->sUSERGROUPDATA['tax']);
1635
            }
1636
        }
1637
1638
        return $userData;
1639
    }
1640
1641
    /**
1642
     * Validates if the provided customer should get a tax free delivery
1643
     * @param array $userData
1644
     * @return bool
1645
     */
1646
    protected function isTaxFreeDelivery($userData)
1647
    {
1648
        if (!empty($userData['additional']['countryShipping']['taxfree'])) {
1649
            return true;
1650
        }
1651
1652
        if (empty($userData['additional']['countryShipping']['taxfree_ustid'])) {
1653
            return false;
1654
        }
1655
1656
        return !empty($userData['shippingaddress']['ustid']);
1657
    }
1658
1659
    /**
1660
     * returns payment name from payment Ids
1661
     * @param integer $paymentId
1662
     * @return string
1663
     */
1664
    private function getPaymentNameById($paymentId)
1665
    {
1666
        $paymentRepo = Shopware()->Models()->getRepository('Shopware\Models\Payment\Payment');
1667
        $payment = $paymentRepo->findOneBy(['id' => $paymentId]);
1668
        return $payment->getName();
1669
    }
1670
}
1671