Completed
Push — master ( 48107f...eccdf7 )
by Mario
04:35
created

pushAction()   C

Complexity

Conditions 7
Paths 13

Size

Total Lines 69
Code Lines 45

Duplication

Lines 33
Ratio 47.83 %

Importance

Changes 0
Metric Value
cc 7
eloc 45
c 0
b 0
f 0
nc 13
nop 0
dl 33
loc 69
rs 6.9081

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
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
        // Register Custom Template
144
        $this->View()->loadTemplate("frontend/checkout/confirm.tpl");
145
        // update dispatch or delivery country in case form was submitted
146
        if ($this->Request()->isPost()) {
147
            // set klarnaPrefill, in case User ovverides Setting with checkbox
148
            if ($this->Request()->getParam('klarnaPreFill') == "on") {
149
                $this->session['klarnaUserPreFill'] = true;
150
            }
151
152
            $this->setDispatch($this->Request()->getPost('sDispatch'));
153
            $postedCountry = $this->Request()->getPost('sCountry');
154
            if (!empty($postedCountry)) {
155
                $shopCountryId = $this->session['sCountry'];
156
                $validKlarnaCountry = $this->plugin->checkValidKlarnaCountry($postedCountry);
157
                if (!$validKlarnaCountry) {
158
                    $this->redirect(['controller' => 'payment_klarna', 'action' => 'otherPayment']);
159
                    return;
160
                }
161
                $shopCountryId = (string)$shopCountryId;
162
                if ($shopCountryId != $postedCountry) {
163
                    $this->session['sCountry'] = $postedCountry;
164
                    // unset klarnaOrder so it will be created with new countryID
165
                    unset($this->session['KlarnaOrder']);
166
                }
167
            }
168
            //$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...
169
        } else {
170
            $this->setDispatch($this->session->sDispatch, $paymentIdDebug);
171
        }
172
        // set shipping costs (Overwrites $session->sCountry!)
173
        $debugShipping = $this->getShippingCosts();
174
        if ($postedCountry) {
175
            $this->session['sCountry'] = $postedCountry;
0 ignored issues
show
Bug introduced by
The variable $postedCountry 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...
176
        } else {
177
            // set Default Country
178
            $bootstrap = $this->get('plugins')->get('Frontend')->get('SwagPaymentKlarna');
179
            $this->session['sCountry'] = $bootstrap->getCountryByShop(Shopware()->Shop());
180
        }
181
182
        $this->basket['sShippingcosts'] = $debugShipping['brutto'];
183
        $this->basket['sShippingcostsWithTax'] = $debugShipping['brutto'];
184
        $this->basket['sShippingcostsNet'] = $debugShipping['netto'];
185
        $this->basket['sShippingcostsTax'] = $debugShipping['tax'];
186
187
        // set missing basket vars for use in view
188
        $this->basket['AmountWithTaxNumeric'] = floatval(
189
            str_replace(',', '.', $this->basket['Amount'])
190
        ) + floatval(
191
            str_replace(',', '.', $debugShipping['brutto'])
192
        );
193
        $this->basket['AmountNetNumeric'] = floatval(str_replace(',', '.', $this->basket['AmountNet']));
194
195
        $klarnaConnector = $this->plugin->getConnector();
196
        $shop = $this->plugin->Application()->Shop();
197
198
        $create = [];
199
        $create['cart']['items'] = $this->plugin->getCheckoutCart($this->basket);
200
        $create['merchant'] = $this->plugin->getCheckoutMerchant();
201
202
        $create['purchase_country'] = $this->plugin->getCountryIsoById($this->session['sCountry']);
203
        $create['purchase_currency'] = $shop->getCurrency()->toString();
204
        $create['locale'] = $this->plugin->getLocale(false, $create['purchase_country']);
205
        $create['options'] = $this->plugin->getCheckoutOptions();
206
207
        if ($this->config->get('KlarnaExternalPayments')) {
208
            list($create['external_payment_methods'], $create['external_checkouts']) = $this->plugin
209
                ->getExternalPaymentMethods($this->basket);
210
        }
211
212
        if ($this->config->get('disableAutofocus')) {
213
            $create['gui']['options'] = ['disable_autofocus'];
214
        }
215
216
        // set Prefill Information
217
218
        if (($preFill == true) || ($this->session['klarnaUserPreFill'] == true)) {
219
            $this->session['klarnaPreFill'] = true;
220
            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...
221
                $bootstrap = $this->get('plugins')->get('Frontend')->get('SwagPaymentKlarna');
222
                $countryId = $bootstrap->getCountryByShop($shop);
223
            } else {
224
                $countryId = $session['sCountry'];
225
            }
226
            if ($user['additional']['countryShipping']['id'] == $countryId
227
                && $user['billingaddress']['zipcode'] != '00000'
228
            ) {
229
                $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...
230
                if ($user['additional']['countryShipping']['id'] == $user['additional']['country']['id']) {
231
                    $create['shipping_address'] = $this->plugin->getCheckoutAddress($user, 'billing');
232
                } else {
233
                    $create['shipping_address'] = $this->plugin->getCheckoutAddress($user, 'shipping');
234
                }
235
            }
236
        } else {
237
            $this->session['klarnaPreFill'] = false;
238
        }
239
240
        // In case Customer fills Iframe and then logs in do not update existing klarnaOrder
241
        if (!empty($this->session['KlarnaOrder']) && !$this->isUserLoggedIn()) {
242
            $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...
243
            $update = [];
244
            $update['cart']['items'] = $this->plugin->getCheckoutCart($this->basket);
245
            $update['purchase_country'] = $this->plugin->getCountryIsoById($this->session['sCountry']);
246
247
            $klarnaOrder->fetch();
248
            // update basket and delivery country in case it changed
249
            $klarnaOrder->update($update);
250
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
251
        } else {
252
            $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...
253
            $klarnaOrder->create($create);
254
        }
255
256
257
        try {
258
            $klarnaOrder->fetch();
259
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
260
        } catch (Exception $e) {
261
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
262
            echo "Entschuldigung, Ein Verbindungsfehler ist aufgetreten, bitte aktualisieren Sie die Seite";
263
            $this->plugin->klarnaLog(
264
                "Verbindungsfehler in onPreDispatchCheckout\nCode:" . $e->getCode() . "Nachricht:\n" . $e->getMessage(),
265
                1
266
            );
267
        }
268
269
        $this->session->KlarnaOrder = $klarnaOrder->getLocation();
270
271
        // Delete old perhaps cancelled Klarna Order
272
273
        if ($klarnaOrder['status'] !== "checkout_incomplete") {
274
            unset($this->session->KlarnaOrder);
275
        }
