Completed
Pull Request — master (#4193)
by Craig
11:12 queued 05:23
created

ZikulaZauthEditCommand::execute()   B

Complexity

Conditions 8
Paths 24

Size

Total Lines 56
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 8
eloc 43
nc 24
nop 2
dl 0
loc 56
rs 7.9875
c 2
b 0
f 1

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\ZAuthModule\Command;
15
16
use Symfony\Component\Console\Command\Command;
17
use Symfony\Component\Console\Input\InputArgument;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\Console\Style\SymfonyStyle;
21
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
22
use Symfony\Component\Validator\Validator\ValidatorInterface;
23
use Symfony\Contracts\Translation\TranslatorInterface;
24
use Zikula\UsersModule\Entity\RepositoryInterface\UserRepositoryInterface;
25
use Zikula\UsersModule\Validator\Constraints\ValidEmail;
26
use Zikula\UsersModule\Validator\Constraints\ValidUname;
27
use Zikula\ZAuthModule\Entity\RepositoryInterface\AuthenticationMappingRepositoryInterface;
28
use Zikula\ZAuthModule\Validator\Constraints\ValidPassword;
29
30
class ZikulaZauthEditCommand extends Command
31
{
32
    protected static $defaultName = 'zikula:zauth:edit';
33
34
    /**
35
     * @var AuthenticationMappingRepositoryInterface
36
     */
37
    private $authenticationMappingRepository;
38
39
    /**
40
     * @var UserRepositoryInterface
41
     */
42
    private $userRepository;
43
44
    /**
45
     * @var TranslatorInterface
46
     */
47
    private $translator;
48
49
    /**
50
     * @var EncoderFactoryInterface
51
     */
52
    private $encoderFactory;
53
54
    /**
55
     * @var ValidatorInterface
56
     */
57
    private $validator;
58
59
    public function __construct(
60
        AuthenticationMappingRepositoryInterface $authenticationMappingRepository,
61
        UserRepositoryInterface $userRepository,
62
        TranslatorInterface $translator,
63
        EncoderFactoryInterface $encoderFactory,
64
        ValidatorInterface $validator
65
    ) {
66
        parent::__construct();
67
        $this->authenticationMappingRepository = $authenticationMappingRepository;
68
        $this->userRepository = $userRepository;
69
        $this->translator = $translator;
70
        $this->encoderFactory = $encoderFactory;
71
        $this->validator = $validator;
72
    }
73
74
    protected function configure()
75
    {
76
        $this
77
            ->addArgument('id', InputArgument::REQUIRED, 'uid, uname or email')
78
            ->setDescription('Edit a ZAuth user mapping')
79
            ->setHelp(
80
                <<<'EOT'
81
The <info>%command.name%</info> command can be used to modify the password, email or username of a user.
82
83
<info>php %command.full_name% 2</info>
84
85
This will load user uid=2 and then ask which property to set.
86
87
You can look up users by their <info>UID</info>, their <info>email address</info> or their <info>username</info>.
88
89
<info>php %command.full_name% [email protected]</info>
90
91
<info>php %command.full_name% fabien</info>
92
93
EOT
94
            );
95
    }
96
97
    protected function execute(InputInterface $input, OutputInterface $output): int
98
    {
99
        $io = new SymfonyStyle($input, $output);
100
        $id = $input->getArgument('id');
101
        if (is_numeric($id)) {
102
            $criteria = ['uid' => (int) $id];
103
        } elseif (filter_var($id, FILTER_VALIDATE_EMAIL)) {
104
            $criteria = ['email' => $id];
105
        } else {
106
            $criteria = ['uname' => $id];
107
        }
108
        try {
109
            $mapping = $this->authenticationMappingRepository->findOneBy($criteria);
110
        } catch (\Exception $e) {
111
            $io->error($this->translator->trans('Found more than one user by that criteria. Try a different criteria (uid works best).'));
112
113
            return 1;
114
        }
115
        if (empty($mapping)) {
116
            $io->error($this->translator->trans('Found zero users by that criteria. Try a different criteria (uid works best).'));
117
118
            return 1;
119
        }
120
        $choices = [
121
            $this->translator->trans('password'),
122
            $this->translator->trans('email'),
123
            $this->translator->trans('username'),
124
        ];
125
        $choice = $io->choice($this->translator->trans('Value to change?'), $choices, $this->translator->trans('password'));
126
        $method = $this->translator->trans('password') === $choice ? 'askHidden' : 'ask';
127
        $value = $io->{$method}($this->translator->trans('New value for %choice%?', ['%choice%' => $choice]));
128
        $validators = array_combine($choices, [new ValidPassword(), new ValidEmail(), new ValidUname()]);
129
        $errors = $this->validator->validate($value, $validators[$choice]);
130
        if (0 !== count($errors)) {
131
            $io->error($this->translator->trans('Invalid %choice%', ['%choice%' => $choice]) . '. ' . $errors[0]->getMessage());
132
133
            return 2;
134
        }
135
136
        switch ($choice) {
137
            case 'password':
138
                $mapping->setPass($this->encoderFactory->getEncoder($mapping)->encodePassword($value, null));
139
                break;
140
            default:
141
                unset($choices[0]);
142
                $methods = array_combine($choices, ['setEmail', 'setUname']);
143
                $mapping->{$methods[$choice]}($value);
144
                $userEntity = $this->userRepository->findOneBy($criteria);
145
                $userEntity->{$methods[$choice]}($value);
146
                $this->userRepository->persistAndFlush($userEntity);
0 ignored issues
show
Bug introduced by
It seems like $userEntity can also be of type null; however, parameter $user of Zikula\UsersModule\Entit...face::persistAndFlush() does only seem to accept Zikula\UsersModule\Entity\UserEntity, maybe add an additional type check? ( Ignorable by Annotation )

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

146
                $this->userRepository->persistAndFlush(/** @scrutinizer ignore-type */ $userEntity);
Loading history...
147
                break;
148
        }
149
        $this->authenticationMappingRepository->persistAndFlush($mapping);
150
        $io->success($this->translator->trans('The %choice% has been changed.', ['%choice%' => $choice]));
151
152
        return 0;
153
    }
154
}
155