Completed
Push — 5.4 ( 61b3b4...a20869 )
by Christian
33:50 queued 15:08
created

preDispatch()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 16
nc 3
nop 0
dl 0
loc 23
rs 8.7972
c 0
b 0
f 0
1
<?php
2
/**
3
 * Shopware 5
4
 * Copyright (c) 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
use Shopware\Bundle\AccountBundle\Form\Account\EmailUpdateFormType;
25
use Shopware\Bundle\AccountBundle\Form\Account\PasswordUpdateFormType;
26
use Shopware\Bundle\AccountBundle\Form\Account\ProfileUpdateFormType;
27
use Shopware\Bundle\AccountBundle\Form\Account\ResetPasswordFormType;
28
use Shopware\Models\Customer\Customer;
29
30
/**
31
 * Account controller
32
 */
33
class Shopware_Controllers_Frontend_Account extends Enlight_Controller_Action
34
{
35
    /**
36
     * @var sAdmin
37
     */
38
    protected $admin;
39
40
    /**
41
     * @var \Shopware\Bundle\AccountBundle\Service\CustomerServiceInterface
42
     */
43
    protected $customerService;
44
45
    /**
46
     * Init controller method
47
     */
48
    public function init()
49
    {
50
        $this->admin = Shopware()->Modules()->Admin();
51
        $this->customerService = Shopware()->Container()->get('shopware_account.customer_service');
52
    }
53
54
    /**
55
     * Pre dispatch method
56
     */
57
    public function preDispatch()
58
    {
59
        $this->View()->setScope(Enlight_Template_Manager::SCOPE_PARENT);
60
        if ($this->shouldForwardToRegister()) {
61
            return $this->forward('index', 'register', 'frontend', $this->getForwardParameters());
62
        }
63
        $userData = $this->admin->sGetUserData();
64
65
        $activeBillingAddressId = $userData['additional']['user']['default_billing_address_id'];
66
        $activeShippingAddressId = $userData['additional']['user']['default_shipping_address_id'];
67
68
        $this->View()->assign('activeBillingAddressId', $activeBillingAddressId);
69
        $this->View()->assign('activeShippingAddressId', $activeShippingAddressId);
70
        $this->View()->assign('sUserData', $userData);
71
        $this->View()->assign('userInfo', $this->get('shopware_account.store_front_greeting_service')->fetch());
72
        $this->View()->assign('sUserLoggedIn', $this->admin->sCheckUser());
73
        $this->View()->assign('sAction', $this->Request()->getActionName());
74
75
        if ($this->isOneTimeAccount() && $this->request->getParams()['action'] !== 'abort') {
76
            $this->logoutAction();
77
            $this->redirect(['controller' => 'register']);
78
        }
79
    }
80
81
    /**
82
     * Index action method
83
     */
84
    public function indexAction()
85
    {
86
        if ($this->Request()->getParam('success')) {
87
            $this->View()->sSuccessAction = $this->Request()->getParam('success');
88
        }
89
    }
90
91
    /**
92
     * Payment action method
93
     *
94
     * Read and change payment mean and payment data
95
     */
96
    public function paymentAction()
97
    {
98
        $this->View()->sPaymentMeans = $this->admin->sGetPaymentMeans();
99
        $this->View()->sFormData = ['payment' => $this->View()->sUserData['additional']['user']['paymentID']];
100
        $this->View()->sTarget = $this->Request()->getParam('sTarget', $this->Request()->getControllerName());
101
        $this->View()->sTargetAction = $this->Request()->getParam('sTargetAction', 'index');
102
103
        $getPaymentDetails = $this->admin->sGetPaymentMeanById($this->View()->sFormData['payment']);
104
105
        $paymentClass = $this->admin->sInitiatePaymentClass($getPaymentDetails);
106
        if ($paymentClass instanceof \ShopwarePlugin\PaymentMethods\Components\BasePaymentMethod) {
107
            $data = $paymentClass->getCurrentPaymentDataAsArray(Shopware()->Session()->sUserId);
108
            if (!empty($data)) {
109
                $this->View()->sFormData += $data;
110
            }
111
        }
112
113
        if ($this->Request()->isPost()) {
114
            $values = $this->Request()->getPost();
115
            $values['payment'] = $this->Request()->getPost('register');
116
            $values['payment'] = $values['payment']['payment'];
117
            $values['isPost'] = true;
118
            $this->View()->sFormData = $values;
119
        }
120
    }
121
122
    /**
123
     * Orders action method
124
     *
125
     * Read last orders
126
     */
127
    public function ordersAction()
128
    {
129
        $destinationPage = (int) $this->Request()->sPage;
130
        $orderData = $this->admin->sGetOpenOrderData($destinationPage);
131
        $orderData = $this->applyTrackingUrl($orderData);
132
133
        $this->View()->sOpenOrders = $orderData['orderData'];
134
        $this->View()->sNumberPages = $orderData['numberOfPages'];
135
        $this->View()->sPages = $orderData['pages'];
136
137
        //this has to be assigned here because the config method in smarty can't handle array structures
138
        $this->View()->sDownloadAvailablePaymentStatus = Shopware()->Config()->get('downloadAvailablePaymentStatus');
139
    }
140
141
    /**
142
     * Downloads action method
143
     *
144
     * Read last downloads
145
     */
146
    public function downloadsAction()
147
    {
148
        $destinationPage = (int) $this->Request()->sPage;
149
150
        if (empty($destinationPage)) {
151
            $destinationPage = 1;
152
        }
153
154
        $orderData = $this->admin->sGetDownloads($destinationPage);
155
        $this->View()->sDownloads = $orderData['orderData'];
156
        $this->View()->sNumberPages = $orderData['numberOfPages'];
157
        $this->View()->sPages = $orderData['pages'];
158
159
        // This has to be assigned here because the config method in smarty can't handle array structures
160
        $this->View()->sDownloadAvailablePaymentStatus = Shopware()->Config()->get('downloadAvailablePaymentStatus');
161
    }
162
163
    /**
164
     * PartnerStatisticMenuItem action method
165
     *
166
     * The partner statistic menu item action displays
167
     * the menu item in the account menu
168
     */
169
    public function partnerStatisticMenuItemAction()
170
    {
171
        // show partner statistic menu
172
        $partnerModel = Shopware()->Models()->getRepository('Shopware\Models\Partner\Partner')
173
                                            ->findOneBy(['customerId' => Shopware()->Session()->sUserId]);
174
        if (!empty($partnerModel)) {
175
            $this->View()->partnerId = $partnerModel->getId();
176
            Shopware()->Session()->partnerId = $partnerModel->getId();
177
        }
178
    }
179
180
    /**
181
     * Partner Statistic action method
182
     * This action returns all data for the partner statistic page
183
     */
184
    public function partnerStatisticAction()
185
    {
186
        $partnerId = Shopware()->Session()->partnerId;
187
188
        if (empty($partnerId)) {
189
            return $this->forward('index');
190
        }
191
192
        $toDate = $this->Request()->toDate;
193
        $fromDate = $this->Request()->fromDate;
194
195
        //if a to date passed, format it over the \DateTime object. Otherwise create a new date with today
196
        if (empty($fromDate) || !Zend_Date::isDate($fromDate, 'Y-m-d')) {
197
            $fromDate = new \DateTime();
198
            $fromDate = $fromDate->sub(new DateInterval('P1M'));
199
        } else {
200
            $fromDate = new \DateTime($fromDate);
201
        }
202
203
        //if a to date passed, format it over the \DateTime object. Otherwise create a new date with today
204
        if (empty($toDate) || !Zend_Date::isDate($toDate, 'Y-m-d')) {
205
            $toDate = new \DateTime();
206
        } else {
207
            $toDate = new \DateTime($toDate);
208
        }
209
210
        $this->View()->partnerStatisticToDate = $toDate->format('Y-m-d');
211
        $this->View()->partnerStatisticFromDate = $fromDate->format('Y-m-d');
212
213
        //to get the right value cause 2012-02-02 is smaller than 2012-02-02 15:33:12
214
        $toDate = $toDate->add(new DateInterval('P1D'));
215
216
        /** @var $repository \Shopware\Models\Partner\Repository */
217
        $repository = Shopware()->Models()->getRepository(\Shopware\Models\Partner\Partner::class);
218
219
        //get the information of the partner chart
220
        $userCurrencyFactor = Shopware()->Shop()->getCurrency()->getFactor();
221
222
        $dataQuery = $repository->getStatisticChartQuery($partnerId, $fromDate, $toDate, $userCurrencyFactor);
223
        $this->View()->sPartnerOrderChartData = $dataQuery->getArrayResult();
224
225
        $dataQuery = $repository->getStatisticListQuery(null, null, null, $partnerId, false, $fromDate, $toDate, $userCurrencyFactor);
226
        $this->View()->sPartnerOrders = $dataQuery->getArrayResult();
227
228
        $dataQuery = $repository->getStatisticListQuery(null, null, null, $partnerId, true, $fromDate, $toDate, $userCurrencyFactor);
229
        $this->View()->sTotalPartnerAmount = $dataQuery->getOneOrNullResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
230
    }
231
232
    /**
233
     * Logout action method
234
     *
235
     * Logout account and delete session
236
     */
237
    public function logoutAction()
238
    {
239
        $this->admin->logout();
240
    }
241
242
    /**
243
     * Abort action method
244
     *
245
     * Abort one time order and delete session
246
     */
247
    public function abortAction()
248
    {
249
        $this->admin->logout();
250
    }
251
252
    /**
253
     * Login action method
254
     *
255
     * Login account and show login errors
256
     */
257
    public function loginAction()
258
    {
259
        $this->View()->sTarget = $this->Request()->getParam('sTarget');
260
261
        if ($this->Request()->isPost()) {
262
            $checkUser = $this->admin->sLogin();
263
            if (!empty($checkUser['sErrorMessages'])) {
264
                $this->View()->sFormData = $this->Request()->getPost();
265
                $this->View()->sErrorFlag = $checkUser['sErrorFlag'];
266
                $this->View()->sErrorMessages = $checkUser['sErrorMessages'];
267
            } else {
268
                $this->refreshBasket();
269
            }
270
        }
271
272
        if (empty($this->View()->sErrorMessages) && $this->admin->sCheckUser()) {
273
            return $this->redirect(
274
                [
275
                    'controller' => $this->Request()->getParam('sTarget', 'account'),
276
                    'action' => $this->Request()->getParam('sTargetAction', 'index'),
277
                ]
278
            );
279
        }
280
281
        $this->forward('index', 'register', 'frontend', [
282
            'sTarget' => $this->Request()->getParam('sTarget'),
283
        ]);
284
    }
285
286
    /**
287
     * Save shipping action
288
     *
289
     * Save shipping address data
290
     */
291
    public function savePaymentAction()
292
    {
293
        if ($this->Request()->isPost()) {
294
            $sourceIsCheckoutConfirm = $this->Request()->getParam('sourceCheckoutConfirm');
295
            $values = $this->Request()->getPost('register');
296
            $this->admin->sSYSTEM->_POST['sPayment'] = $values['payment'];
0 ignored issues
show
Documentation introduced by
The property _POST does not exist on object<sSystem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Deprecated Code introduced by
The property sAdmin::$sSYSTEM has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
297
            $checkData = $this->admin->sValidateStep3();
298
299
            if (!empty($checkData['checkPayment']['sErrorMessages']) || empty($checkData['sProcessed'])) {
300
                if (empty($sourceIsCheckoutConfirm)) {
301
                    $this->View()->sErrorFlag = $checkData['checkPayment']['sErrorFlag'];
302
                    $this->View()->sErrorMessages = $checkData['checkPayment']['sErrorMessages'];
303
                }
304
305
                return $this->forward('payment');
306
            }
307
            $previousPayment = $this->admin->sGetUserData();
308
            $previousPayment = $previousPayment['additional']['user']['paymentID'];
309
310
            $previousPayment = $this->admin->sGetPaymentMeanById($previousPayment);
311
            if ($previousPayment['paymentTable']) {
312
                $deleteSQL = 'DELETE FROM ' . $previousPayment['paymentTable'] . ' WHERE userID=?';
313
                Shopware()->Db()->query($deleteSQL, [Shopware()->Session()->sUserId]);
314
            }
315
316
            $this->admin->sUpdatePayment();
317
318
            if ($checkData['sPaymentObject'] instanceof \ShopwarePlugin\PaymentMethods\Components\BasePaymentMethod) {
319
                $checkData['sPaymentObject']->savePaymentData(Shopware()->Session()->sUserId, $this->Request());
320
            }
321
        }
322
323
        if (!$target = $this->Request()->getParam('sTarget')) {
324
            $target = 'account';
325
        }
326
        $targetAction = $this->Request()->getParam('sTargetAction', 'index');
327
        $this->redirect([
328
            'controller' => $target,
329
            'action' => $targetAction,
330
            'success' => 'payment',
331
        ]);
332
    }
333
334
    /**
335
     * Save newsletter action
336
     *
337
     * Save newsletter address data
338
     */
339
    public function saveNewsletterAction()
340
    {
341
        if ($this->Request()->isPost()) {
342
            $status = $this->Request()->getPost('newsletter') ? true : false;
343
            $this->admin->sUpdateNewsletter($status, $this->admin->sGetUserMailById(), true);
344
            $successMessage = $status ? 'newsletter' : 'deletenewsletter';
345
            if (Shopware()->Config()->optinnewsletter && $status) {
0 ignored issues
show
Documentation introduced by
The property optinnewsletter does not exist on object<Shopware_Components_Config>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
346
                $successMessage = 'optinnewsletter';
347
            }
348
            $this->View()->sSuccessAction = $successMessage;
349
            $this->container->get('session')->offsetSet('sNewsletter', $status);
350
        }
351
        $this->forward('index');
352
    }
353
354
    /**
355
     * Download action
356
     *
357
     * Read and test download file
358
     */
359
    public function downloadAction()
360
    {
361
        $esdID = $this->request->getParam('esdID');
362
363
        if (empty($esdID)) {
364
            return $this->forward('downloads');
365
        }
366
367
        $sql = '
368
            SELECT file, articleID
369
            FROM s_articles_esd ae, s_order_esd oe
370
            WHERE ae.id=oe.esdID
371
            AND oe.userID=?
372
            AND oe.orderdetailsID=?
373
        ';
374
        $download = Shopware()->Db()->fetchRow($sql, [Shopware()->Session()->sUserId, $esdID]);
375
376
        if (empty($download)) {
377
            $sql = '
378
                SELECT e.file, ad.articleID
379
                FROM s_articles_esd e, s_order_details od, s_articles_details ad, s_order o
380
                WHERE e.articledetailsID=ad.id
381
                AND ad.ordernumber=od.articleordernumber
382
                AND o.id=od.orderID
383
                AND o.userID=?
384
                AND od.id=?
385
            ';
386
            $download = Shopware()->Db()->fetchRow($sql, [Shopware()->Session()->sUserId, $esdID]);
387
        }
388
389
        if (empty($download['file'])) {
390
            $this->View()->sErrorCode = 1;
391
392
            return $this->forward('downloads');
393
        }
394
395
        $file = 'files/' . Shopware()->Config()->get('sESDKEY') . '/' . $download['file'];
396
397
        $filePath = $this->container->getParameter('shopware.app.rootdir') . $file;
398
399
        if (!file_exists($filePath)) {
400
            $this->View()->sErrorCode = 2;
401
402
            return $this->forward('downloads');
403
        }
404
405
        switch (Shopware()->Config()->get('esdDownloadStrategy')) {
406
            case 0:
407
                $this->redirect($this->Request()->getBasePath() . '/' . $file);
408
                break;
409
            case 1:
410
                @set_time_limit(0);
411
                $this->Response()
412
                    ->setHeader('Content-Type', 'application/octet-stream')
413
                    ->setHeader('Content-Disposition', 'attachment; filename="' . $download['file'] . '"')
414
                    ->setHeader('Content-Length', filesize($filePath));
415
416
                $this->Front()->Plugins()->ViewRenderer()->setNoRender();
417
418
                readfile($filePath);
419
                break;
420
            case 2:
421
                // Apache2 + X-Sendfile
422
                $this->Response()
423
                    ->setHeader('Content-Type', 'application/octet-stream')
424
                    ->setHeader('Content-Disposition', 'attachment; filename="' . $download['file'] . '"')
425
                    ->setHeader('X-Sendfile', $filePath);
426
427
                $this->Front()->Plugins()->ViewRenderer()->setNoRender();
428
429
                break;
430
            case 3:
431
                // Nginx + X-Accel
432
                $this->Response()
433
                    ->setHeader('Content-Type', 'application/octet-stream')
434
                    ->setHeader('Content-Disposition', 'attachment; filename="' . $download['file'] . '"')
435
                    ->setHeader('X-Accel-Redirect', '/' . $file);
436
437
                $this->Front()->Plugins()->ViewRenderer()->setNoRender();
438
439
                break;
440
        }
441
    }
442
443
    /**
444
     * Send new account password
445
     */
446
    public function passwordAction()
447
    {
448
        $this->View()->sTarget = $this->Request()->getParam('sTarget');
449
450
        if ($this->Request()->isPost()) {
451
            $checkUser = $this->sendResetPasswordConfirmationMail($this->Request()->getParam('email'));
452
            if (!empty($checkUser['sErrorMessages'])) {
453
                $this->View()->sFormData = $this->Request()->getPost();
454
                $this->View()->sErrorFlag = $checkUser['sErrorFlag'];
455
                $this->View()->sErrorMessages = $checkUser['sErrorMessages'];
456
            } else {
457
                $this->View()->sSuccess = true;
458
            }
459
        }
460
    }
461
462
    /**
463
     * Send a mail asking the customer, if he actually wants to reset his password
464
     *
465
     * @param string $email
466
     *
467
     * @return array
468
     */
469
    public function sendResetPasswordConfirmationMail($email)
470
    {
471
        $snippets = Shopware()->Snippets()->getNamespace('frontend/account/password');
472
473
        if (empty($email)) {
474
            return ['sErrorMessages' => [$snippets->get('ErrorForgotMail')]];
475
        }
476
477
        $userID = Shopware()->Modules()->Admin()->sGetUserByMail($email);
478
        if (empty($userID)) {
479
            return;
480
        }
481
482
        $hash = \Shopware\Components\Random::getAlphanumericString(32);
483
484
        $context = [
485
            'sUrlReset' => $this->Front()->Router()->assemble(['controller' => 'account', 'action' => 'resetPassword', 'hash' => $hash]),
486
            'sUrl' => $this->Front()->Router()->assemble(['controller' => 'account', 'action' => 'resetPassword']),
487
            'sKey' => $hash,
488
        ];
489
490
        $sql = 'SELECT 
491
          s_user.accountmode,
492
          s_user.active,
493
          s_user.affiliate,
494
          s_user.birthday,
495
          s_user.confirmationkey,
496
          s_user.customergroup,
497
          s_user.customernumber,
498
          s_user.email,
499
          s_user.failedlogins,
500
          s_user.firstlogin,
501
          s_user.lastlogin,
502
          s_user.language,
503
          s_user.internalcomment,
504
          s_user.lockeduntil,
505
          s_user.subshopID,
506
          s_user.title,
507
          s_user.salutation,
508
          s_user.firstname,
509
          s_user.lastname,
510
          s_user.lastlogin,
511
          s_user.newsletter
512
          FROM s_user
513
          WHERE id = ?';
514
515
        $user = $this->get('dbal_connection')->fetchAssoc($sql, [$userID]);
516
        $email = $user['email'];
517
        $user['attributes'] = $this->get('dbal_connection')->fetchAssoc('SELECT * FROM s_user_attributes WHERE userID = ?', [$userID]);
518
519
        $context['user'] = $user;
520
521
        // Send mail
522
        $mail = Shopware()->TemplateMail()->createMail('sCONFIRMPASSWORDCHANGE', $context);
523
        $mail->addTo($email);
524
        $mail->send();
525
526
        // Add the hash to the optin table
527
        $sql = "INSERT INTO `s_core_optin` (`type`, `datum`, `hash`, `data`) VALUES ('password', NOW(), ?, ?)";
528
        Shopware()->Db()->query($sql, [$hash, $userID]);
529
    }
530
531
    /**
532
     * Shows the reset password form and triggers password reset on submit
533
     */
534
    public function resetPasswordAction()
535
    {
536
        $hash = $this->Request()->getParam('hash');
537
        $this->View()->assign('hash', $hash);
538
539
        try {
540
            $customer = $this->getCustomerByResetHash($hash);
541
        } catch (\Exception $ex) {
542
            $this->View()->assign('invalidToken', true);
543
            $this->View()->assign('sErrorMessages', [$ex->getMessage()]);
544
        }
545
546
        if (!$this->Request()->isPost()) {
547
            return;
548
        }
549
550
        $form = $this->createForm(ResetPasswordFormType::class, $customer);
551
        $form->handleRequest($this->Request());
552
553
        if (!$form->isValid()) {
554
            $errors = ['sErrorFlag' => [], 'sErrorMessages' => []];
555
556
            foreach ($form->getErrors(true) as $error) {
557
                $errors['sErrorFlag'][$error->getOrigin()->getName()] = true;
558
                $errors['sErrorMessages'][] = $this->View()->fetch('string:' . $error->getMessage());
559
            }
560
561
            $this->View()->assign($errors);
562
563
            return;
564
        }
565
566
        $customer->setEncoderName($this->get('PasswordEncoder')->getDefaultPasswordEncoderName());
567
568
        $this->customerService->update($customer);
569
570
        // Perform a login for the user and redirect him to his account
571
        $this->Request()->setPost(['email' => $customer->getEmail(), 'password' => $form->get('password')->getData()]);
572
        $this->admin->sLogin();
573
574
        if (!$target = $this->Request()->getParam('sTarget')) {
575
            $target = 'account';
576
        }
577
578
        $this->redirect(['controller' => $target, 'action' => 'index', 'success' => 'resetPassword']);
579
    }
580
581
    /**
582
     * Profile forms for main data, password and email
583
     */
584
    public function profileAction()
585
    {
586
        $errorFlags = [];
587
        $errorMessages = [];
588
        $postData = $this->Request()->getPost() ?: [];
589
590
        $defaultData = [
591
            'profile' => [
592
                'salutation' => $this->View()->sUserData['additional']['user']['salutation'],
593
                'title' => $this->View()->sUserData['additional']['user']['title'],
594
                'firstname' => $this->View()->sUserData['additional']['user']['firstname'],
595
                'lastname' => $this->View()->sUserData['additional']['user']['lastname'],
596
                'birthday' => [
597
                    'day' => null,
598
                    'month' => null,
599
                    'year' => null,
600
                ],
601
            ],
602
        ];
603
604
        if (!empty($this->View()->sUserData['additional']['user']['birthday'])) {
605
            $datetime = new \DateTime($this->View()->sUserData['additional']['user']['birthday']);
606
            $defaultData['profile']['birthday']['year'] = $datetime->format('Y');
607
            $defaultData['profile']['birthday']['month'] = $datetime->format('m');
608
            $defaultData['profile']['birthday']['day'] = $datetime->format('d');
609
        }
610
611
        $formData = array_merge($defaultData, $postData);
612
613
        if ($this->Request()->getParam('errors')) {
614
            foreach ($this->Request()->getParam('errors') as $error) {
615
                $message = $this->View()->fetch('string:' . $error->getMessage());
616
                $errorFlags[$error->getOrigin()->getName()] = true;
617
                $errorMessages[] = $message;
618
            }
619
620
            $errorMessages = array_unique($errorMessages);
621
        }
622
623
        $this->View()->assign('form_data', $formData);
624
        $this->View()->assign('errorFlags', $errorFlags);
625
        $this->View()->assign('errorMessages', $errorMessages);
626
        $this->View()->assign('success', $this->Request()->getParam('success'));
627
        $this->View()->assign('section', $this->Request()->getParam('section'));
628
    }
629
630
    /**
631
     * Endpoint for changing the main profile data
632
     */
633
    public function saveProfileAction()
634
    {
635
        $userId = $this->get('session')->get('sUserId');
636
637
        /** @var Customer $customer */
638
        $customer = $this->get('models')->find(Customer::class, $userId);
639
640
        $form = $this->createForm(ProfileUpdateFormType::class, $customer);
641
        $form->handleRequest($this->Request());
642
643
        if ($form->isValid()) {
644
            $this->customerService->update($customer);
645
            $this->container->get('session')->offsetSet('userInfo', null);
646
            $this->redirect(['controller' => 'account', 'action' => 'profile', 'success' => true, 'section' => 'profile']);
647
648
            return;
649
        }
650
651
        $this->forward('profile', 'account', 'frontend', ['section' => 'profile', 'errors' => $form->getErrors(true)]);
652
    }
653
654
    /**
655
     * Endpoint for changing the email
656
     */
657
    public function saveEmailAction()
658
    {
659
        $userId = $this->get('session')->get('sUserId');
660
661
        /** @var Customer $customer */
662
        $customer = $this->get('models')->find(Customer::class, $userId);
663
664
        $form = $this->createForm(EmailUpdateFormType::class, $customer);
665
        $form->handleRequest($this->Request());
666
667
        if ($form->isValid()) {
668
            $this->customerService->update($customer);
669
            $this->get('session')->offsetSet('sUserMail', $customer->getEmail());
670
            $this->get('session')->offsetSet('userInfo', null);
671
            $this->redirect(['controller' => 'account', 'action' => 'profile', 'success' => true, 'section' => 'email']);
672
673
            return;
674
        }
675
676
        $this->forward('profile', 'account', 'frontend', ['section' => 'email', 'errors' => $form->getErrors(true)]);
677
    }
678
679
    /**
680
     * Endpoint for changing the password
681
     */
682
    public function savePasswordAction()
683
    {
684
        $userId = $this->get('session')->get('sUserId');
685
        /** @var Customer $customer */
686
        $customer = $this->get('models')->find(Customer::class, $userId);
687
688
        $form = $this->createForm(PasswordUpdateFormType::class, $customer);
689
        $form->handleRequest($this->Request());
690
691
        if ($form->isValid()) {
692
            $this->customerService->update($customer);
693
            $this->get('session')->offsetSet('sUserPassword', $customer->getPassword());
694
695
            $this->redirect(['controller' => 'account', 'action' => 'profile', 'success' => true, 'section' => 'password']);
696
697
            return;
698
        }
699
700
        $this->forward('profile', 'account', 'frontend', ['section' => 'password', 'errors' => $form->getErrors(true)]);
701
    }
702
703
    protected function refreshBasket()
704
    {
705
        Shopware()->Modules()->Basket()->sRefreshBasket();
706
    }
707
708
    /**
709
     * @param array $orderData
710
     *
711
     * @return array
712
     */
713
    private function applyTrackingUrl(array $orderData)
714
    {
715
        foreach ($orderData['orderData'] as &$order) {
716
            if (!empty($order['trackingcode']) && !empty($order['dispatch']) && !empty($order['dispatch']['status_link'])) {
717
                $order['dispatch']['status_link'] = $this->renderTrackingLink(
718
                    $order['dispatch']['status_link'],
719
                    $order['trackingcode']
720
                );
721
            }
722
        }
723
724
        return $orderData;
725
    }
726
727
    /**
728
     * @param string $link
729
     * @param string $trackingCode
730
     *
731
     * @return string
732
     */
733
    private function renderTrackingLink($link, $trackingCode)
734
    {
735
        $regEx = '/(\{\$offerPosition.trackingcode\})/';
736
737
        return preg_replace($regEx, $trackingCode, $link);
738
    }
739
740
    /**
741
     * Delete old expired password-hashes after two hours
742
     */
743
    private function deleteExpiredOptInItems()
744
    {
745
        /** @var \Doctrine\DBAL\Connection $connection */
746
        $connection = $this->get('dbal_connection');
747
748
        $connection->executeUpdate(
749
            'DELETE FROM s_core_optin WHERE datum <= (NOW() - INTERVAL 2 HOUR) AND type = "password"'
750
        );
751
    }
752
753
    /**
754
     * @param string $hash
755
     *
756
     * @throws Exception
757
     *
758
     * @return Customer
759
     */
760
    private function getCustomerByResetHash($hash)
761
    {
762
        $resetPasswordNamespace = $this->container->get('snippets')->getNamespace('frontend/account/reset_password');
763
764
        $this->deleteExpiredOptInItems();
765
766
        /** @var $confirmModel \Shopware\Models\CommentConfirm\CommentConfirm */
767
        $confirmModel = $this->get('models')
768
            ->getRepository('Shopware\Models\CommentConfirm\CommentConfirm')
769
            ->findOneBy(['hash' => $hash, 'type' => 'password']);
770
771
        if (!$confirmModel) {
772
            throw new Exception(
773
                $resetPasswordNamespace->get(
774
                    'PasswordResetNewLinkError',
775
                    'Confirmation link not found. Please check the spelling. Note that the confirmation link is only valid for 2 hours. After that you have to require a new confirmation link.'
776
                )
777
            );
778
        }
779
780
        /** @var $customer Customer */
781
        $customer = $this->get('models')->find(\Shopware\Models\Customer\Customer::class, $confirmModel->getData());
782
        if (!$customer) {
783
            throw new Exception(
784
                $resetPasswordNamespace->get(
785
                    'PasswordResetNewMissingId',
786
                    'Your account could not be found. Please contact us to fix this problem.'
787
                )
788
            );
789
        }
790
791
        return $customer;
792
    }
793
794
    /**
795
     * @return bool
796
     */
797
    private function shouldForwardToRegister()
798
    {
799
        return !in_array($this->Request()->getActionName(), ['login', 'logout', 'password', 'resetPassword'])
800
            && !$this->admin->sCheckUser();
801
    }
802
803
    /**
804
     * @return array
805
     */
806
    private function getForwardParameters()
807
    {
808
        if (!$this->Request()->getParam('sTarget') && !$this->Request()->getParam('sTargetAction')) {
809
            return [
810
                'sTarget' => $this->Request()->getControllerName(),
811
                'sTargetAction' => $this->Request()->getActionName(),
812
            ];
813
        }
814
815
        return [
816
            'sTarget' => $this->Request()->getParam('sTarget'),
817
            'sTargetAction' => $this->Request()->getParam('sTargetAction'),
818
        ];
819
    }
820
821
    /**
822
     * @return bool
823
     */
824
    private function isOneTimeAccount()
825
    {
826
        return $this->container->get('session')->offsetGet('sOneTimeAccount')
827
            || $this->View()->sUserData['additional']['user']['accountmode'] == 1;
828
    }
829
}
830