Creating a Magento CLI command option

With Magento 2, there is a command-line interface (CLI) available to run several tasks. The bin/magento command replaces the separate shell scripts that were used in Magento 1. This command is based on the Symfony Console component and looks just like n98-magerun that is available for Magento 1. Just like the rest of Magento 2, it's possible to extend the CLI tool with your own commands.

Getting ready

Adding commands to the CLI script requires some knowledge of the Symfony Console component. This recipe also uses the service layer created in the previous recipe.

How to do it…

In this recipe, we will add four options to the bin/magento CLI command with the following steps:

  1. Create the AddCommand class; this is used to create a new record through the CLI:

    Console/Command/AddCommand.php

    <?php
    namespace GenmatoSampleConsoleCommand;
    
    use GenmatoSampleApiDemoRepositoryInterface;
    use GenmatoSampleModelDataDemoFactory;
    use GenmatoSampleApiDataDemoInterface;
    
    use SymfonyComponentConsoleInputInputOption;
    use SymfonyComponentConsoleInputInputArgument;
    use SymfonyComponentConsoleCommandCommand;
    use SymfonyComponentConsoleInputInputInterface;
    use SymfonyComponentConsoleOutputOutputInterface;
    use SymfonyComponentConsoleQuestionConfirmationQuestion;
    
    
    class AddCommand extends Command
    {
    
      /** @var  DemoRepositoryInterface */
      private $demoRepository;
    
      /** @var DemoFactory  */
      private $demoFactory;
    
      /**
      * AddCommand constructor.
      * @param DemoRepositoryInterface $demoRepository
      * @param DemoFactory $demoFactory
      * @param null $name
      */
      public function __construct(
        DemoRepositoryInterface $demoRepository,
        DemoFactory $demoFactory,
      $name = null)
      {
        parent::__construct($name);
    
        $this->demoRepository = $demoRepository;
        $this->demoFactory = $demoFactory;
      }
    
      /**
      * {@inheritdoc}
      */
      protected function configure()
      {
        $this->setName('demo:add')
          ->setDescription('Add demo record')
          ->addArgument('title',InputArgument::OPTIONAL, 'Title')
          ->addOption('active', null, InputOption::VALUE_NONE, 'Active')
          ->addOption('visible', null, InputOption::VALUE_NONE, 'Visible')
        ;
      }
    
      /**
      * {@inheritdoc}
      */
      protected function execute(InputInterface $input, OutputInterface $output)
      {
        $title = $input->getArgument('title');
        $active = $input->getOption('active')? 1:0;
        $visible = $input->getOption('visible')? 1:0;
        if (!$title) {
          $dialog = $this->getHelper('dialog');
    
          $title = $dialog->ask($output, '<question>Enter the Title:</question> ',false);
          $active = $dialog->ask($output, '<question>Should record be active: [Y/n]</question> ','y');
          $active = (strtolower($active) == 'y') ? 1:0;
          $visible = $dialog->ask($output, '<question>Should record be visible: [Y/n]</question> ','y');
          $visible = (strtolower($visible) == 'y') ? 1:0;
        }
    
        /** @var DemoInterface $demoRecord */
        $demoRecord = $this->demoFactory->create();
        $demoRecord->setIsActive($active)
          ->setIsVisible($visible)
          ->setTitle($title);
    
        try {
          $demo = $this->demoRepository->save($demoRecord);
          $output->writeln('New record created (id='.$demo->getId().')');
        }catch (Exception $ex) {
          $output->writeln('<error>'.$ex->getMessage().'</error>');
        }
      }
    }
  2. Create the delete option class; this is used to delete a record through the CLI:

    Console/Command/DeleteCommand.php

    <?php
    namespace GenmatoSampleConsoleCommand;
    
    use GenmatoSampleApiDemoRepositoryInterface;
    
    use SymfonyComponentConsoleInputInputOption;
    use SymfonyComponentConsoleCommandCommand;
    use SymfonyComponentConsoleInputInputInterface;
    use SymfonyComponentConsoleOutputOutputInterface;
    use SymfonyComponentConsoleQuestionConfirmationQuestion;
    
    class DeleteCommand extends Command
    {
    
      /** @var  DemoRepositoryInterface */
      private $demoRepository;
    
      public function __construct(
        DemoRepositoryInterface $demoRepository,
      $name = null)
      {
        parent::__construct($name);
    
        $this->demoRepository = $demoRepository;
      }
    
      /**
      * {@inheritdoc}
      */
      protected function configure()
      {
        $this->setName('demo:delete')
          ->setDescription('Delete demo record')
          ->addOption(
            'id',
            null,
            InputOption::VALUE_REQUIRED,
            'Demo record ID to delete'
          )
          ->addOption(
            'force',
            null,
            InputOption::VALUE_NONE,
            'Force delete without confirmation'
          );
      }
    
      /**
      * {@inheritdoc}
      */
      protected function execute(InputInterface $input, OutputInterface $output)
      {
        $helper = $this->getHelper('question');
    
        $id = $input->getOption('id');
    
        try {
          if (!$input->getOption('force')) {
            $data = $this->demoRepository->getById($id);
            $output->writeln('Id        :' . $data->getId());
            $output->writeln('Title     :' . $data->getTitle());
            $question = new ConfirmationQuestion('Are you sure you want to delete this record? ', false);
    
            if (!$helper->ask($input, $output, $question)) {
              return;
            }
          }
    
          $data = $this->demoRepository->deleteById($id);
          if ($data) {
            $output->writeln('<info>Record deleted!</info>');
          } else {
            $output->writeln('<error>Unable to delete record!</error>');
          }
        } catch (Exception $ex) {
          $output->writeln('<error>'.$ex->
            getMessage().'</error>');
        }
      }
    }
  3. Create the get option class; this is used to list a single record through the CLI:

    Console/Command/GetCommand.php

    <?php
    
    namespace GenmatoSampleConsoleCommand;
    
    use GenmatoSampleApiDemoRepositoryInterface;
    
    use SymfonyComponentConsoleCommandCommand;
    use SymfonyComponentConsoleInputInputArgument;
    use SymfonyComponentConsoleInputInputOption;
    use SymfonyComponentConsoleInputInputInterface;
    use SymfonyComponentConsoleOutputOutputInterface;
    
    class GetCommand extends Command
    {
    
      /** @var  DemoRepositoryInterface */
      private $demoRepository;
    
      public function __construct(
        DemoRepositoryInterface $demoRepository,
      $name = null)
      {
        parent::__construct($name);
    
        $this->demoRepository = $demoRepository;
      }
    
      /**
      * {@inheritdoc}
      */
      protected function configure()
      {
        $this->setName('demo:get')
          ->setDescription('Get demo records')
          ->addOption(
            'id',
            null,
            InputOption::VALUE_REQUIRED,
            'Demo record ID to display'
           );
      }
    
      /**
      * {@inheritdoc}
      */
      protected function execute(InputInterface $input, OutputInterface $output)
      {
        $id = $input->getOption('id');
    
        try {
          $data = $this->demoRepository->getById($id);
    
          $table = $this->getHelper('table');
          $table
            ->setHeaders(array(__('ID'), __('Title'), __('Created'), __('Updated'), __('Visible'), __('Active')))
            ->setRows([[
              $data->getId(),
              $data->getTitle(),
              $data->getCreationTime(),
              $data->getUpdateTime(),
              $data->getIsVisible() ? __('Yes') : __('No'),
              $data->getIsActive() ? __('Yes') : __('No')
              ]]);
          $table->render($output);
        } catch (Exception $ex) {
          $output->writeln('<error>'.$ex->getMessage().'</error>');
        }
      }
    }
  4. Create the list option class; this is used to list the available records through the CLI:

    Console/Command/ListCommand.php

    <?php
    namespace GenmatoSampleConsoleCommand;
    
    use MagentoFrameworkApiSearchCriteriaBuilder;
    use GenmatoSampleApiDemoRepositoryInterface;
    
    use SymfonyComponentConsoleCommandCommand;
    use SymfonyComponentConsoleInputInputInterface;
    use SymfonyComponentConsoleOutputOutputInterface;
    
    class ListCommand extends Command
    {
    
      /** @var  DemoRepositoryInterface */
      private $demoRepository;
    
      /**
      * @var SearchCriteriaBuilder
      */
      private $searchCriteriaBuilder;
    
      public function __construct(
        DemoRepositoryInterface $demoRepository,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        $name = null)
      {
        parent::__construct($name);
    
        $this->demoRepository = $demoRepository;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
      }
    
      /**
      * {@inheritdoc}
      */
      protected function configure()
      {
        $this->setName('demo:list')->setDescription('List demo records');
      }
    
      /**
      * {@inheritdoc}
      */
      protected function execute(InputInterface $input, OutputInterface $output)
      {
        // Get list of available records
        $searchCriteria = $this->searchCriteriaBuilder->create();
        $searchResult = $this->demoRepository->getList($searchCriteria);
        $rows = [];
        foreach ($searchResult->getItems() as $item) {
          $rows[] = [$item->getId(), $item->getTitle()];
        }
    
        $table = $this->getHelper('table');
        $table
          ->setHeaders(array(__('ID'), __('Title')))
          ->setRows($rows)
        ;
        $table->render($output);
      }
    }
  5. Register the commands so that they are available for the CLI by adding the following lines to the di.xml configuration file:

    etc/di.xml

    <type name="MagentoFrameworkConsoleCommandList">
      <arguments>
        <argument name="commands" xsi:type="array">
          <item name="demoadd" xsi:type="object">GenmatoSampleConsoleCommandAddCommand</item>
          <item name="demolist" xsi:type="object">GenmatoSampleConsoleCommandListCommand</item>
          <item name="demoget" xsi:type="object">GenmatoSampleConsoleCommandGetCommand</item>
          <item name="demodelete" xsi:type="object">GenmatoSampleConsoleCommandDeleteCommand</item>
        </argument>
      </arguments>
    </type>
  6. Refresh the cache and generated data:
    bin/magento setup:upgrade
    
  7. Check whether the added commands are available by running the following command:
    bin/magento
    

How it works…

Registering new commands works by registering new items through di.xml with the MagentoFrameworkConsoleCommandList class. In the XML file, every item that we want to add is listed with a unique name and the class that is used for this command.

In the class listed, there are two methods that are used:

  • configure: In the configure method, the command is added with the following parameters:
    • setName: This is the option used for the command
    • setDesciption: This is a short description of the command, which is shown in the command listing
    • setArgument (optional): This sets arguments necessary for the command
    • setOption (optional): This sets options necessary for the command
  • execute: This is the actual method that is executed; here, the logic that you want to perform is located
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.199.181