Passed
Push — master ( 9698e0...1a6dcb )
by
unknown
03:06
created

Shopware_Controllers_Frontend_PaymentKlarna   D

Complexity

Total Complexity 184

Size/Duplication

Total Lines 1476
Duplicated Lines 13.48 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 199
loc 1476
rs 4.4102
c 0
b 0
f 0
wmc 184
lcom 1
cbo 2

44 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 8 1
A preDispatch() 0 7 2
A getWhitelistedCSRFActions() 0 18 1
A get() 11 11 4
A indexAction() 0 5 1
B expressAction() 0 24 3
F showIframeAction() 0 190 22
A getCountryByShop() 13 13 3
A addVoucherAction() 0 11 3
A getShippingCosts() 0 10 4
A finishAction() 0 12 1
A changeQuantityAction() 0 9 3
A deleteArticleAction() 0 9 2
A getDispatches() 0 10 3
A setDispatch() 0 17 3
B getSelectedDispatch() 0 21 5
B calculateShippingCostsAction() 0 30 5
A getSelectedCountry() 0 19 3
A getCountryList() 0 4 1
A getSelectedState() 0 8 2
F createAccount() 26 198 44
B saveUser() 0 41 1
A updateCustomer() 0 20 4
B updateShipping() 0 28 3
A updateBilling() 0 18 1
A loginAction() 0 5 1
F returnAction() 25 103 14
A checkKlarnaOrderExistsBySession() 17 17 3
A checkKlarnaOrderExistsByReference() 17 17 3
A checkKlarnaOrderExistsByReservation() 17 17 3
A checkKlarnaOrderExists() 0 17 2
A checkKlarnaOrderDetailsBySession() 18 18 3
A getUserIdByReference() 0 12 1
A getKlarnaOrderNumber() 15 15 1
A getKlarnaOrderId() 15 15 1
B pushAction() 25 54 7
A saveOrderAttribute() 0 16 2
A saveFormDataAction() 0 11 2
B setPaymentAction() 0 53 5
B otherPaymentAction() 0 35 2
A isUserLoggedIn() 0 4 2
B getUserData() 0 27 3
A isTaxFreeDelivery() 0 12 3
A getPaymentNameById() 0 7 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Shopware_Controllers_Frontend_PaymentKlarna often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Shopware_Controllers_Frontend_PaymentKlarna, and based on these observations, apply Extract Interface, too.

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
    /**
42
     * {@inheritdoc}
43
     */
44
    public function preDispatch()
45
    {
46
47
        if (in_array($this->Request()->getActionName(), array('push', 'saveFormData'))) {
48
            $this->Front()->Plugins()->ViewRenderer()->setNoRender();
49
        }
50
    }
51
    
52
    /**
53
     * whitelists indexAction for SW 5.2 compatibility
54
     */
55
    public function getWhitelistedCSRFActions()
56
    {
57
        return [
58
            'index',
59
            'express',
60
            'push',
61
            'login',
62
            'return',
63
            'showIframe',
64
            'calculateShippingCosts',
65
            'savePayment',
66
            'addVoucher',
67
            'deleteArticle',
68
            'saveFormData',
69
            'setPayment',
70
            'otherPayment',
71
        ];
72
    }    
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 View Code Duplication
    public function get($name)
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...
78
    {
79
        if (version_compare(Shopware::VERSION, '4.2.0', '<') && Shopware::VERSION != '___VERSION___') {
80
            if ($name == 'pluginlogger') {
81
                $name = 'log';
82
            }
83
            $name = ucfirst($name);
84
            return Shopware()->Bootstrap()->getResource($name);
85
        }
86
        return parent::get($name);
87
    }
88
    
89
    /**
90
     * Index action method.
91
     *
92
     * Forwards to correct the action.
93
     */
94
    public function indexAction()
95
    {
96
        $this->redirect(array('controller' => 'payment_klarna', 'action' => 'showIframe'));
97
98
    }
99
100
    /**
101
     * Express payment action method.
102
     */
103
    public function expressAction()
