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 Genmato\Sample\Console\Command;
use Genmato\Sample\Api\DemoRepositoryInterface;
use Genmato\Sample\Model\Data\DemoFactory;
use Genmato\Sample\Api\Data\DemoInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
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 Genmato\Sample\Console\Command;
use Genmato\Sample\Api\DemoRepositoryInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
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 Genmato\Sample\Console\Command;
use Genmato\Sample\Api\DemoRepositoryInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
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 Genmato\Sample\Console\Command;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Genmato\Sample\Api\DemoRepositoryInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
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="Magento\Framework\Console\CommandList">
<arguments>
<argument name="commands" xsi:type="array">
<item name="demoadd" xsi:type="object">Genmato\Sample\Console\Command\AddCommand</item>
<item name="demolist" xsi:type="object">Genmato\Sample\Console\Command\ListCommand</item>
<item name="demoget" xsi:type="object">Genmato\Sample\Console\Command\GetCommand</item>
<item name="demodelete" xsi:type="object">Genmato\Sample\Console\Command\DeleteCommand</item>
</argument>
</arguments>
</type>
bin/magento setup:upgrade
bin/magento
Registering new commands works by registering new items through di.xml with the Magento\Framework\Console\CommandList 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 located