Passed
Push — feature/uploadable ( 7c6d25...a7ed20 )
by Daniel
11:07
created

UserCreateCommand::execute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 2
dl 0
loc 12
ccs 0
cts 9
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
 * From 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
    public function __construct(UserFactory $userFactory)
35
    {
36
        parent::__construct();
37
        $this->userFactory = $userFactory;
38
    }
39
40
    protected function configure(): void
41
    {
42
        $this
43
            ->setDescription('Create a user.')
44
            ->setDefinition([
45
                new InputArgument('username', InputArgument::REQUIRED, 'The username'),
46
                new InputArgument('email', InputArgument::REQUIRED, 'The email'),
47
                new InputArgument('password', InputArgument::REQUIRED, 'The password'),
48
                new InputOption('super-admin', null, InputOption::VALUE_NONE, 'Set the user as super admin'),
49
                new InputOption('inactive', null, InputOption::VALUE_NONE, 'Set the user as inactive'),
50
                new InputOption('overwrite', null, InputOption::VALUE_NONE, 'Overwrite the user if they already exist'),
51
            ])
52
            ->setHelp(<<<EOT
53
                The <info>silverback:api-components:user:create</info> command creates a user:
54
                  <info>php %command.full_name% daniel</info>
55
                This interactive shell will ask you for an email and then a password.
56
                You can alternatively specify the email and password as the second and third arguments:
57
                  <info>php %command.full_name% daniel [email protected] mypassword</info>
58
                You can create a super admin via the super-admin flag:
59
                  <info>php %command.full_name% admin --super-admin</info>
60
                You can create an inactive user (will not be able to log in):
61
                  <info>php %command.full_name% disabled_user --inactive</info>
62
                You can overwrite a user if they already exist:
63
                  <info>php %command.full_name% existing_username --overwrite</info>
64
                EOT
65
            );
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    protected function execute(InputInterface $input, OutputInterface $output): void
72
    {
73
        $username = (string) $input->getArgument('username');
74
        $email = (string) $input->getArgument('email');
75
        $password = (string) $input->getArgument('password');
76
        $inactive = $input->getOption('inactive');
77
        $superadmin = $input->getOption('super-admin');
78
        $overwrite = $input->getOption('overwrite');
79
80
        $this->userFactory->create($username, $password, $email, $inactive, $superadmin, $overwrite);
81
82
        $output->writeln(sprintf('Created user <comment>%s</comment>', $username));
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    protected function interact(InputInterface $input, OutputInterface $output): void
89
    {
90
        $this->checkUsernameQuestion($input);
91
        $this->checkEmailQuestion($input);
92
        $this->checkPasswordQuestion($input);
93
94
        foreach ($this->questions as $name => $question) {
95
            $answer = $this->getHelper('question')->ask($input, $output, $question);
96
            $input->setArgument($name, $answer);
97
        }
98
    }
99
100
    private function checkUsernameQuestion(InputInterface $input): void
101
    {
102
        if (!$input->getArgument('username')) {
103
            $question = new Question('Please choose a username:');
104
            $question->setValidator(self::getNotEmptyValidator('Username'));
105
            $this->questions['username'] = $question;
106
        }
107
    }
108
109
    private function checkPasswordQuestion(InputInterface $input): void
110
    {
111
        if (!$input->getArgument('password')) {
112
            $question = new Question('Please choose a password:');
113
            $question->setValidator(self::getNotEmptyValidator('Password'));
114
            $this->questions['password'] = $question;
115
        }
116
    }
117
118
    private function checkEmailQuestion(InputInterface $input): void
119
    {
120
        if (!$input->getArgument('email')) {
121
            $question = new Question('Please choose an email (leave blank to use same as username):');
122
            $this->questions['email'] = $question;
123
        }
124
    }
125
126
    private static function getNotEmptyValidator(string $label): callable
127
    {
128
        return static function (string $string) use ($label) {
129
            if (empty($string)) {
130
                throw new Exception($label . ' can not be empty');
131
            }
132
133
            return $string;
134
        };
135
    }
136
}
137