2012-07-21 7 views
11

symfony2 app/console 명령을 무시할 수 있습니까? 예를 들어, FOS UserBundle에서 콘솔 생성 사용자 명령으로 사용자를 생성 할 때 묻는 몇 가지 필드를 추가하고 싶습니다. 가능합니까, 아니면 내 번들에 내 자신의 콘솔 명령을 만들어야합니까?symfony2 콘솔 명령을 무시 하시겠습니까?

+0

유용한 물건. 정확한 답을 표시해야합니다;) –

답변

5

번들의 자식 인 자신의 번들을 만들거나 이미 소유하고있는 경우 번들의 콘솔 명령을 무시할 수 있습니다 (Bundle Inheritance 참조). 그런 다음 원래 명령과 동일한 위치/이름으로 클래스를 배치하여 효과적으로 오버라이드합니다.

예를 들어, FOS/UserBundle/Command/CreateUserCommand.php를 재정의하려면 MyCompanyUserBundle에 부모로 FOSUserBundle이있는 MyCompany/UserBundle/Command/CreateUserCommand를 작성하십시오.

명령 클래스는 FOS 명령 클래스를 확장하여 해당 비트를 재사용 할 수 있습니다. 그러나 FOS CreateUserCommand를 살펴보면 입력 필드를 더 추가하기 위해 모든 메서드를 재정의해야한다고 생각합니다.이 경우 입력 필드를 추가 할 때 이점이 없습니다. 물론 이것은 또한 당신이 임의의 번들에서 당신 만의 커맨드를 생성 할 수 있음을 의미하지만, 제 생각에 FOSUserBundle을 자식 번들에 커스터마이징하는 것이 낫습니다.

14

명령에 더 많은 필드를 추가하는 전체 프로세스는 다음과 같습니다

1.In 당신의 AcmeDemoBundle 클래스를 사용하면 부모로서 FOSUser을 설정해야합니다

<?php 

namespace Acme\UserBundle; 

use Symfony\Component\HttpKernel\Bundle\Bundle; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 

class AcmeUserBundle extends Bundle 
{ 
    public function getParent() 
    { 
     return 'FOSUserBundle'; 
    } 
} 

2.Once 당신을 다시 할 수있는 당신이 할 CreateUserCommand 번들에 :

<?php 

namespace Acme\UserBundle\Command; 

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; 
use Symfony\Component\Console\Input\InputArgument; 
use Symfony\Component\Console\Input\InputOption; 
use Symfony\Component\Console\Input\InputInterface; 
use Symfony\Component\Console\Output\OutputInterface; 
use FOS\UserBundle\Model\User; 

/** 
* @author Matthieu Bontemps <[email protected]> 
* @author Thibault Duplessis <[email protected]> 
* @author Luis Cordova <[email protected]> 
*/ 
class CreateUserCommand extends ContainerAwareCommand 
{ 
    /** 
    * @see Command 
    */ 
    protected function configure() 
    { 
     $this 
      ->setName('fos:user:create') 
      ->setDescription('Create a user.') 
      ->setDefinition(array(
       new InputArgument('username', InputArgument::REQUIRED, 'The username'), 
       new InputArgument('email', InputArgument::REQUIRED, 'The email'), 
       new InputArgument('password', InputArgument::REQUIRED, 'The password'), 
       new InputArgument('name', InputArgument::REQUIRED, 'The name'), 
       new InputOption('super-admin', null, InputOption::VALUE_NONE, 'Set the user as super admin'), 
       new InputOption('inactive', null, InputOption::VALUE_NONE, 'Set the user as inactive'), 
      )) 
      ->setHelp(<<<EOT 
The <info>fos:user:create</info> command creates a user: 

    <info>php app/console fos:user:create matthieu</info> 

This interactive shell will ask you for an email and then a password. 

You can alternatively specify the email and password as the second and third arguments: 

    <info>php app/console fos:user:create matthieu [email protected] mypassword</info> 

You can create a super admin via the super-admin flag: 

    <info>php app/console fos:user:create admin --super-admin</info> 

You can create an inactive user (will not be able to log in): 

    <info>php app/console fos:user:create thibault --inactive</info> 

EOT 
      ); 
    } 

    /** 
    * @see Command 
    */ 
    protected function execute(InputInterface $input, OutputInterface $output) 
    { 
     $username = $input->getArgument('username'); 
     $email  = $input->getArgument('email'); 
     $password = $input->getArgument('password'); 
     $name  = $input->getArgument('name'); 
     $inactive = $input->getOption('inactive'); 
     $superadmin = $input->getOption('super-admin'); 

     $manipulator = $this->getContainer()->get('acme.util.user_manipulator'); 
     $manipulator->create($username, $password, $email, $name, !$inactive, $superadmin); 

     $output->writeln(sprintf('Created user <comment>%s</comment>', $username)); 
    } 

