Using and extending the Magento 2 command line
In the days of Magento 1, using the command line was optional. Actually, it was not even possible to do much without the n98-magerun package.
While this was a good thing for smaller shops, doing daily operations via the web interface, with no automation capabilities and small memory limits, was not feasable.
In Magento 2, the command line is a first class citizen and, even more than that, basic knowledge is required to administer the site as some operations, like compiling and reindexing, can only be done via command line. In the guide below, I am listing the most common tasks one can do via CLI.
The basics
To use the Magento command line, you have to SSH into the server, go to your Magento's root directory, and run:
php bin/magento
The above will list all available commands:
Usage:
command [options] [arguments]
Options:
--help (-h) Display this help message
--quiet (-q) Do not output any message
--verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
--version (-V) Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
--no-interaction (-n) Do not ask any interactive question
Available commands:
help Displays help for a command
list Lists commands
admin
admin:user:create Creates an administrator
admin:user:unlock Unlock Admin Account
......
To find out more about a command, simply run it with the --help option:
php bin/magento admin:user:create --help
This will list all of the parameters for the specific command. A nice surprise is that you will get suggestions for typos and are also able to use short codes.
Deployments
Magento 2 comes with more deployment modes — developer, default, and production. The first thing you want to do in production is to turn on the production mode:
php bin/magento deploy:mode:set production
When pulling new code, you need to run a few commands...
First, start maintenance to make sure the site is not used while you deploy:
php bin/magento maintenance:enable
Then, if you added new modules, you will need to upgrade the database:
php bin/magento setup:upgrade
Compile the files:
php bin/magento setup:di:compile
Compile static assets:
php bin/magento setup:static-content:deploy -j1
And finally disable maintenance:
php bin/magento maintenance:enable
Of course, you can put them all in one line (which probably should go in a deploy script):
php bin/magento maintenance:enable && php bin/magento setup:upgrade && php bin/magento setup:di:compile && php bin/magento cache:clean && php bin/magento setup:static-content:deploy -j1 && php bin/magento maintenance:disable
Getting information
A list with all modules can be obtained with:
php bin/magento module:status
Then you can enable a module with:
php bin/magento module:enable Foo_Bar
See if indexers are up to date:
php bin/magento indexer:status
Administrative tasks
Cleaning the cache is way easier with CLI:
php bin/magento cache:clean
So is reindexing (which cannot be done via the web UI anymore, since it can be a very long process):
php bin/magento indexer:reindex
Run the cron:
php bin/magento cron:run
Or even create an admin user:
php bin/magento admin:user:create
Short Codes
As I was mentioning earlier, you can use short codes for every command, as long as there is no confusion in parsing them. So instead of writing:
php bin/magento cache:clean
You can get away with:
php bin/magento c:c
Try using whatever is shorter and mnemonic.
Creating your own command
You can easily extend the command line with your own command. For this you will need to write a Magento module. Start by creating a new folder structure in app/code/MyCompany/MyCommand . Here, add a new file, etc/module.xml to register the module:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="MyCompany_MyCommand" setup_version="1.0.0">
</module>
</config>
The only relevenat part above is that MyCompany_MyCommand matches the folder structure of MyCompany/MyCommand (vendor/module_name). Yet another file is needed for registration, app/code/MyCompany/MyCommand/registration.php:
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'MyCompany_MyCommand',
__DIR__
);
If all went well, you should be able to see your module by running:
php bin/magento module:status
Go ahead and enable it:
php bin/magento module:enable MyCompany_MyCommand && php bin/magento setup:upgrade
As you can see, the module can only be enabled via the command line. It will not enable automatically when cleaning the cache, as was the case with Magento 1.
We now need to expose the new command. Create a new file, MyCompany/MyCommand/etc/di.xml:
<?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="hello_world" xsi:type="object">MyCompany\MyCommand\Console\Command\HelloWorldCommand</item>
</argument>
</arguments>
</type>
</config>
In here, we simply tell Magento about the new command that is to be implemented in the MyCompany\MyCommand\Console\Command\HelloWorldCommand class. The next step is to create this class, in app/code/MyCompany/MyCommand/Console/Command/HelloWorldCommand.php:
namespace MyCompany\MyCommand\Console\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
class HelloWorldCommand extends Command
{
protected function configure()
{
$this->setName('mycompany:hello_world')->setDescription('So much hello world.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Hello World!');
}
}
The structure is pretty simple. The configure method is responsible for defining the command name and the description, while the execute method will do the logic.
Once this is done, start by clearning the Magento cache:
php bin/magento cache:clean
Then you should be able to see your command in the command list:
php bin/magento
And execute it:
php bin/magento mycompany:hello_world
Conclusion
The Magento 2 CLI interface is a pretty well built feature that allows you to script common operations. It's also extensible (you can write your own commands) which makes it even better. Make sure you know the existing commands, as they will certanly help you with your day-to-day Magento administration tasks.