276
277
        $userAdditionalArray = [];
278
        $userAdditionalArray['additional']['charge_vat'] = 1;
279
280
        $userPayment = [];
281
        $userPayment['id'] = $this->plugin->getPayment()->getId();
282
283
        // persist basket changes
284
        Shopware()->Session()->sOrderVariables['sBasket'] = $this->basket;
285
286
        // Klarna Iframe Information
287
        $this->View()->assign('KlarnaOrder', $klarnaOrder->marshal());
288
289
        // Klarna Prefill checkBox
290
        if ($this->isUserLoggedIn()) {
291
               $this->View()->assign('KlarnaPreFillSelect', !$this->session['klarnaPreFill']);
292
        }
293
294
        // Iframe Backend Config
295
        $this->plugin->getViewConfig($this->View(), $this->config);
296
        $this->View()->sBasket = $this->basket;
297
        $this->View()->sDispatches = $this->getDispatches($paymentIdDebug);
298
        if ($postedCountry) {
299
            $this->session['sCountry'] = $postedCountry;
300
        }
301
        $this->View()->sDispatch = $this->getSelectedDispatch();
302
303
        // Neccessary if user is not logged in
304
        $this->View()->sPayment = $userPayment;
305
306
        $this->basket['sShippingcosts'] = $debugShipping['brutto'];
307
        $this->basket['sShippingcostsWithTax'] = $debugShipping['brutto'];
308
        $this->basket['sShippingcostsNet'] = $debugShipping['netto'];
309
        $this->basket['sShippingcostsTax'] = $debugShipping['tax'];
310
311
        $this->basket['sAmount'] = floatval($this->basket['Amount']) + floatval($this->basket['sShippingcosts']);
312
        $this->basket['sAmountNet'] = floatval($this->basket['AmountNetNumeric']) + floatval($debugShipping['netto']);
313
314
        $this->basket['sAmountTax'] = 1.9;
315
        $this->View()->sShippingcosts = $debugShipping['brutto'];
316
        $this->View()->sShippingcostsWithTax =  $debugShipping['brutto'];
317
        $this->View()->sShippingcostsNet = $debugShipping['netto'];
318
        $this->View()->sShippingcostsTax = $debugShipping['tax'];
319
        $this->View()->sAmount = $this->basket['AmountWithTaxNumeric'] ;
320
321
        $this->View()->sAmountNet = $this->basket['sAmountNet'];
322
        $this->View()->sAmountTax = $this->basket['sAmountTax'];
323
        $this->View()->assign('sUserData', $userAdditionalArray);
324
        $this->View()->sPayments = $this->plugin->filterPayments($this->admin->sGetPaymentMeans());
325
        $this->View()->sUserLoggedIn = $this->isUserLoggedIn();
326
    }
327
328
    /**
329
     * Add voucher to cart
330
     *
331
     * At failure view variable sVoucherError will give further information
332
     * At success return to cart / confirm view
333
     */
334
    public function addVoucherAction()
335
    {
336
        $basketObj = $this->get('modules')->Basket();
337
        if ($this->Request()->isPost()) {
338
            $voucher = $basketObj->sAddVoucher($this->Request()->getParam('sVoucher'));
339
            if (!empty($voucher['sErrorMessages'])) {
340
                $this->View()->assign('sVoucherError', $voucher['sErrorMessages'], null, Smarty::SCOPE_ROOT);
341
            }
342
        }
343
        $this->forward('showIframe');
344
    }
345
346
347
348
    /**
349
     * Get shipping costs as an array (brutto / netto) depending on selected country / payment
350
     *
351
     * @return array
352
     */
353
    public function getShippingCosts()
354
    {
355
        $country = $this->getSelectedCountry();
356
        $payment = $this->plugin->getPayment()->getId();
357
        if (empty($country) || empty($payment)) {
358
            return ['brutto' =>0, 'netto' =>0];
359
        }
360
        $shippingcosts = $this->admin->sGetPremiumShippingcosts($country);
361
        return empty($shippingcosts) ? ['brutto' =>0, 'netto' =>0] : $shippingcosts;
362
    }
363
364
    /**
365
     * Express Iframe Test
366
     */
367
    public function finishAction()
368
    {
369
        $connector = $this->plugin->getConnector();
370
        $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...
371
        $klarnaOrder->fetch();
372
        $this->View()->loadTemplate("frontend/checkout/finish.tpl");
373
        $this->View()->assign('KlarnaOrder', $klarnaOrder->marshal());
374
        // reset basket
375
        unset($this->session['KlarnaOrder']);
376
        unset($this->session['sBasketQuantity']);
377
        unset($this->session['sBasketAmount']);
378
    }
379
380
    /**
381
     * Change quantity of a certain product
382
     * @param sArticle = The article to update
383
     * @param sQuantity = new quantity
384
     * Forward to cart / confirm view after success
385
     */
386
    public function changeQuantityAction()
387
    {
388
        $basketObj = $this->get('modules')->Basket();
389
390
        if ($this->Request()->getParam('sArticle') && $this->Request()->getParam('sQuantity')) {
391
            $this->View()->sBasketInfo = $basketObj->sUpdateArticle(
392
                $this->Request()->getParam('sArticle'),
393
                $this->Request()->getParam('sQuantity')
394
            );
395
        }
396
        $this->redirect(['action' => $this->Request()->getParam('sTargetAction', 'showIframe')]);
397
    }
398
399
    /**
400
     * Delete an article from cart -
401
     * @param sDelete = id from s_basket identifying the product to delete
402
     * Forward to cart / confirmation page after success
403
     */
404
    public function deleteArticleAction()
405
    {
406
        $basketObj = $this->get('modules')->Basket();
407
408
        if ($this->Request()->getParam('sDelete')) {
409
            $basketObj->sDeleteArticle($this->Request()->getParam('sDelete'));
410
        }
411
        $this->forward($this->Request()->getParam('sTargetAction', 'index'));
412
    }
413
414
    /**
415
     * Get all dispatches available in selected country from sAdmin object
416
     *
417
     * @param null $paymentId
418
     * @return array|boolean list of dispatches
419
     */
420
    public function getDispatches($paymentId = null)
421
    {
422
        $country = $this->getSelectedCountry();
423
        $state = $this->getSelectedState();
424
        if (empty($country)) {
425
            return false;
426
        }
427
        $stateId = !empty($state['id']) ? $state['id'] : null;
428
        return $this->admin->sGetPremiumDispatches($country['id'], $paymentId, $stateId);
429
    }
430
431
    /**
432
     * Set the provided dispatch method
433
     *
434
     * @param int $dispatchId ID of the dispatch method to set
435
     * @param int|null $paymentId Payment id to validate
436
     * @return int set dispatch method id
437
     */