104
    {
105
        if (!empty($this->session->PaypalResponse)){
106
            $this->plugin->klarnaLog("Paypal Payment in Progress detected Redirecting To Index Page", 3);
107
            $this->redirect(
108
                array(
109
                    'controller' => 'index',
110
                    'action' => 'index'
111
                )
112
            );
113
            return;
114
        }        
115
        
116
        if ($this->Request()->getPost('sCountry')) {
117
            $this->session['sCountry'] = (int)$this->Request()->getPost('sCountry');
118
            $this->session["sState"] = 0;
119
            $this->session["sArea"] = Shopware()->Db()->fetchOne("
120
                SELECT areaID FROM s_core_countries WHERE id = ?
121
            ", array($this->session['sCountry']));
122
            unset($this->session->KlarnaOrder);
123
            $this->session['sChangedCountry'] = (int)$this->Request()->getPost('sCountry');
124
        }
125
        $this->forward('index');
126
    }
127
128
129
    /**
130
     * Express Iframe Test
131
     */
132
    public function showIframeAction() {
133
134
        $this->basket = $this->get('modules')->Basket()->sGetBasket();
135
         $preFill = $this->config['preFillCheckout'];
136
        if ($this->isUserLoggedIn()){
137
            $user = Shopware()->Modules()->Admin()->sGetUserData();
138
        }
139
140
        $paymentIdDebug = $this->plugin->getPayment()->getId();
141
142
        // set payment to klarna checkout
143
        $this->session['sPaymentID'] = $this->plugin->getPayment()->getId();
144
145
        // Register Custom Template
146
        $this->View()->loadTemplate("frontend/checkout/confirm.tpl");
147
        // update dispatch or delivery country in case form was submitted
148
        if ($this->Request()->isPost()) {
149
150
            // set klarnaPrefill, in case User ovverides Setting with checkbox
151
152
            if ($this->Request()->getParam('klarnaPreFill') == "on"){
153
                $this->session['klarnaUserPreFill'] = true;
154
            }
155
156
            $this->setDispatch($this->Request()->getPost('sDispatch'));
157
            $postedCountry = $this->Request()->getPost('sCountry');
158
            if (!empty($postedCountry)) {
159
                $shopCountryId = $this->session['sCountry'];
160
                $validKlarnaCountry = $this->plugin->checkValidKlarnaCountry($postedCountry);
161
                if (!$validKlarnaCountry) {
162
                    $this->redirect(array('controller' => 'payment_klarna', 'action' => 'otherPayment'));
163
                    return;
164
                }
165
                $shopCountryId = (string)$shopCountryId;
166
                if ($shopCountryId != $postedCountry) {
167
                    $this->session['sCountry'] = $postedCountry;
168
                    // unset klarnaOrder so it will be created with new countryID
169
                    unset($this->session['KlarnaOrder']);
170
                }
171
            }
172
            //$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...
173
        } else {
174
            $this->setDispatch($this->session->sDispatch, $paymentIdDebug);
175
        }
176
        // set shipping costs (Overwrites $session->sCountry!)
177
        $debugShipping = $this->getShippingCosts();
178
        if ($postedCountry){
179
            $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...
180
        } else {
181
            // set Default Country
182
            $this->session['sCountry'] = $this->getCountryByShop(Shopware()->Shop());
183
        }
184
185
        $this->basket['sShippingcosts'] = $debugShipping['brutto'];;
186
        $this->basket['sShippingcostsWithTax'] = $debugShipping['brutto'];
187
        $this->basket['sShippingcostsNet'] = $debugShipping['netto'];
188
        $this->basket['sShippingcostsTax'] = $debugShipping['tax'];
189
190
        // set missing basket vars for use in view
191
        $this->basket['AmountWithTaxNumeric'] = floatval(str_replace(',','.',$this->basket['Amount'])) + floatval(str_replace(',','.',$debugShipping['brutto']));
192
        $this->basket['AmountNetNumeric'] = floatval(str_replace(',','.',$this->basket['AmountNet']));
193
194
        $klarnaConnector = $this->plugin->getConnector();
195
        $shop = $this->plugin->Application()->Shop();
196
197
        $create = array();
198
        $create['cart']['items'] = $this->plugin->getCheckoutCart($this->basket);
199
        $create['merchant'] = $this->plugin->getCheckoutMerchant();
200
201
        $create['purchase_country'] = $this->plugin->getCountryIsoById($this->session['sCountry']);
202
        $create['purchase_currency'] = $shop->getCurrency()->toString();
203
        $create['locale'] = $this->plugin->getLocale(false, $create['purchase_country']);
204
        $create['options'] = $this->plugin->getCheckoutOptions();
205
206
        if ($this->config->get('KlarnaExternalPayments')) {
207
            list($create['external_payment_methods'], $create['external_checkouts']) = $this->plugin->getExternalPaymentMethods($this->basket);
208
        }
209
210
        if ($this->config->get('disableAutofocus')) {
211
            $create['gui']['options'] = array('disable_autofocus');
212
        }
213
214
        // set Prefill Information
215
216
        if (($preFill == true) || ($this->session['klarnaUserPreFill'] == true)) {
217
            $this->session['klarnaPreFill'] = true;
218
            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...
219
                $countryId = $this->getCountryByShop($shop);
220
            }
221
            else {
222
                $countryId = $session['sCountry'];
223
            }
224
            if ($user ['additional']['countryShipping']['id'] == $countryId
225
                && $user['billingaddress']['zipcode'] != '00000'
226
            ) {
227
                $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...
228
                if ($user['additional']['countryShipping']['id'] == $user['additional']['country']['id']) {
229
                    $create['shipping_address'] = $this->plugin->getCheckoutAddress($user, 'billing');
230
                } else {
231
                    $create['shipping_address'] = $this->plugin->getCheckoutAddress($user, 'shipping');
232
                }
233
            }
234
        } else {
235
            $this->session['klarnaPreFill'] = false;
236
        }
237
238
        // In case Customer fills Iframe and then logs in do not update existing klarnaOrder
239
        if (!empty($this->session['KlarnaOrder']) && !$this->isUserLoggedIn()){
240
            $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...
241
            $update = array();
242
            $update['cart']['items'] = $this->plugin->getCheckoutCart($this->basket);
243
            $update['purchase_country'] = $this->plugin->getCountryIsoById($this->session['sCountry']);
244
245
            $klarnaOrder->fetch();
246
            // update basket and delivery country in case it changed
247
            $klarnaOrder->update($update);
248
249
        } else {
250
            $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...
251
            $klarnaOrder->create($create);
252
        }
253
254
255
        try {
256
            $klarnaOrder->fetch();
257
258
        } catch (Exception $e) {
259
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
260
            echo "Entschuldigung, Ein Verbindungsfehler ist aufgetreten, bitte aktualisieren Sie die Seite";
261
            $this->plugin->klarnaLog("Verbindungsfehler in onPreDispatchCheckout\nCode:".$e->getCode()."Nachricht:\n".$e->getMessage(),1);
262
        }
263
264
        $this->session->KlarnaOrder = $klarnaOrder->getLocation();
265
266
        // Delete old perhaps cancelled Klarna Order
267
268
        if ($klarnaOrder['status'] !== "checkout_incomplete"){
269
            unset($this->session->KlarnaOrder);
270
        }
271
272
        $userAdditionalArray = array();
273
        $userAdditionalArray['additional']['charge_vat'] = 1;
274
275
        $userPayment = array();
276
        $userPayment['id'] = $this->plugin->getPayment()->getId();
277
278
        // persist basket changes
279
        Shopware()->Session()->sOrderVariables['sBasket'] = $this->basket;
280
281
        // Klarna Iframe Information
282
        $this->View()->assign('KlarnaOrder', $klarnaOrder->marshal());
283
284
        // Klarna Prefill checkBox
285
        if ($this->isUserLoggedIn()) {
286
               $this->View()->assign('KlarnaPreFillSelect', !$this->session['klarnaPreFill']);
287
        }
288
289
        // Iframe Backend Config
290
        $this->plugin->getViewConfig($this->View(), $this->config);
291
        $this->View()->sBasket = $this->basket;
292
        $this->View()->sDispatches = $this->getDispatches($paymentIdDebug);
293
        if ($postedCountry){
294
            $this->session['sCountry'] = $postedCountry;
295
        }
296
        $this->View()->sDispatch = $this->getSelectedDispatch();
297
298
        // Neccessary if user is not logged in
299
        $this->View()->sPayment = $userPayment;
300
301
        $this->basket['sShippingcosts'] = $debugShipping['brutto'];;
302
        $this->basket['sShippingcostsWithTax'] = $debugShipping['brutto'];
303
        $this->basket['sShippingcostsNet'] = $debugShipping['netto'];
304
        $this->basket['sShippingcostsTax'] = $debugShipping['tax'];
305
306
        $this->basket['sAmount'] = floatval ($this->basket['Amount']) + floatval($this->basket['sShippingcosts']);
307
        $this->basket['sAmountNet'] = floatval($this->basket['AmountNetNumeric']) + floatval($debugShipping['netto']);
308
309
        $this->basket['sAmountTax'] = 1.9;
310
        $this->View()->sShippingcosts = $debugShipping['brutto'];
311
        $this->View()->sShippingcostsWithTax =  $debugShipping['brutto'];
312
        $this->View()->sShippingcostsNet = $debugShipping['netto'];
313
        $this->View()->sShippingcostsTax = $debugShipping['tax'];
314
        $this->View()->sAmount = $this->basket['AmountWithTaxNumeric'] ;
315
316
        $this->View()->sAmountNet = $this->basket['sAmountNet'];
317
        $this->View()->sAmountTax = $this->basket['sAmountTax'];
318
        $this->View()->assign('sUserData', $userAdditionalArray);
319
        $this->View()->sPayments = $this->admin->sGetPaymentMeans();
320
        $this->View()->sUserLoggedIn = $this->isUserLoggedIn();
321
    }
322
323
    /**
324
     * @param $shop Shopware\Models\Shop\Shop
325
     * @return int|null
326
     */
327 View Code Duplication
    public function getCountryByShop($shop)
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...
328
    {
329
        $locale = $shop->getLocale()->getLocale();
330
        $this->plugin->klarnaLog("Entering Bootstrap::getCountryByShop", 3);
331
        $locale = explode('_', $locale);
332
        $locale = isset($locale[1]) ? $locale[1] : $locale[0];
333
        $this->plugin->klarnaLog("Bootstrap::getCountryByShop locale to request for:".$locale,3);
334
        $sql = 'SELECT id FROM s_core_countries WHERE countryiso=?';
335
        $countryId = Shopware()->Db()->fetchOne($sql, array($locale));
336
        $countryId = ($countryId) ? (int)$countryId : null;
337
338
        return $countryId;
339
    }
