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.
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.
In this recipe, we will add four options to the bin/magento
CLI command with the following steps:
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>'); } } }
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>'); } } }
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>'); } } }
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); } }
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>
bin/magento setup:upgrade
bin/magento
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 commandsetDesciption
: This is a short description of the command, which is shown in the command listingsetArgument
(optional): This sets arguments necessary for the commandsetOption
(optional): This sets options necessary for the commandexecute
: This is the actual method that is executed; here, the logic that you want to perform is located18.116.15.161