Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 43 | class DeleteUserCommand extends Command |
||
| 44 | { |
||
| 45 | /** |
||
| 46 | * @var string |
||
| 47 | */ |
||
| 48 | protected static $defaultName = 'app:delete-user'; |
||
| 49 | |||
| 50 | /** @var SymfonyStyle */ |
||
| 51 | private $io; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * @var EntityManagerInterface |
||
| 55 | */ |
||
| 56 | private $entityManager; |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @var UserValidationService |
||
| 60 | */ |
||
| 61 | private $validator; |
||
| 62 | |||
| 63 | /** |
||
| 64 | * @var UserService |
||
| 65 | */ |
||
| 66 | private $userService; |
||
| 67 | |||
| 68 | public function __construct(EntityManagerInterface $em, UserValidationService $validator, UserService $userService) |
||
| 69 | { |
||
| 70 | parent::__construct(); |
||
| 71 | |||
| 72 | $this->entityManager = $em; |
||
| 73 | $this->validator = $validator; |
||
| 74 | $this->userService = $userService; |
||
| 75 | } |
||
| 76 | |||
| 77 | /** |
||
| 78 | * {@inheritdoc} |
||
| 79 | */ |
||
| 80 | protected function configure(): void |
||
| 81 | { |
||
| 82 | $this |
||
| 83 | ->setDescription('Deletes users from the database') |
||
| 84 | ->addArgument('username', InputArgument::REQUIRED, 'The username of an existing user') |
||
| 85 | ->setHelp(<<<'HELP' |
||
| 86 | The <info>%command.name%</info> command deletes users from the database: |
||
|
|
|||
| 87 | |||
| 88 | <info>php %command.full_name%</info> <comment>username</comment> |
||
| 89 | |||
| 90 | If you omit the argument, the command will ask you to |
||
| 91 | provide the missing value: |
||
| 92 | |||
| 93 | <info>php %command.full_name%</info> |
||
| 94 | HELP |
||
| 95 | ); |
||
| 96 | } |
||
| 97 | |||
| 98 | protected function initialize(InputInterface $input, OutputInterface $output): void |
||
| 99 | { |
||
| 100 | // SymfonyStyle is an optional feature that Symfony provides so you can |
||
| 101 | // apply a consistent look to the commands of your application. |
||
| 102 | // See https://symfony.com/doc/current/console/style.html |
||
| 103 | $this->io = new SymfonyStyle($input, $output); |
||
| 104 | } |
||
| 105 | |||
| 106 | protected function interact(InputInterface $input, OutputInterface $output): void |
||
| 107 | { |
||
| 108 | if ($input->getArgument('username') !== null) { |
||
| 109 | return; |
||
| 110 | } |
||
| 111 | |||
| 112 | $this->io->title('Delete User Command Interactive Wizard'); |
||
| 113 | $this->io->text([ |
||
| 114 | 'If you prefer to not use this interactive wizard, provide the', |
||
| 115 | 'arguments required by this command as follows:', |
||
| 116 | '', |
||
| 117 | ' $ php bin/console app:delete-user username', |
||
| 118 | '', |
||
| 119 | 'Now we\'ll ask you for the value of all the missing command arguments.', |
||
| 120 | '', |
||
| 121 | ]); |
||
| 122 | |||
| 123 | $username = $this->io->ask('Username', null, [$this->validator, 'validateUsername']); |
||
| 124 | $input->setArgument('username', $username); |
||
| 125 | } |
||
| 126 | |||
| 127 | protected function execute(InputInterface $input, OutputInterface $output): void |
||
| 128 | { |
||
| 129 | $username = $input->getArgument('username'); |
||
| 130 | |||
| 131 | $this->userService->deleteUser($username); |
||
| 132 | |||
| 133 | $this->entityManager->flush(); |
||
| 134 | |||
| 135 | $this->io->success(sprintf('User "%s" was successfully deleted.', $username)); |
||
| 136 | } |
||
| 137 | } |
||
| 138 |