340
341
    /**
342
     * Add voucher to cart
343
     *
344
     * At failure view variable sVoucherError will give further information
345
     * At success return to cart / confirm view
346
     */
347
    public function addVoucherAction()
348
    {
349
        $this->basket = $this->get('modules')->Basket()->sGetBasket();
350
        if ($this->Request()->isPost()) {
351
            $voucher = $this->basket->sAddVoucher($this->Request()->getParam('sVoucher'));
352
            if (!empty($voucher['sErrorMessages'])) {
353
                $this->View()->assign('sVoucherError', $voucher['sErrorMessages'], null, Smarty::SCOPE_ROOT);
354
            }
355
        }
356
        $this->forward('showIframe');
357
    }
358
359
360
361
    /**
362
     * Get shipping costs as an array (brutto / netto) depending on selected country / payment
363
     *
364
     * @return array
365
     */
366
    public function getShippingCosts()
367
    {
368
        $country = $this->getSelectedCountry();
369
        $payment = $this->plugin->getPayment()->getId();
370
        if (empty($country) || empty($payment)) {
371
            return array('brutto'=>0, 'netto'=>0);
372
        }
373
        $shippingcosts = $this->admin->sGetPremiumShippingcosts($country);
374
        return empty($shippingcosts) ? array('brutto'=>0, 'netto'=>0) : $shippingcosts;
375
    }
376
377
    /**
378
     * Express Iframe Test
379
     */
380
    public function finishAction()
381
    {
382
        $connector = $this->plugin->getConnector();
383
        $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...
384
        $klarnaOrder->fetch();
385
        $this->View()->loadTemplate("frontend/checkout/finish.tpl");
386
        $this->View()->assign('KlarnaOrder', $klarnaOrder->marshal());
387
        // reset basket
388
        unset($this->session['KlarnaOrder']);
389
        unset($this->session['sBasketQuantity']);
390
        unset($this->session['sBasketAmount']);
391
    }
392
393
    /**
394
     * Change quantity of a certain product
395
     * @param sArticle = The article to update
396
     * @param sQuantity = new quantity
397
     * Forward to cart / confirm view after success
398
     */
399
    public function changeQuantityAction()
400
    {
401
        $basketObj = $this->get('modules')->Basket();
402
403
        if ($this->Request()->getParam('sArticle') && $this->Request()->getParam('sQuantity')) {
404
            $this->View()->sBasketInfo = $basketObj->sUpdateArticle($this->Request()->getParam('sArticle'), $this->Request()->getParam('sQuantity'));
405
        }
406
       $this->redirect(['action' => $this->Request()->getParam('sTargetAction', 'showIframe')]);
407
    }
408
409
    /**
410
     * Delete an article from cart -
411
     * @param sDelete = id from s_basket identifying the product to delete
412
     * Forward to cart / confirmation page after success
413
     */
414
    public function deleteArticleAction()
415
    {
416
        $basketObj = $this->get('modules')->Basket();
417
418
        if ($this->Request()->getParam('sDelete')) {
419
            $basketObj->sDeleteArticle($this->Request()->getParam('sDelete'));
420
        }
421
        $this->forward($this->Request()->getParam('sTargetAction', 'index'));
422
    }
423
424
    /**
425
     * Get all dispatches available in selected country from sAdmin object
426
     *
427
     * @param null $paymentId
428
     * @return array list of dispatches
429
     */
430
    public function getDispatches($paymentId = null)
431
    {
432
        $country = $this->getSelectedCountry();
433
        $state = $this->getSelectedState();
434
        if (empty($country)) {
435
            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...ntKlarna::getDispatches 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...
436
        }
437
        $stateId = !empty($state['id']) ? $state['id'] : null;
438
        return $this->admin->sGetPremiumDispatches($country['id'], $paymentId, $stateId);
439
    }
440
441
    /**
442
     * Set the provided dispatch method
443
     *
444
     * @param $dispatchId ID of the dispatch method to set
445
     * @param int|null $paymentId Payment id to validate
446
     * @return int set dispatch method id
447
     */
448
    public function setDispatch($dispatchId, $paymentId = null)
449
    {
450
        $supportedDispatches = $this->getDispatches($paymentId);
451
452
        // Iterate over supported dispatches, look for the provided one
453
        foreach ($supportedDispatches as $dispatch) {
454
            if ($dispatch['id'] == $dispatchId) {
455
                $this->session['sDispatch'] = $dispatchId;
456
                return $dispatchId;
457
            }
458
        }
459
460
        // If it was not found, we fallback to the default (head of supported)
461
        $defaultDispatch = array_shift($supportedDispatches);
462
        $this->session['sDispatch'] = $defaultDispatch['id'];
463
        return $this->session['sDispatch'];
464
    }
465
466
    /**
467
     * Get selected dispatch or select a default dispatch
468
     *
469
     * @return boolean|array
470
     */
471
    public function getSelectedDispatch()
472
    {
473
        if (empty($this->session['sCountry'])) {
474
            return false;
475
        }
476
477
        $dispatches = $this->admin->sGetPremiumDispatches($this->session['sCountry'], null, $this->session['sState']);
478
        if (empty($dispatches)) {
479
            unset($this->session['sDispatch']);
480
            return false;
481
        }
482
483
        foreach ($dispatches as $dispatch) {
484
            if ($dispatch['id'] == $this->session['sDispatch']) {
485
                return $dispatch;
486
            }
487
        }
488
        $dispatch = reset($dispatches);
489
        $this->session['sDispatch'] = (int) $dispatch['id'];
490
        return $dispatch;
491
    }
492
493
    /**
494
     * On any change on country, payment or dispatch recalculate shipping costs
495
     * and forward to cart / confirm view
496
     */
497
    public function calculateShippingCostsAction()
