Passed
Push — master ( 7b1e85...a75848 )
by Daniel
16:43 queued 09:45
created

UserCreateCommand::execute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 10
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 15
ccs 11
cts 11
cp 1
crap 1
rs 9.9332
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\Command;
15
16
use Exception;
17
use Silverback\ApiComponentsBundle\Factory\User\UserFactory;
18
use Symfony\Component\Console\Command\Command;
19
use Symfony\Component\Console\Input\InputArgument;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
use Symfony\Component\Console\Question\Question;
24
25
/**
26
 * Based on FOSUserBundle: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Command/CreateUserCommand.php.
27
 */
28
class UserCreateCommand extends Command
29
{
30
    protected static $defaultName = 'silverback:api-components:user:create';
31
    private UserFactory $userFactory;
32
    private array $questions = [];
33
34 5
    public function __construct(UserFactory $userFactory)
35
    {
36 5
        parent::__construct();
37 5
        $this->userFactory = $userFactory;
38 5
    }
39
40 5
    protected function configure(): void
41
    {
42
        $this
43 5
            ->setDescription('Create a user.')
44 5
            ->setDefinition(
45
                [
46 5
                    new InputArgument('username', InputArgument::REQUIRED, 'The username'),
47 5
                    new InputArgument('email', InputArgument::REQUIRED, 'The email'),
48 5
                    new InputArgument('password', InputArgument::REQUIRED, 'The password'),
49 5
                    new InputOption('admin', null, InputOption::VALUE_NONE, 'Set the user as super admin'),
50 5
                    new InputOption('super-admin', null, InputOption::VALUE_NONE, 'Set the user as super admin'),
51 5
                    new InputOption('inactive', null, InputOption::VALUE_NONE, 'Set the user as inactive'),
52 5
                    new InputOption('overwrite', null, InputOption::VALUE_NONE, 'Overwrite the user if they already exist'),
53
                ]
54
            )
55 5
            ->setHelp(
56
                <<<EOT
57 5
                    The <info>silverback:api-components:user:create</info> command creates a user:
58
                      <info>php %command.full_name% daniel</info>
59
                    This interactive shell will ask you for an email and then a password.
60
                    You can alternatively specify the email and password as the second and third arguments:
61
                      <info>php %command.full_name% daniel [email protected] mypassword</info>
62
                    You can create an admin via the admin flag:
63
                      <info>php %command.full_name% admin --admin</info>
64
                    You can create a super admin via the super-admin flag:
65
                      <info>php %command.full_name% admin --super-admin</info>
66
                    You can create an inactive user (will not be able to log in):
67
                      <info>php %command.full_name% disabled_user --inactive</info>
68
                    You can overwrite a user if they already exist:
69
                      <info>php %command.full_name% existing_username --overwrite</info>
70
                    EOT
71
            );
72 5
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 2
    protected function execute(InputInterface $input, OutputInterface $output): int
78
    {
79 2
        $username = (string) $input->getArgument('username');
80 2
        $email = (string) $input->getArgument('email');
81 2
        $password = (string) $input->getArgument('password');
82 2
        $inactive = $input->getOption('inactive');
83 2
        $superAdmin = $input->getOption('super-admin');
84 2
        $admin = $input->getOption('admin');
85 2
        $overwrite = $input->getOption('overwrite');
86
87 2
        $this->userFactory->create($username, $password, $email, $inactive, $superAdmin, $admin, $overwrite);
88
89 2
        $output->writeln(sprintf('Created user: <comment>%s</comment>', $username));
90
91 2
        return 0;
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97 5
    protected function interact(InputInterface $input, OutputInterface $output): void
98
    {
99 5
        $this->checkUsernameQuestion($input);
100 5
        $this->checkEmailQuestion($input);
101 5
        $this->checkPasswordQuestion($input);
102
103 5
        foreach ($this->questions as $name => $question) {
104 4
            $answer = $this->getHelper('question')->ask($input, $output, $question);
105 1
            $input->setArgument($name, $answer);
106
        }
107 2
    }
108
109 5
    private function checkUsernameQuestion(InputInterface $input): void
110
    {
111 5
        if (!$input->getArgument('username')) {
112 2
            $question = new Question('Please choose a username:');
113 2
            $question->setValidator(self::getNotEmptyValidator('Username'));
114 2
            $this->questions['username'] = $question;
115
        }
116 5
    }
117
118 5
    private function checkPasswordQuestion(InputInterface $input): void
119
    {
120 5
        if (!$input->getArgument('password')) {
121 4
            $question = new Question('Please choose a password:');
122
            $question
123 4
                ->setValidator(self::getNotEmptyValidator('Password'))
124 4
                ->isHidden();
125 4
            $this->questions['password'] = $question;
126
        }
127 5
    }
128
129 5
    private function checkEmailQuestion(InputInterface $input): void
130
    {
131 5
        if (!$input->getArgument('email')) {
132 3
            $question = new Question('Please choose an email (leave blank to use same as username):');
133 3
            $this->questions['email'] = $question;
134
        }
135 5
    }
136
137 4
    private static function getNotEmptyValidator(string $label): callable
138
    {
139
        return static function (string $string) use ($label) {
140 1
            if (empty($string)) {
141
                throw new Exception($label . ' can not be empty');
142
            }
143
144 1
            return $string;
145 4
        };
146
    }
147
}
148