438
    public function setDispatch($dispatchId, $paymentId = null)
439
    {
440
        $supportedDispatches = $this->getDispatches($paymentId);
441
442
        // Iterate over supported dispatches, look for the provided one
443
        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...
444
            if ($dispatch['id'] == $dispatchId) {
445
                $this->session['sDispatch'] = $dispatchId;
446
                return $dispatchId;
447
            }
448
        }
449
450
        // If it was not found, we fallback to the default (head of supported)
451
        $defaultDispatch = array_shift($supportedDispatches);
452
        $this->session['sDispatch'] = $defaultDispatch['id'];
453
        return $this->session['sDispatch'];
454
    }
455
456
    /**
457
     * Get selected dispatch or select a default dispatch
458
     *
459
     * @return boolean|array
460
     */
461
    public function getSelectedDispatch()
462
    {
463
        if (empty($this->session['sCountry'])) {
464
            return false;
465
        }
466
467
        $dispatches = $this->admin->sGetPremiumDispatches($this->session['sCountry'], null, $this->session['sState']);
468
        if (empty($dispatches)) {
469
            unset($this->session['sDispatch']);
470
            return false;
471
        }
472
473
        foreach ($dispatches as $dispatch) {
474
            if ($dispatch['id'] == $this->session['sDispatch']) {
475
                return $dispatch;
476
            }
477
        }
478
        $dispatch = reset($dispatches);
479
        $this->session['sDispatch'] = (int) $dispatch['id'];
480
        return $dispatch;
481
    }
482
483
    /**
484
     * On any change on country, payment or dispatch recalculate shipping costs
485
     * and forward to cart / confirm view
486
     */
487
    public function calculateShippingCostsAction()
