1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/** |
3
|
|
|
* Shopware |
4
|
|
|
* Copyright © 2015 shopware AG |
5
|
|
|
* |
6
|
|
|
* According to our dual licensing model, this program can be used either |
7
|
|
|
* under the terms of the GNU Affero General Public License, version 3, |
8
|
|
|
* or under a proprietary license. |
9
|
|
|
* |
10
|
|
|
* The texts of the GNU Affero General Public License with an additional |
11
|
|
|
* permission and of our proprietary license can be found at and |
12
|
|
|
* in the LICENSE file you have received along with this program. |
13
|
|
|
* |
14
|
|
|
* This program is distributed in the hope that it will be useful, |
15
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
16
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17
|
|
|
* GNU Affero General Public License for more details. |
18
|
|
|
* |
19
|
|
|
* "Shopware" is a registered trademark of shopware AG. |
20
|
|
|
* The licensing of the program under the AGPLv3 does not imply a |
21
|
|
|
* trademark license. Therefore any rights, title and interest in |
22
|
|
|
* our trademarks remain entirely with us. |
23
|
|
|
*/ |
24
|
|
|
|
25
|
|
|
use Doctrine\DBAL\Connection; |
26
|
|
|
use Shopware\Components\StreetSplitService; |
27
|
|
|
|
28
|
|
|
# Load dummy interface CSRFWhitelistAware for SW < 5.2 |
29
|
|
|
require_once __DIR__ . '/Components/CSRFWhitelistAware.php'; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Shopware Klarna Plugin |
33
|
|
|
*/ |
34
|
|
|
class Shopware_Plugins_Frontend_SwagPaymentKlarna_Bootstrap extends Shopware_Components_Plugin_Bootstrap |
35
|
|
|
{ |
36
|
|
|
/** |
37
|
|
|
* The klarna payment object. |
38
|
|
|
* @var \Shopware\Models\Payment\Payment |
39
|
|
|
*/ |
40
|
|
|
private $klarnaPayment = null; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Instance of API-Object |
44
|
|
|
* @var object |
45
|
|
|
*/ |
46
|
|
|
private $klarnaService = null; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Instance of klarna address object |
50
|
|
|
* @var object |
51
|
|
|
*/ |
52
|
|
|
private $klarnaAddr = null; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @return array |
56
|
|
|
*/ |
57
|
|
|
public function install($isUpdate = false) |
58
|
|
|
{ |
59
|
|
|
$this->createMyEvents(); |
60
|
|
|
if (!$isUpdate) { |
61
|
|
|
$this->createMyPayment(); |
62
|
|
|
} |
63
|
|
|
$this->createMyForm(); |
64
|
|
|
$this->createMyTranslations(); |
65
|
|
|
$this->createMyAttributes(); |
66
|
|
|
|
67
|
|
|
$aReturn = [ |
68
|
|
|
'success' => true, |
69
|
|
|
'invalidateCache' => ['backend'] |
70
|
|
|
]; |
71
|
|
|
|
72
|
|
|
return $aReturn; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @param string $version |
77
|
|
|
* @return array|bool |
78
|
|
|
*/ |
79
|
|
|
public function update($version) |
80
|
|
|
{ |
81
|
|
|
if ($version == '0.0.1') { |
82
|
|
|
return false; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
if (version_compare($version, '2.0.0', '<')) { |
86
|
|
|
$em = $this->get('models'); |
87
|
|
|
$form = $this->Form(); |
88
|
|
|
if ($form->getElement('hideCheckoutSteps')) { |
89
|
|
|
$em->remove($form->getElement('hideCheckoutSteps')); |
90
|
|
|
} |
91
|
|
|
if ($form->getElement('expressButton')) { |
92
|
|
|
$em->remove($form->getElement('expressButton')); |
93
|
|
|
} |
94
|
|
|
if ($form->getElement('expressButtonLayer')) { |
95
|
|
|
$em->remove($form->getElement('expressButtonLayer')); |
96
|
|
|
} |
97
|
|
|
if ($form->getElement('noAccountCheckout')) { |
98
|
|
|
$em->remove($form->getElement('noAccountCheckout')); |
99
|
|
|
} |
100
|
|
|
$em->flush(); |
101
|
|
|
|
102
|
|
|
$this->updatePayment(); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
return $this->install(true); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* @return bool |
110
|
|
|
*/ |
111
|
|
|
public function uninstall() |
112
|
|
|
{ |
113
|
|
|
try { |
114
|
|
|
$this->get('models')->removeAttribute( |
115
|
|
|
's_order_attributes', |
116
|
|
|
'swag_klarna', |
117
|
|
|
'status' |
118
|
|
|
); |
119
|
|
|
$this->get('models')->removeAttribute( |
120
|
|
|
's_order_attributes', |
121
|
|
|
'swag_klarna', |
122
|
|
|
'invoice_number' |
123
|
|
|
); |
124
|
|
|
$this->get('models')->removeAttribute( |
125
|
|
|
's_order_details_attributes', |
126
|
|
|
'swag_klarna', |
127
|
|
|
'invoice_number' |
128
|
|
|
); |
129
|
|
|
$this->get('models')->generateAttributeModels( |
130
|
|
|
[ |
131
|
|
|
's_order_attributes', |
132
|
|
|
's_order_details_attributes' |
133
|
|
|
] |
134
|
|
|
); |
135
|
|
|
} catch (Exception $e) { |
|
|
|
|
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
return true; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @param string $name |
143
|
|
|
* @return mixed |
144
|
|
|
*/ |
145
|
|
|
public function get($name) |
146
|
|
|
{ |
147
|
|
|
if (version_compare(Shopware::VERSION, '4.2.0', '<') && Shopware::VERSION != '___VERSION___') { |
148
|
|
|
$name = ucfirst($name); |
149
|
|
|
return $this->Application()->Bootstrap()->getResource($name); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
return parent::get($name); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Fetches and returns klarna payment row instance. |
157
|
|
|
* |
158
|
|
|
* @return \Shopware\Models\Payment\Payment |
159
|
|
|
*/ |
160
|
|
|
public function getPayment() |
161
|
|
|
{ |
162
|
|
|
if ($this->klarnaPayment === null) { |
163
|
|
|
$this->klarnaPayment = $this->Payments()->findOneBy( |
164
|
|
|
['name' => 'klarna_checkout'] |
165
|
|
|
); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
return $this->klarnaPayment; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* @return \Klarna_Checkout_Connector |
173
|
|
|
*/ |
174
|
|
|
public function getConnector() |
175
|
|
|
{ |
176
|
|
|
return $this->Application()->KlarnaCheckoutConnector(); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @return \Klarna |
181
|
|
|
*/ |
182
|
|
|
public function getService() |
183
|
|
|
{ |
184
|
|
|
/** @var Klarna $service */ |
185
|
|
|
$service = $this->Application()->KlarnaService(); |
186
|
|
|
$service->setActivateInfo('flags', KlarnaFlags::RSRV_SEND_BY_EMAIL); |
187
|
|
|
$service->setVersion($this->buildKlarnaVersion($service)); |
188
|
|
|
$service->config( |
189
|
|
|
$this->Config()->get('merchantId'), |
190
|
|
|
$this->Config()->get('sharedSecret'), |
191
|
|
|
KlarnaCountry::DE, |
192
|
|
|
KlarnaLanguage::DE, |
193
|
|
|
KlarnaCurrency::EUR, |
194
|
|
|
$this->Config()->get('testDrive') ? Klarna::BETA : Klarna::LIVE, |
195
|
|
|
'pdo', |
196
|
|
|
[ |
|
|
|
|
197
|
|
|
'table' => 's_klarna_pclasses', |
198
|
|
|
'pdo' => $this->Application()->Db()->getConnection() |
199
|
|
|
] |
200
|
|
|
); |
201
|
|
|
|
202
|
|
|
return $service; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Activate the plugin klarna plugin. |
207
|
|
|
* Sets the active flag in the payment row. |
208
|
|
|
* |
209
|
|
|
* @return array |
210
|
|
|
*/ |
211
|
|
|
public function enable() |
212
|
|
|
{ |
213
|
|
|
$payment = $this->getPayment(); |
214
|
|
|
if ($payment !== null) { |
215
|
|
|
$payment->setActive(true); |
216
|
|
|
$this->get('models')->flush($payment); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
return [ |
220
|
|
|
'success' => true, |
221
|
|
|
'invalidateCache' => ['backend', 'frontend'] |
222
|
|
|
]; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Disable plugin method and sets the active flag in the payment row |
227
|
|
|
* |
228
|
|
|
* @return bool |
229
|
|
|
*/ |
230
|
|
|
public function disable() |
231
|
|
|
{ |
232
|
|
|
$payment = $this->getPayment(); |
233
|
|
|
if ($payment !== null) { |
234
|
|
|
$payment->setActive(false); |
235
|
|
|
$this->get('models')->flush($payment); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return true; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Returns an instance of klarna object |
243
|
|
|
* |
244
|
|
|
* @param void |
245
|
|
|
* @return \Klarna |
246
|
|
|
*/ |
247
|
|
|
public function getKLarnaService() |
248
|
|
|
{ |
249
|
|
|
if ($this->klarnaService === null) { |
250
|
|
|
require_once __DIR__ . '/Components/Klarna/Klarna.php'; |
251
|
|
|
require_once __DIR__ . '/Components/Klarna/transport/xmlrpc-3.0.0.beta/lib/xmlrpc.inc'; |
252
|
|
|
$this->klarnaService = new Klarna(); |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
return $this->klarnaService; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* Returns an instance of klarna address object |
260
|
|
|
* |
261
|
|
|
* @param void |
262
|
|
|
* @return object |
263
|
|
|
*/ |
264
|
|
|
public function getKlarnaAddr() |
265
|
|
|
{ |
266
|
|
|
if ($this->klarnaAddr === null) { |
267
|
|
|
$this->klarnaAddr = new KlarnaAddr(); |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
return $this->klarnaAddr; |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
/** |
274
|
|
|
* Creates and subscribe the events and hooks. |
275
|
|
|
*/ |
276
|
|
|
protected function createMyEvents() |
277
|
|
|
{ |
278
|
|
|
// BACKEND |
279
|
|
|
$this->subscribeEvent( |
280
|
|
|
'Enlight_Controller_Action_PostDispatch_Backend_Order', |
281
|
|
|
'onLoadOrderBackendModule' |
282
|
|
|
); |
283
|
|
|
$this->subscribeEvent( |
284
|
|
|
'Enlight_Controller_Action_PostDispatch_Backend_Payment', |
285
|
|
|
'onLoadPaymentBackendModule' |
286
|
|
|
); |
287
|
|
|
|
288
|
|
|
$this->subscribeEvent( |
289
|
|
|
'Enlight_Controller_Dispatcher_ControllerPath_Backend_PaymentKlarna', |
290
|
|
|
'onGetControllerPathBackend' |
291
|
|
|
); |
292
|
|
|
|
293
|
|
|
// FRONTEND |
294
|
|
|
$this->subscribeEvent( |
295
|
|
|
'Enlight_Controller_Dispatcher_ControllerPath_Frontend_PaymentKlarna', |
296
|
|
|
'onGetControllerPathFrontend' |
297
|
|
|
); |
298
|
|
|
$this->subscribeEvent( |
299
|
|
|
'Enlight_Controller_Action_Frontend_Checkout_Express', |
300
|
|
|
'onCheckoutExpress' |
301
|
|
|
); |
302
|
|
|
|
303
|
|
|
$this->subscribeEvent( |
304
|
|
|
'Enlight_Controller_Action_PostDispatch', |
305
|
|
|
'onPostDispatch', |
306
|
|
|
110 |
307
|
|
|
); |
308
|
|
|
|
309
|
|
|
// CONNECTOR |
310
|
|
|
$this->subscribeEvent( |
311
|
|
|
'Enlight_Bootstrap_InitResource_KlarnaCheckoutConnector', |
312
|
|
|
'onInitResourceKlarnaCheckoutConnector' |
313
|
|
|
); |
314
|
|
|
|
315
|
|
|
// SERVICES |
316
|
|
|
$this->subscribeEvent( |
317
|
|
|
'Enlight_Bootstrap_InitResource_KlarnaService', |
318
|
|
|
'onInitResourceKlarnaService' |
319
|
|
|
); |
320
|
|
|
|
321
|
|
|
$this->subscribeEvent( |
322
|
|
|
'Enlight_Bootstrap_InitResource_StreetSplitService', |
323
|
|
|
'onGetStreetSplitService' |
324
|
|
|
); |
325
|
|
|
|
326
|
|
|
$this->subscribeEvent( |
327
|
|
|
'Enlight_Controller_Action_PostDispatch_Frontend_Register', |
328
|
|
|
'onPostDispatchFrontendRegister' |
329
|
|
|
); |
330
|
|
|
|
331
|
|
|
$this->subscribeEvent( |
332
|
|
|
'Shopware\Models\Customer\Repository::getListQueryBuilder::after', |
333
|
|
|
'onAfterGetCustomerListQueryBuilder' |
334
|
|
|
); |
335
|
|
|
|
336
|
|
|
$this->subscribeEvent( |
337
|
|
|
'Theme_Compiler_Collect_Plugin_Javascript', |
338
|
|
|
'addJsFiles' |
339
|
|
|
); |
340
|
|
|
|
341
|
|
|
// Subscribe the needed event for less merge and compression |
342
|
|
|
$this->subscribeEvent( |
343
|
|
|
'Theme_Compiler_Collect_Plugin_Less', |
344
|
|
|
'addLessFiles' |
345
|
|
|
); |
346
|
|
|
|
347
|
|
|
// Hook event subscriptions below this line |
348
|
|
|
|
349
|
|
|
$this->subscribeEvent( |
350
|
|
|
'Shopware_Controllers_Backend_Payment::updatePaymentsAction::before', |
351
|
|
|
'onBeforeUpdatePayment' |
352
|
|
|
); |
353
|
|
|
|
354
|
|
|
$this->subscribeEvent( |
355
|
|
|
'Shopware_Controllers_Backend_Order::saveAction::after', |
356
|
|
|
'onBackendOrderSaveAfter' |
357
|
|
|
); |
358
|
|
|
$this->subscribeEvent( |
359
|
|
|
'Shopware_Controllers_Backend_Order::deleteAction::after', |
360
|
|
|
'onBackendOrderDeleteAfter' |
361
|
|
|
); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* Method will be triggered on clicking save on order details |
366
|
|
|
* |
367
|
|
|
* @param Enlight_Hook_HookArgs $args |
368
|
|
|
* @return void |
369
|
|
|
* @throws Exception |
370
|
|
|
*/ |
371
|
|
|
public function onBackendOrderSaveAfter(Enlight_Hook_HookArgs $args) |
372
|
|
|
{ |
373
|
|
|
$orderDataRaw = $args->getSubject()->Request()->getPost(); |
374
|
|
|
$orderId = $orderDataRaw['id']; |
375
|
|
|
$paymentName = $orderDataRaw['payment'][0]['name']; |
376
|
|
|
|
377
|
|
|
$orderStatus = $this->getOrderStatusById($orderId); |
378
|
|
|
|
379
|
|
|
$validUpdateDataToKlarna = ( |
380
|
|
|
$orderStatus != 'activate' && |
381
|
|
|
( |
382
|
|
|
$paymentName == 'klarna_checkout' || |
383
|
|
|
$paymentName == 'klarna_account' || |
384
|
|
|
$paymentName == 'klarna_invoice' |
385
|
|
|
) |
386
|
|
|
); |
387
|
|
|
|
388
|
|
|
if ($validUpdateDataToKlarna) { |
389
|
|
|
$klarnaService = $this->getService(); |
390
|
|
|
|
391
|
|
|
$klarnaAddrBilling = $this->getKlarnaAddrByRawOrderData($orderDataRaw, 'billing'); |
392
|
|
|
$klarnaAddrShipping = $this->getKlarnaAddrByRawOrderData($orderDataRaw, 'shipping'); |
393
|
|
|
|
394
|
|
|
$transactionId = $orderDataRaw['transactionId']; |
395
|
|
|
|
396
|
|
|
$klarnaService->setAddress(KlarnaFlags::IS_BILLING, $klarnaAddrBilling); |
|
|
|
|
397
|
|
|
$klarnaService->setAddress(KlarnaFlags::IS_SHIPPING, $klarnaAddrShipping); |
|
|
|
|
398
|
|
|
try { |
399
|
|
|
$klarnaService->update($transactionId); |
400
|
|
|
} catch (Exception $e) { |
401
|
|
|
throw new Exception($e->getMessage()); |
402
|
|
|
} |
403
|
|
|
} |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
/** |
407
|
|
|
* @param $orderId |
408
|
|
|
* @return string |
409
|
|
|
*/ |
410
|
|
|
protected function getOrderStatusById($orderId) |
411
|
|
|
{ |
412
|
|
|
$klarnaOrderStatus = Shopware()->Db()->fetchOne('SELECT swag_klarna_status FROM s_order_attributes WHERE orderID = ?', [$orderId]); |
413
|
|
|
|
414
|
|
|
return $klarnaOrderStatus; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
|
418
|
|
|
/** |
419
|
|
|
* Method will be triggered on clicking delete on order overview |
420
|
|
|
* |
421
|
|
|
* @param Enlight_Hook_HookArgs $args |
422
|
|
|
* @return void |
423
|
|
|
*/ |
424
|
|
|
public function onBackendOrderDeleteAfter(Enlight_Hook_HookArgs $args) |
425
|
|
|
{ |
426
|
|
|
$orderDataRaw = $args->getSubject()->Request()->getPost(); |
427
|
|
|
$paymentName = $orderDataRaw['payment'][0]['name']; |
428
|
|
|
|
429
|
|
|
if ($paymentName == 'klarna_checkout') { |
430
|
|
|
$klarnaService = $this->getService(); |
431
|
|
|
$transactionId = $orderDataRaw['transactionId']; |
432
|
|
|
try { |
433
|
|
|
$klarnaService->cancelReservation($transactionId); |
434
|
|
|
} catch (Exception $e) { |
435
|
|
|
throw new Exception($e->getMessage()); |
436
|
|
|
} |
437
|
|
|
} |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* Hook to change the absolute media-path to a normalized virtual path. |
443
|
|
|
* @param Enlight_Hook_HookArgs $args |
444
|
|
|
*/ |
445
|
|
|
public function onBeforeUpdatePayment(Enlight_Hook_HookArgs $args) |
446
|
|
|
{ |
447
|
|
|
if (!$this->assertMinimumVersion('5.1')) { |
448
|
|
|
return; |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
/** @var Zend_Controller_Request_Http $request */ |
452
|
|
|
$request = $args->getSubject()->Request(); |
453
|
|
|
$attributes = $request->getParam('attribute'); |
454
|
|
|
$attribute = reset($attributes); |
455
|
|
|
|
456
|
|
|
if (empty($attribute['swagKlarnaKlarnaMedia'])) { |
457
|
|
|
return; |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
$mediaService = $this->get('shopware_media.media_service'); |
461
|
|
|
$attribute['swagKlarnaKlarnaMedia'] = $mediaService->normalize($attribute['swagKlarnaKlarnaMedia']); |
462
|
|
|
$attributes[0] = $attribute; |
463
|
|
|
$request->setParam('attribute', $attributes); |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
/** |
467
|
|
|
* Needed to implement an additional "where"-condition to filter temporary klarna-customers, so they won't be shown |
468
|
|
|
* in the backend anymore. |
469
|
|
|
* |
470
|
|
|
* @param Enlight_Hook_HookArgs $args |
471
|
|
|
*/ |
472
|
|
|
public function onAfterGetCustomerListQueryBuilder(Enlight_Hook_HookArgs $args) |
473
|
|
|
{ |
474
|
|
|
/** @var \Doctrine\DBAL\Query\QueryBuilder $builder */ |
475
|
|
|
$builder = $args->getReturn(); |
476
|
|
|
|
477
|
|
|
$builder->andWhere('billing.lastName != :lastName')->setParameter('lastName', 'Klarna Checkout'); |
478
|
|
|
|
479
|
|
|
$args->setReturn($builder); |
480
|
|
|
} |
481
|
|
|
|
482
|
|
|
/** |
483
|
|
|
* @return StreetSplitService |
484
|
|
|
*/ |
485
|
|
|
public function onGetStreetSplitService() |
486
|
|
|
{ |
487
|
|
|
$this->Application()->Loader()->registerNamespace( |
488
|
|
|
'Shopware\Components', |
489
|
|
|
__DIR__ . '/Components/' |
490
|
|
|
); |
491
|
|
|
|
492
|
|
|
return new StreetSplitService(); |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
/** |
496
|
|
|
* Logs a message |
497
|
|
|
* |
498
|
|
|
* @param string $message |
499
|
|
|
* @param int $logLevelMessage |
500
|
|
|
* @param mixed $mPrintableElement |
501
|
|
|
* @return void |
502
|
|
|
*/ |
503
|
|
View Code Duplication |
public function klarnaLog($message, $logLevelMessage = 1, $mPrintableElement = null) |
|
|
|
|
504
|
|
|
{ |
505
|
|
|
$configname = 'klarnaLogLevel'; |
506
|
|
|
$elementId = Shopware()->Db()->fetchOne('SELECT id FROM s_core_config_elements WHERE name = ?', [$configname]); |
507
|
|
|
$logLevelConfigSetting = Shopware()->Db()->fetchOne('SELECT value FROM s_core_config_values WHERE element_id = ?', [$elementId]); |
508
|
|
|
$logLevelConfigSetting = unserialize($logLevelConfigSetting); |
509
|
|
|
$logLevelSetting = (is_numeric($logLevelConfigSetting) && $logLevelConfigSetting >=0 && $logLevelConfigSetting <=4) ? (int)$logLevelConfigSetting : 1; |
510
|
|
|
|
511
|
|
|
if ($logLevelMessage <= $logLevelSetting) { |
512
|
|
|
$prefix = "[".date('Y-m-d H:i:s')."] "; |
513
|
|
|
$debugBacktrace = ''; |
514
|
|
|
if ($logLevelSetting >= 4) { |
515
|
|
|
$debugBacktrace = print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), true); |
516
|
|
|
} |
517
|
|
|
$sPrintableElementMessage = ''; |
518
|
|
|
if ($mPrintableElement !== null) { |
519
|
|
|
$sPrintableElementMessage = print_r($mPrintableElement, true); |
520
|
|
|
} |
521
|
|
|
$fullMessage = $prefix.$message."\n".$sPrintableElementMessage.$debugBacktrace; |
522
|
|
|
$shopPath = Shopware()->DocPath(); |
523
|
|
|
$logfilePath = $shopPath.'/var/log/klarnaTrace.log'; |
524
|
|
|
$fileHandler = fopen($logfilePath, 'a'); |
525
|
|
|
fwrite($fileHandler, $fullMessage); |
526
|
|
|
fclose($fileHandler); |
527
|
|
|
} |
528
|
|
|
} |
529
|
|
|
|
530
|
|
|
/** |
531
|
|
|
* Method returns matching address parts by address type |
532
|
|
|
* |
533
|
|
|
* @param array $orderDataRaw |
534
|
|
|
* @param string $type |
535
|
|
|
* @return bool|KlarnaAddr |
536
|
|
|
*/ |
537
|
|
|
protected function getKlarnaAddrByRawOrderData($orderDataRaw, $type) |
538
|
|
|
{ |
539
|
|
|
$klarnaAddr = false; |
540
|
|
|
$baseData = (isset($orderDataRaw[$type][0])) ? $orderDataRaw[$type][0] : false; |
541
|
|
|
$baseData = $this->convertEncoding($baseData); |
542
|
|
|
|
543
|
|
|
if ($baseData) { |
|
|
|
|
544
|
|
|
$addressParts = $this->fetchStreetAndHouseNumber($baseData); |
545
|
|
|
|
546
|
|
|
$manager = $this->get('models'); |
547
|
|
|
$repository = 'Shopware\Models\Country\Country'; |
548
|
|
|
$repository = $manager->getRepository($repository); |
549
|
|
|
$country = $repository->findOneBy(['id' => $baseData['countryId']]); |
550
|
|
|
$countryiso = $country->getIso(); |
551
|
|
|
|
552
|
|
|
$klarnaAddr = new KlarnaAddr(); |
553
|
|
|
$klarnaAddr->setEmail($orderDataRaw['customerEmail']); |
554
|
|
|
$klarnaAddr->setFirstName($baseData['firstName']); |
555
|
|
|
$klarnaAddr->setLastName($baseData['lastName']); |
556
|
|
|
$klarnaAddr->setTelno($baseData['phone']); |
557
|
|
|
$klarnaAddr->setStreet($addressParts['street']); |
558
|
|
|
$klarnaAddr->setHouseNumber($addressParts['streetnr']); |
559
|
|
|
$klarnaAddr->setHouseExt($addressParts['streetnr_extension']); |
560
|
|
|
$klarnaAddr->setCompanyName($baseData['company']); |
561
|
|
|
$klarnaAddr->setCareof($baseData['department']); |
562
|
|
|
$klarnaAddr->setZipCode($baseData['zipCode']); |
563
|
|
|
$klarnaAddr->setCity($baseData['city']); |
564
|
|
|
$klarnaAddr->setCountry($countryiso); |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
$this->klarnaLog('Update order address from backend with following address data:', 3, $klarnaAddr); |
568
|
|
|
return $klarnaAddr; |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
|
572
|
|
|
/** |
573
|
|
|
* Method splits street, streetnr and streetnr extension from basestring |
574
|
|
|
* |
575
|
|
|
* @param array $baseData |
576
|
|
|
* @return array |
577
|
|
|
*/ |
578
|
|
|
protected function fetchStreetAndHouseNumber($baseData) |
579
|
|
|
{ |
580
|
|
|
|
581
|
|
|
$addressParts = explode(' ', $baseData['street']); |
582
|
|
|
$index = 0; |
583
|
|
|
$street = $streetnr = ''; |
584
|
|
|
$houseNumberFound = false; |
585
|
|
|
|
586
|
|
|
foreach ($addressParts as $addressPart) { |
587
|
|
|
if (!$houseNumberFound) { |
588
|
|
|
// check if current addresspart is numeric |
589
|
|
|
$houseNumberFound = is_numeric($addressPart); |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
$index++; |
593
|
|
|
if ($index == count($addressParts) || $houseNumberFound) { |
594
|
|
|
// at least last element should be streetnr |
595
|
|
|
if (!empty($streetnr)) { |
596
|
|
|
$streetnr .= ' '; |
597
|
|
|
} |
598
|
|
|
$streetnr .= (string) $addressPart; |
599
|
|
|
} else { |
600
|
|
|
$street .= (string)' '.$addressPart; |
601
|
|
|
} |
602
|
|
|
} |
603
|
|
|
|
604
|
|
|
$streetnr_extension = ''; |
605
|
|
|
if (!empty($baseData['additionalAddressLine1'])) { |
606
|
|
|
$streetnr_extension .= $baseData['additionalAddressLine1']; |
607
|
|
|
} |
608
|
|
|
if (!empty($baseData['additionalAddressLine2'])) { |
609
|
|
|
$streetnr_extension .= "\n".$baseData['additionalAddressLine2']; |
610
|
|
|
} |
611
|
|
|
|
612
|
|
|
$return = [ |
613
|
|
|
'street' => $street, |
614
|
|
|
'streetnr' => $streetnr, |
615
|
|
|
'streetnr_extension' => $streetnr_extension, |
616
|
|
|
]; |
617
|
|
|
|
618
|
|
|
return $return; |
619
|
|
|
} |
620
|
|
|
|
621
|
|
|
|
622
|
|
|
/** |
623
|
|
|
* Converts encoding in all string fields of an array |
624
|
|
|
* |
625
|
|
|
* @param array $data |
626
|
|
|
* @return array |
627
|
|
|
*/ |
628
|
|
|
protected function convertEncoding($data) |
629
|
|
|
{ |
630
|
|
|
$out = []; |
631
|
|
|
foreach ($data as $key => $value) { |
632
|
|
|
if (is_string($value)) { |
633
|
|
|
$value = mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8'); |
634
|
|
|
} |
635
|
|
|
|
636
|
|
|
$out[$key] = $value; |
637
|
|
|
} |
638
|
|
|
|
639
|
|
|
return $out; |
640
|
|
|
} |
641
|
|
|
|
642
|
|
|
/** |
643
|
|
|
* Creates and save the payment row. |
644
|
|
|
*/ |
645
|
|
|
protected function createMyPayment() |
646
|
|
|
{ |
647
|
|
|
/** @var \Shopware\Components\Model\ModelManager $manager */ |
648
|
|
|
$manager = $this->get('models'); |
649
|
|
|
$repository = 'Shopware\Models\Country\Country'; |
650
|
|
|
$repository = $manager->getRepository($repository); |
651
|
|
|
$countries = [ |
652
|
|
|
$repository->findOneBy(['iso' => 'SE']), |
653
|
|
|
$repository->findOneBy(['iso' => 'DE']), |
654
|
|
|
$repository->findOneBy(['iso' => 'NO']), |
655
|
|
|
$repository->findOneBy(['iso' => 'FI']), |
656
|
|
|
$repository->findOneBy(['iso' => 'AT']) |
657
|
|
|
]; |
658
|
|
|
$this->createPayment( |
659
|
|
|
[ |
660
|
|
|
'name' => 'klarna_checkout', |
661
|
|
|
'description' => $this->getLabel(), |
662
|
|
|
'action' => 'payment_klarna', |
663
|
|
|
'additionalDescription' => '', |
664
|
|
|
'countries' => $countries |
665
|
|
|
] |
666
|
|
|
); |
667
|
|
|
} |
668
|
|
|
|
669
|
|
|
/** |
670
|
|
|
* Creates and stores the payment config form. |
671
|
|
|
*/ |
672
|
|
|
protected function createMyForm() |
673
|
|
|
{ |
674
|
|
|
$form = $this->Form(); |
675
|
|
|
|
676
|
|
|
// API settings |
677
|
|
|
$form->setElement( |
678
|
|
|
'boolean', |
679
|
|
|
'testDrive', |
680
|
|
|
[ |
681
|
|
|
'label' => 'Testmodus aktvieren', |
682
|
|
|
'value' => false, |
683
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
684
|
|
|
'position' => 0 |
685
|
|
|
] |
686
|
|
|
); |
687
|
|
|
|
688
|
|
|
$form->setElement( |
689
|
|
|
'text', |
690
|
|
|
'merchantId', |
691
|
|
|
[ |
692
|
|
|
'label' => 'API-HändlerID (EID)', |
693
|
|
|
'required' => true, |
694
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
695
|
|
|
'position' => 1 |
696
|
|
|
] |
697
|
|
|
); |
698
|
|
|
|
699
|
|
|
$form->setElement( |
700
|
|
|
'text', |
701
|
|
|
'sharedSecret', |
702
|
|
|
[ |
703
|
|
|
'label' => 'API-Secret (sharedsecret)', |
704
|
|
|
'required' => true, |
705
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
706
|
|
|
'position' => 2 |
707
|
|
|
] |
708
|
|
|
); |
709
|
|
|
|
710
|
|
|
$form->setElement( |
711
|
|
|
'number', |
712
|
|
|
'termSiteId', |
713
|
|
|
[ |
714
|
|
|
'label' => 'Shopseite mit den Geschäftsbedingungen', |
715
|
|
|
'value' => 4, |
716
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
717
|
|
|
'position' => 3 |
718
|
|
|
] |
719
|
|
|
); |
720
|
|
|
|
721
|
|
|
$form->setElement( |
722
|
|
|
'boolean', |
723
|
|
|
'allowSeparateShippingAddress', |
724
|
|
|
[ |
725
|
|
|
'label' => 'Abweichende Lieferadresse erlauben', |
726
|
|
|
'value' => true, |
727
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
728
|
|
|
'position' => 4 |
729
|
|
|
] |
730
|
|
|
); |
731
|
|
|
|
732
|
|
|
$form->setElement( |
733
|
|
|
'boolean', |
734
|
|
|
'supportPackstation', |
735
|
|
|
[ |
736
|
|
|
'label' => 'DHL Packstation unterstützen', |
737
|
|
|
'value' => false, |
738
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
739
|
|
|
'position' => 5, |
740
|
|
|
'helpText' => 'Die abweichende Lieferadresse muss erlaubt sein' |
741
|
|
|
] |
742
|
|
|
); |
743
|
|
|
|
744
|
|
|
$form->setElement( |
745
|
|
|
'text', |
746
|
|
|
'postnumberField', |
747
|
|
|
[ |
748
|
|
|
'label' => 'Alternatives Feld für die DHL-Postnummer', |
749
|
|
|
'value' => 'attribute1', |
750
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
751
|
|
|
'position' => 6 |
752
|
|
|
] |
753
|
|
|
); |
754
|
|
|
|
755
|
|
|
$form->setElement( |
756
|
|
|
'boolean', |
757
|
|
|
'mandatoryPhone', |
758
|
|
|
[ |
759
|
|
|
'label' => 'Telefonummer als Pflichtfeld', |
760
|
|
|
'value' => false, |
761
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
762
|
|
|
'position' => 7 |
763
|
|
|
] |
764
|
|
|
); |
765
|
|
|
|
766
|
|
|
$form->setElement( |
767
|
|
|
'boolean', |
768
|
|
|
'mandatoryBirthday', |
769
|
|
|
[ |
770
|
|
|
'label' => 'Geburtsdatum als Pflichtfeld', |
771
|
|
|
'value' => false, |
772
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
773
|
|
|
'position' => 8 |
774
|
|
|
] |
775
|
|
|
); |
776
|
|
|
|
777
|
|
|
$form->setElement( |
778
|
|
|
'boolean', |
779
|
|
|
'disableAutofocus', |
780
|
|
|
[ |
781
|
|
|
'label' => 'Autofokus deaktivieren', |
782
|
|
|
'value' => false, |
783
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
784
|
|
|
'position' => 9 |
785
|
|
|
] |
786
|
|
|
); |
787
|
|
|
|
788
|
|
|
$form->setElement( |
789
|
|
|
'boolean', |
790
|
|
|
'showKlarnaButton', |
791
|
|
|
[ |
792
|
|
|
'label' => 'Klarna Checkout-Button anzeigen', |
793
|
|
|
'value' => true, |
794
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
795
|
|
|
'position' => 10 |
796
|
|
|
] |
797
|
|
|
); |
798
|
|
|
|
799
|
|
|
$form->setElement( |
800
|
|
|
'boolean', |
801
|
|
|
'preFillCheckout', |
802
|
|
|
[ |
803
|
|
|
'label' => 'Klarna Checkout für registrierte Kunden vorausfüllen', |
804
|
|
|
'value' => true, |
805
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
806
|
|
|
'position' => 11 |
807
|
|
|
] |
808
|
|
|
); |
809
|
|
|
|
810
|
|
|
$form->setElement( |
811
|
|
|
'color', |
812
|
|
|
'checkoutButtonColor', |
813
|
|
|
[ |
814
|
|
|
'label' => 'Checkout Button Farbe', |
815
|
|
|
'value' => null, |
816
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
817
|
|
|
'position' => 12 |
818
|
|
|
] |
819
|
|
|
); |
820
|
|
|
|
821
|
|
|
$form->setElement( |
822
|
|
|
'color', |
823
|
|
|
'checkoutButtonTextColor', |
824
|
|
|
[ |
825
|
|
|
'label' => 'Checkout Buttontext Farbe', |
826
|
|
|
'value' => null, |
827
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
828
|
|
|
'position' => 13 |
829
|
|
|
] |
830
|
|
|
); |
831
|
|
|
|
832
|
|
|
$form->setElement( |
833
|
|
|
'color', |
834
|
|
|
'checkoutCheckboxColor', |
835
|
|
|
[ |
836
|
|
|
'label' => 'Checkout Checkbox Farbe', |
837
|
|
|
'value' => null, |
838
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
839
|
|
|
'position' => 14 |
840
|
|
|
] |
841
|
|
|
); |
842
|
|
|
|
843
|
|
|
$form->setElement( |
844
|
|
|
'color', |
845
|
|
|
'checkoutCheckboxCheckmarkColor', |
846
|
|
|
[ |
847
|
|
|
'label' => 'Checkout Checkbox Häckchen Farbe', |
848
|
|
|
'value' => null, |
849
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
850
|
|
|
'position' => 15 |
851
|
|
|
] |
852
|
|
|
); |
853
|
|
|
|
854
|
|
|
$form->setElement( |
855
|
|
|
'color', |
856
|
|
|
'checkoutHeaderColor', |
857
|
|
|
[ |
858
|
|
|
'label' => 'Checkout Header Farbe', |
859
|
|
|
'value' => null, |
860
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
861
|
|
|
'position' => 16 |
862
|
|
|
] |
863
|
|
|
); |
864
|
|
|
|
865
|
|
|
$form->setElement( |
866
|
|
|
'color', |
867
|
|
|
'checkoutLinkColor', |
868
|
|
|
[ |
869
|
|
|
'label' => 'Checkout Link Farbe', |
870
|
|
|
'value' => null, |
871
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
872
|
|
|
'position' => 17 |
873
|
|
|
] |
874
|
|
|
); |
875
|
|
|
|
876
|
|
|
$form->setElement( |
877
|
|
|
'boolean', |
878
|
|
|
'KlarnaExternalPayments', |
879
|
|
|
[ |
880
|
|
|
'label' => 'Externe Zahlungsarten im Klarna Checkout darstellen', |
881
|
|
|
'value' => null, |
882
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
883
|
|
|
'helpText' => 'Ihr Klarna-Konto muss für diese Funktion freigeschaltet werden', |
884
|
|
|
'position' => 18 |
885
|
|
|
] |
886
|
|
|
); |
887
|
|
|
|
888
|
|
|
$form->setElement( |
889
|
|
|
'select', |
890
|
|
|
'displayType', |
891
|
|
|
[ |
892
|
|
|
'label' => 'Klarna Checkout Darstellungs-Art', |
893
|
|
|
'value' => 1, |
894
|
|
|
'store' => [ |
895
|
|
|
[1, 'Tab-Darstellung'], |
896
|
|
|
[2, 'Nur Klarna Checkout-Darstellung'], |
897
|
|
|
[3, 'Einseiten-Darstellung'] |
898
|
|
|
], |
899
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
900
|
|
|
'position' => 19 |
901
|
|
|
] |
902
|
|
|
); |
903
|
|
|
|
904
|
|
|
$form->setElement( |
905
|
|
|
'boolean', |
906
|
|
|
'showB2bSelect', |
907
|
|
|
[ |
908
|
|
|
'label' => 'B2B-Auswahl anzeigen', |
909
|
|
|
'value' => true, |
910
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
911
|
|
|
'helpText' => 'In dem Klarna Checkout wird eine Auswahl "Privatkunde / Firma" angezeigt', |
912
|
|
|
'position' => 20 |
913
|
|
|
] |
914
|
|
|
); |
915
|
|
|
|
916
|
|
|
$form->setElement( |
917
|
|
|
'boolean', |
918
|
|
|
'showLoginPanel', |
919
|
|
|
[ |
920
|
|
|
'label' => 'Login-Formular anzeigen', |
921
|
|
|
'value' => true, |
922
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
923
|
|
|
'helpText' => 'In dem Klarna Checkout wird ein Login-Formular angezeigt', |
924
|
|
|
'position' => 21 |
925
|
|
|
] |
926
|
|
|
); |
927
|
|
|
|
928
|
|
|
$form->setElement( |
929
|
|
|
'boolean', |
930
|
|
|
'showMiniBasket', |
931
|
|
|
[ |
932
|
|
|
'label' => 'Warenkorb anzeigen', |
933
|
|
|
'value' => true, |
934
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
935
|
|
|
'helpText' => 'In dem Klarna Checkout wird eine kleine Übersicht des Warenkorbs angezeigt', |
936
|
|
|
'position' => 22 |
937
|
|
|
] |
938
|
|
|
); |
939
|
|
|
|
940
|
|
|
$form->setElement( |
941
|
|
|
'boolean', |
942
|
|
|
'showDispatch', |
943
|
|
|
[ |
944
|
|
|
'label' => 'Lieferland & Versandarten anzeigen', |
945
|
|
|
'value' => true, |
946
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
947
|
|
|
'helpText' => 'In dem Klarna Checkout wird eine Lieferland- sowie Versandarten-Auswahl angezeigt', |
948
|
|
|
'position' => 23 |
949
|
|
|
] |
950
|
|
|
); |
951
|
|
|
|
952
|
|
|
$form->setElement( |
953
|
|
|
'select', |
954
|
|
|
'positionOrder', |
955
|
|
|
[ |
956
|
|
|
'label' => 'Reihenfolge der Elemente', |
957
|
|
|
'value' => 1, |
958
|
|
|
'store' => [ |
959
|
|
|
[1, 'Login-Formular, Mini-Warenkorb, Versandauswahl, Zahlungsauswahl'], |
960
|
|
|
[2, 'Login-Formular, Mini-Warenkorb, Zahlungsauswahl, Versandauswahl'], |
961
|
|
|
[3, 'Versandauswahl, Zahlungsauswahl, Login-Formular, Mini-Warenkorb'], |
962
|
|
|
[4, 'Zahlungsauswahl, Versandauswahl, Login-Formular, Mini-Warenkorb'] |
963
|
|
|
], |
964
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
965
|
|
|
'helpText' => 'Die \'Zahlungsauswahl\' wird nur in der \'Einseitig\'-Darstellung angezeigt.', |
966
|
|
|
'position' => 24 |
967
|
|
|
] |
968
|
|
|
); |
969
|
|
|
|
970
|
|
|
$form->setElement( |
971
|
|
|
'boolean', |
972
|
|
|
'partPaymentWidget', |
973
|
|
|
[ |
974
|
|
|
'label' => 'Teilzahlungs-Widget auf der Detailseite anzeigen', |
975
|
|
|
'value' => true, |
976
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
977
|
|
|
'position' => 25 |
978
|
|
|
] |
979
|
|
|
); |
980
|
|
|
|
981
|
|
|
$form->setElement( |
982
|
|
|
'boolean', |
983
|
|
|
'convertShippingFee', |
984
|
|
|
[ |
985
|
|
|
'label' => 'Versandkosten in eine Bestellposition umwandeln', |
986
|
|
|
'value' => true, |
987
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
988
|
|
|
'position' => 26 |
989
|
|
|
] |
990
|
|
|
); |
991
|
|
|
|
992
|
|
|
$form->setElement( |
993
|
|
|
'select', |
994
|
|
|
'statusId', |
995
|
|
|
[ |
996
|
|
|
'label' => 'Zahlstatus nach der Bestellung', |
997
|
|
|
'value' => 18, |
998
|
|
|
'store' => 'base.PaymentStatus', |
999
|
|
|
'displayField' => 'description', |
1000
|
|
|
'valueField' => 'id', |
1001
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
1002
|
|
|
'position' => 27 |
1003
|
|
|
] |
1004
|
|
|
); |
1005
|
|
|
|
1006
|
|
|
$form->setElement( |
1007
|
|
|
'select', |
1008
|
|
|
'activateStatusId', |
1009
|
|
|
[ |
1010
|
|
|
'label' => 'Zahlungsstatus nach der Aktivierung', |
1011
|
|
|
'value' => 12, |
1012
|
|
|
'store' => 'base.PaymentStatus', |
1013
|
|
|
'displayField' => 'description', |
1014
|
|
|
'valueField' => 'id', |
1015
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
1016
|
|
|
'position' => 28 |
1017
|
|
|
] |
1018
|
|
|
); |
1019
|
|
|
|
1020
|
|
|
$form->setElement( |
1021
|
|
|
'select', |
1022
|
|
|
'cancelStatusId', |
1023
|
|
|
[ |
1024
|
|
|
'label' => 'Zahlungsstatus nach der Stornierung', |
1025
|
|
|
'value' => 17, |
1026
|
|
|
'store' => 'base.PaymentStatus', |
1027
|
|
|
'displayField' => 'description', |
1028
|
|
|
'valueField' => 'id', |
1029
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
1030
|
|
|
'position' => 29 |
1031
|
|
|
] |
1032
|
|
|
); |
1033
|
|
|
|
1034
|
|
|
$form->setElement( |
1035
|
|
|
'select', |
1036
|
|
|
'klarnaLogLevel', |
1037
|
|
|
[ |
1038
|
|
|
'label' => 'Detaillevel der Logeinträge zur Fehlerverfolgung', |
1039
|
|
|
'value' => 0, |
1040
|
|
|
'store' => [ |
1041
|
|
|
[0, 'Nichts protokollieren'], |
1042
|
|
|
[1, 'Nur Fehler protokollieren'], |
1043
|
|
|
[2, 'Fehler und Warnungen protokollieren'], |
1044
|
|
|
[3, 'Alle Meldungen protokollieren'], |
1045
|
|
|
[4, 'Alle Meldungen und zusätzlich Entwicklerinformationen protokollieren (Große Logdateien!)'], |
1046
|
|
|
], |
1047
|
|
|
'scope' => \Shopware\Models\Config\Element::SCOPE_SHOP, |
1048
|
|
|
'helpText' => 'Diese Einstellmöglichkeit dient vor allem der Nachverfolgung von Fehlern im Ablauf. Die Logdatei finden Sie unter var/log/klarnaTrace.log ihrer Shopware-Installation.', |
1049
|
|
|
'position' => 30 |
1050
|
|
|
] |
1051
|
|
|
); |
1052
|
|
|
} |
1053
|
|
|
|
1054
|
|
|
/** |
1055
|
|
|
* |
1056
|
|
|
*/ |
1057
|
|
|
public function createMyTranslations() |
1058
|
|
|
{ |
1059
|
|
|
$form = $this->Form(); |
1060
|
|
|
$translations = $this->getTranslationArray(); |
1061
|
|
|
|
1062
|
|
|
// In 4.2.2 we introduced a helper function for this, so we can skip the custom logic |
1063
|
|
|
if ($this->assertMinimumVersion('4.2.2')) { |
1064
|
|
|
$this->addFormTranslations($translations); |
1065
|
|
|
return true; |
1066
|
|
|
} |
1067
|
|
|
|
1068
|
|
|
$shopRepository = Shopware()->Models()->getRepository('\Shopware\Models\Shop\Locale'); |
1069
|
|
|
foreach ($translations as $locale => $snippets) { |
1070
|
|
|
/** @var \Shopware\Models\Shop\Locale|null $localeModel */ |
1071
|
|
|
$localeModel = $shopRepository->findOneBy(['locale' => $locale]); |
1072
|
|
|
if ($localeModel === null) { |
1073
|
|
|
continue; |
1074
|
|
|
} |
1075
|
|
|
foreach ($snippets as $element => $snippet) { |
1076
|
|
|
$translationModel = null; |
1077
|
|
|
//get the form element by name |
1078
|
|
|
$elementModel = $form->getElement($element); |
1079
|
|
|
|
1080
|
|
|
//not found? continue with next snippet |
1081
|
|
|
if ($elementModel === null) { |
1082
|
|
|
continue; |
1083
|
|
|
} |
1084
|
|
|
|
1085
|
|
|
// Try to load existing translation |
1086
|
|
|
foreach ($elementModel->getTranslations() as $translation) { |
1087
|
|
|
if ($translation->getLocale()->getLocale() == $locale) { |
1088
|
|
|
$translationModel = $translation; |
1089
|
|
|
break; |
1090
|
|
|
} |
1091
|
|
|
} |
1092
|
|
|
|
1093
|
|
|
// If none found create a new one |
1094
|
|
|
if (!$translationModel) { |
1095
|
|
|
$translationModel = new \Shopware\Models\Config\ElementTranslation(); |
1096
|
|
|
$translationModel->setLocale($localeModel); |
1097
|
|
|
//add the translation to the form element |
1098
|
|
|
$elementModel->addTranslation($translationModel); |
1099
|
|
|
} |
1100
|
|
|
|
1101
|
|
|
if ($snippet['label']) { |
1102
|
|
|
$translationModel->setLabel($snippet['label']); |
1103
|
|
|
} |
1104
|
|
|
|
1105
|
|
|
if ($snippet['description']) { |
1106
|
|
|
$translationModel->setDescription($snippet['description']); |
1107
|
|
|
} |
1108
|
|
|
} |
1109
|
|
|
} |
1110
|
|
|
} |
1111
|
|
|
|
1112
|
|
|
/** |
1113
|
|
|
* |
1114
|
|
|
*/ |
1115
|
|
|
public function createMyAttributes() |
1116
|
|
|
{ |
1117
|
|
|
try { |
1118
|
|
|
$this->get('models')->addAttribute( |
1119
|
|
|
's_order_details_attributes', |
1120
|
|
|
'swag_klarna', |
1121
|
|
|
'invoice_number', |
1122
|
|
|
'VARCHAR(255)' |
1123
|
|
|
); |
1124
|
|
|
} catch (Exception $e) { |
|
|
|
|
1125
|
|
|
} |
1126
|
|
|
|
1127
|
|
|
$this->get('models')->generateAttributeModels( |
1128
|
|
|
[ |
1129
|
|
|
's_order_details_attributes' |
1130
|
|
|
] |
1131
|
|
|
); |
1132
|
|
|
|
1133
|
|
|
try { |
1134
|
|
|
$this->get('models')->addAttribute( |
1135
|
|
|
's_order_attributes', |
1136
|
|
|
'swag_klarna', |
1137
|
|
|
'status', |
1138
|
|
|
'VARCHAR(255)' |
1139
|
|
|
); |
1140
|
|
|
$this->get('models')->addAttribute( |
1141
|
|
|
's_order_attributes', |
1142
|
|
|
'swag_klarna', |
1143
|
|
|
'invoice_number', |
1144
|
|
|
'VARCHAR(255)' |
1145
|
|
|
); |
1146
|
|
|
|
1147
|
|
|
$this->get('models')->addAttribute( |
1148
|
|
|
's_core_paymentmeans_attributes', |
1149
|
|
|
'swag_klarna', |
1150
|
|
|
'show_in_klarna_iframe', |
1151
|
|
|
'int(11)' |
1152
|
|
|
); |
1153
|
|
|
$this->get('models')->addAttribute( |
1154
|
|
|
's_core_paymentmeans_attributes', |
1155
|
|
|
'swag_klarna', |
1156
|
|
|
'allow_in_payment_container', |
1157
|
|
|
'int(11)' |
1158
|
|
|
); |
1159
|
|
|
$this->get('models')->addAttribute( |
1160
|
|
|
's_core_paymentmeans_attributes', |
1161
|
|
|
'swag_klarna', |
1162
|
|
|
'klarna_media', |
1163
|
|
|
'VARCHAR(255)' |
1164
|
|
|
); |
1165
|
|
|
} catch (Exception $e) { |
|
|
|
|
1166
|
|
|
} |
1167
|
|
|
|
1168
|
|
|
$this->get('models')->generateAttributeModels( |
1169
|
|
|
[ |
1170
|
|
|
's_order_attributes', |
1171
|
|
|
's_core_paymentmeans_attributes' |
1172
|
|
|
] |
1173
|
|
|
); |
1174
|
|
|
|
1175
|
|
|
if ($this->assertMinimumVersion('5.2')) { |
1176
|
|
|
$this->get('shopware_attribute.crud_service')->update( |
1177
|
|
|
's_core_paymentmeans_attributes', |
1178
|
|
|
'swag_klarna_show_in_klarna_iframe', |
1179
|
|
|
'boolean', |
1180
|
|
|
[ |
1181
|
|
|
'label' => 'In Klarna Checkout einbinden', |
1182
|
|
|
'helpText' => 'Bindet die Zahlungsart direkt in das Klarna iFrame ein', |
1183
|
|
|
'displayInBackend' => true, |
1184
|
|
|
'pluginId' => $this->getId() |
1185
|
|
|
] |
1186
|
|
|
); |
1187
|
|
|
$this->get('shopware_attribute.crud_service')->update( |
1188
|
|
|
's_core_paymentmeans_attributes', |
1189
|
|
|
'swag_klarna_allow_in_payment_container', |
1190
|
|
|
'boolean', |
1191
|
|
|
[ |
1192
|
|
|
'label' => 'Nicht neben dem Klarna Checkout anzeigen', |
1193
|
|
|
'helpText' => 'Versteckt die Zahlungsart in dem "Andere Zahlungsarten-Container" im Klarna Checkout', |
1194
|
|
|
'displayInBackend' => true, |
1195
|
|
|
'pluginId' => $this->getId() |
1196
|
|
|
] |
1197
|
|
|
); |
1198
|
|
|
$this->get('shopware_attribute.crud_service')->update( |
1199
|
|
|
's_core_paymentmeans_attributes', |
1200
|
|
|
'swag_klarna_klarna_media', |
1201
|
|
|
'string', |
1202
|
|
|
[ |
1203
|
|
|
'label' => 'Bild Name für Klarna Checkout', |
1204
|
|
|
'helpText' => 'Zeigt die Zahlungsart zusätzlich mit einem Bild im iFrame an. Funktioniert nur, wenn SSL konfiguriert ist. Optimale Größe: 276x48px.' |
1205
|
|
|
. 'Das Bild muss im Order /media/image gespeichert werden', |
1206
|
|
|
'displayInBackend' => true, |
1207
|
|
|
'pluginId' => $this->getId() |
1208
|
|
|
] |
1209
|
|
|
); |
1210
|
|
|
} |
1211
|
|
|
} |
1212
|
|
|
|
1213
|
|
|
public function registerMyTemplateDir($isBackend = false) |
1214
|
|
|
{ |
1215
|
|
|
if ($isBackend) { |
1216
|
|
|
$this->get('template')->addTemplateDir(__DIR__ . '/Views/', 'klarna'); |
1217
|
|
|
} elseif ($this->isTemplateResponsive()) { |
1218
|
|
|
$this->get('template')->addTemplateDir(__DIR__ . '/Views/responsive', 'klarna'); |
1219
|
|
|
} else { |
1220
|
|
|
$this->get('template')->addTemplateDir(__DIR__ . '/Views/_emotion', 'klarna'); |
1221
|
|
|
} |
1222
|
|
|
} |
1223
|
|
|
|
1224
|
|
|
/** |
1225
|
|
|
* Checks if the the current Template is responsive |
1226
|
|
|
* |
1227
|
|
|
* @return bool |
1228
|
|
|
*/ |
1229
|
|
|
public function isTemplateResponsive() |
1230
|
|
|
{ |
1231
|
|
|
$template = $this->Application()->Shop()->getTemplate()->getVersion(); |
1232
|
|
|
if ($template < 3) { |
|
|
|
|
1233
|
|
|
return false; |
1234
|
|
|
} |
1235
|
|
|
|
1236
|
|
|
return true; |
1237
|
|
|
} |
1238
|
|
|
|
1239
|
|
|
/** |
1240
|
|
|
* Returns the path to a frontend controller for an event. |
1241
|
|
|
* |
1242
|
|
|
* @return string |
1243
|
|
|
*/ |
1244
|
|
|
public function onGetControllerPathFrontend() |
1245
|
|
|
{ |
1246
|
|
|
$this->registerMyTemplateDir(); |
1247
|
|
|
|
1248
|
|
|
return __DIR__ . '/Controllers/Frontend/PaymentKlarna.php'; |
1249
|
|
|
} |
1250
|
|
|
|
1251
|
|
|
/** |
1252
|
|
|
* Returns the path to a backend controller for an event. |
1253
|
|
|
* |
1254
|
|
|
* @return string |
1255
|
|
|
*/ |
1256
|
|
|
public function onGetControllerPathBackend() |
1257
|
|
|
{ |
1258
|
|
|
$this->registerMyTemplateDir(true); |
1259
|
|
|
$this->Application()->Snippets()->addConfigDir( |
1260
|
|
|
__DIR__ . '/Snippets/' |
1261
|
|
|
); |
1262
|
|
|
|
1263
|
|
|
return __DIR__ . '/Controllers/Backend/PaymentKlarna.php'; |
1264
|
|
|
} |
1265
|
|
|
|
1266
|
|
|
/** |
1267
|
|
|
* @param Enlight_Event_EventArgs $args |
1268
|
|
|
*/ |
1269
|
|
|
public function onPostDispatch(Enlight_Event_EventArgs $args) |
1270
|
|
|
{ |
1271
|
|
|
/** @var $action Enlight_Controller_Action */ |
1272
|
|
|
$action = $args->getSubject(); |
1273
|
|
|
$request = $action->Request(); |
1274
|
|
|
$response = $action->Response(); |
1275
|
|
|
$view = $action->View(); |
1276
|
|
|
|
1277
|
|
|
if (!$request->isDispatched() |
1278
|
|
|
|| $response->isException() |
1279
|
|
|
|| $request->getModuleName() != 'frontend' |
1280
|
|
|
|| !$view->hasTemplate() |
1281
|
|
|
) { |
1282
|
|
|
return; |
1283
|
|
|
} |
1284
|
|
|
|
1285
|
|
|
// just return in case kco payment is deactivated in backend |
1286
|
|
|
|
1287
|
|
|
if (!$this->isKcoPaymentActive()){ |
1288
|
|
|
return; |
1289
|
|
|
} |
1290
|
|
|
$user = $view->getAssign('sUserData'); |
1291
|
|
|
$config = $this->Config(); |
1292
|
|
|
|
1293
|
|
|
// this is used for showing klarna buttons in basket |
1294
|
|
|
if ($request->getControllerName() == 'checkout' |
1295
|
|
|
&& ($request->getActionName() == 'cart' || $request->getActionName() == 'ajaxCart') |
1296
|
|
|
) { |
1297
|
|
|
$this->registerMyTemplateDir(); |
1298
|
|
|
$view->assign('KlarnaEnableButton', (bool)$config->get('showKlarnaButton')); |
1299
|
|
|
$view->assign('KlarnaShowCheckoutButton', $this->getShowCheckoutButton($user)); |
1300
|
|
|
$view->assign('klarnaKcoPaymentActive', $this->isKlarnaKcoPaymentActive($user)); |
1301
|
|
|
$view->assign('KlarnaPaymentDescription', $this->getPayment()->getDescription()); |
1302
|
|
|
if (!$this->isTemplateResponsive()) { |
1303
|
|
|
$view->extendsTemplate('frontend/payment_klarna_checkout/cart.tpl'); |
1304
|
|
|
} |
1305
|
|
|
} |
1306
|
|
|
|
1307
|
|
|
// show klarna invoice information on article detail pages |
1308
|
|
|
if (!empty($config->partPaymentWidget) |
1309
|
|
|
&& $request->getControllerName() == 'detail' && $request->getActionName() == 'index' |
1310
|
|
|
) { |
1311
|
|
|
$this->registerMyTemplateDir(); |
1312
|
|
|
//Do not shot the logo on the detail page if the kpm-plugin is active |
1313
|
|
|
$view->KlarnaShowLogo = !$this->isKpmActive(); |
1314
|
|
|
$view->KlarnaLocale = $this->getLocale(); |
1315
|
|
|
$view->KlarnaMerchantId = $config->get('merchantId'); |
1316
|
|
|
if (!$this->isTemplateResponsive()) { |
1317
|
|
|
$view->extendsTemplate('frontend/payment_klarna_part/detail.tpl'); |
1318
|
|
|
} |
1319
|
|
|
} |
1320
|
|
|
|
1321
|
|
|
if ($request->getControllerName() == 'register' && $request->getActionName() == 'index') { |
1322
|
|
|
$this->registerMyTemplateDir(); |
1323
|
|
|
$view->assign('KlarnaLocale', $this->getLocale()); |
1324
|
|
|
$view->assign('KlarnaMerchantId', $config->get('merchantId')); |
1325
|
|
|
$view->assign('KlarnaHideCheckoutSteps', true); |
1326
|
|
|
|
1327
|
|
|
if (version_compare(Shopware::VERSION, '5.2.0', '<')){ |
1328
|
|
|
$view->assign('KlarnaSkipLoginFix', true); |
1329
|
|
|
} |
1330
|
|
|
if (!$this->isTemplateResponsive()) { |
1331
|
|
|
$view->extendsTemplate('frontend/payment_klarna_checkout/register.tpl'); |
1332
|
|
|
} |
1333
|
|
|
|
|
|
|
|
1334
|
|
|
} |
1335
|
|
|
|
1336
|
|
|
if ($request->getControllerName() == 'account' && $request->getActionName() == 'ajax_login') { |
1337
|
|
|
$this->registerMyTemplateDir(); |
1338
|
|
|
$view->assign('KlarnaLocale', $this->getLocale()); |
1339
|
|
|
$view->assign('KlarnaMerchantId', $config->get('merchantId')); |
1340
|
|
|
|
1341
|
|
|
if (!$this->isTemplateResponsive()) { |
1342
|
|
|
$view->extendsTemplate('frontend/payment_klarna_checkout/ajax_login.tpl'); |
1343
|
|
|
} |
1344
|
|
|
} |
1345
|
|
|
|
1346
|
|
|
} |
1347
|
|
|
|
1348
|
|
|
/** |
1349
|
|
|
* Populate register form with saved data on changing klarna and register tabs |
1350
|
|
|
* |
1351
|
|
|
* @param Enlight_Event_EventArgs $args |
1352
|
|
|
*/ |
1353
|
|
|
public function onPostDispatchFrontendRegister($args) |
1354
|
|
|
{ |
1355
|
|
|
/** @var $action Enlight_Controller_Action */ |
1356
|
|
|
$action = $args->getSubject(); |
1357
|
|
|
$view = $action->View(); |
1358
|
|
|
$request = $action->Request(); |
1359
|
|
|
/** @var Enlight_Components_Session_Namespace $session */ |
1360
|
|
|
$session = $this->Application()->Session(); |
1361
|
|
|
|
1362
|
|
|
// Switch User to external PaymentId after registration |
1363
|
|
|
if (isset($session['KlarnaExternalPaymentId'])) { |
1364
|
|
|
$this->savePayment($session['KlarnaExternalPaymentId']); |
1365
|
|
|
} |
|
|
|
|
1366
|
|
|
|
1367
|
|
|
$view->assign('klarnaRedirect', $request->has('klarnaRedirect') && $request->getParam('klarnaRedirect') == 1); |
1368
|
|
|
} |
1369
|
|
|
|
1370
|
|
|
|
1371
|
|
|
/** |
1372
|
|
|
* Helper method to set the selected payment-method into the session to change it in the customer-account after logging in |
1373
|
|
|
* |
1374
|
|
|
* @param $paymentId |
1375
|
|
|
* @throws Enlight_Exception |
1376
|
|
|
*/ |
1377
|
|
|
public function savePayment($paymentId) |
1378
|
|
|
{ |
1379
|
|
|
$admin = Shopware()->Modules()->Admin(); |
1380
|
|
|
$admin->sSYSTEM->_POST['sPayment'] = $paymentId; |
1381
|
|
|
$admin->sUpdatePayment($paymentId); |
1382
|
|
|
|
1383
|
|
|
} |
1384
|
|
|
|
1385
|
|
|
public function addJsFiles() |
1386
|
|
|
{ |
1387
|
|
|
$jsPath = [ |
1388
|
|
|
__DIR__ . '/Views/responsive/frontend/_public/src/js/jquery.klarna_checkout.js' |
1389
|
|
|
]; |
1390
|
|
|
|
1391
|
|
|
return new Doctrine\Common\Collections\ArrayCollection($jsPath); |
1392
|
|
|
} |
1393
|
|
|
|
1394
|
|
|
/** |
1395
|
|
|
* @param Enlight_Event_EventArgs $args |
1396
|
|
|
*/ |
1397
|
|
View Code Duplication |
public function onLoadOrderBackendModule(Enlight_Event_EventArgs $args) |
|
|
|
|
1398
|
|
|
{ |
1399
|
|
|
/** @var $subject Enlight_Controller_Action */ |
1400
|
|
|
$subject = $args->getSubject(); |
1401
|
|
|
$request = $subject->Request(); |
1402
|
|
|
$view = $subject->View(); |
1403
|
|
|
|
1404
|
|
|
switch ($request->getActionName()) { |
1405
|
|
|
case 'load': |
1406
|
|
|
$this->registerMyTemplateDir(true); |
1407
|
|
|
$view->extendsTemplate('backend/order/payment_klarna.js'); |
1408
|
|
|
break; |
1409
|
|
|
default: |
1410
|
|
|
break; |
1411
|
|
|
} |
1412
|
|
|
} |
1413
|
|
|
|
1414
|
|
|
/** |
1415
|
|
|
* @param Enlight_Event_EventArgs $args |
1416
|
|
|
*/ |
1417
|
|
View Code Duplication |
public function onLoadPaymentBackendModule(Enlight_Event_EventArgs $args) |
|
|
|
|
1418
|
|
|
{ |
1419
|
|
|
/** @var $subject Enlight_Controller_Action */ |
1420
|
|
|
$subject = $args->getSubject(); |
1421
|
|
|
$request = $subject->Request(); |
1422
|
|
|
$view = $subject->View(); |
1423
|
|
|
|
1424
|
|
|
switch ($request->getActionName()) { |
1425
|
|
|
case 'load': |
1426
|
|
|
$this->registerMyTemplateDir(true); |
1427
|
|
|
$view->extendsTemplate('backend/payment/payment_klarna.js'); |
1428
|
|
|
break; |
1429
|
|
|
default: |
1430
|
|
|
break; |
1431
|
|
|
} |
1432
|
|
|
} |
1433
|
|
|
|
1434
|
|
|
public function updateOrderVariables() |
1435
|
|
|
{ |
1436
|
|
|
$session = Shopware()->Session(); |
1437
|
|
|
$admin = Shopware()->Modules()->Admin(); |
1438
|
|
|
/** @var ArrayObject $orderVariables */ |
1439
|
|
|
$orderVariables = $session['sOrderVariables']; |
1440
|
|
|
$userData = $admin->sGetUserData(); |
1441
|
|
|
$userData['payment'] = $orderVariables['sUserData']['payment']; |
1442
|
|
|
$userData['additional'] = array_merge( |
1443
|
|
|
$orderVariables['sUserData']['additional'], |
1444
|
|
|
$userData['additional'] |
1445
|
|
|
); |
1446
|
|
|
|
1447
|
|
|
if (isset($session['sChangedCountry'])){ |
1448
|
|
|
|
1449
|
|
|
/** @var \Shopware\Components\Model\ModelManager $em */ |
1450
|
|
|
$em = $this->get('models'); |
1451
|
|
|
|
1452
|
|
|
/** @var \Shopware\Models\Customer\Customer $customer */ |
1453
|
|
|
$country = $em->getRepository('Shopware\Models\Country\Country')->findOneBy(['id' => $session['sChangedCountry']]); |
1454
|
|
|
$userData['shippingaddress']['country'] =$country; |
1455
|
|
|
$userData['billingaddress']['country'] =$country; |
1456
|
|
|
$userData['shippingaddress']['countryID'] = $session['sChangedCountry']; |
1457
|
|
|
$userData['billingaddress']['countryID'] = $session['sChangedCountry']; |
1458
|
|
|
} |
|
|
|
|
1459
|
|
|
|
1460
|
|
|
$orderVariables['sUserData'] = $userData; |
1461
|
|
|
$testbreakpoint = 0; |
|
|
|
|
1462
|
|
|
|
1463
|
|
|
} |
1464
|
|
|
|
1465
|
|
|
/** |
1466
|
|
|
* @param $shop Shopware\Models\Shop\Shop |
1467
|
|
|
* @return int|null |
1468
|
|
|
*/ |
1469
|
|
|
public function getCountryByShop($shop) |
1470
|
|
|
{ |
1471
|
|
|
$locale = $shop->getLocale()->getLocale(); |
1472
|
|
|
$this->klarnaLog("Entering Bootstrap::getCountryByShop", 3); |
1473
|
|
|
$locale = explode('_', $locale); |
1474
|
|
|
$locale = isset($locale[1]) ? $locale[1] : $locale[0]; |
1475
|
|
|
$this->klarnaLog("Bootstrap::getCountryByShop locale to request for:".$locale,3); |
1476
|
|
|
$sql = 'SELECT id FROM s_core_countries WHERE countryiso=?'; |
1477
|
|
|
$countryId = Shopware()->Db()->fetchOne($sql, [$locale]); |
1478
|
|
|
$countryId = ($countryId) ? (int)$countryId : null; |
1479
|
|
|
|
1480
|
|
|
return $countryId; |
1481
|
|
|
} |
1482
|
|
|
|
1483
|
|
|
/** |
1484
|
|
|
* Get user country by country id |
1485
|
|
|
* |
1486
|
|
|
* @param $id |
1487
|
|
|
* @return string |
1488
|
|
|
*/ |
1489
|
|
|
public function getCountryIsoById($id) |
1490
|
|
|
{ |
1491
|
|
|
$sql = 'SELECT countryiso FROM s_core_countries WHERE id = ?'; |
1492
|
|
|
$countryIso = Shopware()->Db()->fetchOne($sql, [$id]); |
1493
|
|
|
|
1494
|
|
|
return $countryIso; |
1495
|
|
|
} |
1496
|
|
|
|
1497
|
|
|
public function getLocale($underscore = false, $countryIso = null) |
1498
|
|
|
{ |
1499
|
|
|
/** @var \Shopware\Models\Shop\Shop $shop */ |
1500
|
|
|
$shop = $this->Application()->Shop(); |
1501
|
|
|
$locale = $shop->getLocale()->getLocale(); |
1502
|
|
|
$locale = strtolower($locale); |
1503
|
|
|
if (!$underscore) { |
1504
|
|
|
$locale = str_replace('_', '-', $locale); |
1505
|
|
|
} |
1506
|
|
|
$locale = $locale == 'nn-no' ? 'nb-no' : $locale; |
1507
|
|
|
|
1508
|
|
|
if ($locale == 'de-de') { |
1509
|
|
|
if($countryIso == 'CH') { |
|
|
|
|
1510
|
|
|
$locale = 'de-ch'; |
1511
|
|
|
} elseif ($countryIso == 'AT') { |
1512
|
|
|
$locale = 'de-at'; |
1513
|
|
|
} |
1514
|
|
|
} |
1515
|
|
|
|
1516
|
|
|
return $locale; |
1517
|
|
|
} |
1518
|
|
|
|
1519
|
|
|
public function getCheckoutOptions($allowPackstation = true, $dispatch = []) |
1520
|
|
|
{ |
1521
|
|
|
$config = $this->Config(); |
1522
|
|
|
$options = $this->getColorConfigOptions($config); |
1523
|
|
|
|
1524
|
|
|
$options['allow_separate_shipping_address'] = (bool)$config->get('allowSeparateShippingAddress'); |
1525
|
|
|
$options['packstation_enabled'] = (bool)$config->get('supportPackstation') && $allowPackstation; |
1526
|
|
|
$options['phone_mandatory'] = (bool)$config->get('mandatoryPhone'); |
1527
|
|
|
$options['date_of_birth_mandatory'] = (bool)$config->get('mandatoryBirthday'); |
1528
|
|
|
|
1529
|
|
|
if (!empty($dispatch)) { |
1530
|
|
|
$options['shipping_details'] = $dispatch['description']; |
1531
|
|
|
} |
1532
|
|
|
|
1533
|
|
|
return $options; |
1534
|
|
|
} |
1535
|
|
|
|
1536
|
|
|
public function getCheckoutCart($basket) |
1537
|
|
|
{ |
1538
|
|
|
$cart = []; |
1539
|
|
|
foreach ($basket['content'] as $index=>$basketItem) { |
|
|
|
|
1540
|
|
|
// compatibility to shopware plugin custom products |
1541
|
|
|
if (isset($basketItem['custom_product_prices'])) { |
1542
|
|
|
$basketItemPrice = (double)$basketItem['custom_product_prices']['total']; |
1543
|
|
|
} |
1544
|
|
|
else { |
1545
|
|
|
$basketItemPrice = (double)str_replace(',', '.', $basketItem['price']); |
1546
|
|
|
} |
1547
|
|
|
$unitPrice = round($basketItemPrice * 100); |
1548
|
|
|
$cart[] = [ |
1549
|
|
|
'type' => $unitPrice >= 0 ? 'physical' : 'discount', |
1550
|
|
|
'reference' => $basketItem['ordernumber'], |
1551
|
|
|
'name' => $basketItem['articlename'], |
1552
|
|
|
'quantity' => (int)$basketItem['quantity'], |
1553
|
|
|
'unit_price' => (int)$unitPrice, |
1554
|
|
|
'tax_rate' => (int)round($basketItem['tax_rate'] * 100) |
1555
|
|
|
]; |
1556
|
|
|
} |
1557
|
|
|
if (!empty($basket['sShippingcosts'])) { |
1558
|
|
|
$shippingCostsWithTax = $basket['sShippingcostsWithTax']; |
1559
|
|
|
$shippingAmount = !empty($shippingCostsWithTax) ? $shippingCostsWithTax : $basket['sShippingcosts']; |
1560
|
|
|
$cart[] = [ |
1561
|
|
|
'type' => 'shipping_fee', |
1562
|
|
|
'reference' => 'SHIPPING', |
1563
|
|
|
'name' => 'Shipping Fee', |
1564
|
|
|
'quantity' => 1, |
1565
|
|
|
'unit_price' => (int)round($shippingAmount * 100), |
1566
|
|
|
'tax_rate' => (int)round($basket['sShippingcostsTax'] * 100), |
1567
|
|
|
]; |
1568
|
|
|
} |
1569
|
|
|
|
1570
|
|
|
return $cart; |
1571
|
|
|
} |
1572
|
|
|
|
1573
|
|
|
public function getCheckoutMerchant() |
1574
|
|
|
{ |
1575
|
|
|
/** @var \Shopware\Components\Routing\RouterInterface $router */ |
1576
|
|
|
$router = $this->Application()->Front()->Router(); |
1577
|
|
|
$merchant = []; |
1578
|
|
|
$merchant['id'] = $this->Config()->get('merchantId'); |
1579
|
|
|
$merchant['terms_uri'] = $router->assemble( |
1580
|
|
|
[ |
1581
|
|
|
'controller' => 'custom', |
1582
|
|
|
'sCustom' => $this->Config()->get('termSiteId', 4), |
1583
|
|
|
'forceSecure' => true |
1584
|
|
|
] |
1585
|
|
|
); |
1586
|
|
|
$merchant['checkout_uri'] = $router->assemble( |
1587
|
|
|
[ |
1588
|
|
|
'action' => 'confirm' |
1589
|
|
|
] |
1590
|
|
|
); |
1591
|
|
|
$merchant['confirmation_uri'] = $router->assemble( |
1592
|
|
|
[ |
1593
|
|
|
'controller' => 'payment_klarna', |
1594
|
|
|
'action' => 'return', |
1595
|
|
|
'forceSecure' => true |
1596
|
|
|
] |
1597
|
|
|
) . "?transactionId={checkout.order.uri}"; |
1598
|
|
|
$merchant['push_uri'] = $router->assemble( |
1599
|
|
|
[ |
1600
|
|
|
'controller' => 'payment_klarna', |
1601
|
|
|
'action' => 'push', |
1602
|
|
|
'forceSecure' => true, |
1603
|
|
|
'appendSession' => true |
1604
|
|
|
] |
1605
|
|
|
) . "&transactionId={checkout.order.uri}"; |
1606
|
|
|
$merchant['back_to_store_uri'] = $router->assemble( |
1607
|
|
|
[ |
1608
|
|
|
'controller' => 'index', |
1609
|
|
|
'action' => 'index' |
1610
|
|
|
] |
1611
|
|
|
); |
1612
|
|
|
|
1613
|
|
|
return $merchant; |
1614
|
|
|
} |
1615
|
|
|
|
1616
|
|
|
public function getCheckoutAddress($user, $type = 'billing') |
1617
|
|
|
{ |
1618
|
|
|
if (empty($user[$type . 'address']['zipcode']) || $user[$type . 'address']['zipcode'] == '00000') { |
1619
|
|
|
return []; |
1620
|
|
|
} |
1621
|
|
|
|
1622
|
|
|
$address = [ |
1623
|
|
|
'given_name' => $user[$type . 'address']['firstname'], |
1624
|
|
|
'family_name' => $user[$type . 'address']['lastname'], |
1625
|
|
|
'postal_code' => $user[$type . 'address']['zipcode'], |
1626
|
|
|
'city' => $user[$type . 'address']['city'], |
1627
|
|
|
'country' => $user['additional'][$type == 'billing' ? 'country' : 'countryShipping']['countryiso'], |
1628
|
|
|
'email' => $user['additional']['user']['email'], |
1629
|
|
|
'phone' => $user['billingaddress']['phone'], |
1630
|
|
|
]; |
1631
|
|
|
$address['country'] = strtolower($address['country']); |
1632
|
|
|
if ($address['country'] == 'de' || $address['country'] == 'nl') { |
1633
|
|
|
$address['title'] = $user[$type . 'address']['salutation'] == 'ms' ? 'Frau' : 'Herr'; |
1634
|
|
|
if ($this->assertMinimumVersion('5.0.0')) { |
1635
|
|
|
/** @var StreetSplitService $streetSplitService */ |
1636
|
|
|
$streetSplitService = Shopware()->StreetSplitService(); |
1637
|
|
|
$streetAndNumber = $streetSplitService->split($user[$type . 'address']['street']); |
1638
|
|
|
|
1639
|
|
|
$address['street_name'] = $streetAndNumber['streetName']; |
1640
|
|
|
$address['street_number'] = $streetAndNumber['streetNumber']; |
1641
|
|
View Code Duplication |
} else { |
1642
|
|
|
$address['street_name'] = $user[$type . 'address']['street']; |
1643
|
|
|
$address['street_number'] = $user[$type . 'address']['streetnumber']; |
1644
|
|
|
} |
1645
|
|
View Code Duplication |
} else { |
1646
|
|
|
$address['street_address'] = trim( |
1647
|
|
|
$user[$type . 'address']['street'] . ' ' . $user[$type . 'address']['streetnumber'] |
1648
|
|
|
); |
1649
|
|
|
} |
1650
|
|
|
|
1651
|
|
|
// Make sure phone number is unset if empty |
1652
|
|
|
if ($address['phone'] === null){ |
1653
|
|
|
unset($address['phone']); |
1654
|
|
|
} |
1655
|
|
|
return $address; |
1656
|
|
|
} |
1657
|
|
|
|
1658
|
|
|
public function getCheckoutCustomer($user) |
1659
|
|
|
{ |
1660
|
|
|
$customer = [ |
1661
|
|
|
'type' => 'person' |
1662
|
|
|
]; |
1663
|
|
|
if (!empty($user['billingaddress']['birthday']) && $user['billingaddress']['birthday'] != '0000-00-00') { |
1664
|
|
|
$customer['date_of_birth'] = $user['billingaddress']['birthday']; |
1665
|
|
|
} |
1666
|
|
|
// SW 5.2 and newer |
1667
|
|
|
if (!empty($user['additional']['user']['birthday']) && $user['additional']['user'] != '0000-00-00') { |
1668
|
|
|
$customer['date_of_birth'] = $user['additional']['user']['birthday']; |
1669
|
|
|
} |
1670
|
|
|
|
1671
|
|
|
return $customer; |
1672
|
|
|
} |
1673
|
|
|
|
1674
|
|
|
/** |
1675
|
|
|
* |
1676
|
|
|
* @return string |
1677
|
|
|
*/ |
1678
|
|
|
public function getLabel() |
1679
|
|
|
{ |
1680
|
|
|
return 'Klarna Checkout'; |
1681
|
|
|
} |
1682
|
|
|
|
1683
|
|
|
/** |
1684
|
|
|
* @return string |
1685
|
|
|
* @throws Exception |
1686
|
|
|
*/ |
1687
|
|
|
public function getVersion() |
1688
|
|
|
{ |
1689
|
|
|
$info = json_decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'plugin.json'), true); |
1690
|
|
|
|
1691
|
|
|
if ($info) { |
1692
|
|
|
return $info['currentVersion']; |
1693
|
|
|
} else { |
1694
|
|
|
throw new Exception('The plugin has an invalid version file.'); |
1695
|
|
|
} |
1696
|
|
|
} |
1697
|
|
|
|
1698
|
|
|
/** |
1699
|
|
|
* @return array |
1700
|
|
|
*/ |
1701
|
|
|
public function getInfo() |
1702
|
|
|
{ |
1703
|
|
|
return [ |
1704
|
|
|
'version' => $this->getVersion(), |
1705
|
|
|
'label' => $this->getLabel(), |
1706
|
|
|
'description' => file_get_contents(__DIR__ . '/info.txt') |
1707
|
|
|
]; |
1708
|
|
|
} |
1709
|
|
|
|
1710
|
|
|
/** |
1711
|
|
|
* Creates and returns the klarna client for an event. |
1712
|
|
|
* |
1713
|
|
|
* @return \Klarna_Checkout_Connector |
|
|
|
|
1714
|
|
|
*/ |
1715
|
|
|
public function onInitResourceKlarnaCheckoutConnector() |
1716
|
|
|
{ |
1717
|
|
|
require_once __DIR__ . '/Components/KlarnaCheckout/Checkout.php'; |
1718
|
|
|
if ($this->Config()->get('testDrive')) { |
1719
|
|
|
Klarna_Checkout_Order::$baseUri = 'https://checkout.testdrive.klarna.com/checkout/orders'; |
1720
|
|
|
} else { |
1721
|
|
|
Klarna_Checkout_Order::$baseUri = 'https://checkout.klarna.com/checkout/orders'; |
1722
|
|
|
} |
1723
|
|
|
Klarna_Checkout_Order::$contentType = "application/vnd.klarna.checkout.aggregated-order-v2+json"; |
1724
|
|
|
$sharedSecret = $this->Config()->get('sharedSecret'); |
1725
|
|
|
$connector = Klarna_Checkout_Connector::create($sharedSecret); |
1726
|
|
|
$this->klarnaLog("Created Klarna Connector:", 4, $connector); |
1727
|
|
|
|
1728
|
|
|
return $connector; |
1729
|
|
|
} |
1730
|
|
|
|
1731
|
|
|
/** |
1732
|
|
|
* @return Klarna |
1733
|
|
|
*/ |
1734
|
|
|
public function onInitResourceKlarnaService() |
1735
|
|
|
{ |
1736
|
|
|
require_once __DIR__ . '/Components/Klarna/Klarna.php'; |
1737
|
|
|
require_once __DIR__ . '/Components/Klarna/transport/xmlrpc-3.0.0.beta/lib/xmlrpc.inc'; |
1738
|
|
|
|
1739
|
|
|
$k = new Klarna(); |
1740
|
|
|
return $k; |
1741
|
|
|
} |
1742
|
|
|
|
1743
|
|
|
/** |
1744
|
|
|
* Provide the file collection for less |
1745
|
|
|
* |
1746
|
|
|
* @return \Doctrine\Common\Collections\ArrayCollection |
1747
|
|
|
*/ |
1748
|
|
|
public function addLessFiles() |
1749
|
|
|
{ |
1750
|
|
|
$less = new \Shopware\Components\Theme\LessDefinition( |
1751
|
|
|
[], |
1752
|
|
|
[ |
1753
|
|
|
__DIR__ . '/Views/responsive/frontend/_public/src/less/all.less' |
1754
|
|
|
], |
1755
|
|
|
__DIR__ |
1756
|
|
|
); |
1757
|
|
|
|
1758
|
|
|
return new Doctrine\Common\Collections\ArrayCollection([$less]); |
1759
|
|
|
} |
1760
|
|
|
|
1761
|
|
|
/** |
1762
|
|
|
* @param string $requiredVersion |
1763
|
|
|
* @return bool|mixed |
1764
|
|
|
*/ |
1765
|
|
|
protected function assertMinimumVersion($requiredVersion) |
1766
|
|
|
{ |
1767
|
|
|
if (Shopware::VERSION === '___VERSION___') { |
1768
|
|
|
return true; |
1769
|
|
|
} |
1770
|
|
|
|
1771
|
|
|
return version_compare(Shopware::VERSION, $requiredVersion, '>='); |
1772
|
|
|
} |
1773
|
|
|
|
1774
|
|
|
/** |
1775
|
|
|
* This event is executed when the expressAction of the checkout-controller should be executed. |
1776
|
|
|
* It is needed to redirect the user back to the klarna checkout after deleting an article in the klarna checkout. |
1777
|
|
|
* |
1778
|
|
|
* @param Enlight_Event_EventArgs $args |
1779
|
|
|
* @return bool |
1780
|
|
|
*/ |
1781
|
|
|
public function onCheckoutExpress(Enlight_Event_EventArgs $args) |
1782
|
|
|
{ |
1783
|
|
|
/** @var $action Enlight_Controller_Action */ |
1784
|
|
|
$action = $args->get('subject'); |
1785
|
|
|
|
1786
|
|
|
$action->redirect(['controller' => 'payment_klarna', 'action' => 'express']); |
1787
|
|
|
return true; |
1788
|
|
|
} |
1789
|
|
|
|
1790
|
|
|
/** |
1791
|
|
|
* Helper method to read the color-config options properly. |
1792
|
|
|
* |
1793
|
|
|
* @param $config Enlight_Config |
1794
|
|
|
* @return mixed |
1795
|
|
|
*/ |
1796
|
|
|
private function getColorConfigOptions($config) |
1797
|
|
|
{ |
1798
|
|
|
$options = []; |
1799
|
|
|
$checkoutButtonColor = $config->get('checkoutButtonColor'); |
1800
|
|
|
$checkoutButtonTextColor = $config->get('checkoutButtonTextColor'); |
1801
|
|
|
$checkoutCheckboxColor = $config->get('checkoutCheckboxColor'); |
1802
|
|
|
$checkoutCheckboxCheckMarkColor = $config->get('checkoutCheckboxCheckmarkColor'); |
1803
|
|
|
$checkoutHeaderColor = $config->get('checkoutHeaderColor'); |
1804
|
|
|
$checkoutLinkColor = $config->get('checkoutLinkColor'); |
1805
|
|
|
|
1806
|
|
|
if (!empty($checkoutButtonColor) && $checkoutButtonColor !== "#") { |
1807
|
|
|
$options['color_button'] = $checkoutButtonColor; |
1808
|
|
|
} |
1809
|
|
|
if (!empty($checkoutButtonTextColor) && $checkoutButtonTextColor !== "#") { |
1810
|
|
|
$options['color_button_text'] = $checkoutButtonTextColor; |
1811
|
|
|
} |
1812
|
|
|
if (!empty($checkoutCheckboxColor) && $checkoutCheckboxColor !== "#") { |
1813
|
|
|
$options['color_checkbox'] = $checkoutCheckboxColor; |
1814
|
|
|
} |
1815
|
|
|
if (!empty($checkoutCheckboxCheckMarkColor) && $checkoutCheckboxCheckMarkColor !== "#") { |
1816
|
|
|
$options['color_checkbox_checkmark'] = $checkoutCheckboxCheckMarkColor; |
1817
|
|
|
} |
1818
|
|
|
if (!empty($checkoutHeaderColor) && $checkoutHeaderColor !== "#") { |
1819
|
|
|
$options['color_header'] = $checkoutHeaderColor; |
1820
|
|
|
} |
1821
|
|
|
if (!empty($checkoutLinkColor) && $checkoutLinkColor !== "#") { |
1822
|
|
|
$options['color_link'] = $checkoutLinkColor; |
1823
|
|
|
} |
1824
|
|
|
|
1825
|
|
|
return $options; |
1826
|
|
|
} |
1827
|
|
|
|
1828
|
|
|
/** |
1829
|
|
|
* @param $view Enlight_View_Default |
1830
|
|
|
* @param $config Enlight_Config |
1831
|
|
|
*/ |
1832
|
|
|
public function getViewConfig($view, $config) |
1833
|
|
|
{ |
1834
|
|
|
/** @var sAdmin $adminModule */ |
1835
|
|
|
$adminModule = $this->get('modules')->Admin(); |
1836
|
|
|
$session = $this->get('session'); |
1837
|
|
|
$view->assign('sCountryId', $session['sCountry']); |
1838
|
|
|
$view->assign('sPayments', $this->filterPayments($adminModule->sGetPaymentMeans())); |
1839
|
|
|
$view->assign('sCountryList', $adminModule->sGetCountryList()); |
1840
|
|
|
$view->assign('KlarnaHideCheckoutSteps', true); |
1841
|
|
|
$view->assign('KlarnaShowB2bSelect', (bool)$config->get('showB2bSelect')); |
1842
|
|
|
$view->assign('KlarnaShowBasket', (bool)$config->get('showMiniBasket')); |
1843
|
|
|
$view->assign('KlarnaShowDispatch', (bool)$config->get('showDispatch')); |
1844
|
|
|
$view->assign( |
1845
|
|
|
'KlarnaCDNLink', |
1846
|
|
|
$this->buildCDNLink() |
1847
|
|
|
); |
1848
|
|
|
$view->assign( |
1849
|
|
|
'KlarnaLoggedInUser', |
1850
|
|
|
$view->sUserData['billingaddress']['lastname'] == 'Klarna Checkout' |
1851
|
|
|
); |
1852
|
|
|
$view->assign( |
1853
|
|
|
'KlarnaShowLogin', |
1854
|
|
|
$this->getShowLoginConfig($config, !empty($session->sUserId)) |
1855
|
|
|
); |
1856
|
|
|
$view->assign( |
1857
|
|
|
'KlarnaDisplayType', |
1858
|
|
|
$this->getKlarnaDisplayType($config) |
1859
|
|
|
); |
1860
|
|
|
$view->assign( |
1861
|
|
|
'KlarnaPositionOrder', |
1862
|
|
|
$this->getPositionOrder($config) |
1863
|
|
|
); |
1864
|
|
|
} |
1865
|
|
|
|
1866
|
|
|
/** |
1867
|
|
|
* Helper method to get the config whether or not to show the login-panel in the klarna-checkout. |
1868
|
|
|
* |
1869
|
|
|
* @param Enlight_Config $config |
1870
|
|
|
* @param $userLoggedIn |
1871
|
|
|
* @return bool |
1872
|
|
|
*/ |
1873
|
|
|
private function getShowLoginConfig($config, $userLoggedIn) |
1874
|
|
|
{ |
1875
|
|
|
return (bool) $config->get('showLoginPanel') && !($userLoggedIn); |
1876
|
|
|
} |
1877
|
|
|
|
1878
|
|
|
/** |
1879
|
|
|
* Helper method to find the correct display-type for the frontend. |
1880
|
|
|
* Will return the value configured in the plugin-config, if there is at least one more payment-mean besides klarna. |
1881
|
|
|
* @param $config Enlight_Config |
1882
|
|
|
* @return int |
1883
|
|
|
*/ |
1884
|
|
|
private function getKlarnaDisplayType($config) |
1885
|
|
|
{ |
1886
|
|
|
if (!$this->getOtherPayments()) { |
1887
|
|
|
return 2; |
1888
|
|
|
} |
1889
|
|
|
return $config->get('displayType'); |
1890
|
|
|
} |
1891
|
|
|
|
1892
|
|
|
/** |
1893
|
|
|
* Helper method to find other payment-means besides klarna. |
1894
|
|
|
* @return bool |
1895
|
|
|
*/ |
1896
|
|
|
private function getOtherPayments() |
1897
|
|
|
{ |
1898
|
|
|
$payments = $this->Application()->Modules()->Admin()->sGetPaymentMeans(); |
1899
|
|
|
|
1900
|
|
|
foreach ($payments as $payment) { |
1901
|
|
|
if ($payment['action'] != 'payment_klarna') { |
1902
|
|
|
return true; |
1903
|
|
|
} |
1904
|
|
|
} |
1905
|
|
|
|
1906
|
|
|
return false; |
1907
|
|
|
} |
1908
|
|
|
|
1909
|
|
|
/** |
1910
|
|
|
* Helper method to figure out whether or not to show the extra klarna checkout button. |
1911
|
|
|
* |
1912
|
|
|
* @param array $user |
1913
|
|
|
* @return bool |
1914
|
|
|
*/ |
1915
|
|
|
private function getShowCheckoutButton($user) |
1916
|
|
|
{ |
1917
|
|
|
if (!empty($user['additional']['payment']['id']) && |
|
|
|
|
1918
|
|
|
$user['additional']['payment']['id'] != $this->getPayment()->getId() |
1919
|
|
|
) { |
1920
|
|
|
return true; |
1921
|
|
|
} |
1922
|
|
|
|
1923
|
|
|
return false; |
1924
|
|
|
} |
1925
|
|
|
|
1926
|
|
|
/** |
1927
|
|
|
* Helper method to get the correct order for the elements |
1928
|
|
|
* |
1929
|
|
|
* @param $config Enlight_Config |
1930
|
|
|
* @return array Array with the order of the elements |
1931
|
|
|
*/ |
1932
|
|
|
private function getPositionOrder($config) |
1933
|
|
|
{ |
1934
|
|
|
$loginPanel = 'login_panel'; |
1935
|
|
|
$miniBasket = 'mini_basket'; |
1936
|
|
|
$dispatch = 'dispatch'; |
1937
|
|
|
$payments = 'payments'; |
1938
|
|
|
switch ($config->get('positionOrder')) { |
1939
|
|
|
case 1: |
1940
|
|
|
return [$loginPanel, $miniBasket, $dispatch, $payments]; |
1941
|
|
|
case 2: |
1942
|
|
|
return [$loginPanel, $miniBasket, $payments, $dispatch]; |
1943
|
|
|
case 3: |
1944
|
|
|
return [$dispatch, $payments, $loginPanel, $miniBasket]; |
1945
|
|
|
case 4: |
1946
|
|
|
default: |
1947
|
|
|
return [$payments, $dispatch, $loginPanel, $miniBasket]; |
1948
|
|
|
} |
1949
|
|
|
} |
1950
|
|
|
|
1951
|
|
|
/** |
1952
|
|
|
* Helper method to build the proper cdn-link for the image in the tabs-layout. |
1953
|
|
|
* @return string |
1954
|
|
|
*/ |
1955
|
|
|
private function buildCDNLink() |
1956
|
|
|
{ |
1957
|
|
|
$validLocales = [ |
1958
|
|
|
'de_de', |
1959
|
|
|
'de_at', |
1960
|
|
|
'en_us', |
1961
|
|
|
'en_gb', |
1962
|
|
|
'fi_fi', |
1963
|
|
|
'sv_se', |
1964
|
|
|
'nb_no', |
1965
|
|
|
]; |
1966
|
|
|
$locale = str_replace('-', '_', $this->getLocale()); |
1967
|
|
|
|
1968
|
|
|
if (!in_array($locale, $validLocales)) { |
1969
|
|
|
$locale = 'en_gb'; |
1970
|
|
|
} |
1971
|
|
|
return "https://cdn.klarna.com/1.0/shared/image/generic/badge/{$locale}/checkout/long-no-klarna-logo.png"; |
1972
|
|
|
} |
1973
|
|
|
|
1974
|
|
|
/** |
1975
|
|
|
* Helper method to read the customer-data from the klarna order-object. |
1976
|
|
|
* @param Klarna_Checkout_Order $order |
1977
|
|
|
* @return array |
1978
|
|
|
*/ |
1979
|
|
|
private function getKlarnaCustomerData($order) |
|
|
|
|
1980
|
|
|
{ |
1981
|
|
|
$billingAddress = $order['billing_address']; |
1982
|
|
|
|
1983
|
|
|
return [ |
1984
|
|
|
'personal' => [ |
1985
|
|
|
'customer_type' => 'private', |
1986
|
|
|
'salutation' => $billingAddress['title'], |
1987
|
|
|
'firstname' => $billingAddress['given_name'], |
1988
|
|
|
'lastname' => $billingAddress['family_name'], |
1989
|
|
|
'email' => $billingAddress['email'], |
1990
|
|
|
'birthday' => $order['customer']['date_of_birth'], |
1991
|
|
|
'phone' => $billingAddress['phone'] |
1992
|
|
|
], |
1993
|
|
|
'billing' => [ |
1994
|
|
|
'street' => $billingAddress['street_name'] . ' ' . $billingAddress['street_number'], |
1995
|
|
|
'zipcode' => $billingAddress['postal_code'], |
1996
|
|
|
'city' => $billingAddress['city'] |
1997
|
|
|
] |
1998
|
|
|
]; |
1999
|
|
|
} |
2000
|
|
|
|
2001
|
|
|
/** |
2002
|
|
|
* Returns an array with all translations |
2003
|
|
|
* @return array |
2004
|
|
|
*/ |
2005
|
|
|
private function getTranslationArray() |
2006
|
|
|
{ |
2007
|
|
|
return [ |
2008
|
|
|
'en_GB' => [ |
2009
|
|
|
'testDrive' => [ |
2010
|
|
|
'label' => 'Activate test-modus' |
2011
|
|
|
], |
2012
|
|
|
'merchantId' => [ |
2013
|
|
|
'label' => 'API merchant ID (EID)' |
2014
|
|
|
], |
2015
|
|
|
'sharedSecret' => [ |
2016
|
|
|
'label' => 'API-Secret (sharedsecret)' |
2017
|
|
|
], |
2018
|
|
|
'termSiteId' => [ |
2019
|
|
|
'label' => 'Shopsite including the terms and conditions' |
2020
|
|
|
], |
2021
|
|
|
'allowSeparateShippingAddress' => [ |
2022
|
|
|
'label' => 'Enable differing shipping address' |
2023
|
|
|
], |
2024
|
|
|
'supportPackstation' => [ |
2025
|
|
|
'label' => 'Support DHL-packstation', |
2026
|
|
|
'helpText' => 'The differing shipping address must be enabled' |
2027
|
|
|
], |
2028
|
|
|
'postnumberField' => [ |
2029
|
|
|
'label' => 'Alternative field for the DHL-postnumber' |
2030
|
|
|
], |
2031
|
|
|
'mandatoryPhone' => [ |
2032
|
|
|
'label' => 'Phone mandatory field' |
2033
|
|
|
], |
2034
|
|
|
'mandatoryBirthday' => [ |
2035
|
|
|
'label' => 'Birthday mandatory field' |
2036
|
|
|
], |
2037
|
|
|
'disableAutofocus' => [ |
2038
|
|
|
'label' => 'Disable auto-focus' |
2039
|
|
|
], |
2040
|
|
|
'showKlarnaButton' => [ |
2041
|
|
|
'label' => 'Show klarna-checkout button' |
2042
|
|
|
], |
2043
|
|
|
'checkoutButtonColor' => [ |
2044
|
|
|
'label' => 'Checkout Button Color' |
2045
|
|
|
], |
2046
|
|
|
'checkoutButtonTextColor' => [ |
2047
|
|
|
'label' => 'Checkout Buttontext Color' |
2048
|
|
|
], |
2049
|
|
|
'checkoutCheckboxColor' => [ |
2050
|
|
|
'label' => 'Checkout Checkbox Color' |
2051
|
|
|
], |
2052
|
|
|
'checkoutCheckboxCheckmarkColor' => [ |
2053
|
|
|
'label' => 'Checkout Checkbox Tick Color' |
2054
|
|
|
], |
2055
|
|
|
'checkoutHeaderColor' => [ |
2056
|
|
|
'label' => 'Checkout Header Color' |
2057
|
|
|
], |
2058
|
|
|
'checkoutLinkColor' => [ |
2059
|
|
|
'label' => 'Checkout Link Color' |
2060
|
|
|
], |
2061
|
|
|
'KlarnaExternalPayments' => [ |
2062
|
|
|
'label' => 'Display external payment-methods in klarna checkout', |
2063
|
|
|
'helpText' => 'Your klarna-account has to be unlocked for this feature', |
2064
|
|
|
], |
2065
|
|
|
'displayType' => [ |
2066
|
|
|
'label' => 'Klarna Checkout display-type', |
2067
|
|
|
'store' => [ |
2068
|
|
|
[1, 'Display tabs'], |
2069
|
|
|
[2, 'Display only klarna checkout'], |
2070
|
|
|
[3, 'One-page display'] |
2071
|
|
|
], |
2072
|
|
|
], |
2073
|
|
|
'showB2bSelect' => [ |
2074
|
|
|
'label' => 'Show B2B-select', |
2075
|
|
|
'helpText' => 'Displays a new select-box containing "Private customer" and "Company" in the klarna checkout' |
2076
|
|
|
], |
2077
|
|
|
'showLoginPanel' => [ |
2078
|
|
|
'label' => 'Show login-panel', |
2079
|
|
|
'helpText' => 'Displays a login-panel in the klarna-checkout', |
2080
|
|
|
], |
2081
|
|
|
'showMiniBasket' => [ |
2082
|
|
|
'label' => 'Show mini-basket', |
2083
|
|
|
'helpText' => 'Displays a small overview of the basket in the klarna-checkout', |
2084
|
|
|
], |
2085
|
|
|
'showDispatch' => [ |
2086
|
|
|
'label' => 'Show shipping-country and -method', |
2087
|
|
|
'helpText' => 'Shows a shipping-country and shipping-method select in the klarna-checkout' |
2088
|
|
|
], |
2089
|
|
|
'partPaymentWidget' => [ |
2090
|
|
|
'label' => 'Show partial-payment-widget on detail-page' |
2091
|
|
|
], |
2092
|
|
|
'convertShippingFee' => [ |
2093
|
|
|
'label' => 'Convert shipping-costs to an order-position' |
2094
|
|
|
], |
2095
|
|
|
'statusId' => [ |
2096
|
|
|
'label' => 'Payment status after order' |
2097
|
|
|
], |
2098
|
|
|
'activateStatusId' => [ |
2099
|
|
|
'label' => 'Payment status after activation' |
2100
|
|
|
], |
2101
|
|
|
'cancelStatusId' => [ |
2102
|
|
|
'label' => 'Payment status after cancellation' |
2103
|
|
|
] |
2104
|
|
|
] |
2105
|
|
|
]; |
2106
|
|
|
} |
2107
|
|
|
|
2108
|
|
|
/** |
2109
|
|
|
* Helper method to update the klarna-payment when updating from any version to >= 2.0 of klarna. |
2110
|
|
|
* It adds "austria" to the valid countries. |
2111
|
|
|
*/ |
2112
|
|
|
private function updatePayment() |
2113
|
|
|
{ |
2114
|
|
|
/** @var \Shopware\Components\Model\ModelManager $manager */ |
2115
|
|
|
$manager = $this->get('models'); |
2116
|
|
|
$payment = $manager->getRepository('Shopware\Models\Payment\Payment')->findOneBy([ |
2117
|
|
|
'name' => 'klarna_checkout' |
2118
|
|
|
]); |
2119
|
|
|
|
2120
|
|
|
if (empty($payment)) { |
2121
|
|
|
return; |
2122
|
|
|
} |
2123
|
|
|
|
2124
|
|
|
$updateNeeded = true; |
2125
|
|
|
$countries = $payment->getCountries(); |
2126
|
|
|
/** @var Shopware\Models\Country\Country $country */ |
2127
|
|
|
foreach ($countries as $country) { |
2128
|
|
|
if ($country->getIso() == 'AT') { |
2129
|
|
|
$updateNeeded = false; |
2130
|
|
|
} |
2131
|
|
|
} |
2132
|
|
|
|
2133
|
|
|
if ($updateNeeded) { |
2134
|
|
|
$countries->add($manager->getRepository('Shopware\Models\Country\Country')->findOneBy(['iso' => 'AT'])); |
2135
|
|
|
$payment->setCountries($countries); |
2136
|
|
|
|
2137
|
|
|
$manager->persist($payment); |
2138
|
|
|
$manager->flush(); |
2139
|
|
|
} |
2140
|
|
|
} |
2141
|
|
|
|
2142
|
|
|
/** |
2143
|
|
|
* Method checks if selected country is valid for use with klarna |
2144
|
|
|
* |
2145
|
|
|
* @param string $countryId |
2146
|
|
|
* @return boolean |
2147
|
|
|
*/ |
2148
|
|
|
public function checkValidKlarnaCountry($countryId) |
2149
|
|
|
{ |
2150
|
|
|
$allowedCountries = []; |
2151
|
|
|
$countries = $this->getPayment()->getCountries(); |
2152
|
|
|
foreach ($countries as $country) { |
2153
|
|
|
$allowedCountries[] = $country->getId(); |
2154
|
|
|
} |
2155
|
|
|
|
2156
|
|
|
$countryPaymentisAllowed = in_array($countryId, $allowedCountries); |
2157
|
|
|
// early return if country is not active for KCO in backend settings |
2158
|
|
|
if (!$countryPaymentisAllowed) { |
2159
|
|
|
return false; |
2160
|
|
|
} |
2161
|
|
|
|
2162
|
|
|
// always allow austrian KCO for german shops and vice-versa |
2163
|
|
|
$shopCountry = $this->getCountryByShop(Shopware()->Shop()); |
2164
|
|
|
if ($shopCountry == "2" && $countryId == "23") { |
2165
|
|
|
return true; |
2166
|
|
|
} elseif ($shopCountry == "23" && $countryId == "2") { |
2167
|
|
|
return true; |
2168
|
|
|
} else { |
2169
|
|
|
return ($countryId == $shopCountry); |
2170
|
|
|
} |
2171
|
|
|
} |
2172
|
|
|
|
2173
|
|
|
|
2174
|
|
|
/** |
2175
|
|
|
* Helper method to read all payments, that should be displayed in the klarna checkout. |
2176
|
|
|
* @param $basket |
2177
|
|
|
* @return array |
2178
|
|
|
*/ |
2179
|
|
|
public function getExternalPaymentMethods($basket) |
2180
|
|
|
{ |
2181
|
|
|
$payments = Shopware()->Models()->getRepository('Shopware\Models\Attribute\Payment')->findBy([ |
2182
|
|
|
'swagKlarnaShowInKlarnaIframe' => 1, |
2183
|
|
|
'swagKlarnaAllowInPaymentContainer' => 0 |
2184
|
|
|
]); |
2185
|
|
|
|
2186
|
|
|
$externalPayments = []; |
2187
|
|
|
$externalCheckouts = []; |
2188
|
|
|
/** @var Shopware\Models\Attribute\Payment $payment */ |
2189
|
|
|
foreach ($payments as $payment) { |
2190
|
|
|
$paymentObj = $payment->getPayment(); |
2191
|
|
|
if (is_null($paymentObj)) { |
2192
|
|
|
$paymentName = false; |
2193
|
|
|
} else { |
2194
|
|
|
$paymentName = $paymentObj->getName(); |
2195
|
|
|
} |
2196
|
|
|
|
2197
|
|
|
if (!$paymentName) { |
2198
|
|
|
continue; |
2199
|
|
|
} |
2200
|
|
|
|
2201
|
|
|
if ($paymentName && $paymentName == 'klarna_checkout') { |
2202
|
|
|
continue; |
2203
|
|
|
} |
2204
|
|
|
$paymentArray = [ |
2205
|
|
|
'name' => $payment->getPayment()->getDescription(), |
2206
|
|
|
'redirect_uri' => $this->getRedirectUri() . '/paymentId/' . $payment->getPaymentId() |
2207
|
|
|
]; |
2208
|
|
|
|
2209
|
|
|
if ($fee = $this->getFee($payment->getPayment(), $basket)) { |
2210
|
|
|
$paymentArray['fee'] = $fee; |
2211
|
|
|
} |
2212
|
|
|
|
2213
|
|
|
if ($description = $payment->getPayment()->getAdditionalDescription()) { |
2214
|
|
|
//Shorten the description to max. 500 characters |
2215
|
|
|
$description = strip_tags($description); |
2216
|
|
|
$description = preg_replace('#<!--.*-->#ms', '', $description); |
2217
|
|
|
$paymentArray['description'] = substr($description, 0, 497) . '...'; |
2218
|
|
|
} |
2219
|
|
|
|
2220
|
|
|
//Only add to external checkouts if an image is set and if the shop supports SSL |
2221
|
|
|
if (Shopware()->Shop()->getSecure() && $image = $this->getImageForKlarna($payment)) { |
2222
|
|
|
$paymentArray['image_uri'] = $image; |
2223
|
|
|
$externalCheckouts[] = $paymentArray; |
2224
|
|
|
} |
2225
|
|
|
|
2226
|
|
|
$externalPayments[] = $paymentArray; |
2227
|
|
|
} |
2228
|
|
|
|
2229
|
|
|
return [$externalPayments, $externalCheckouts]; |
2230
|
|
|
} |
2231
|
|
|
|
2232
|
|
|
/** |
2233
|
|
|
* @param Shopware\Models\Payment\Payment $payment |
2234
|
|
|
* @param $basket |
2235
|
|
|
* @return bool |
|
|
|
|
2236
|
|
|
*/ |
2237
|
|
|
private function getFee($payment, $basket) |
2238
|
|
|
{ |
2239
|
|
|
$fee = 0; |
2240
|
|
|
$amount = str_replace(',', '.', $basket['Amount']); |
2241
|
|
|
|
2242
|
|
|
if ($surcharge = $payment->getSurcharge()) { |
2243
|
|
|
$fee += $surcharge; |
2244
|
|
|
$amount += $surcharge; |
2245
|
|
|
} |
2246
|
|
|
|
2247
|
|
|
if ($percent = $payment->getDebitPercent()) { |
2248
|
|
|
$fee += round($amount / 100 * $percent, 3); |
2249
|
|
|
} |
2250
|
|
|
|
2251
|
|
|
return round($fee * 100); |
2252
|
|
|
} |
2253
|
|
|
|
2254
|
|
|
/** |
2255
|
|
|
* Helper method to get the redirect-uri |
2256
|
|
|
* @return string |
2257
|
|
|
*/ |
2258
|
|
|
private function getRedirectUri() |
2259
|
|
|
{ |
2260
|
|
|
return Shopware()->Front()->Router()->assemble([ |
2261
|
|
|
'controller' => 'PaymentKlarna', |
2262
|
|
|
'action' => 'setPayment' |
2263
|
|
|
]); |
2264
|
|
|
} |
2265
|
|
|
|
2266
|
|
|
/** |
2267
|
|
|
* Helper method to read the image for the klarna-checkout if set |
2268
|
|
|
* @param Shopware\Models\Attribute\Payment $payment |
2269
|
|
|
* @return null|string |
2270
|
|
|
*/ |
2271
|
|
|
private function getImageForKlarna($payment) |
2272
|
|
|
{ |
2273
|
|
|
$media = $payment->getSwagKlarnaKlarnaMedia(); |
2274
|
|
|
if (!$payment->getSwagKlarnaShowInKlarnaIframe() || !empty($media)) { |
2275
|
|
|
if ($this->assertMinimumVersion('5.1') && version_compare(Shopware::VERSION, '5.2.0', '<=')) { |
2276
|
|
|
$media = $this->get('shopware_media.media_service')->getUrl($media); |
2277
|
|
|
} else { |
2278
|
|
|
/** @var Enlight_Controller_Front $front */ |
2279
|
|
|
$front = $this->get('front'); |
2280
|
|
|
$request = $front->Request(); |
2281
|
|
|
if ($request && $request->getHttpHost()) { |
2282
|
|
|
$url = ($request->isSecure() ? 'https' : 'http') . |
2283
|
|
|
'://' . $request->getHttpHost() . |
2284
|
|
|
$request->getBasePath() . "/"; |
2285
|
|
|
} else { |
2286
|
|
|
$url = $front->Router()->assemble(['controller' => 'index', 'module' => 'frontend']); |
2287
|
|
|
} |
2288
|
|
|
if (version_compare(Shopware::VERSION, '5.2.0', '>=')) { |
2289
|
|
|
# make sure me get only the image name, path is set in case of upgarde from SW.5.1 to 5.2 |
2290
|
|
|
$parts = explode('/', $media); |
2291
|
|
|
$end = end($parts); |
2292
|
|
|
$media = $url . 'media/image/' . $end; |
2293
|
|
|
} else { |
2294
|
|
|
$media = $url . $media; |
2295
|
|
|
} |
2296
|
|
|
} |
2297
|
|
|
|
2298
|
|
|
return $media; |
2299
|
|
|
} |
2300
|
|
|
return null; |
2301
|
|
|
} |
2302
|
|
|
|
2303
|
|
|
/** |
2304
|
|
|
* Helper method to filter the available payment-means. |
2305
|
|
|
* @param $sGetPaymentMeans |
2306
|
|
|
* @return array |
2307
|
|
|
*/ |
2308
|
|
|
public function filterPayments($sGetPaymentMeans) |
2309
|
|
|
{ |
2310
|
|
|
$paymentArray = []; |
2311
|
|
|
foreach ($sGetPaymentMeans as $paymentMean) { |
2312
|
|
|
if (!$this->isPaymentAllowed($paymentMean)) { |
2313
|
|
|
continue; |
2314
|
|
|
} |
2315
|
|
|
|
2316
|
|
|
$paymentArray[] = $paymentMean; |
2317
|
|
|
} |
2318
|
|
|
return $paymentArray; |
2319
|
|
|
} |
2320
|
|
|
|
2321
|
|
|
/** |
2322
|
|
|
* Helper method to check if a payment is allowed to be |
2323
|
|
|
* @param $payment |
2324
|
|
|
* @return bool |
2325
|
|
|
*/ |
2326
|
|
|
private function isPaymentAllowed($payment) |
2327
|
|
|
{ |
2328
|
|
|
if ($payment['name'] == 'klarna_checkout') { |
2329
|
|
|
return false; |
2330
|
|
|
} |
2331
|
|
|
$connection = Shopware()->Models()->getConnection(); |
2332
|
|
|
|
2333
|
|
|
$builder = $connection->createQueryBuilder(); |
2334
|
|
|
$builder->select('swag_klarna_allow_in_payment_container', 'swag_klarna_show_in_klarna_iframe') |
2335
|
|
|
->from('s_core_paymentmeans_attributes') |
2336
|
|
|
->where('paymentmeanID = :id') |
2337
|
|
|
->setParameter(':id', $payment['id']); |
2338
|
|
|
|
2339
|
|
|
$result = reset($builder->execute()->fetchAll()); |
|
|
|
|
2340
|
|
|
return !$result['swag_klarna_allow_in_payment_container'] && !$result['swag_klarna_show_in_klarna_iframe']; |
2341
|
|
|
} |
2342
|
|
|
|
2343
|
|
|
/** |
2344
|
|
|
* Builds the new klarna version-string. |
2345
|
|
|
* |
2346
|
|
|
* @param Klarna $klarna |
2347
|
|
|
* @return string |
2348
|
|
|
*/ |
2349
|
|
|
private function buildKlarnaVersion(Klarna $klarna) |
2350
|
|
|
{ |
2351
|
|
|
$versionInfo = [ |
2352
|
|
|
'Shopware', |
2353
|
|
|
$this->Application()->Config()->version, |
2354
|
|
|
'KCO-Plugin', |
2355
|
|
|
$this->getVersion(), |
2356
|
|
|
$klarna->getVersion() |
2357
|
|
|
]; |
2358
|
|
|
|
2359
|
|
|
return implode(':', $versionInfo); |
2360
|
|
|
} |
2361
|
|
|
|
2362
|
|
|
/** |
2363
|
|
|
* Helper method to find out if the kpm plugin is active |
2364
|
|
|
*/ |
2365
|
|
View Code Duplication |
public function isKpmActive() |
|
|
|
|
2366
|
|
|
{ |
2367
|
|
|
/** @var Doctrine\DBAL\Query\QueryBuilder $queryBuilder */ |
2368
|
|
|
$queryBuilder = Shopware()->Models()->getConnection()->createQueryBuilder(); |
2369
|
|
|
|
2370
|
|
|
$result = $queryBuilder->select('plugin.id') |
2371
|
|
|
->from('s_core_plugins', 'plugin') |
2372
|
|
|
->where('plugin.name = :name') |
2373
|
|
|
->andWhere('plugin.active = 1') |
2374
|
|
|
->setParameter('name', 'SwagPaymentKlarnaKpm') |
2375
|
|
|
->execute() |
2376
|
|
|
->fetchColumn(); |
2377
|
|
|
|
2378
|
|
|
return !empty($result); |
2379
|
|
|
} |
2380
|
|
|
|
2381
|
|
|
/** |
2382
|
|
|
* Helper method to find out if the kco paymentmean is active |
2383
|
|
|
*/ |
2384
|
|
View Code Duplication |
public function isKcoPaymentActive() |
|
|
|
|
2385
|
|
|
{ |
2386
|
|
|
/** @var Doctrine\DBAL\Query\QueryBuilder $queryBuilder */ |
2387
|
|
|
$queryBuilder = Shopware()->Models()->getConnection()->createQueryBuilder(); |
2388
|
|
|
|
2389
|
|
|
$result = $queryBuilder->select('payment.id') |
2390
|
|
|
->from('s_core_paymentmeans', 'payment') |
2391
|
|
|
->where('payment.name = :name') |
2392
|
|
|
->andWhere('payment.active = 1') |
2393
|
|
|
->setParameter('name', 'klarna_checkout') |
2394
|
|
|
->execute() |
2395
|
|
|
->fetchColumn(); |
2396
|
|
|
|
2397
|
|
|
return !empty($result); |
2398
|
|
|
} |
2399
|
|
|
|
2400
|
|
|
/** |
2401
|
|
|
* Helper method to find out if the klarna kco payment is active. |
2402
|
|
|
* Necessary to disable the checkout-button. |
2403
|
|
|
* @param array $user |
2404
|
|
|
* @return bool |
2405
|
|
|
*/ |
2406
|
|
|
public function isKlarnaKcoPaymentActive($user) |
2407
|
|
|
{ |
2408
|
|
|
$payment = $this->getPayment(); |
2409
|
|
|
if (!$payment) { |
2410
|
|
|
return false; |
2411
|
|
|
} |
2412
|
|
|
$data = $this->get('modules')->Admin()->sGetPaymentMeanById($payment->getId(), $user); |
2413
|
|
|
if (empty($data) || $data['id'] != $payment->getId()) { |
|
|
|
|
2414
|
|
|
return false; |
2415
|
|
|
} |
2416
|
|
|
return true; |
2417
|
|
|
} |
2418
|
|
|
} |
2419
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.