498
    {
499
        if ($this->Request()->getPost('sCountry')) {
500
            $this->session['sCountry'] = (int) $this->Request()->getPost('sCountry');
501
            $this->session["sState"] = 0;
502
            $this->session["sArea"] = Shopware()->Db()->fetchOne("
503
            SELECT areaID FROM s_core_countries WHERE id = ?
504
            ", array($this->session['sCountry']));
505
        }
506
507
        if ($this->Request()->getPost('sPayment')) {
508
            $this->session['sPaymentID'] = (int) $this->Request()->getPost('sPayment');
509
        }
510
511
        if ($this->Request()->getPost('sDispatch')) {
512
            $this->session['sDispatch'] = (int) $this->Request()->getPost('sDispatch');
513
        }
514
515
        if ($this->Request()->getPost('sState')) {
516
            $this->session['sState'] = (int) $this->Request()->getPost('sState');
517
        }
518
519
        // We might change the shop context here so we need to initialize it again
520
        $this->get('shopware_storefront.context_service')->initializeShopContext();
521
522
        // We need an indicator in the view to expand the shipping costs pre-calculation on page load
523
        $this->View()->assign('calculateShippingCosts', true);
524
525
        $this->forward('showIframe');
526
    }
527
528
    /**
529
     * Get current selected country - if no country is selected, choose first one from list
530
     * of available countries
531
     *
532
     * @return array with country information
533
     */
534
    public function getSelectedCountry()
535
    {
536
        if (!empty($this->View()->sUserData['additional']['countryShipping'])) {
537
            $this->session['sCountry'] = (int) $this->View()->sUserData['additional']['countryShipping']['id'];
538
            $this->session['sArea'] = (int) $this->View()->sUserData['additional']['countryShipping']['areaID'];
539
540
            return $this->View()->sUserData['additional']['countryShipping'];
541
        }
542
        $countries = $this->getCountryList();
543
        if (empty($countries)) {
544
            unset($this->session['sCountry']);
545
            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...
546
        }
547
        $country = reset($countries);
548
        $this->session['sCountry'] = (int) $country['id'];
549
        $this->session['sArea'] = (int) $country['areaID'];
550
        $this->View()->sUserData['additional']['countryShipping'] = $country;
551
        return $country;
552
    }
553
554
    /**
555
     * Get all countries from database via sAdmin object
556
     *
557
     * @return array list of countries
558
     */
559
    public function getCountryList()
560
    {
561
        return $this->admin->sGetCountryList();
562
    }
563
564
    /**
565
     * Get current selected country - if no country is selected, choose first one from list
566
     * of available countries
567
     *
568
     * @return array with country information
569
     */
570
    public function getSelectedState()
571
    {
572
        if (!empty($this->View()->sUserData['additional']['stateShipping'])) {
573
            $this->session['sState'] = (int) $this->View()->sUserData['additional']['stateShipping']['id'];
574
            return $this->View()->sUserData['additional']['stateShipping'];
575
        }
576
        return array("id" => $this->session['sState']);
577
    }
578
579
   /**
580
     * @param Klarna_Checkout_Order $order
581
     */
582
    public function createAccount($order = null, $checkLoginState=true)
583
    {
584
        $this->plugin->klarnaLog('Entering Shopware_Controllers_Frontend_PaymentKlarna::createAccount', 3);
585
        $module = Shopware()->Modules()->Admin();
586
        $session = Shopware()->Session();
587
        $version = Shopware()->Config()->version;
588
589
        if ($version == '___VERSION___' || version_compare($version, '4.1.0', '>=')) {
590
            $encoder = Shopware()->PasswordEncoder()->getDefaultPasswordEncoderName();
591
        }
592
        
593
        $data = array();
594
595
        if ($order !== null && !empty($order['billing_address']['email'])) {
596
            $data['auth']['email'] = $order['billing_address']['email'];
597
            $data['auth']['password'] = $order['reference'];
598
        } else {
599
            $sessionId = Shopware()->SessionID();
600
            // email is only varchar(70) so we cut the sessionid
601
            //$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...
602
            $data['auth']['email'] = substr($sessionId, 0,49) . '@klarna.com';
603
            $data['auth']['password'] = $sessionId;
604
        }
605
        $data['auth']['accountmode'] = '1';
606
607
        $phone = $order['billing_address']['phone'];
608
        $data['billing']['phone'] = !empty($phone) ? $phone : ' ';
609
        $data['phone'] = !empty($phone) ? $phone : ' ';
610
        if (!empty($order['customer']['date_of_birth'])) {
611
            list($data['billing']['birthyear'], $data['billing']['birthmonth'], $data['billing']['birthday']) = explode(
612
                '-',
613
                $order['customer']['date_of_birth']
614
            );
615
        }
616
617
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->order:",4, $order);
618
        
619
        foreach (array('billing', 'shipping') as $type) {
620
            if (isset($order[$type . '_address'])) {
621
                $orderAddress = $order[$type . '_address'];
622
                if (isset($orderAddress['title'])) {
623
                    $data[$type]['salutation'] = $orderAddress['title'] == 'Frau' ? 'ms' : 'mr';
624
                } else {
625
                    $data[$type]['salutation'] = 'mr';
626
                }
627
                $data[$type]['firstname'] = $orderAddress['given_name'];
628
                $data[$type]['lastname'] = $orderAddress['family_name'];
629
                if (isset($orderAddress['street_name']) && $orderAddress['street_number']) {
630
                    if (version_compare(Shopware::VERSION, '5.0.0', '>=')) {
631
                        $data[$type]['street'] = $orderAddress['street_name'] . ' ' . $orderAddress['street_number'];
632 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...
633
                        $data[$type]['street'] = $orderAddress['street_name'];
634
                        $data[$type]['streetnumber'] = $orderAddress['street_number'];
635
                    }
636
                } else {
637
                    $data[$type]['street'] = $orderAddress['street_address'];
638
                    $data[$type]['streetnumber'] = ' ';
639
                }
640
                $data[$type]['zipcode'] = $orderAddress['postal_code'];
641
                $data[$type]['city'] = $orderAddress['city'];
642
                if (!empty($orderAddress['care_of'])) {
643
                    if ($orderAddress['street_name'] == 'Packstation') {
644
                        $data[$type]['postnumber'] = $orderAddress['care_of'];
645
                        $data[$type]['swagDhlPostnumber'] = $data[$type]['postnumber'];
646
                    } else {
647
                        $data[$type]['company'] = $orderAddress['care_of'];
648
                    }
649
                }
650
            }
651
652
            if (!isset($data[$type]['company'])) {
653
                $data[$type]['company'] = '';
654
            }
655
            $data[$type]['department'] = '';
656
657
            if (!empty($order[$type . '_address']['country'])) {
658
                $sql = 'SELECT id FROM s_core_countries WHERE countryiso=?';
659
                $countryId = Shopware()->Db()->fetchOne($sql, array($order[$type . '_address']['country']));
660
            } else {
661
                $countryId = $session['sCountry'];
662
            }
663
            // make sure country is set in case of lost sessions defualt to germany
664
            if (empty($countryId)){
665
                $countryId = 2;
666
            }            
667
668
            $data[$type]['country'] = $countryId;
669
        }
670
671
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->data AFTER ADDRESSES:",4,$data);
672
        $sql = 'SELECT id FROM s_core_paymentmeans WHERE name=?';
673
        $paymentId = Shopware()->Db()->fetchOne($sql, array('klarna_checkout'));
674
675
        if ($order !== null && !empty($order['billing_address']['email'])) {
676
            $shop = $this->get('shop');
677
            $shop = $shop->getMain() ?: $shop;
678
            $sql = 'SELECT id, email, `password` FROM `s_user` WHERE `email` LIKE ? AND `active` = 1 ';
679
            if ($shop->getCustomerScope()) {
680
                $sql .= "AND `subshopID` = {$shop->getId()} ";
681
            }
682
            $sql .= 'ORDER BY `accountmode`';
683
            $user = Shopware()->Db()->fetchRow($sql, array($data['auth']['email']));
684
            // First try login 
685
            if (!empty($user)) {
686
                $session->offsetSet('sUserMail', $user['email']);
687
                $session->offsetSet('sUserPassword', $user['password']);
688
                $session->offsetSet('sUserId', $user['id']);
689
            } else {
690
                $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->user Not Found in DB SQL was:" .$sql,1);                
691
            }
692
        }
693
694
        if ($checkLoginState) {
695
            // Check login status
696
            if (!empty($session->sUserId)) {
697
                if ($order !== null) {
698
                    $module->sSYSTEM->_POST = $data['shipping'];
699 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...
700
                        $userId = $session->offsetGet('sUserId');
701
                        $this->updateShipping($userId, $data['shipping']);
702
                    } else {
703
                        $module->sUpdateShipping();
704
                    }
705
                    $module->sSYSTEM->_POST = $data['billing'];
706 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...
707
                         $userId = $session->offsetGet('sUserId');
708
                         $this->updateBilling($userId, $data['billing']);
709
                    } else{
710
                        $module->sUpdateBilling();
711
                    }
712
                    unset($data['auth']['password']);
713
                    $module->sSYSTEM->_POST = $data['auth'];
714
                    if (Shopware::VERSION === '___VERSION___' || version_compare(Shopware::VERSION, '5.2.0', '>=')) {
715
                        $userId = $session->offsetGet('sUserId');
716
                        $this->updateCustomer($data, $userId);
717
                        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->updateCustomer:",3, $data);                                                
718
                    } else{
719
                        $module->sUpdateAccount();
720
                        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->updateAccount:",3, $this->front->Request()->getPost());                                                                        
721
                    }
722
                } else {
723
                    /** @var Enlight_Controller_Front $front */
724
                    $front = $this->get('front');
725
                    $front->Request()->setPost(array());
726
                    $module->sSYSTEM->_POST = array('country' => $data['shipping']['country']);
727
                    $shippingId = $this->get('db')->fetchOne(
728
                        'SELECT id FROM s_user_shippingaddress WHERE userID = ?',
729
                        array($session->offsetGet('sUserId'))
730
                    );
731 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...
732
                        if (Shopware::VERSION === '___VERSION___' || version_compare(Shopware::VERSION, '5.2.0', '>=')) {
733
                            $userId = $session->offsetGet('sUserId');
734
                            $this->updateShipping($userId, $data['shipping']);
735
                        } else {
736
                            $module->sUpdateShipping();
737
                        }
738
                    } else {
739
                        $module->sUpdateBilling();
740
                    }
741
                }
742
                $module->sSYSTEM->_POST = array('sPayment' => $paymentId);
743
                $module->sUpdatePayment();
744
            } else {
745
                $data['payment']['object'] = $module->sGetPaymentMeanById($paymentId);
746
                if (isset($encoder)) {
747
                    $data["auth"]["encoderName"] = $encoder;
748
                    $data["auth"]["password"] = Shopware()->PasswordEncoder()->encodePassword($data["auth"]["password"], $encoder);
749
                } else {
750
                    $data['auth']['password'] = md5($data['auth']['password']);
751
                }
752
                $session->sRegisterFinished = false;
753
                if (version_compare(Shopware::VERSION, '4.3.0', '>=') && version_compare(Shopware::VERSION, '5.2.0', '<')) {
754
                    $session->sRegister = $data;
755
                } elseif (version_compare(Shopware::VERSION, '4.3.0', '<')) {
756
                    $session->sRegister = new ArrayObject($data, ArrayObject::ARRAY_AS_PROPS);
757
                }
758
                try {
759
                    if (Shopware::VERSION === '___VERSION___' || version_compare(Shopware::VERSION, '5.2.0', '>=')) {
760
                        $newdata = $this->saveUser($data);
761
                        $module->sSYSTEM->_POST = $newdata['auth'];
762
                        $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...
763
                        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser:",3, $newdata);
764
                    } else {
765
                        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser->Register:",3, $session->sRegister);                         
766
                        $module->sSaveRegister();
767
                        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->saveUser->RegisterFinished:",3, $session->offsetGet('sRegisterFinished')); 
768
                    }
769
                    
770
                } catch (\Exception $ex) { /* do nothing */
771
                    $this->plugin->klarnaLog("ERROR while creating User. Exception information:".$ex->getMessage(),1);
772
                    
773
                }
774
            }
