2012-07-21 10 views
11

क्या symfony2 ऐप/कंसोल कमांड को ओवरराइड करना संभव है? उदाहरण के लिए, एफओएस उपयोगकर्ता बंडल में मैं कुछ और फ़ील्ड जोड़ना चाहता हूं, जब यह उपयोगकर्ता को कंसोल के साथ उपयोगकर्ता कंसोल बनाता है तो उपयोगकर्ता कमांड बनाता है। क्या यह संभव है, या मुझे अपने स्वयं के बंडल में अपना कंसोल कमांड बनाने की ज़रूरत है?symfony2 कंसोल कमांड ओवरराइड करें?

+0

सहायक सामान। आपको एक उत्तर को सही के रूप में चिह्नित करना चाहिए;) –

उत्तर

5

यदि आप उस बंडल के बच्चे हैं (Bundle Inheritance देखें) तो आप अपने बंडल को बनाते हैं (या पहले से ही) बनाते हैं, तो आप एक बंडल के कंसोल कमांड को ओवरराइड कर सकते हैं। फिर मूल बंडल के रूप में उसी स्थान/नाम के साथ अपने बंडल में एक कक्षा डालकर आप इसे प्रभावी ढंग से ओवरराइड करते हैं।

तो उदाहरण के लिए, एफओएस/यूजरबंडल/कमांड/CreateUserCommand.php को ओवरराइड करने के लिए, MyCompany/UserBundle/Command/CreateUserCommand बनाएं जहां MyCompanyUserBundle में इसके माता-पिता के रूप में FOSUserBundle है।

आपकी कमांड क्लास एफओएस कमांड क्लास को फिर से उपयोग करने के लिए (बिट्स) का विस्तार करने के लिए बढ़ा सकती है। हालांकि, एफओएस 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 सेवा का उपयोग कर रहा नामक एक नए इनपुट तर्क को शामिल किया है मूल एक ओएस मैं उपयोगकर्ता के नाम को भी संसाधित करने जा रहा हूं।

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; 
    } 
} 

इस वर्ग मैं केवल समारोह बनाने इसलिए आदेशों के बाकी को बढ़ावा देने के पसंद अवनत जरूरत में .. आपके उपयोगकर्ता के नए गुणों के बारे में पता नहीं है तो मुझे नहीं पता पूरी सेवा को ओवरराइड करने के लिए एक कंपाइलरपास बनाने की आवश्यकता है।

4.Finally, संसाधन/config निर्देशिका में इस नए UserManipulator सेवा को परिभाषित करने और DependencyInjection एक्सटेंशन में जोड़ें:

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

हो गया !!!

+0

हाय @ nass600! आपके विस्तृत उत्तर के लिए धन्यवाद, लेकिन क्या आप अंतिम भाग भी विस्तारित कर सकते हैं: "इसे निर्भरता इंजेक्शन एक्सटेंशन में जोड़ें"। बहुत बहुत धन्यवाद – Reveclair

0

सिम्फनी (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); 

    // ... 
} 
संबंधित मुद्दे