问题描述
在我的 Symfony 项目中,我创建了一个命令类来删除特定用户。
我在 Command 类构造函数中注入了必需的参数“email”。
我从未尝试过在控制器中实现命令,所以我在那里遇到了问题。
我想在控制器中触发 API 调用,如果命令成功,它将返回所需的 json 输出。
我怎样才能做到这一点?
我的命令类:
protected static $defaultName = 'user:delete';
$entityManager;
private $userService;
private $email;
public function __construct(string $email = null,EntityManagerInterface $entityManager,KeycloakApi $keycloakApi)
{
parent::__construct($email);
$this->entityManager = $entityManager;
$this->userService = $userService;
}
protected function configure()
{
$this
->setDescription('Deletion of selected user.')
->addArgument('email',InputArgument::required,'User email');
}
protected function execute(InputInterface $input,OutputInterface $output)
{
$user = $this->userService->getUserByEmail($this->email);
if (empty($user)) {
throw new Exception('USER_DOESNT_EXIST');
}
$this->userService->deleteUser($user['id']);
$output->writeln('Done!');
}
我尝试在控制器中得到我想要的:
/**
* @Route("/delete/test",name="delete_test")
*/
public function testDelete(): JsonResponse
{
$application = new Application($this->kernel);
$application->setAutoExit(false);
$input = new ArrayInput(array("user:delete"));
$output = new BufferedOutput();
// Run the command
$retval = $application->run($input,$output);
dump($retval);die;
}
主要问题是如何在需要为此端点提供的命令中传递电子邮件参数?
解决方法
正如评论所说,您不应该从控制器调用命令,两者都是应用程序的不同入口点。控制器用于从网络访问和从cli执行的命令。
您不应将域逻辑放在这两个文件中。
这是一个可能的例子:
控制器:
/**
* @Route("/delete/{email}",name="delete")
*/
public function delete(string $email,DeleteUserHandler $handler): JsonResponse
{
$handler->handle($email);
return new JsonReponse(null,204);
}
删除用户处理程序:
...
public function handle(string $email): void
{
$user = $this->userService->getUserByEmail($this->email);
if (empty($user)) {
throw new Exception('USER_DOESNT_EXIST');
}
$this->userService->deleteUser($user['id']);
}
我保留了一些你的代码,但在删除之前你甚至不需要找到 IMO(只是可能添加一个安全性以避免任何人删除任何人)
使用这种代码,如果需要,您可以在命令(或任何地方)中重用“DeleteUserHandler”,并且真正删除用户的代码不再与入口点耦合