775
            
776
        }
777
        
778
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::createAccount->data END OF METHOD:",4, $data);
779
    }
780
    
781
    /**
782
     * Saves a new user to the system.
783
     *
784
     * @param array $data
785
     * @return array $data
786
     */
787
    private function saveUser($data)
788
    {
789
790
        $plainbilling = array_merge($data['auth'], $data['billing']);
791
        $plainshipping = array_merge($data['auth'], $data['shipping']);
792
793
        //Create forms and validate the input
794
        $customer = new Shopware\Models\Customer\Customer();
795
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\PersonalFormType', $customer);
796
        $form->submit($plainbilling);
797
798
        $billingaddress = new Shopware\Models\Customer\Address();
799
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\AddressFormType', $billingaddress);
800
        $form->submit($plainbilling);
801
802
        $shippingaddress = new Shopware\Models\Customer\Address();
803
        $form = $this->createForm('Shopware\Bundle\AccountBundle\Form\Account\AddressFormType', $shippingaddress);
804
        $form->submit($plainshipping);
805
806
        /** @var Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface $context */
807
        $context = $this->get('shopware_storefront.context_service')->getShopContext();
808
809
        /** @var Shopware\Bundle\StoreFrontBundle\Struct\Shop $shop */
810
        $shop = $context->getShop();
811
812
        /** @var Shopware\Bundle\AccountBundle\Service\RegisterServiceInterface $registerService */
813
        $registerService = $this->get('shopware_account.register_service');
814
        $data['birthdate'] = $data['billing']['birthyear'].'-'.$data['billing']['birthmonth'].'-'.$data['billing']['birthday'];
815
        $customer->setBirthday($data['birthdate']);
816
        $registerService->register($shop, $customer, $billingaddress, $shippingaddress);
817
818
        // get updated password; it is md5 randomized after register
819
        $getUser = Shopware()->Models()->getRepository('Shopware\Models\Customer\Customer')->findOneBy(
820
		array('email' =>  $data['auth']['email'])
821
		);
822
823
       $data['auth']['password']= $getUser->getPassword();
824
       $data['auth']['passwordMD5']= $getUser->getPassword();
825
       $data['auth']['encoderName'] = 'md5';
826
       return $data;
827
    }
828
829
830
    /**
831
     * Endpoint for changing the main profile data
832
     */
833
    public function updateCustomer($data, $userId)
834
    {
835
        if (empty($data['billing']['birthyear']) || empty($data['billing']['birthmonth']) || empty($data['billing']['birthday'])){
836
            $data['birthdate'] == "0000-00-00";
837
        } else {
838
            $data['birthdate'] = $data['billing']['birthyear'].'-'.$data['billing']['birthmonth'].'-'.$data['billing']['birthday'];
839
            $data['birthday'] = $data['birthdate'];
840
        }
841
        $data['email'] = $data['auth']['email'];
842
        $data['firstname'] = $data['billing']['firstname'];
843
        $data['lastname'] = $data['billing']['lastname'];
844
        unset ($data['shipping']);
845
        unset ($data['billing']);        
846
847
        $customer = Shopware()->Models()->getRepository('Shopware\Models\Customer\Customer')->findOneBy(
848
		array('id' =>  $userId)
849
		);
850
        $customer->fromArray($data);
851
        Shopware()->Container()->get('shopware_account.customer_service')->update($customer);
852
    }
853
854
855
     /**
856
     * Updates the shipping address
857
     *
858
     * @param int $userId
859
     * @param array $shippingData
860
     */
861
    private function updateShipping($userId, $shippingData)