    /** 
    * @see Command 
    */ 
    protected function interact(InputInterface $input, OutputInterface $output) 
    { 
     if (!$input->getArgument('username')) { 
      $username = $this->getHelper('dialog')->askAndValidate(
       $output, 
       'Please choose a username:', 
       function($username) { 
        if (empty($username)) { 
         throw new \Exception('Username can not be empty'); 
        } 

        return $username; 
       } 
      ); 
      $input->setArgument('username', $username); 
     } 

     if (!$input->getArgument('email')) { 
      $email = $this->getHelper('dialog')->askAndValidate(
       $output, 
       'Please choose an email:', 
       function($email) { 
        if (empty($email)) { 
         throw new \Exception('Email can not be empty'); 
        } 

        return $email; 
       } 
      ); 
      $input->setArgument('email', $email); 
     } 

     if (!$input->getArgument('password')) { 
      $password = $this->getHelper('dialog')->askAndValidate(
       $output, 
       'Please choose a password:', 
       function($password) { 
        if (empty($password)) { 
         throw new \Exception('Password can not be empty'); 
        } 

        return $password; 
       } 
      ); 
      $input->setArgument('password', $password); 
     } 

     if (!$input->getArgument('name')) { 
      $name = $this->getHelper('dialog')->askAndValidate(
       $output, 
       'Please choose a name:', 
       function($name) { 
        if (empty($name)) { 
         throw new \Exception('Name can not be empty'); 
        } 

        return $name; 
       } 
      ); 
      $input->setArgument('name', $name); 
     } 
    } 
} 

주 나는 이름과 명령 안에 내가 acme.util.user_manipulator 서비스 대신 사용하고라는 새로운 입력 인수를 추가 한 원래 하나의 OS가 나는 또한 사용자의 이름을 처리하려고합니다.

3.Create 자신의 UserManipulator : 난 단지 명령의 나머지 촉진 강등 같은 기능을 만들 필요가이 클래스에서

<?php 

namespace Acme\UserBundle\Util; 

use FOS\UserBundle\Model\UserManagerInterface; 

/** 
* Executes some manipulations on the users 
* 
* @author Christophe Coevoet <[email protected]> 
* @author Luis Cordova <[email protected]> 
*/ 
class UserManipulator 
{ 
    /** 
    * User manager 
    * 
    * @var UserManagerInterface 
    */ 
    private $userManager; 

    public function __construct(UserManagerInterface $userManager) 
    { 
     $this->userManager = $userManager; 
    } 

    /** 
    * Creates a user and returns it. 
    * 
    * @param string $username 
    * @param string $password 
    * @param string $email 
    * @param string $name 
    * @param Boolean $active 
    * @param Boolean $superadmin 
    * 
    * @return \FOS\UserBundle\Model\UserInterface 
    */ 
    public function create($username, $password, $email, $name, $active, $superadmin) 
    { 
     $user = $this->userManager->createUser(); 
     $user->setUsername($username); 
     $user->setEmail($email); 
     $user->setName($name); 
     $user->setPlainPassword($password); 
     $user->setEnabled((Boolean)$active); 
     $user->setSuperAdmin((Boolean)$superadmin); 
     $this->userManager->updateUser($user); 

     return $user; 
    } 
} 

.. 그래서 난 안 사용자의 새로운 속성에 대해 알고하지 않습니다 전체 서비스를 무효화하려면 CompilerPass를 생성해야합니다.

4.Finally, 리소스/config 디렉토리에이 새로운 UserManipulator 서비스를 정의하고 의존성 주입 확장에 추가 :

services: 
    acme.util.user_manipulator: 
     class:  Acme\UserBundle\Util\UserManipulator 
     arguments: [@fos_user.user_manager] 

을 완료를!

+0

안녕하세요 @ nass600! 자세한 답변을 주셔서 감사합니다. 그러나 마지막 부분 인 "DependencyInjection Extension에 추가하십시오." 고마워. – Reveclair

0

symfony (3.3)에서이 링크를 따라 콘솔 명령을 무시할 수 있습니다. https://symfony.com/doc/current/console/calling_commands.html 와 심포니 문서에서 https://symfony.com/doc/current/console/input.html

코드의 옵션 :이 질문에

use Symfony\Component\Console\Input\ArrayInput; 
// ... 

protected function execute(InputInterface $input, OutputInterface $output) 
{ 
    $command = $this->getApplication()->find('demo:greet'); 

    $arguments = array(
     'command' => 'demo:greet', 
     'name' => 'Fabien', 
     '--yell' => true, 
    ); 

    $greetInput = new ArrayInput($arguments); 
    $returnCode = $command->run($greetInput, $output); 

    // ... 
} 
관련 문제