Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Console commands

Joomla has a console program — the file cli/joomla.php. It lets you maintain the site without a browser: update it, clean the cache, create users. Your own commands are added with a plugin of the console group — handy for data imports and scheduled jobs.

Built-in commands

Commands are run from the site root folder:

php cli/joomla.php list

The list command prints all available commands with descriptions.

CommandWhat it does
cache:cleanCleans the cache
extension:listLists installed extensions
extension:install --path=/tmp/mod_hello.zipInstalls an extension from an archive
extension:discover:installInstalls extensions found by Discover
user:addCreates a user
core:updateUpdates Joomla
site:down, site:upTakes the site offline and back online

Files of your own command

Create a plugin of the console group by hand:

plugins/console/hello/
├── hello.xml
├── services/provider.php
└── src/
    ├── Command/
    │   └── CountCommand.php         the command itself
    └── Extension/
        └── Hello.php                the plugin: registers the command

The manifest and the provider are the same as for the content plugin: the console group, the name plg_console_hello, the namespace My\Plugin\Console\Hello.

The command class

// plugins/console/hello/src/Command/CountCommand.php
namespace My\Plugin\Console\Hello\Command;
 
defined('_JEXEC') or die;
 
use Joomla\Console\Command\AbstractCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
 
class CountCommand extends AbstractCommand
{
    protected static $defaultName = 'hello:count';
 
    protected function configure(): void
    {
        $this->setDescription('Shows the number of blog posts');
    }
 
    protected function doExecute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
 
        $io->success('The command works');
 
        return 0;
    }
}

$defaultName is the command name. The doExecute() method does the work and returns an exit code: 0 means success.

Registering it in the plugin

// plugins/console/hello/src/Extension/Hello.php
namespace My\Plugin\Console\Hello\Extension;
 
defined('_JEXEC') or die;
 
use Joomla\Application\ApplicationEvents;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\SubscriberInterface;
use My\Plugin\Console\Hello\Command\CountCommand;
 
final class Hello extends CMSPlugin implements SubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            ApplicationEvents::BEFORE_EXECUTE => 'registerCommands',
        ];
    }
 
    public function registerCommands(): void
    {
        $this->getApplication()->addCommand(new CountCommand());
    }
}

The BEFORE_EXECUTE event happens before any console command runs — at that moment the plugin adds its own to the application.

Running it

Install the plugin through Discover, enable it and run:

php cli/joomla.php hello:count

The terminal shows a green line [OK] The command works. The command is also visible in the list output.

Working with the database

Now the command can do real work. Replace the body of doExecute():

// plugins/console/hello/src/Command/CountCommand.php
use Joomla\CMS\Factory;
use Joomla\Database\DatabaseInterface;
 
protected function doExecute(InputInterface $input, OutputInterface $output): int
{
    $db = Factory::getContainer()->get(DatabaseInterface::class);
 
    $query = $db->getQuery(true)
        ->select('COUNT(*)')
        ->from($db->quoteName('#__hello_posts'));
 
    $total = (int) $db->setQuery($query)->loadResult();
 
    (new SymfonyStyle($input, $output))->success('Posts in the blog: ' . $total);
 
    return 0;
}

The command prints [OK] Posts in the blog: 2.

Running on a schedule

Any command can be started by the system scheduler, cron. For example, the built-in Joomla task scheduler (System → Scheduled Tasks) is more reliable when called this way instead of waiting for site visitors:

*/5 * * * * php /var/www/site/cli/joomla.php scheduler:run

The line runs pending tasks every five minutes.

Common mistake

The command is run with a different PHP version than the one the site uses: on hosting the php command in the console often points to an old version. Joomla then complains about an unsuitable version or missing modules. Check php -v and, if needed, give the full path to the right PHP executable.

Thanks for reading!

Donate to the site — we work hard for you.