862
    {
863
        /** @var \Shopware\Components\Model\ModelManager $em */
864
        $em = $this->get('models');
865
866
        /** @var \Shopware\Models\Customer\Customer $customer */
867
        $customer = $em->getRepository('Shopware\Models\Customer\Customer')->findOneBy(array('id' => $userId));
868
869
        /** @var \Shopware\Models\Customer\Address $address */
870
        $addressold = $customer->getDefaultShippingAddress();
871
        $address = new \Shopware\Models\Customer\Address();
872
        
873
         /** @var \Shopware\Models\Country\Country $country */
874
        $country = $addressold->getCountry();
875
        $shippingData['country'] = $country;
876
        if ($shippingData['phone'] === null) {
877
            $shippingData['phone'] = ' ';
878
        }
879
        $address->fromArray($shippingData);
880
        try {
881
            $addressService = $this->get('shopware_account.address_service');
882
            $addressService->create($address, $customer);
883
            $addressService->setDefaultShippingAddress($address);
884
        } catch (Exception $ex) {
885
            $this->plugin->klarnaLog("ERROR while creating address via address service. Exception information:".$ex->getMessage(),1);
886
        }
887
        
888
    }
889
890
    /**
891
     * Updates the billing address
892
     *
893
     * @param int $userId
894
     * @param array $billingData
895
     */
896
    private function updateBilling($userId, $billingData)
897
    {
898
        /** @var \Shopware\Components\Model\ModelManager $em */
899
        $em = $this->get('models');
900
901
        /** @var \Shopware\Models\Customer\Customer $customer */
902
        $customer = $em->getRepository('Shopware\Models\Customer\Customer')->findOneBy(array('id' => $userId));
903
904
        /** @var \Shopware\Models\Customer\Address $address */
905
        $address = $customer->getDefaultBillingAddress();
906
        
907
         /** @var \Shopware\Models\Country\Country $country */
908
        $country = $address->getCountry();
909
        $billingData['country'] = $country;
910
        $address->fromArray($billingData);
911
912
        $this->get('shopware_account.address_service')->update($address);
913
    }
914
915
916
    /**
917
     * Needed to reset the session when the user logs in
918
     */
919
    public function loginAction()
920
    {
921
        // 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...
922
        $this->redirect(array('controller' => 'payment_klarna', 'action' => 'showIframe'));
923
    }
924
925
    /**
926
     * Return action method
927
     *
928
     * Reads the transactionResult and represents it for the customer.
929
     */
930
    public function returnAction()
931
    {
932
        $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction",3);
933
        $transactionId = $this->Request()->getParam('transactionId');
934
        $connector = $this->plugin->getConnector();
935
936
        $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...
937
        $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction->transactionId:\n".$transactionId,3);
938
        $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction->order:",4, $order);
939
        $orderNumber = '';
940
        $session = Shopware()->Session();
941
942
        // set payment to Klarna Checkout Dangerous??
943
        $session['sPaymentID'] = $this->plugin->getPayment()->getId();
944
945
        try {
946
            $order->fetch();
947
948
            // if already created by pushaction just redirect
949
950
            if ($order['status'] === 'created'){
951
                $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::returnAction: OrderStatus is already created... nothing to do: " .$orderNumber,1);
952
                $this->redirect(array(
953
                    'controller' => 'payment_klarna',
954
                    'action' => 'finish',
955
                    'sUniqueID' => $order['reference']
956
                ));
957
            }
958
959
            $this->createAccount($order);
960
            // After createAccount update PaymentId to Klarna, could be defaultpayment
961
            $this->plugin->savePayment($this->plugin->getPayment()->getId());
962
            Shopware()->Session()->sOrderVariables['sUserData'] = $this->getUserData();
963
964 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...
965
                $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: checkout_complete. Save oder if session values match.",3);
966
             if (Shopware()->Session()->offsetGet('KlarnaTransactionId') == null){
967
                    $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: Session matches. Order will be saved",3);
968
                    Shopware()->Session()->offsetSet('KlarnaTransactionId', $transactionId );
969
                    $orderNumber = $this->saveOrder(
970
                        $order['reservation'],
971
                        $order['reference']
972
                    );
973
                     Shopware()->Session()->offsetSet('KlarnaTransactionId', null );
974
                }
975
            }
976
977
978 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...
979
                $orderNumber = $order['merchant_reference']['orderid1'];
980
            }
981
982 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...
983
                $update = array();
984
985
                $update['status'] = 'created';
986
                $update['merchant_reference'] = array(
987
                    'orderid1' => (string)$orderNumber,
988
                    'orderid2' => (string)$order['reference']
989
                );
990
                $order->update($update);
991
            }
992
           
993
            // Saves postnumber for dhl packstation
994
            if (!empty($orderNumber)
995
                && !empty($order['shipping_address']['care_of'])
996
                && $order['shipping_address']['street_name'] == 'Packstation'
997
                && $this->config->get('postnumberField')
998
            ) {
999
                $field = $this->config->get('postnumberField');
1000
                $value = $order['shipping_address']['care_of'];
1001
                $this->saveOrderAttribute($orderNumber, $field, $value);
1002
            }
1003
1004
            $session['KlarnaOrder'] = $order->getLocation();
1005
1006
            if ($order['status'] == 'created' || $order['status'] == 'checkout_complete') {
1007
                $this->saveOrderAttribute($orderNumber, 'swag_klarna_status', 'created');
1008
                $this->savePaymentStatus(
1009
                                $order['reservation'],
1010
                                $order['reference'],
1011
                                $this->config->get('statusId')
1012
                            );                
1013
                $this->redirect(array(
1014
                    'controller' => 'payment_klarna',
1015
                    'action' => 'finish',
1016
                    'sUniqueID' => $order['reference']
1017
                ));
1018
            } else {
1019
                $this->redirect(array('controller' => 'checkout', 'action' => 'confirm'));
1020
            }
1021
        } catch (Exception $e) {
1022
            Shopware()->Plugins()->Controller()->ViewRenderer()->setNoRender();
1023
            $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::returnAction: Catch. Searching for Order:",3);   
1024
            $this->checkKlarnaOrderExistsByReservation($order['reservation']);
1025
            $this->checkKlarnaOrderExistsByReference($order['reference']);
1026
            $this->checkKlarnaOrderExistsBySession(Shopware()->Session()->sUserId); 
1027
            $this->checkKlarnaOrderDetailsBySession(Shopware()->Session()->sUserId); 
1028
            echo "Entschuldigung, Ein Verbindungsfehler ist aufgetreten, bitte aktualisieren Sie die Seite";
1029
            echo $e->getMessage();
1030
1031
        }            
1032
    }
1033
    
1034
    /**
1035
     * Method checks if certain klarna order exists or not
1036
     * 
1037
     * @param string $sessionID
1038
     * @return bool
1039
     */
1040 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...
1041
        $sql = '
1042
            SELECT * FROM s_order
1043
            WHERE userID=?
1044
        ';
1045
        
1046
        $order = Shopware()->Db()->fetchAll($sql, array(
1047
                $sessionID
1048
        ));
1049
        
1050
        $orderExists = (empty($order)) ? false : true;
1051
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsBySession:",3);   
1052
        if ($orderExists){
1053
            $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsBySession: Order Found: ",3, $order);   
1054
        }
1055
        return $orderExists;
1056
    }    
1057
    