488
    {
489
        if ($this->Request()->getPost('sCountry')) {
490
            $this->session['sCountry'] = (int) $this->Request()->getPost('sCountry');
491
            $this->session["sState"] = 0;
492
            $this->session["sArea"] = Shopware()->Db()->fetchOne("
493
            SELECT areaID FROM s_core_countries WHERE id = ?
494
            ", [$this->session['sCountry']]);
495
        }
496
497
        if ($this->Request()->getPost('sPayment')) {
498
            $this->session['sPaymentID'] = (int) $this->Request()->getPost('sPayment');
499
        }
500
501
        if ($this->Request()->getPost('sDispatch')) {
502
            $this->session['sDispatch'] = (int) $this->Request()->getPost('sDispatch');
503
        }
504
505
        if ($this->Request()->getPost('sState')) {
506
            $this->session['sState'] = (int) $this->Request()->getPost('sState');
507
        }
508
509
        // We might change the shop context here so we need to initialize it again
510
        $this->get('shopware_storefront.context_service')->initializeShopContext();
511
512
        // We need an indicator in the view to expand the shipping costs pre-calculation on page load
513
        $this->View()->assign('calculateShippingCosts', true);
514
515
        $this->forward('showIframe');
516
    }
517
518
    /**
519
     * Get current selected country - if no country is selected, choose first one from list
520
     * of available countries
521
     *
522
     * @return array with country information
523
     */
524
    public function getSelectedCountry()
525
    {
526
        if (!empty($this->View()->sUserData['additional']['countryShipping'])) {
527
            $this->session['sCountry'] = (int) $this->View()->sUserData['additional']['countryShipping']['id'];
528
            $this->session['sArea'] = (int) $this->View()->sUserData['additional']['countryShipping']['areaID'];
529
530
            return $this->View()->sUserData['additional']['countryShipping'];
531
        }
532
        $countries = $this->getCountryList();
533
        if (empty($countries)) {
534
            unset($this->session['sCountry']);
535
            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...
536
        }
537
        $country = reset($countries);
538
        $this->session['sCountry'] = (int) $country['id'];
539
        $this->session['sArea'] = (int) $country['areaID'];
540
        $this->View()->sUserData['additional']['countryShipping'] = $country;
541
        return $country;
542
    }
543
544
    /**
545
     * Get all countries from database via sAdmin object
546
     *
547
     * @return array list of countries
548
     */
549
    public function getCountryList()
550
    {
551
        return $this->admin->sGetCountryList();
552
    }
553
554
    /**
555
     * Get current selected country - if no country is selected, choose first one from list
556
     * of available countries
557
     *
558
     * @return array with country information
559
     */
560
    public function getSelectedState()
561
    {
562
        if (!empty($this->View()->sUserData['additional']['stateShipping'])) {
563
            $this->session['sState'] = (int) $this->View()->sUserData['additional']['stateShipping']['id'];
564
            return $this->View()->sUserData['additional']['stateShipping'];
565
        }
566
        return ["id" => $this->session['sState']];
567
    }
568
569
    /**
570
     * @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...
571
     * @param bool $checkLoginState
572
     */
573
    public function createAccount($order = null, $checkLoginState = true)
574
    {
575
        $this->plugin->klarnaLog('Entering Shopware_Controllers_Frontend_PaymentKlarna::createAccount', 3);
576
        $module = Shopware()->Modules()->Admin();
577
        $session = Shopware()->Session();
578
        $version = Shopware()->Config()->version;
579
580
        if ($version == '___VERSION___' || version_compare($version, '4.1.0', '>=')) {
581
            $encoder = Shopware()->PasswordEncoder()->getDefaultPasswordEncoderName();
582
        }
583
        
584
        $data = [];
585
586
        if ($order !== null && !empty($order['billing_address']['email'])) {
587
            $data['auth']['email'] = $order['billing_address']['email'];
588
            $data['auth']['password'] = $order['reference'];
589
        } else {
590
            $sessionId = Shopware()->SessionID();
591
            // email is only varchar(70) so we cut the sessionid
592
            //$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...
593
            $data['auth']['email'] = substr($sessionId, 0, 49) . '@klarna.com';
594
            $data['auth']['password'] = $sessionId;
595
        }
596
        $data['auth']['accountmode'] = '1';
597
598
        $phone = $order['billing_address']['phone'];
599
        $data['billing']['phone'] = !empty($phone) ? $phone : ' ';
600
        $data['phone'] = !empty($phone) ? $phone : ' ';
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 {
1 ignored issue
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...
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
            }
642
643
            if (!isset($data[$type]['company'])) {
644
                $data[$type]['company'] = '';
645
            }
646
            $data[$type]['department'] = '';
647
648
            if (!empty($order[$type . '_address']['country'])) {
649
                $sql = 'SELECT id FROM s_core_countries WHERE countryiso=?';
650
                $countryId = Shopware()->Db()->fetchOne($sql, [$order[$type . '_address']['country']]);
651
            } else {
652
                $countryId = $session['sCountry'];
653
            }
654
            // make sure country is set in case of lost sessions defualt to germany
655
            if (empty($countryId)) {
656
                $countryId = 2;
657
            }
658
659
            $data[$type]['country'] = $countryId;
660
        }
661
662
        $this->plugin->klarnaLog(
663
            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->data AFTER ADDRESSES:",
664
            4,
665
            $data
666
        );
667
        $sql = 'SELECT id FROM s_core_paymentmeans WHERE name=?';
668
        $paymentId = Shopware()->Db()->fetchOne($sql, ['klarna_checkout']);
669
670
        if ($order !== null && !empty($order['billing_address']['email'])) {
671
            $shop = $this->get('shop');
672
            $shop = $shop->getMain() ?: $shop;
673
            $sql = 'SELECT id, email, `password` FROM `s_user` WHERE `email` LIKE ? AND `active` = 1 ';
674
            if ($shop->getCustomerScope()) {
675
                $sql .= "AND `subshopID` = {$shop->getId()} ";
676
            }
677
            $sql .= 'ORDER BY `accountmode`';
678
            $user = Shopware()->Db()->fetchRow($sql, [$data['auth']['email']]);
679
            // First try login
680
            if (!empty($user)) {
681
                $session->offsetSet('sUserMail', $user['email']);
682
                $session->offsetSet('sUserPassword', $user['password']);
683
                $session->offsetSet('sUserId', $user['id']);
684
            } else {
685
                $this->plugin->klarnaLog(
686
                    "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->user Not Found in DB SQL was:" . $sql,
687
                    1
688
                );
689
            }
690
        }
691
692
        if ($checkLoginState) {
693
            // Check login status
694
            if (!empty($session->sUserId)) {
695
                if ($order !== null) {
696
                    $module->sSYSTEM->_POST = $data['shipping'];
697 View Code Duplication
                    if (Shopware::VERSION === '___VERSION___' || version_compare(Shopware::VERSION, '5.2.0', '>=')) {
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...
698
                        $userId = $session->offsetGet('sUserId');
699
                        $this->updateShipping($userId, $data['shipping']);
700
                    } else {
701
                        $module->sUpdateShipping();
702
                    }
703
                    $module->sSYSTEM->_POST = $data['billing'];
704 View Code Duplication
                    if (Shopware::VERSION === '___VERSION___' || version_compare(Shopware::VERSION, '5.2.0', '>=')) {
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...
705
                         $userId = $session->offsetGet('sUserId');
706
                         $this->updateBilling($userId, $data['billing']);
707
                    } else {
708
                        $module->sUpdateBilling();
709
                    }
710
                    unset($data['auth']['password']);
711
                    $module->sSYSTEM->_POST = $data['auth'];
712
                    if (Shopware::VERSION === '___VERSION___' || version_compare(Shopware::VERSION, '5.2.0', '>=')) {
713
                        $userId = $session->offsetGet('sUserId');
714
                        $this->updateCustomer($data, $userId);
715
                        $this->plugin->klarnaLog(
716
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->updateCustomer:",
717
                            3,
718
                            $data
719
                        );
720
                    } else {
721
                        $module->sUpdateAccount();
722
                        $this->plugin->klarnaLog(
723
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->updateAccount:",
724
                            3,
725
                            $this->front->Request()->getPost()
726
                        );
727
                    }
728
                } else {
729
                    /** @var Enlight_Controller_Front $front */
730
                    $front = $this->get('front');
731
                    $front->Request()->setPost([]);
732
                    $module->sSYSTEM->_POST = ['country' => $data['shipping']['country']];
733
                    $shippingId = $this->get('db')->fetchOne(
734
                        'SELECT id FROM s_user_shippingaddress WHERE userID = ?',
735
                        [$session->offsetGet('sUserId')]
736
                    );
737 View Code Duplication
                    if (!empty($shippingId)) {
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...
738
                        if (Shopware::VERSION === '___VERSION___' ||
739
                            version_compare(Shopware::VERSION, '5.2.0', '>=')
740
                        ) {
741
                            $userId = $session->offsetGet('sUserId');
742
                            $this->updateShipping($userId, $data['shipping']);
743
                        } else {
744
                            $module->sUpdateShipping();
745
                        }
746
                    } else {
747
                        $module->sUpdateBilling();
748
                    }
749
                }
750
                $module->sSYSTEM->_POST = ['sPayment' => $paymentId];
751
                $module->sUpdatePayment();
752
            } else {
753
                $data['payment']['object'] = $module->sGetPaymentMeanById($paymentId);
754
                if (isset($encoder)) {
755
                    $data["auth"]["encoderName"] = $encoder;
756
                    $data["auth"]["password"] = Shopware()->PasswordEncoder()
757
                        ->encodePassword($data["auth"]["password"], $encoder);
758
                } else {
759
                    $data['auth']['password'] = md5($data['auth']['password']);
760
                }
761
                $session->sRegisterFinished = false;
762
                if (version_compare(Shopware::VERSION, '4.3.0', '>=') &&
763
                    version_compare(Shopware::VERSION, '5.2.0', '<')
764
                ) {
765
                    $session->sRegister = $data;
766
                } elseif (version_compare(Shopware::VERSION, '4.3.0', '<')) {
767
                    $session->sRegister = new ArrayObject($data, ArrayObject::ARRAY_AS_PROPS);
768
                }
769
                try {
770
                    if (Shopware::VERSION === '___VERSION___' || version_compare(Shopware::VERSION, '5.2.0', '>=')) {
771
                        $newdata = $this->saveUser($data);
772
                        $module->sSYSTEM->_POST = $newdata['auth'];
773
                        $errors = $module->sLogin(true);
0 ignored issues
show
Unused Code introduced by
$errors 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...
774
                        $this->plugin->klarnaLog(
775
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser:",
776
                            3,
777
                            $newdata
778
                        );
779
                    } else {
780
                        $this->plugin->klarnaLog(
781
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser->Register:",
782
                            3,
783
                            $session->sRegister
784
                        );
785
                        $module->sSaveRegister();
786
                        $this->plugin->klarnaLog(
787
                            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser->RegisterFinished:",
788
                            3,
789
                            $session->offsetGet('sRegisterFinished')
790
                        );
791
                    }
792
                } catch (\Exception $ex) { /* do nothing */
793
                    $this->plugin->klarnaLog("ERROR while creating User. Exception information:". $ex->getMessage(), 1);
794
                }
795
            }
796
        }
797
        
798
        $this->plugin->klarnaLog(
799
            "Shopware_Controllers_Frontend_PaymentKlarna::createAccount->data END OF METHOD:",
800
            4,
801
            $data
802
        );
803
    }
