Passed
Push — master ( eade60...eec955 )
by Paweł
02:46
created

UserCreateCommand::execute()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 37
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 24
nc 4
nop 2
dl 0
loc 37
rs 8.9137
c 0
b 0
f 0
1
<?php
2
3
namespace App\Command;
4
5
use App\Entity\User;
6
use App\Repository\CourseRepositoryInterface;
7
use App\Repository\UserRepositoryInterface;
8
use Doctrine\ORM\EntityManagerInterface;
9
use Exception;
10
use InvalidArgumentException;
11
use Symfony\Component\Console\Command\Command;
12
use Symfony\Component\Console\Input\InputArgument;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Input\InputOption;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Symfony\Component\Console\Style\SymfonyStyle;
17
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
18
19
class UserCreateCommand extends Command
20
{
21
    protected static $defaultName = 'app:user:create';
22
23
    private $courseRepository;
24
    private $userRepository;
25
    private $entityManager;
26
    private $passwordEncoder;
27
28
    public function __construct(
29
        CourseRepositoryInterface $courseRepository,
30
        UserRepositoryInterface $userRepository,
31
        UserPasswordEncoderInterface $passwordEncoder,
32
        EntityManagerInterface $entityManager
33
    ) {
34
        parent::__construct();
35
        $this->courseRepository = $courseRepository;
36
        $this->userRepository = $userRepository;
37
        $this->passwordEncoder = $passwordEncoder;
38
        $this->entityManager = $entityManager;
39
    }
40
41
    protected function configure()
42
    {
43
        $this
44
            ->setDescription('Create new user')
45
            ->addArgument('email', InputArgument::REQUIRED, 'User email')
46
            ->addArgument('password', InputArgument::REQUIRED, 'User password')
47
            ->addArgument('firstName', InputArgument::REQUIRED, 'User first name')
48
            ->addArgument('lastName', InputArgument::REQUIRED, 'User last name')
49
            ->addOption('courses', null, InputOption::VALUE_REQUIRED, 'Courses assigned to user("," sperated by title)');
50
    }
51
52
    protected function execute(InputInterface $input, OutputInterface $output)
53
    {
54
        $io = new SymfonyStyle($input, $output);
55
        $email = $input->getArgument('email');
56
57
        if (!is_string($email)) {
58
            throw new InvalidArgumentException('Provided email must be string!');
59
        }
60
61
        $user = $this->userRepository->getOneByEmail($email);
62
        if (null !== $user) {
63
            throw new Exception('User with provided email already exists!');
64
        }
65
66
        $user = new User();
67
        $user->setEmail($email);
68
        $user->setRoles(['ROLE_USER']);
69
        $generatedPassword = $this->passwordEncoder->encodePassword($user, (string) $input->getArgument('password'));
70
        $user->setPassword($generatedPassword);
71
        $user->setFirstName((string) $input->getArgument('firstName'));
72
        $user->setLastName((string) $input->getArgument('lastName'));
73
74
        if ($input->hasOption('courses')) {
75
            $coursesTitles = explode(',', $input->getOption('courses'));
0 ignored issues
show
Bug introduced by
It seems like $input->getOption('courses') can also be of type string[]; however, parameter $string of explode() does only seem to accept string, 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

75
            $coursesTitles = explode(',', /** @scrutinizer ignore-type */ $input->getOption('courses'));
Loading history...
76
            foreach ($coursesTitles as $coursesTitle) {
77
                $course = $this->courseRepository->findOneBy(['title' => $coursesTitle]);
0 ignored issues
show
Bug introduced by
The method findOneBy() does not exist on App\Repository\CourseRepositoryInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to App\Repository\CourseRepositoryInterface. ( Ignorable by Annotation )

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

77
                /** @scrutinizer ignore-call */ 
78
                $course = $this->courseRepository->findOneBy(['title' => $coursesTitle]);
Loading history...
78
                if (null !== $course) {
79
                    $user->addCourse($course);
80
                }
81
            }
82
        }
83
84
        $this->entityManager->persist($user);
85
        $this->entityManager->flush();
86
87
        $io->success(sprintf('User was created successfully.'));
88
        $io->note('Use app:user:promote to add new roles for this user');
89
    }
90
}
91