Introduction to Console Commands
Magento 2 has a powerful command line framework integrated with it for performing the utility tasks such as cache cleaning, index management, module enable/disable, deployment etc. Magento Core Provides many useful commands out of the box, we can also create our own Console command for our needs.
Example Use Case: Listing themes
In this article i’ll explain the Necessary steps to create our own custom console command. So in the First Part of the Article we will create a custom console command that will list the THEMES currently deployed/installed in magento2 site. In the Next article we will create a custom command to switch the frontend theme without logging in to the admin panel.
For this example, i’ll skip the basic module creation step and proceed directly to the concept.
How the Command List Works
In Magento 2 the class that is responsible for creating new console command is Magento\Framework\Console\CommandList
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
namespace Magento\Framework\Console; /** * Class CommandList has a list of commands, which can be extended via DI configuration. */ class CommandList implements CommandListInterface { /** * @var string[] */ protected $commands; /** * Constructor * * @param array $commands */ public function __construct(array $commands = []) { $this->commands = $commands; } } |
Every Magento2 core module will instantiate the above class and register the commands.
So in order to register our own custom command we need to extend this class using di.xml.
Creating di.xml to register custom command
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Framework\Console\CommandList"> <arguments> <argument name="commands" xsi:type="array"> <item name="mydons_themeconsolecmd_command_listthemes" xsi:type="object">Mydons\ThemeConsoleCmd\Command\ListThemes</item> </argument> </arguments> </type> </config> |
The type node accepts the name of the class to be extended.
So for our use case this will be “Magento\Framework\Console\CommandList” class.
Inside the arguments node we can define our commands as argument. Each item defined
under the argument node will be passed to the constructor of the base class. Under the argument we can
define the list of items, so here the command identifier and the sub class are defined.
Creating the Custom class that defines the Custom Command
The Subclass Mydons\ThemeConsoleCmd\Command\ListThemes contains two methods configure and execute
Under the configure method the command name,description and input option are defined.
Here I have added an option to skip the “Admin Theme” from the listing.
1 2 3 4 5 6 7 8 9 10 11 12 |
protected function configure() { $this->setName("mydons:listthemes"); $this->setDescription("A custom command to retrieve the list of available themes in Magento2 admin"); $this->addOption( self::EXCLUDE_ADMINTHEME_OPTION, 'exclude-admintheme', InputOption::VALUE_NONE, 'Excludes Admin Theme from the theme listing ' ); parent::configure(); } |
Execute method will fetch the list of themes available in the magento2 database. It will also detect any new theme uploaded.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
protected function execute(InputInterface $input, OutputInterface $output) { $this->themeRegistration->register(); $output->writeln("Available Themes"); // Get the Input option from the command line $excludeAdminTheme = $input->getOption(self::EXCLUDE_ADMINTHEME_OPTION); if($excludeAdminTheme){ // Apply the Frontend Area filter $themeItems = $this->themeCollectionFactory->addAreaFilter('frontend'); } else { $themeItems = $this->themeCollectionFactory; } foreach($themeItems as $theme) { // Console output with theme details $output->writeln(print_r($theme->getData(),true)); } } |
Complete Code that handles the command exeuction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<?php namespace Mydons\ThemeConsoleCmd\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Magento\Theme\Model\Theme\Registration as ThemeRegistration; use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollectionFactory; class ListThemes extends Command { const EXCLUDE_ADMINTHEME_OPTION = 'exclude-admintheme'; protected $themeCollectionFactory; protected $themeRegistration; public function __construct( ThemeCollectionFactory $themeCollectionFactory, ThemeRegistration $themeRegistration ) { $this->themeCollectionFactory = $themeCollectionFactory; $this->themeRegistration = $themeRegistration; return parent::__construct(); } protected function configure() { $this->setName("mydons:listthemes"); $this->setDescription("A custom command to retrieve the list of available themes in Magento2 admin"); $this->addOption( self::EXCLUDE_ADMINTHEME_OPTION, 'exclude-admintheme', InputOption::VALUE_NONE, 'Excludes Admin Theme from the theme listing ' ); parent::configure(); } protected function execute(InputInterface $input, OutputInterface $output) { $this->themeRegistration->register(); $output->writeln("Available Themes"); // Get the Input option from the command line $excludeAdminTheme = $input->getOption(self::EXCLUDE_ADMINTHEME_OPTION); if($excludeAdminTheme){ // Apply the Frontend Area filter $themeItems = $this->themeCollectionFactory->addAreaFilter('frontend'); } else { $themeItems = $this->themeCollectionFactory; } foreach($themeItems as $theme) { // Console output with theme details $output->writeln(print_r($theme->getData(),true)); } } } |
Once the module is installed and enabled, we can see the custom command in the command list
Listing Commands
1 |
php bin/magento |
Command Help
1 |
php bin/magento help mydons:listthemes |
Command in action
1 |
php bin/magento mydons:listthemes --exclude-admintheme |