804
    
805
    /**
806
     * Saves a new user to the system.
807
     *
808
     * @param array $data
809
     * @return array $data
810
     */
811
    private function saveUser($data)
812
    {
813
814
        $plainbilling = array_merge($data['auth'], $data['billing']);
815
        $plainshipping = array_merge($data['auth'], $data['shipping']);
816
817
        //Create forms and validate the input
818
        $customer = new Shopware\Models\Customer\Customer();
819
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\PersonalFormType', $customer);
820
        $form->submit($plainbilling);
821
822
        $billingaddress = new Shopware\Models\Customer\Address();
823
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\AddressFormType', $billingaddress);
824
        $form->submit($plainbilling);
825
826
        $shippingaddress = new Shopware\Models\Customer\Address();
827
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\AddressFormType', $shippingaddress);
828
        $form->submit($plainshipping);
829
830
        /** @var Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface $context */
831
        $context = $this->get('shopware_storefront.context_service')->getShopContext();
832
833
        /** @var Shopware\Bundle\StoreFrontBundle\Struct\Shop $shop */
834
        $shop = $context->getShop();
835
836
        /** @var Shopware\Bundle\AccountBundle\Service\RegisterServiceInterface $registerService */
837
        $registerService = $this->get('shopware_account.register_service');
838
        $data['birthdate'] = $data['billing']['birthyear'] . '-' .
839
            $data['billing']['birthmonth'] . '-' .
840
            $data['billing']['birthday'];
841
        $customer->setBirthday($data['birthdate']);
842
        $registerService->register($shop, $customer, $billingaddress, $shippingaddress);
843
844
        // get updated password; it is md5 randomized after register
845
        $getUser = Shopware()->Models()->getRepository('Shopware\Models\Customer\Customer')->findOneBy(
846
            ['email' =>  $data['auth']['email']]
847
        );
848
849
        $data['auth']['password'] = $getUser->getPassword();
850
        $data['auth']['passwordMD5'] = $getUser->getPassword();
851
        $data['auth']['encoderName'] = 'md5';
852
853
        return $data;
854
    }
855
856
857
    /**
858
     * Endpoint for changing the main profile data
859
     */
860
    public function updateCustomer($data, $userId)
861
    {
862
        if (empty($data['billing']['birthyear']) ||
863
            empty($data['billing']['birthmonth']) ||
864
            empty($data['billing']['birthday'])
865
        ) {
866
            $data['birthdate'] = "0000-00-00";
867
        } else {
868
            $data['birthdate'] = $data['billing']['birthyear'] . '-' .
869
                $data['billing']['birthmonth'] . '-' . $data['billing']['birthday'];
870
            $data['birthday'] = $data['birthdate'];
871
        }
872
        $data['email'] = $data['auth']['email'];
873
        $data['firstname'] = $data['billing']['firstname'];
874
        $data['lastname'] = $data['billing']['lastname'];
875
        unset($data['shipping']);
876
        unset($data['billing']);
877
878
        $customer = Shopware()->Models()->getRepository('Shopware\Models\Customer\Customer')->findOneBy(
879
            ['id' =>  $userId]
880
        );
881
        $customer->fromArray($data);
882
        Shopware()->Container()->get('shopware_account.customer_service')->update($customer);
883
    }
884
885
886
     /**
887
     * Updates the shipping address
888
     *
889
     * @param int $userId
890
     * @param array $shippingData
891
     */
892
    private function updateShipping($userId, $shippingData)
893
    {
894
        /** @var \Shopware\Components\Model\ModelManager $em */
895
        $em = $this->get('models');
896
897
        /** @var \Shopware\Models\Customer\Customer $customer */
898
        $customer = $em->getRepository('Shopware\Models\Customer\Customer')->findOneBy(['id' => $userId]);
899
900
        /** @var \Shopware\Models\Customer\Address $address */
901
        $addressold = $customer->getDefaultShippingAddress();
902
        $address = new \Shopware\Models\Customer\Address();
903
        
904
         /** @var \Shopware\Models\Country\Country $country */
905
        $country = $addressold->getCountry();
906
        $shippingData['country'] = $country;
907
        if ($shippingData['phone'] === null) {
908
            $shippingData['phone'] = ' ';
909
        }
910
        $address->fromArray($shippingData);
911
        try {
912
            $addressService = $this->get('shopware_account.address_service');
913
            $addressService->create($address, $customer);
914
            $addressService->setDefaultShippingAddress($address);
915
        } catch (Exception $ex) {
916
            $this->plugin->klarnaLog(
917
                "ERROR while creating address via address service. Exception information:" . $ex->getMessage(),
918
                1
919
            );
920
        }
921
    }
922
923
    /**
924
     * Updates the billing address
925
     *
926
     * @param int $userId
927
     * @param array $billingData
928
     */
929
    private function updateBilling($userId, $billingData)
930
    {
931
        /** @var \Shopware\Components\Model\ModelManager $em */
932
        $em = $this->get('models');
933
934
        /** @var \Shopware\Models\Customer\Customer $customer */
935
        $customer = $em->getRepository('Shopware\Models\Customer\Customer')->findOneBy(['id' => $userId]);
936
937
        /** @var \Shopware\Models\Customer\Address $address */
938
        $address = $customer->getDefaultBillingAddress();
939
        
940
         /** @var \Shopware\Models\Country\Country $country */
941
        $country = $address->getCountry();
942
        $billingData['country'] = $country;
943
        $address->fromArray($billingData);
944
945
        $this->get('shopware_account.address_service')->update($address);
946
    }
947
948
949
    /**
950
     * Needed to reset the session when the user logs in
951
     */
952
    public function loginAction()
953
    {
954
        // 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...
955
        $this->redirect(['controller' => 'payment_klarna', 'action' => 'showIframe']);
956
    }
957
958
    /**
959
     * Return action method
960
     *
961
     * Reads the transactionResult and represents it for the customer.
962
     */
963
    public function returnAction()
