Completed
Push — 5.0 ( a48099...63af02 )
by
unknown
11:33
created

AdminBundle/Command/CreateUserCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\AdminBundle\Command;
4
5
use Doctrine\ORM\EntityManager;
6
use Kunstmaan\AdminBundle\Entity\Group;
7
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
8
use Symfony\Component\Console\Input\ArrayInput;
9
use Symfony\Component\Console\Input\InputArgument;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Console\Question\ChoiceQuestion;
14
use Symfony\Component\Console\Question\Question;
15
use Symfony\Component\Console\Exception\InvalidArgumentException;
16
17
/**
18
 * Symfony CLI command to create a user using bin/console kuma:user:create <username_of_the_user>
19
 */
20
class CreateUserCommand extends ContainerAwareCommand
21
{
22
    /** @var array */
23
    protected $groups = [];
24
25
    protected function configure()
26
    {
27
        parent::configure();
28
29
        $this->setName('kuma:user:create')
30
            ->setDescription('Create a user.')
31
            ->setDefinition(array(
32
                new InputArgument('username', InputArgument::REQUIRED, 'The username'),
33
                new InputArgument('email', InputArgument::REQUIRED, 'The email'),
34
                new InputArgument('password', InputArgument::REQUIRED, 'The password'),
35
                new InputArgument('locale', InputArgument::OPTIONAL, 'The locale (language)'),
36
                new InputOption('group', null, InputOption::VALUE_REQUIRED, 'The group(s) the user should belong to'),
37
                new InputOption('super-admin', null, InputOption::VALUE_NONE, 'Set the user as super admin'),
38
                new InputOption('inactive', null, InputOption::VALUE_NONE, 'Set the user as inactive'),
39
            ))
40
            ->setHelp(<<<EOT
41
The <info>kuma:user:create</info> command creates a user:
42
43
  <info>php bin/console kuma:user:create matthieu --group=Users</info>
44
45
This interactive shell will ask you for an email and then a password.
46
47
You can alternatively specify the email, password and locale and group as extra arguments:
48
49
  <info>php bin/console kuma:user:create matthieu [email protected] mypassword en --group=Users</info>
50
51
You can create a super admin via the super-admin flag:
52
53
  <info>php bin/console kuma:user:create admin --super-admin --group=Administrators</info>
54
55
You can create an inactive user (will not be able to log in):
56
57
  <info>php bin/console kuma:user:create thibault --inactive --group=Users</info>
58
59
<comment>Note:</comment> You have to specify at least one group.
60
61
EOT
62
            );
63
    }
64
65
    protected function initialize(InputInterface $input, OutputInterface $output)
66
    {
67
        $this->groups = $this->getGroups();
68
    }
69
70
71
    /**
72
     * Executes the current command.
73
     *
74
     * @param InputInterface $input The input
75
     * @param OutputInterface $output The output
76
     *
77
     * @return int
78
     */
79
    protected function execute(InputInterface $input, OutputInterface $output)
80
    {
81
        /* @var EntityManager $em */
82
        $em = $this->getContainer()->get('doctrine.orm.entity_manager');
83
84
        $username = $input->getArgument('username');
85
        $email = $input->getArgument('email');
86
        $password = $input->getArgument('password');
87
        $locale = $input->getArgument('locale');
88
        $superAdmin = $input->getOption('super-admin');
89
        $inactive = $input->getOption('inactive');
90
        $groupOption = $input->getOption('group');
91
92
        if (null === $locale) {
93
            $locale = $this->getContainer()->getParameter('kunstmaan_admin.default_admin_locale');
94
        }
95
        $command = $this->getApplication()->find('fos:user:create');
96
        $arguments = array(
97
            'command' => 'fos:user:create',
98
            'username' => $username,
99
            'email' => $email,
100
            'password' => $password,
101
            '--super-admin' => $superAdmin,
102
            '--inactive' => $inactive,
103
        );
104
105
        $input = new ArrayInput($arguments);
106
        $command->run($input, $output);
107
108
        // Fetch user that was just created
109
        $userClassName = $this->getContainer()->getParameter('fos_user.model.user.class');
110
        $user = $em->getRepository($userClassName)->findOneBy(array('username' => $username));
111
112
        // Attach groups
113
        $groupOutput = [];
114
115
116
        foreach (explode(',', $groupOption) as $groupId) {
117
118
            if ((int)$groupId === 0) {
119
                foreach ($this->groups as $value) {
120
                    if ($groupId === $value->getName()) {
121
                        $group = $value;
122
                        break;
123
                    }
124
                }
125
            } else {
126
                $group = $this->groups[$groupId];
127
            }
128
129
            if (isset($group) && $group instanceof Group) {
130
                $groupOutput[] = $group->getName();
131
                $user->getGroups()->add($group);
132
            } else {
133
                throw new \RuntimeException(
134
                    'The selected group(s) can\'t be found.'
135
                );
136
            }
137
        }
138
139
        // Set admin interface locale and enable password changed
140
        $user->setAdminLocale($locale);
141
        $user->setPasswordChanged(true);
142
143
        // Persist
144
        $em->persist($user);
145
        $em->flush();
146
147
        $output->writeln(sprintf('Added user <comment>%s</comment> to groups <comment>%s</comment>', $input->getArgument('username'), implode(',', $groupOutput)));
148
    }
149
150
    /**
151
     * Interacts with the user.
152
     *
153
     * @param InputInterface $input The input
154
     * @param OutputInterface $output The output
155
     *
156
     * @throws \InvalidArgumentException
157
     *
158
     * @return void
159
     */
160
    protected function interact(InputInterface $input, OutputInterface $output)
161
    {
162 View Code Duplication
        if (!$input->getArgument('username')) {
163
            $question = New Question('Please choose a username:');
164
            $question->setValidator(function ($username) {
165
                if (null === $username) {
166
                    throw new \InvalidArgumentException('Username can not be empty');
167
                }
168
169
                return $username;
170
            });
171
            $username = $this->getHelper('question')->ask(
172
                $input,
173
                $output,
174
                $question
175
            );
176
            $input->setArgument('username', $username);
177
        }
178
179 View Code Duplication
        if (!$input->getArgument('email')) {
180
            $question = New Question('Please choose an email:');
181
            $question->setValidator(function ($email) {
182
                if (null === $email) {
183
                    throw new \InvalidArgumentException('Email can not be empty');
184
                }
185
186
                return $email;
187
            });
188
            $email = $this->getHelper('question')->ask(
189
                $input,
190
                $output,
191
                $question
192
            );
193
            $input->setArgument('email', $email);
194
        }
195
196
        if (!$input->getArgument('password')) {
197
198
            $question = New Question('Please choose a password:');
199
            $question->setHidden(true);
200
            $question->setHiddenFallback(false);
201
            $question->setValidator(function ($password) {
202
                if (null === $password) {
203
                    throw new \InvalidArgumentException('Password can not be empty');
204
                }
205
206
                return $password;
207
            });
208
            $password = $this->getHelper('question')->ask(
209
                $input,
210
                $output,
211
                $question
212
            );
213
214
            $input->setArgument('password', $password);
215
        }
216
217
        if (!$input->getArgument('locale')) {
218
            $locale = $this->getHelper('question')->ask(
219
                $input,
220
                $output,
221
                new Question('Please enter the locale (or leave empty for default admin locale):')
222
            );
223
            $input->setArgument('locale', $locale);
224
        }
225
226
        if (!$input->getOption('group')) {
227
            $question = new ChoiceQuestion(
228
                'Please enter the group(s) the user should be a member of (multiple possible, separated by comma):',
229
                $this->groups,
230
                ''
231
            );
232
            $question->setMultiselect(true);
233
            $question->setValidator(function ($groupsInput) {
234
235
                if (!$this->groups) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->groups of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
236
                    throw new \RuntimeException('No user group(s) could be found');
237
                }
238
239
                // Validate that the chosen group options exist in the available groups
240
                $groupNames = array_unique(explode(',', $groupsInput));
241
                if (count(array_intersect_key(array_flip($groupNames),$this->groups)) !== count($groupNames)) {
242
                    throw new InvalidArgumentException('You have chosen non existing group(s)');
243
                }
244
245
                if ($groupsInput === '') {
246
                    throw new \RuntimeException(
247
                        'Group(s) must be of type integer and can not be empty'
248
                    );
249
                }
250
                return $groupsInput;
251
            });
252
253
            // Group has to be imploded because $input->setOption expects a string
254
            $groups = $this->getHelper('question')->ask($input, $output, $question);
255
256
            $input->setOption('group', $groups);
257
        }
258
    }
259
260
    private function getGroups()
261
    {
262
        $groups = $this->getContainer()->get('fos_user.group_manager')->findGroups();
263
264
        // reindexing the array, using the db id as the key
265
        $newGroups = [];
266
        foreach($groups as $group) {
267
            $newGroups[$group->getId()] = $group;
268
        }
269
270
        return $newGroups;
271
    }
272
}
273