1058
    /**
1059
     * Method checks if certain klarna order exists or not
1060
     * 
1061
     * @param string $transactionId
0 ignored issues
show
Bug introduced by
There is no parameter named $transactionId. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1062
     * @param string $paymentUniqueId
1063
     * @return bool
1064
     */
1065 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...
1066
        $sql = '
1067
            SELECT * FROM s_order
1068
            WHERE temporaryID=?
1069
        ';
1070
        
1071
        $order = Shopware()->Db()->fetchAll($sql, array(
1072
                $paymentUniqueId
1073
        ));
1074
        
1075
        $orderExists = (empty($order)) ? false : true;
1076
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReference:",3);   
1077
        if ($orderExists){
1078
            $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReference: Order Found: ",3, $order);   
1079
        }
1080
        return $orderExists;
1081
    }
1082
    
1083
    /**
1084
     * Method checks if certain klarna order exists or not
1085
     * 
1086
     * @param string $transactionId
1087
     * @param string $paymentUniqueId
0 ignored issues
show
Bug introduced by
There is no parameter named $paymentUniqueId. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1088
     * @return bool
1089
     */
1090 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...
1091
        $sql = '
1092
            SELECT * FROM s_order
1093
            WHERE transactionID=?
1094
        ';
1095
        
1096
        $order = Shopware()->Db()->fetchAll($sql, array(
1097
                $transactionId
1098
        ));
1099
        
1100
        $orderExists = (empty($order)) ? false : true;
1101
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReservation:",3);   
1102
        if ($orderExists){
1103
            $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderExistsByReservation: Order Found: ",3, $order);   
1104
        }
1105
        return $orderExists;
1106
    }    
1107
    
1108
    /**
1109
     * Method checks if certain klarna order exists or not
1110
     * 
1111
     * @param string $transactionId
1112
     * @param string $paymentUniqueId
1113
     * @param string $userId
1114
     * @return bool
1115
     */
1116
    protected function checkKlarnaOrderExists($transactionId, $paymentUniqueId, $userId) {
1117
        $sql = '
1118
            SELECT ordernumber FROM s_order
1119
            WHERE transactionID=? AND temporaryID=?
1120
            AND status!=-1 AND userID=?
1121
        ';
1122
        
1123
        $orderNumber = Shopware()->Db()->fetchOne($sql, array(
1124
                $transactionId,
1125
                $paymentUniqueId,
1126
                $userId
1127
        ));
1128
        
1129
        $orderExists = (empty($orderNumber)) ? false : true;
1130
        
1131
        return $orderExists;
1132
    }
1133
    
1134
    /**
1135
     * Method checks if certain klarna order exists or not
1136
     * 
1137
     * @param string $sessionID
1138
     * @return bool
1139
     */
1140 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...
1141
        $sql = '
1142
            SELECT * FROM s_order
1143
            LEFT JOIN s_order_details ON s_order.id = s_order_details.orderID
1144
            WHERE userID=?
1145
        ';
1146
        
1147
        $orderDetails = Shopware()->Db()->fetchAll($sql, array(
1148
                $sessionID
1149
        ));
1150
        
1151
        $orderExists = (empty($orderDetails)) ? false : true;
1152
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderDetailsBySession:",3);   
1153
        if ($orderExists){
1154
            $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::checkKlarnaOrderDetailsBySession: OrderDetails Found: ",3, $orderDetails);
1155
        }
1156
        return $orderExists;
1157
    }
1158
    
1159
    /**
1160
     * Method checks if certain klarna order exists or not
1161
     * 
1162
     * @param string $paymentUniqueId
1163
     * @return string
1164
     */
1165
    protected function getUserIdByReference($paymentUniqueId) {
1166
        $sql = '
1167
            SELECT userID FROM s_order
1168
            WHERE temporaryID=?
1169
        ';
1170
        
1171
        $userId = Shopware()->Db()->fetchOne($sql, array(
1172
                $paymentUniqueId
1173
        ));
1174
1175
        return $userId;
1176
    }    
1177
    
1178
    /**
1179
     *
1180
     *
1181
     * @param string $transactionId
1182
     * @param string $paymentUniqueId
1183
     * @param string $userId
1184
     * @return string $orderNumber
1185
     */
1186 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...
1187
        $sql = '
1188
            SELECT ordernumber FROM s_order
1189
            WHERE transactionID=? AND temporaryID=?
1190
            AND status!=-1 AND userID=?
1191
        ';
1192
1193
        $orderNumber = Shopware()->Db()->fetchOne($sql, array(
1194
            $transactionId,
1195
            $paymentUniqueId,
1196
            $userId
1197
        ));
1198
1199
        return $orderNumber;
1200
    }
1201
1202
    /**
1203
     *
1204
     *
1205
     * @param string $transactionId
1206
     * @param string $paymentUniqueId
1207
     * @param string $userId
1208
     * @return string $orderId
1209
     */
1210 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...
1211
        $sql = '
1212
            SELECT id FROM s_order
1213
            WHERE transactionID=? AND temporaryID=?
1214
            AND status!=-1 AND userID=?
1215
        ';
1216
1217
        $orderId = Shopware()->Db()->fetchOne($sql, array(
1218
            $transactionId,
1219
            $paymentUniqueId,
1220
            $userId
1221
        ));
1222
1223
        return $orderId;
1224
    }
1225
1226
1227
    /**
1228
     * Notify action method
1229
     */
1230
    public function pushAction()
1231
    {
1232
        $transactionId = $this->Request()->getParam('transactionId');
1233
1234
        $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::pushAction->transactionId:\n".$transactionId,3);
1235
        $connector = $this->plugin->getConnector();
1236
        $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...
1237
1238
        $order->fetch();
1239
1240
        if ($order['status'] === 'created'){
1241
            $this->plugin->klarnaLog("Shopware_Controllers_Frontend_PaymentKlarna::pushAction: OrderStatus is already created... nothing to do: ",1);
1242
            return;
1243
        }
1244
1245
        $this->createAccount($order);
1246
        // After createAccount update PaymentId to Klarna, could be defaultpayment
1247
        $this->plugin->savePayment($this->plugin->getPayment()->getId());
1248
        Shopware()->Session()->sOrderVariables['sUserData'] = $this->getUserData();
1249
1250 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...
1251
            $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: checkout_complete. Save oder if session values match.",3);
1252
            if (Shopware()->Session()->offsetGet('KlarnaTransactionId') == null){
1253
                $this->plugin->klarnaLog("Entering Shopware_Controllers_Frontend_PaymentKlarna::returnAction: Session matches. Order will be saved",3);
1254
                Shopware()->Session()->offsetSet('KlarnaTransactionId', $transactionId );
1255
                $orderNumber = $this->saveOrder(
1256
                    $order['reservation'],
1257
                    $order['reference']
1258
                );
1259
                Shopware()->Session()->offsetSet('KlarnaTransactionId', null );
1260
            }
1261
        }
1262
1263 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...
1264
            $orderNumber = $order['merchant_reference']['orderid1'];
1265
        }
1266
1267 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...
1268
            $update = array();
1269
1270
            $update['status'] = 'created';
1271
            $update['merchant_reference'] = array(
1272
                'orderid1' => (string)$orderNumber,
1273
                'orderid2' => (string)$order['reference']
1274
            );
1275
            $order->update($update);
1276
        }