964
    {
965
        $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction", 3);
966
        $transactionId = $this->Request()->getParam('transactionId');
967
        $connector = $this->plugin->getConnector();
968
969
        $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...
970
        $this->plugin->klarnaLog(
971
            "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction->transactionId:\n" . $transactionId,
972
            3
973
        );
974
        $this->plugin->klarnaLog(
975
            "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction->order:",
976
            4,
977
            $order
978
        );
979
        $orderNumber = '';
980
        $session = Shopware()->Session();
981
982
        // set payment to Klarna Checkout Dangerous??
983
        $session['sPaymentID'] = $this->plugin->getPayment()->getId();
984
985
        try {
986
            $order->fetch();
987
988
            // if already created by pushaction just redirect
989
990
            if ($order['status'] === 'created') {
991
                $this->plugin->klarnaLog(
992
                    "Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
993
                    "OrderStatus is already created... nothing to do: " . $orderNumber,
994
                    1
995
                );
996
                $this->redirect([
997
                    'controller' => 'payment_klarna',
998
                    'action' => 'finish',
999
                    'sUniqueID' => $order['reference']
1000
                ]);
1001
            }
1002
1003
            $this->createAccount($order);
1004
            // After createAccount update PaymentId to Klarna, could be defaultpayment
1005
            $this->plugin->savePayment($this->plugin->getPayment()->getId());
1006
            Shopware()->Session()->sOrderVariables['sUserData'] = $this->getUserData();
1007
1008 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...
1009
                $this->plugin->klarnaLog(
1010
                    "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1011
                    "checkout_complete. Save oder if session values match.",
1012
                    3
1013
                );
1014
                if (Shopware()->Session()->offsetGet('KlarnaTransactionId') == null) {
1015
                    $this->plugin->klarnaLog(
1016
                        "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1017
                        "Session matches. Order will be saved",
1018
                        3
1019
                    );
1020
                    Shopware()->Session()->offsetSet('KlarnaTransactionId', $transactionId);
1021
                    $orderNumber = $this->saveOrder(
1022
                        $order['reservation'],
1023
                        $order['reference']
1024
                    );
1025
                    Shopware()->Session()->offsetSet('KlarnaTransactionId', null);
1026
                }
1027
            }
1028
1029
1030 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...
1031
                $orderNumber = $order['merchant_reference']['orderid1'];
1032
            }
1033
1034 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...
1035
                $update = [];
1036
1037
                $update['status'] = 'created';
1038
                $update['merchant_reference'] = [
1039
                    'orderid1' => (string)$orderNumber,
1040
                    'orderid2' => (string)$order['reference']
1041
                ];
1042
                $order->update($update);
1043
            }
1044
           
1045
            // Saves postnumber for dhl packstation
1046
            if (!empty($orderNumber)
1047
                && !empty($order['shipping_address']['care_of'])
1048
                && $order['shipping_address']['street_name'] == 'Packstation'
1049
                && $this->config->get('postnumberField')
1050
            ) {
1051
                $field = $this->config->get('postnumberField');
1052
                $value = $order['shipping_address']['care_of'];
1053
                $this->saveOrderAttribute($orderNumber, $field, $value);
1054
            }
1055
1056
            $session['KlarnaOrder'] = $order->getLocation();
1057
1058
            if ($order['status'] == 'created' || $order['status'] == 'checkout_complete') {
1059
                $this->saveOrderAttribute($orderNumber, 'swag_klarna_status', 'created');
1060
                $this->savePaymentStatus(
1061
                    $order['reservation'],
1062
                    $order['reference'],
1063
                    $this->config->get('statusId')
1064
                );
1065
                $this->redirect([
1066
                    'controller' => 'payment_klarna',
1067
                    'action' => 'finish',
1068
                    'sUniqueID' => $order['reference']
1069
                ]);
1070
            } else {
1071
                $this->redirect(['controller' => 'checkout', 'action' => 'confirm']);
1072
            }
1073
        } catch (Exception $e) {
1074
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
1075
            $this->plugin->klarnaLog(
1076
                "Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1077
                "Catch. Searching for Order:",
1078
                3
1079
            );
1080
            $this->checkKlarnaOrderExistsByReservation($order['reservation']);
1081
            $this->checkKlarnaOrderExistsByReference($order['reference']);
1082
            $this->checkKlarnaOrderExistsBySession(Shopware()->Session()->sUserId);
1083
            $this->checkKlarnaOrderDetailsBySession(Shopware()->Session()->sUserId);
1084
            echo "Entschuldigung, Ein Verbindungsfehler ist aufgetreten, bitte aktualisieren Sie die Seite";
1085
            echo $e->getMessage();
1086
        }
1087
    }
1088
    
1089
    /**
1090
     * Method checks if certain klarna order exists or not
1091
     *
1092
     * @param string $sessionID
1093
     * @return bool
1094
     */
1095 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...
1096
    {
1097
        $sql = '
1098
            SELECT * FROM s_order
1099
            WHERE userID=?
1100
        ';
1101
        
1102
        $order = Shopware()->Db()->fetchAll($sql, [
1103
                $sessionID
1104
        ]);
1105
        
1106
        $orderExists = (empty($order)) ? false : true;
1107
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsBySession:", 3);
1108
        if ($orderExists) {
1109
            $this->plugin->klarnaLog(
1110
                "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsBySession: Order Found: ",
1111
                3,
1112
                $order
1113
            );
1114
        }
1115
        return $orderExists;
1116
    }
1117
1118
    /**
1119
     * Method checks if certain klarna order exists or not
1120
     *
1121
     * @param string $paymentUniqueId
1122
     * @return bool
1123
     * @internal param string $transactionId
1124
     */
1125 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...
1126
    {
1127
        $sql = '
1128
            SELECT * FROM s_order
1129
            WHERE temporaryID=?
1130
        ';
1131
        
1132
        $order = Shopware()->Db()->fetchAll($sql, [
1133
                $paymentUniqueId
1134
        ]);
1135
        
1136
        $orderExists = (empty($order)) ? false : true;
1137
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReference:", 3);
1138
        if ($orderExists) {
1139
            $this->plugin->klarnaLog(
1140
                "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReference: Order Found: ",
1141
                3,
1142
                $order
1143
            );
1144
        }
1145
        return $orderExists;
1146
    }
1147
1148
    /**
1149
     * Method checks if certain klarna order exists or not
1150
     *
1151
     * @param string $transactionId
1152
     * @return bool
1153
     * @internal param string $paymentUniqueId
1154
     */
1155 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...
1156
    {
1157
        $sql = '
1158
            SELECT * FROM s_order
1159
            WHERE transactionID=?
1160
        ';
1161
        
1162
        $order = Shopware()->Db()->fetchAll($sql, [
1163
                $transactionId
1164
        ]);
1165
        
1166
        $orderExists = (empty($order)) ? false : true;
1167
        $this->plugin->klarnaLog(
1168
            "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReservation:",
1169
            3
1170
        );
1171
        if ($orderExists) {
1172
            $this->plugin->klarnaLog(
1173
                "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReservation: Order Found: ",
1174
                3,
1175
                $order
1176
            );
1177
        }
1178
        return $orderExists;
1179
    }
1180
    
1181
    /**
1182
     * Method checks if certain klarna order exists or not
1183
     *
1184
     * @param string $transactionId
1185
     * @param string $paymentUniqueId
1186
     * @param string $userId
1187
     * @return bool
1188
     */
