ConfigController::indexAction()   F
last analyzed

Complexity

Conditions 26
Paths 24

Size

Total Lines 196
Code Lines 119

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 119
nc 24
nop 1
dl 0
loc 196
rs 3.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
namespace Wallabag\CoreBundle\Controller;
4
5
use JMS\Serializer\SerializationContext;
6
use JMS\Serializer\SerializerBuilder;
7
use PragmaRX\Recovery\Recovery as BackupCodes;
8
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
9
use Symfony\Component\HttpFoundation\JsonResponse;
10
use Symfony\Component\HttpFoundation\RedirectResponse;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
14
use Symfony\Component\Routing\Annotation\Route;
15
use Symfony\Component\Validator\Constraints\Locale as LocaleConstraint;
16
use Wallabag\CoreBundle\Entity\Config;
17
use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule;
18
use Wallabag\CoreBundle\Entity\RuleInterface;
19
use Wallabag\CoreBundle\Entity\TaggingRule;
20
use Wallabag\CoreBundle\Form\Type\ChangePasswordType;
21
use Wallabag\CoreBundle\Form\Type\ConfigType;
22
use Wallabag\CoreBundle\Form\Type\FeedType;
23
use Wallabag\CoreBundle\Form\Type\IgnoreOriginUserRuleType;
24
use Wallabag\CoreBundle\Form\Type\TaggingRuleImportType;
25
use Wallabag\CoreBundle\Form\Type\TaggingRuleType;
26
use Wallabag\CoreBundle\Form\Type\UserInformationType;
27
use Wallabag\CoreBundle\Tools\Utils;
28
29
class ConfigController extends Controller
30
{
31
    /**
32
     * @Route("/config", name="config")
33
     */
34
    public function indexAction(Request $request)
35
    {
36
        $em = $this->getDoctrine()->getManager();
37
        $config = $this->getConfig();
38
        $userManager = $this->container->get('fos_user.user_manager');
39
        $user = $this->getUser();
40
41
        // handle basic config detail (this form is defined as a service)
42
        $configForm = $this->createForm(ConfigType::class, $config, ['action' => $this->generateUrl('config')]);
43
        $configForm->handleRequest($request);
44
45
        if ($configForm->isSubmitted() && $configForm->isValid()) {
46
            $em->persist($config);
47
            $em->flush();
48
49
            $request->getSession()->set('_locale', $config->getLanguage());
50
51
            // switch active theme
52
            $activeTheme = $this->get('liip_theme.active_theme');
53
            $activeTheme->setName($config->getTheme());
54
55
            $this->addFlash(
56
                'notice',
57
                'flashes.config.notice.config_saved'
58
            );
59
60
            return $this->redirect($this->generateUrl('config'));
61
        }
62
63
        // handle changing password
64
        $pwdForm = $this->createForm(ChangePasswordType::class, null, ['action' => $this->generateUrl('config') . '#set4']);
65
        $pwdForm->handleRequest($request);
66
67
        if ($pwdForm->isSubmitted() && $pwdForm->isValid()) {
68
            if ($this->get('craue_config')->get('demo_mode_enabled') && $this->get('craue_config')->get('demo_mode_username') === $user->getUsername()) {
69
                $message = 'flashes.config.notice.password_not_updated_demo';
70
            } else {
71
                $message = 'flashes.config.notice.password_updated';
72
73
                $user->setPlainPassword($pwdForm->get('new_password')->getData());
0 ignored issues
show
Bug introduced by
The method setPlainPassword() does not exist on Symfony\Component\Security\Core\User\UserInterface. It seems like you code against a sub-type of Symfony\Component\Security\Core\User\UserInterface such as FOS\UserBundle\Model\UserInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
                $user->/** @scrutinizer ignore-call */ 
74
                       setPlainPassword($pwdForm->get('new_password')->getData());
Loading history...
74
                $userManager->updateUser($user, true);
75
            }
76
77
            $this->addFlash('notice', $message);
78
79
            return $this->redirect($this->generateUrl('config') . '#set4');
80
        }
81
82
        // handle changing user information
83
        $userForm = $this->createForm(UserInformationType::class, $user, [
84
            'validation_groups' => ['Profile'],
85
            'action' => $this->generateUrl('config') . '#set3',
86
        ]);
87
        $userForm->handleRequest($request);
88
89
        if ($userForm->isSubmitted() && $userForm->isValid()) {
90
            $userManager->updateUser($user, true);
91
92
            $this->addFlash(
93
                'notice',
94
                'flashes.config.notice.user_updated'
95
            );
96
97
            return $this->redirect($this->generateUrl('config') . '#set3');
98
        }
99
100
        // handle feed information
101
        $feedForm = $this->createForm(FeedType::class, $config, ['action' => $this->generateUrl('config') . '#set2']);
102
        $feedForm->handleRequest($request);
103
104
        if ($feedForm->isSubmitted() && $feedForm->isValid()) {
105
            $em->persist($config);
106
            $em->flush();
107
108
            $this->addFlash(
109
                'notice',
110
                'flashes.config.notice.feed_updated'
111
            );
112
113
            return $this->redirect($this->generateUrl('config') . '#set2');
114
        }
115
116
        // handle tagging rule
117
        $taggingRule = new TaggingRule();
118
        $action = $this->generateUrl('config') . '#set5';
119
120
        if ($request->query->has('tagging-rule')) {
121
            $taggingRule = $this->getDoctrine()
122
                ->getRepository('WallabagCoreBundle:TaggingRule')
123
                ->find($request->query->get('tagging-rule'));
124
125
            if ($this->getUser()->getId() !== $taggingRule->getConfig()->getUser()->getId()) {
0 ignored issues
show
Bug introduced by
The method getId() does not exist on Symfony\Component\Security\Core\User\UserInterface. It seems like you code against a sub-type of Symfony\Component\Security\Core\User\UserInterface such as FOS\OAuthServerBundle\Te...\TestBundle\Entity\User or FOS\UserBundle\Model\UserInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

125
            if ($this->getUser()->/** @scrutinizer ignore-call */ getId() !== $taggingRule->getConfig()->getUser()->getId()) {
Loading history...
126
                return $this->redirect($action);
127
            }
128
129
            $action = $this->generateUrl('config') . '?tagging-rule=' . $taggingRule->getId() . '#set5';
130
        }
131
132
        $newTaggingRule = $this->createForm(TaggingRuleType::class, $taggingRule, ['action' => $action]);
133
        $newTaggingRule->handleRequest($request);
134
135
        if ($newTaggingRule->isSubmitted() && $newTaggingRule->isValid()) {
136
            $taggingRule->setConfig($config);
137
            $em->persist($taggingRule);
138
            $em->flush();
139
140
            $this->addFlash(
141
                'notice',
142
                'flashes.config.notice.tagging_rules_updated'
143
            );
144
145
            return $this->redirect($this->generateUrl('config') . '#set5');
146
        }
147
148
        // handle tagging rules import
149
        $taggingRulesImportform = $this->createForm(TaggingRuleImportType::class);
150
        $taggingRulesImportform->handleRequest($request);
151
152
        if ($taggingRulesImportform->isSubmitted() && $taggingRulesImportform->isValid()) {
153
            $message = 'flashes.config.notice.tagging_rules_not_imported';
154
            $file = $taggingRulesImportform->get('file')->getData();
155
156
            if (null !== $file && $file->isValid() && \in_array($file->getClientMimeType(), ['application/json', 'application/octet-stream'], true)) {
157
                $content = json_decode(file_get_contents($file->getPathname()), true);
158
159
                if (\is_array($content)) {
160
                    foreach ($content as $rule) {
161
                        $taggingRule = new TaggingRule();
162
                        $taggingRule->setRule($rule['rule']);
163
                        $taggingRule->setTags($rule['tags']);
164
                        $taggingRule->setConfig($config);
165
                        $em->persist($taggingRule);
166
                    }
167
168
                    $em->flush();
169
170
                    $message = 'flashes.config.notice.tagging_rules_imported';
171
                }
172
            }
173
174
            $this->addFlash('notice', $message);
175
176
            return $this->redirect($this->generateUrl('config') . '#set5');
177
        }
178
179
        // handle ignore origin rules
180
        $ignoreOriginUserRule = new IgnoreOriginUserRule();
181
        $action = $this->generateUrl('config') . '#set6';
182
183
        if ($request->query->has('ignore-origin-user-rule')) {
184
            $ignoreOriginUserRule = $this->getDoctrine()
185
                ->getRepository('WallabagCoreBundle:IgnoreOriginUserRule')
186
                ->find($request->query->get('ignore-origin-user-rule'));
187
188
            if ($this->getUser()->getId() !== $ignoreOriginUserRule->getConfig()->getUser()->getId()) {
189
                return $this->redirect($action);
190
            }
191
192
            $action = $this->generateUrl('config', [
193
                'ignore-origin-user-rule' => $ignoreOriginUserRule->getId(),
194
            ]) . '#set6';
195
        }
196
197
        $newIgnoreOriginUserRule = $this->createForm(IgnoreOriginUserRuleType::class, $ignoreOriginUserRule, ['action' => $action]);
198
        $newIgnoreOriginUserRule->handleRequest($request);
199
200
        if ($newIgnoreOriginUserRule->isSubmitted() && $newIgnoreOriginUserRule->isValid()) {
201
            $ignoreOriginUserRule->setConfig($config);
202
            $em->persist($ignoreOriginUserRule);
203
            $em->flush();
204
205
            $this->addFlash(
206
                'notice',
207
                'flashes.config.notice.ignore_origin_rules_updated'
208
            );
209
210
            return $this->redirect($this->generateUrl('config') . '#set6');
211
        }
212
213
        return $this->render('WallabagCoreBundle:Config:index.html.twig', [
214
            'form' => [
215
                'config' => $configForm->createView(),
216
                'feed' => $feedForm->createView(),
217
                'pwd' => $pwdForm->createView(),
218
                'user' => $userForm->createView(),
219
                'new_tagging_rule' => $newTaggingRule->createView(),
220
                'import_tagging_rule' => $taggingRulesImportform->createView(),
221
                'new_ignore_origin_user_rule' => $newIgnoreOriginUserRule->createView(),
222
            ],
223
            'feed' => [
224
                'username' => $user->getUsername(),
225
                'token' => $config->getFeedToken(),
226
            ],
227
            'twofactor_auth' => $this->getParameter('twofactor_auth'),
228
            'wallabag_url' => $this->getParameter('domain_name'),
229
            'enabled_users' => $this->get('wallabag_user.user_repository')->getSumEnabledUsers(),
230
        ]);
231
    }
232
233
    /**
234
     * Disable 2FA using email.
235
     *
236
     * @Route("/config/otp/email/disable", name="disable_otp_email")
237
     */
238
    public function disableOtpEmailAction()
239
    {
240
        if (!$this->getParameter('twofactor_auth')) {
241
            return $this->createNotFoundException('two_factor not enabled');
242
        }
243
244
        $user = $this->getUser();
245
        $user->setEmailTwoFactor(false);
0 ignored issues
show
Bug introduced by
The method setEmailTwoFactor() does not exist on Symfony\Component\Security\Core\User\UserInterface. It seems like you code against a sub-type of Symfony\Component\Security\Core\User\UserInterface such as Wallabag\UserBundle\Entity\User. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

245
        $user->/** @scrutinizer ignore-call */ 
246
               setEmailTwoFactor(false);
Loading history...
246
247
        $this->container->get('fos_user.user_manager')->updateUser($user, true);
248
249
        $this->addFlash(
250
            'notice',
251
            'flashes.config.notice.otp_disabled'
252
        );
253
254
        return $this->redirect($this->generateUrl('config') . '#set3');
255
    }
256
257
    /**
258
     * Enable 2FA using email.
259
     *
260
     * @Route("/config/otp/email", name="config_otp_email")
261
     */
262
    public function otpEmailAction()
263
    {
264
        if (!$this->getParameter('twofactor_auth')) {
265
            return $this->createNotFoundException('two_factor not enabled');
266
        }
267
268
        $user = $this->getUser();
269
270
        $user->setGoogleAuthenticatorSecret(null);
0 ignored issues
show
Bug introduced by
The method setGoogleAuthenticatorSecret() does not exist on Symfony\Component\Security\Core\User\UserInterface. It seems like you code against a sub-type of Symfony\Component\Security\Core\User\UserInterface such as Wallabag\UserBundle\Entity\User. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

270
        $user->/** @scrutinizer ignore-call */ 
271
               setGoogleAuthenticatorSecret(null);
Loading history...
271
        $user->setBackupCodes(null);
0 ignored issues
show
Bug introduced by
The method setBackupCodes() does not exist on Symfony\Component\Security\Core\User\UserInterface. It seems like you code against a sub-type of Symfony\Component\Security\Core\User\UserInterface such as Wallabag\UserBundle\Entity\User. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

271
        $user->/** @scrutinizer ignore-call */ 
272
               setBackupCodes(null);
Loading history...
272
        $user->setEmailTwoFactor(true);
273
274
        $this->container->get('fos_user.user_manager')->updateUser($user, true);
275
276
        $this->addFlash(
277
            'notice',
278
            'flashes.config.notice.otp_enabled'
279
        );
280
281
        return $this->redirect($this->generateUrl('config') . '#set3');
282
    }
283
284
    /**
285
     * Disable 2FA using OTP app.
286
     *
287
     * @Route("/config/otp/app/disable", name="disable_otp_app")
288
     */
289
    public function disableOtpAppAction()
290
    {
291
        if (!$this->getParameter('twofactor_auth')) {
292
            return $this->createNotFoundException('two_factor not enabled');
293
        }
294
295
        $user = $this->getUser();
296
297
        $user->setGoogleAuthenticatorSecret('');
298
        $user->setBackupCodes(null);
299
300
        $this->container->get('fos_user.user_manager')->updateUser($user, true);
301
302
        $this->addFlash(
303
            'notice',
304
            'flashes.config.notice.otp_disabled'
305
        );
306
307
        return $this->redirect($this->generateUrl('config') . '#set3');
308
    }
309
310
    /**
311
     * Enable 2FA using OTP app, user will need to confirm the generated code from the app.
312
     *
313
     * @Route("/config/otp/app", name="config_otp_app")
314
     */
315
    public function otpAppAction()
316
    {
317
        if (!$this->getParameter('twofactor_auth')) {
318
            return $this->createNotFoundException('two_factor not enabled');
319
        }
320
321
        $user = $this->getUser();
322
        $secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
323
324
        $user->setGoogleAuthenticatorSecret($secret);
325
        $user->setEmailTwoFactor(false);
326
327
        $backupCodes = (new BackupCodes())->toArray();
328
        $backupCodesHashed = array_map(
329
            function ($backupCode) {
330
                return password_hash($backupCode, \PASSWORD_DEFAULT);
331
            },
332
            $backupCodes
333
        );
334
335
        $user->setBackupCodes($backupCodesHashed);
336
337
        $this->container->get('fos_user.user_manager')->updateUser($user, true);
338
339
        $this->addFlash(
340
            'notice',
341
            'flashes.config.notice.otp_enabled'
342
        );
343
344
        return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [
345
            'backupCodes' => $backupCodes,
346
            'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user),
347
            'secret' => $secret,
348
        ]);
349
    }
350
351
    /**
352
     * Cancelling 2FA using OTP app.
353
     *
354
     * @Route("/config/otp/app/cancel", name="config_otp_app_cancel")
355
     */
356
    public function otpAppCancelAction()
357
    {
358
        if (!$this->getParameter('twofactor_auth')) {
359
            return $this->createNotFoundException('two_factor not enabled');
360
        }
361
362
        $user = $this->getUser();
363
        $user->setGoogleAuthenticatorSecret(null);
364
        $user->setBackupCodes(null);
365
366
        $this->container->get('fos_user.user_manager')->updateUser($user, true);
367
368
        return $this->redirect($this->generateUrl('config') . '#set3');
369
    }
370
371
    /**
372
     * Validate OTP code.
373
     *
374
     * @Route("/config/otp/app/check", name="config_otp_app_check")
375
     */
376
    public function otpAppCheckAction(Request $request)
377
    {
378
        $isValid = $this->get('scheb_two_factor.security.google_authenticator')->checkCode(
379
            $this->getUser(),
380
            $request->get('_auth_code')
381
        );
382
383
        if (true === $isValid) {
384
            $this->addFlash(
385
                'notice',
386
                'flashes.config.notice.otp_enabled'
387
            );
388
389
            return $this->redirect($this->generateUrl('config') . '#set3');
390
        }
391
392
        $this->addFlash(
393
            'two_factor',
394
            'scheb_two_factor.code_invalid'
395
        );
396
397
        return $this->redirect($this->generateUrl('config_otp_app'));
398
    }
399
400
    /**
401
     * @Route("/generate-token", name="generate_token")
402
     *
403
     * @return RedirectResponse|JsonResponse
404
     */
405
    public function generateTokenAction(Request $request)
406
    {
407
        $config = $this->getConfig();
408
        $config->setFeedToken(Utils::generateToken());
409
410
        $em = $this->getDoctrine()->getManager();
411
        $em->persist($config);
412
        $em->flush();
413
414
        if ($request->isXmlHttpRequest()) {
415
            return new JsonResponse(['token' => $config->getFeedToken()]);
416
        }
417
418
        $this->addFlash(
419
            'notice',
420
            'flashes.config.notice.feed_token_updated'
421
        );
422
423
        return $this->redirect($this->generateUrl('config') . '#set2');
424
    }
425
426
    /**
427
     * @Route("/revoke-token", name="revoke_token")
428
     *
429
     * @return RedirectResponse|JsonResponse
430
     */
431
    public function revokeTokenAction(Request $request)
432
    {
433
        $config = $this->getConfig();
434
        $config->setFeedToken(null);
435
436
        $em = $this->getDoctrine()->getManager();
437
        $em->persist($config);
438
        $em->flush();
439
440
        if ($request->isXmlHttpRequest()) {
441
            return new JsonResponse();
442
        }
443
444
        $this->addFlash(
445
            'notice',
446
            'flashes.config.notice.feed_token_revoked'
447
        );
448
449
        return $this->redirect($this->generateUrl('config') . '#set2');
450
    }
451
452
    /**
453
     * Deletes a tagging rule and redirect to the config homepage.
454
     *
455
     * @Route("/tagging-rule/delete/{id}", requirements={"id" = "\d+"}, name="delete_tagging_rule")
456
     *
457
     * @return RedirectResponse
458
     */
459
    public function deleteTaggingRuleAction(TaggingRule $rule)
460
    {
461
        $this->validateRuleAction($rule);
462
463
        $em = $this->getDoctrine()->getManager();
464
        $em->remove($rule);
465
        $em->flush();
466
467
        $this->addFlash(
468
            'notice',
469
            'flashes.config.notice.tagging_rules_deleted'
470
        );
471
472
        return $this->redirect($this->generateUrl('config') . '#set5');
473
    }
474
475
    /**
476
     * Edit a tagging rule.
477
     *
478
     * @Route("/tagging-rule/edit/{id}", requirements={"id" = "\d+"}, name="edit_tagging_rule")
479
     *
480
     * @return RedirectResponse
481
     */
482
    public function editTaggingRuleAction(TaggingRule $rule)
483
    {
484
        $this->validateRuleAction($rule);
485
486
        return $this->redirect($this->generateUrl('config') . '?tagging-rule=' . $rule->getId() . '#set5');
487
    }
488
489
    /**
490
     * Deletes an ignore origin rule and redirect to the config homepage.
491
     *
492
     * @Route("/ignore-origin-user-rule/delete/{id}", requirements={"id" = "\d+"}, name="delete_ignore_origin_rule")
493
     *
494
     * @return RedirectResponse
495
     */
496
    public function deleteIgnoreOriginRuleAction(IgnoreOriginUserRule $rule)
497
    {
498
        $this->validateRuleAction($rule);
499
500
        $em = $this->getDoctrine()->getManager();
501
        $em->remove($rule);
502
        $em->flush();
503
504
        $this->addFlash(
505
            'notice',
506
            'flashes.config.notice.ignore_origin_rules_deleted'
507
        );
508
509
        return $this->redirect($this->generateUrl('config') . '#set6');
510
    }
511
512
    /**
513
     * Edit an ignore origin rule.
514
     *
515
     * @Route("/ignore-origin-user-rule/edit/{id}", requirements={"id" = "\d+"}, name="edit_ignore_origin_rule")
516
     *
517
     * @return RedirectResponse
518
     */
519
    public function editIgnoreOriginRuleAction(IgnoreOriginUserRule $rule)
520
    {
521
        $this->validateRuleAction($rule);
522
523
        return $this->redirect($this->generateUrl('config') . '?ignore-origin-user-rule=' . $rule->getId() . '#set6');
524
    }
525
526
    /**
527
     * Remove all annotations OR tags OR entries for the current user.
528
     *
529
     * @Route("/reset/{type}", requirements={"id" = "annotations|tags|entries"}, name="config_reset")
530
     *
531
     * @return RedirectResponse
532
     */
533
    public function resetAction($type)
534
    {
535
        switch ($type) {
536
            case 'annotations':
537
                $this->getDoctrine()
538
                    ->getRepository('WallabagAnnotationBundle:Annotation')
539
                    ->removeAllByUserId($this->getUser()->getId());
540
                break;
541
            case 'tags':
542
                $this->removeAllTagsByUserId($this->getUser()->getId());
543
                break;
544
            case 'entries':
545
                // SQLite doesn't care about cascading remove, so we need to manually remove associated stuff
546
                // otherwise they won't be removed ...
547
                if ($this->get('doctrine')->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) {
548
                    $this->getDoctrine()->getRepository('WallabagAnnotationBundle:Annotation')->removeAllByUserId($this->getUser()->getId());
549
                }
550
551
                // manually remove tags to avoid orphan tag
552
                $this->removeAllTagsByUserId($this->getUser()->getId());
553
554
                $this->get('wallabag_core.entry_repository')->removeAllByUserId($this->getUser()->getId());
555
                break;
556
            case 'archived':
557
                if ($this->get('doctrine')->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) {
558
                    $this->removeAnnotationsForArchivedByUserId($this->getUser()->getId());
559
                }
560
561
                // manually remove tags to avoid orphan tag
562
                $this->removeTagsForArchivedByUserId($this->getUser()->getId());
563
564
                $this->get('wallabag_core.entry_repository')->removeArchivedByUserId($this->getUser()->getId());
565
                break;
566
        }
567
568
        $this->addFlash(
569
            'notice',
570
            'flashes.config.notice.' . $type . '_reset'
571
        );
572
573
        return $this->redirect($this->generateUrl('config') . '#set3');
574
    }
575
576
    /**
577
     * Delete account for current user.
578
     *
579
     * @Route("/account/delete", name="delete_account")
580
     *
581
     * @throws AccessDeniedHttpException
582
     *
583
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
584
     */
585
    public function deleteAccountAction(Request $request)
586
    {
587
        $enabledUsers = $this->get('wallabag_user.user_repository')
588
            ->getSumEnabledUsers();
589
590
        if ($enabledUsers <= 1) {
591
            throw new AccessDeniedHttpException();
592
        }
593
594
        $user = $this->getUser();
595
596
        // logout current user
597
        $this->get('security.token_storage')->setToken(null);
598
        $request->getSession()->invalidate();
599
600
        $em = $this->get('fos_user.user_manager');
601
        $em->deleteUser($user);
602
603
        return $this->redirect($this->generateUrl('fos_user_security_login'));
604
    }
605
606
    /**
607
     * Switch view mode for current user.
608
     *
609
     * @Route("/config/view-mode", name="switch_view_mode")
610
     *
611
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
612
     */
613
    public function changeViewModeAction(Request $request)
614
    {
615
        $user = $this->getUser();
616
        $user->getConfig()->setListMode(!$user->getConfig()->getListMode());
0 ignored issues
show
Bug introduced by
The method getConfig() does not exist on Symfony\Component\Security\Core\User\UserInterface. It seems like you code against a sub-type of Symfony\Component\Security\Core\User\UserInterface such as Wallabag\UserBundle\Entity\User. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

616
        $user->/** @scrutinizer ignore-call */ 
617
               getConfig()->setListMode(!$user->getConfig()->getListMode());
Loading history...
617
618
        $em = $this->getDoctrine()->getManager();
619
        $em->persist($user);
620
        $em->flush();
621
622
        return $this->redirect($request->headers->get('referer'));
623
    }
624
625
    /**
626
     * Change the locale for the current user.
627
     *
628
     * @param string $language
629
     *
630
     * @Route("/locale/{language}", name="changeLocale")
631
     *
632
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
633
     */
634
    public function setLocaleAction(Request $request, $language = null)
635
    {
636
        $errors = $this->get('validator')->validate($language, (new LocaleConstraint()));
637
638
        if (0 === \count($errors)) {
639
            $request->getSession()->set('_locale', $language);
640
        }
641
642
        return $this->redirect($request->headers->get('referer', $this->generateUrl('homepage')));
643
    }
644
645
    /**
646
     * Export tagging rules for the logged in user.
647
     *
648
     * @Route("/tagging-rule/export", name="export_tagging_rule")
649
     *
650
     * @return Response
651
     */
652
    public function exportTaggingRulesAction()
653
    {
654
        $data = SerializerBuilder::create()->build()->serialize(
655
            $this->getUser()->getConfig()->getTaggingRules(),
656
            'json',
657
            SerializationContext::create()->setGroups(['export_tagging_rule'])
658
        );
659
660
        return Response::create(
661
            $data,
662
            200,
663
            [
664
                'Content-type' => 'application/json',
665
                'Content-Disposition' => 'attachment; filename="tagging_rules_' . $this->getUser()->getUsername() . '.json"',
666
                'Content-Transfer-Encoding' => 'UTF-8',
667
            ]
668
        );
669
    }
670
671
    /**
672
     * Remove all tags for given tags and a given user and cleanup orphan tags.
673
     *
674
     * @param array $tags
675
     * @param int   $userId
676
     */
677
    private function removeAllTagsByStatusAndUserId($tags, $userId)
678
    {
679
        if (empty($tags)) {
680
            return;
681
        }
682
683
        $this->get('wallabag_core.entry_repository')
684
            ->removeTags($userId, $tags);
685
686
        // cleanup orphan tags
687
        $em = $this->getDoctrine()->getManager();
688
689
        foreach ($tags as $tag) {
690
            if (0 === \count($tag->getEntries())) {
691
                $em->remove($tag);
692
            }
693
        }
694
695
        $em->flush();
696
    }
697
698
    /**
699
     * Remove all tags for a given user and cleanup orphan tags.
700
     *
701
     * @param int $userId
702
     */
703
    private function removeAllTagsByUserId($userId)
704
    {
705
        $tags = $this->get('wallabag_core.tag_repository')->findAllTags($userId);
706
        $this->removeAllTagsByStatusAndUserId($tags, $userId);
707
    }
708
709
    /**
710
     * Remove all tags for a given user and cleanup orphan tags.
711
     *
712
     * @param int $userId
713
     */
714
    private function removeTagsForArchivedByUserId($userId)
715
    {
716
        $tags = $this->get('wallabag_core.tag_repository')->findForArchivedArticlesByUser($userId);
717
        $this->removeAllTagsByStatusAndUserId($tags, $userId);
718
    }
719
720
    private function removeAnnotationsForArchivedByUserId($userId)
721
    {
722
        $em = $this->getDoctrine()->getManager();
723
724
        $archivedEntriesAnnotations = $this->getDoctrine()
725
            ->getRepository('WallabagAnnotationBundle:Annotation')
726
            ->findAllArchivedEntriesByUser($userId);
727
728
        foreach ($archivedEntriesAnnotations as $archivedEntriesAnnotation) {
729
            $em->remove($archivedEntriesAnnotation);
730
        }
731
732
        $em->flush();
733
    }
734
735
    /**
736
     * Validate that a rule can be edited/deleted by the current user.
737
     */
738
    private function validateRuleAction(RuleInterface $rule)
739
    {
740
        if ($this->getUser()->getId() !== $rule->getConfig()->getUser()->getId()) {
0 ignored issues
show
Bug introduced by
The method getConfig() does not exist on Wallabag\CoreBundle\Entity\RuleInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Wallabag\CoreBundle\Enti...gnoreOriginInstanceRule. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

740
        if ($this->getUser()->getId() !== $rule->/** @scrutinizer ignore-call */ getConfig()->getUser()->getId()) {
Loading history...
741
            throw $this->createAccessDeniedException('You can not access this rule.');
742
        }
743
    }
744
745
    /**
746
     * Retrieve config for the current user.
747
     * If no config were found, create a new one.
748
     *
749
     * @return Config
750
     */
751
    private function getConfig()
752
    {
753
        $config = $this->getDoctrine()
754
            ->getRepository('WallabagCoreBundle:Config')
755
            ->findOneByUser($this->getUser());
0 ignored issues
show
Bug introduced by
The method findOneByUser() does not exist on Wallabag\CoreBundle\Repository\ConfigRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

755
            ->/** @scrutinizer ignore-call */ findOneByUser($this->getUser());
Loading history...
756
757
        // should NEVER HAPPEN ...
758
        if (!$config) {
759
            $config = new Config($this->getUser());
760
        }
761
762
        return $config;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $config also could return the type array|integer which is incompatible with the documented return type Wallabag\CoreBundle\Entity\Config.
Loading history...
763
    }
764
}
765