1277
1278
        $this->savePaymentStatus(
1279
            $order['reservation'],
1280
            $order['reference'],
1281
            $this->config->get('statusId')
1282
        );
1283
    }
1284
1285
    private function saveOrderAttribute($orderNumber, $field, $value)
1286
    {
1287
        try {
1288
            $sql = "
1289
                INSERT INTO s_order_attributes (orderID, `$field`)
1290
                SELECT id, ? FROM s_order WHERE ordernumber = ?
1291
                ON DUPLICATE KEY UPDATE `$field` = VALUES(`$field`)
1292
            ";
1293
            $this->get('db')->query($sql, array(
1294
                $value,
1295
                $orderNumber
1296
            ));
1297
        } catch (Exception $e) {
1298
            $this->plugin->klarnaLog("PROBLEM SAVING ORDER ATTRIBUTES AFTER KLARNA PUSH!:\n".$e->getMessage(),1);
1299
        }
1300
    }
1301
1302
    /**
1303
     * Save register form so we can use it if user change between klarna and register tab
1304
     */
1305
    public function saveFormDataAction()
1306
    {
1307
        $form = $this->Request()->getPost();
1308
1309
        //unset password from passed post
1310
        unset($form['register']['personal']['password']);
1311
1312
        if (!empty($form)) {
1313
            Shopware()->Session()->klarnaSavedRegister = $form;
1314
        }
1315
    }
1316
1317
    /**
1318
     * Helper method to redirect the request to the proper page to set the payment into the customer account
1319
     */
1320
    public function setPaymentAction()
1321
    {
1322
        if ($this->Request()->isPost()) {
1323
            $values = $this->Request()->getPost('register');
1324
            $payment = $values['payment'];
1325
        } else {
1326
            $payment = $this->Request()->getParam('paymentId');
1327
        }
1328
1329
        if (empty($payment)) {
1330
            return;
1331
        }
1332
        $session = Shopware()->Session();
1333
        $session['KlarnaExternalPaymentId'] = $payment;
1334
1335
        // if external payment is paypal redirect to paypal express checkout to prevent user registration
1336
1337
        $paymentName = $this->getPaymentNameById($session['KlarnaExternalPaymentId']);
1338
        if ($paymentName === 'paypal') {
1339
            $this->redirect(
1340
                array(
1341
                    'controller' => 'payment_paypal',
1342
                    'action' => 'express'
1343
                )
1344
            );
1345
1346
        } else {
1347
            $user = Shopware()->Modules()->Admin()->sGetUserData();
1348
            if (empty($user)) {
1349
1350
                $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...
1351
                $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...
1352
                $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...
1353
1354
                $this->redirect(
1355
                    array(
1356
                        'controller' => 'register',
1357
                        'action' => 'index',
1358
                        'sTarget' => 'checkout',
1359
                        'sTargetAction' => 'confirm'
1360
                    )
1361
                );
1362
            } else {
1363
                $this->plugin->savePayment($payment);
1364
                $this->redirect(
1365
                    array(
1366
                        'controller' => 'checkout',
1367
                        'action' => 'confirm'
1368
                    )
1369
                );
1370
            }
1371
        }
1372
    }
1373
1374
    /**
1375
     * This action is called when the user is not logged in and tries to change the payment from klarna to another payment.
1376
     * Only used in responsive theme.
1377
     */
1378
    public function otherPaymentAction()
1379
    {
1380
        $userData = Shopware()->Modules()->Admin()->sGetUserData();
1381
        $session = Shopware()->Session();
1382
1383
        // reset country
1384
        $session['sCountry'] = $userData['additional']['country']['id'];
1385
        unset($session['sChangedCountry']);
1386
1387
        //Register-controller redirects to checkout by default when the user is logged in already.
1388
        /*        $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...
1389
                    'controller' => 'checkout',
1390
                    'action' => 'shippingPayment',
1391
                    'klarnaRedirect' => 1
1392
                    //'sTarget' => 'checkout',
1393
                    //'sTargetAction' => 'shippingPayment'
1394
                ));
1395
*/
1396
        if ($this->isUserLoggedIn()) {
1397
            $this->redirect(array(
1398
                'controller' => 'checkout',
1399
                'klarnaRedirect' => 1,
1400
                'action' => 'shippingPayment',
1401
                'sTarget' => 'checkout'
1402
            ));
1403
1404
        } else {
1405
            $this->redirect(array(
1406
                'controller' => 'register',
1407
                'klarnaRedirect' => 1,
1408
                'sTarget' => 'checkout',
1409
                'sTargetAction' => 'shippingPayment'
1410
            ));
1411
        }
1412
    }
1413
1414
    protected function isUserLoggedIn()
1415
    {        
1416
         return (isset($this->session->sUserId) && !empty($this->session->sUserId));
1417
    }
1418
1419
    /**
1420
     * Get complete user-data as an array to use in view
1421
     *
1422
     * @return array
1423
     */
1424
    public function getUserData()
1425
    {
1426
        $system = Shopware()->System();
1427
        $admin = Shopware()->Modules()->Admin();
1428
        $userData = $admin->sGetUserData();
1429
        if (!empty($userData['additional']['countryShipping'])) {
1430
            $system->sUSERGROUPDATA = Shopware()->Db()->fetchRow("
1431
                SELECT * FROM s_core_customergroups
1432
                WHERE groupkey = ?
1433
            ", array($system->sUSERGROUP));
1434
1435
            if ($this->isTaxFreeDelivery($userData)) {
1436
                $system->sUSERGROUPDATA['tax'] = 0;
1437
                $system->sCONFIG['sARTICLESOUTPUTNETTO'] = 1; //Old template
1438
                Shopware()->Session()->sUserGroupData = $system->sUSERGROUPDATA;
1439
                $userData['additional']['charge_vat'] = false;
1440
                $userData['additional']['show_net'] = false;
1441
                Shopware()->Session()->sOutputNet = true;
1442
            } else {
1443
                $userData['additional']['charge_vat'] = true;
1444
                $userData['additional']['show_net'] = !empty($system->sUSERGROUPDATA['tax']);
1445
                Shopware()->Session()->sOutputNet = empty($system->sUSERGROUPDATA['tax']);
1446
            }
1447
        }
1448
1449
        return $userData;
1450
    }
1451
1452
    /**
1453
     * Validates if the provided customer should get a tax free delivery
1454
     * @param array $userData
1455
     * @return bool
1456
     */
1457
    protected function isTaxFreeDelivery($userData)
1458
    {
1459
        if (!empty($userData['additional']['countryShipping']['taxfree'])) {
1460
            return true;
1461
        }
1462
1463
        if (empty($userData['additional']['countryShipping']['taxfree_ustid'])) {
1464
            return false;
1465
        }
1466
1467
        return !empty($userData['shippingaddress']['ustid']);
1468
    }
1469
1470
    /**
1471
     * returns payment name from payment Ids
1472
     * @param integer $paymentId
1473
     * @return string
1474
     */
1475
    private function getPaymentNameById($paymentId)
1476
    {
1477
        $paymentRepo = Shopware()->Models()->getRepository('Shopware\Models\Payment\Payment');
1478
        $payment = $paymentRepo->findOneBy(array('id' => $paymentId));
1479
        return $payment->getName();
1480
1481
    }
1482
1483
}
1484
1485
1486