1189
    protected function checkKlarnaOrderExists($transactionId, $paymentUniqueId, $userId)
1190
    {
1191
        $sql = '
1192
            SELECT ordernumber FROM s_order
1193
            WHERE transactionID=? AND temporaryID=?
1194
            AND status!=-1 AND userID=?
1195
        ';
1196
        
1197
        $orderNumber = Shopware()->Db()->fetchOne($sql, [
1198
                $transactionId,
1199
                $paymentUniqueId,
1200
                $userId
1201
        ]);
1202
        
1203
        $orderExists = (empty($orderNumber)) ? false : true;
1204
        
1205
        return $orderExists;
1206
    }
1207
    
1208
    /**
1209
     * Method checks if certain klarna order exists or not
1210
     *
1211
     * @param string $sessionID
1212
     * @return bool
1213
     */
1214 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...
1215
    {
1216
        $sql = '
1217
            SELECT * FROM s_order
1218
            LEFT JOIN s_order_details ON s_order.id = s_order_details.orderID
1219
            WHERE userID=?
1220
        ';
1221
        
1222
        $orderDetails = Shopware()->Db()->fetchAll($sql, [
1223
                $sessionID
1224
        ]);
1225
        
1226
        $orderExists = (empty($orderDetails)) ? false : true;
1227
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderDetailsBySession:", 3);
1228
        if ($orderExists) {
1229
            $this->plugin->klarnaLog(
1230
                "Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderDetailsBySession: OrderDetails Found: ",
1231
                3,
1232
                $orderDetails
1233
            );
1234
        }
1235
        return $orderExists;
1236
    }
1237
    
1238
    /**
1239
     * Method checks if certain klarna order exists or not
1240
     *
1241
     * @param string $paymentUniqueId
1242
     * @return string
1243
     */
1244
    protected function getUserIdByReference($paymentUniqueId)
1245
    {
1246
        $sql = '
1247
            SELECT userID FROM s_order
1248
            WHERE temporaryID=?
1249
        ';
1250
        
1251
        $userId = Shopware()->Db()->fetchOne($sql, [
1252
                $paymentUniqueId
1253
        ]);
1254
1255
        return $userId;
1256
    }
1257
    
1258
    /**
1259
     *
1260
     *
1261
     * @param string $transactionId
1262
     * @param string $paymentUniqueId
1263
     * @param string $userId
1264
     * @return string $orderNumber
1265
     */
1266 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...
1267
    {
1268
        $sql = '
1269
            SELECT ordernumber FROM s_order
1270
            WHERE transactionID=? AND temporaryID=?
1271
            AND status!=-1 AND userID=?
1272
        ';
1273
1274
        $orderNumber = Shopware()->Db()->fetchOne($sql, [
1275
            $transactionId,
1276
            $paymentUniqueId,
1277
            $userId
1278
        ]);
1279
1280
        return $orderNumber;
1281
    }
1282
1283
    /**
1284
     *
1285
     *
1286
     * @param string $transactionId
1287
     * @param string $paymentUniqueId
1288
     * @param string $userId
1289
     * @return string $orderId
1290
     */
1291 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...
1292
    {
1293
        $sql = '
1294
            SELECT id FROM s_order
1295
            WHERE transactionID=? AND temporaryID=?
1296
            AND status!=-1 AND userID=?
1297
        ';
1298
1299
        $orderId = Shopware()->Db()->fetchOne($sql, [
1300
            $transactionId,
1301
            $paymentUniqueId,
1302
            $userId
1303
        ]);
1304
1305
        return $orderId;
1306
    }
1307
1308
1309
    /**
1310
     * Notify action method
1311
     */
1312
    public function pushAction()
1313
    {
1314
        $transactionId = $this->Request()->getParam('transactionId');
1315
1316
        $this->plugin->klarnaLog(
1317
            "Shopware_Controllers_Frontend_PaymentKlarna::pushAction->transactionId:\n" . $transactionId,
1318
            3
1319
        );
1320
        $connector = $this->plugin->getConnector();
1321
        $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...
1322
1323
        $order->fetch();
1324
1325
        if ($order['status'] === 'created') {
1326
            $this->plugin->klarnaLog(
1327
                "Shopware_Controllers_Frontend_PaymentKlarna::pushAction: " .
1328
                "OrderStatus is already created... nothing to do: ",
1329
                1
1330
            );
1331
            return;
1332
        }
1333
1334
        $this->createAccount($order);
1335
        // After createAccount update PaymentId to Klarna, could be defaultpayment
1336
        $this->plugin->savePayment($this->plugin->getPayment()->getId());
1337
        Shopware()->Session()->sOrderVariables['sUserData'] = $this->getUserData();
1338
1339 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...
1340
            $this->plugin->klarnaLog(
1341
                "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1342
                "checkout_complete. Save oder if session values match.",
1343
                3
1344
            );
1345
            if (Shopware()->Session()->offsetGet('KlarnaTransactionId') == null) {
1346
                $this->plugin->klarnaLog(
1347
                    "Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: " .
1348
                    "Session matches. Order will be saved",
1349
                    3
1350
                );
1351
                Shopware()->Session()->offsetSet('KlarnaTransactionId', $transactionId);
1352
                $orderNumber = $this->saveOrder(
1353
                    $order['reservation'],
1354
                    $order['reference']
1355
                );
1356
                Shopware()->Session()->offsetSet('KlarnaTransactionId', null);
1357
            }
1358
        }
1359
1360 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...
1361
            $orderNumber = $order['merchant_reference']['orderid1'];
1362
        }
1363
1364 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...
1365
            $update = [];
1366
1367
            $update['status'] = 'created';
1368
            $update['merchant_reference'] = [
1369
                'orderid1' => (string)$orderNumber,
1370
                'orderid2' => (string)$order['reference']
1371
            ];
1372
            $order->update($update);
1373
        }
1374
1375
        $this->savePaymentStatus(
1376
            $order['reservation'],
1377
            $order['reference'],
1378
            $this->config->get('statusId')
1379
        );
1380
    }
1381
1382
    private function saveOrderAttribute($orderNumber, $field, $value)
1383
    {
1384
        try {
1385
            $sql = "
1386
                INSERT INTO s_order_attributes (orderID, `$field`)
1387
                SELECT id, ? FROM s_order WHERE ordernumber = ?
1388
                ON DUPLICATE KEY UPDATE `$field` = VALUES(`$field`)
1389
            ";
1390
            $this->get('db')->query($sql, [
1391
                $value,
1392
                $orderNumber
1393
            ]);
1394
        } catch (Exception $e) {
1395
            $this->plugin->klarnaLog("PROBLEM SAVING ORDER ATTRIBUTES AFTER KLARNA PUSH!:\n" . $e->getMessage(), 1);
1396
        }
1397
    }
1398
1399
    /**
1400
     * Save register form so we can use it if user change between klarna and register tab
1401
     */
1402
    public function saveFormDataAction()
1403
    {
1404
        $form = $this->Request()->getPost();
1405
1406
        //unset password from passed post
1407
        unset($form['register']['personal']['password']);
1408
1409
        if (!empty($form)) {
1410
            Shopware()->Session()->klarnaSavedRegister = $form;
1411
        }
1412
    }
1413
1414
    /**
1415
     * Helper method to redirect the request to the proper page to set the payment into the customer account
1416
     */
1417
    public function setPaymentAction()
1418
    {
1419
        if ($this->Request()->isPost()) {
1420
            $values = $this->Request()->getPost('register');
1421
            $payment = $values['payment'];
1422
        } else {
1423
            $payment = $this->Request()->getParam('paymentId');
1424
        }
1425
1426
        if (empty($payment)) {
1427
            return;
1428
        }
1429
        $session = Shopware()->Session();
1430
        $session['KlarnaExternalPaymentId'] = $payment;
1431
1432
        $paymentName = $this->getPaymentNameById($session['KlarnaExternalPaymentId']);
1433
        $user = Shopware()->Modules()->Admin()->sGetUserData();
1434
        $userID = $user['additional']['user']['id'];
1435
1436
        // If user is not already registered and has selected external payment method
1437
        // PayPal redirect to PayPal Express checkout to prevent user registration
1438
        if ($paymentName === 'paypal' && empty($userID)) {
1439
            $this->redirect(
1440
                [
1441
                    'controller' => 'payment_paypal',
1442
                    'action'     => 'express',
1443
                ]
1444
            );
1445
        } elseif (empty($userID)) {
1446
            $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...
1447
            $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...
1448
            $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...
1449
1450
            $this->redirect(
1451
                [
1452
                    'controller'    => 'register',
1453
                    'action'        => 'index',
1454
                    'sTarget'       => 'checkout',
1455
                    'sTargetAction' => 'confirm',
1456
                ]
1457
            );
1458
        } else {
1459
            $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...
1460
            $this->plugin->savePayment($payment);
1461
            $this->redirect(
1462
                [
1463
                    'controller' => 'checkout',
1464
                    'action'     => 'confirm',
1465
                ]
1466
            );
1467
        }
1468
    }
1469
1470
    /**
1471
     * This action is called when the user is not logged in and tries to change
1472
     * the payment from klarna to another payment. Only used in responsive theme.
1473
     */
1474
    public function otherPaymentAction()
1475
    {
1476
        $userData = Shopware()->Modules()->Admin()->sGetUserData();
1477
        $session = Shopware()->Session();
1478
1479
        // reset country
1480
        $session['sCountry'] = $userData['additional']['country']['id'];
1481
        unset($session['sChangedCountry']);
1482
1483
        //Register-controller redirects to checkout by default when the user is logged in already.
1484
        /*        $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...
1485
                    'controller' => 'checkout',
1486
                    'action' => 'shippingPayment',
1487
                    'klarnaRedirect' => 1
1488
                    //'sTarget' => 'checkout',
1489
                    //'sTargetAction' => 'shippingPayment'
1490
                ));
1491
        */
1492
        if ($this->isUserLoggedIn()) {
1493
            $this->redirect([
1494
                'controller' => 'checkout',
1495
                'klarnaRedirect' => 1,
1496
                'action' => 'shippingPayment',
1497
                'sTarget' => 'checkout'
1498
            ]);
1499
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
1500
        } else {
1501
            $this->redirect([
1502
                'controller' => 'register',
1503
                'klarnaRedirect' => 1,
1504
                'sTarget' => 'checkout',
1505
                'sTargetAction' => 'shippingPayment'
1506
            ]);
1507
        }
1508
    }
1509
1510
    /**
1511
     * @return bool
1512
     */
1513
    protected function isUserLoggedIn()
1514
    {
1515
         return (isset($this->session->sUserId) && !empty($this->session->sUserId));
1516
    }
1517
1518
    /**
1519
     * Get complete user-data as an array to use in view
1520
     *
1521
     * @return array
1522
     */
1523
    public function getUserData()
1524
    {
1525
        $system = Shopware()->System();
1526
        $admin = Shopware()->Modules()->Admin();
1527
        $userData = $admin->sGetUserData();
1528
        if (!empty($userData['additional']['countryShipping'])) {
1529
            $system->sUSERGROUPDATA = Shopware()->Db()->fetchRow("
1530
                SELECT * FROM s_core_customergroups
1531
                WHERE groupkey = ?
1532
            ", [$system->sUSERGROUP]);
1533
1534
            if ($this->isTaxFreeDelivery($userData)) {
1535
                $system->sUSERGROUPDATA['tax'] = 0;
1536
                $system->sCONFIG['sARTICLESOUTPUTNETTO'] = 1; //Old template
1537
                Shopware()->Session()->sUserGroupData = $system->sUSERGROUPDATA;
1538
                $userData['additional']['charge_vat'] = false;
1539
                $userData['additional']['show_net'] = false;
1540
                Shopware()->Session()->sOutputNet = true;
1541
            } else {
1542
                $userData['additional']['charge_vat'] = true;
1543
                $userData['additional']['show_net'] = !empty($system->sUSERGROUPDATA['tax']);
1544
                Shopware()->Session()->sOutputNet = empty($system->sUSERGROUPDATA['tax']);
1545
            }
1546
        }
1547
1548
        return $userData;
1549
    }
1550
1551
    /**
1552
     * Validates if the provided customer should get a tax free delivery
1553
     * @param array $userData
1554
     * @return bool
1555
     */
1556
    protected function isTaxFreeDelivery($userData)
1557
    {
1558
        if (!empty($userData['additional']['countryShipping']['taxfree'])) {
1559
            return true;
1560
        }
1561
1562
        if (empty($userData['additional']['countryShipping']['taxfree_ustid'])) {
1563
            return false;
1564
        }
1565
1566
        return !empty($userData['shippingaddress']['ustid']);
1567
    }
1568
1569
    /**
1570
     * returns payment name from payment Ids
1571
     * @param integer $paymentId
1572
     * @return string
1573
     */
1574
    private function getPaymentNameById($paymentId)
1575
    {
1576
        $paymentRepo = Shopware()->Models()->getRepository('Shopware\Models\Payment\Payment');
1577
        $payment = $paymentRepo->findOneBy(['id' => $paymentId]);
1578
        return $payment->getName();
1579
    }
1580
}
1581