Console Plugin Example - Execute a file of SQL statements
Introduction
This example expands the concepts described in the Basic Helloworld Console Plugin to cover:
- plugin options
- defining an argument in the command line
- defining an option in the command line
- using the standard Joomla command line options
It describes the use of several methods of the Joomla\Console\Command\AbstractCommand
class.
Functionality
This console plugin enables a CLI utility called sql:execute-file
to run a series of SQL commands in a file, where the commands include the Joomla table prefix, as in:
CREATE TABLE IF NOT EXISTS `#__temp_table` (
`s` VARCHAR(255) NOT NULL DEFAULT '',
`i` INT NOT NULL DEFAULT 1,
PRIMARY KEY (`i`)
);
INSERT INTO `#__temp_table` (`s`, `i`) VALUES ('Hello', 22),('there', 23);
We need to pass the filename in the command line:
php cli/joomla.php sql:execute-file sqlfile.sql
We also define a command line option which will enable the actual SQL statements (with the prefix translated) to be logged to a file, and we use the Joomla-defined verbose
option to determine what output to display on the terminal.
Finally, we incorporate a plugin option which controls whether transaction control is applied to the series of commands.
For simplicity we'll just use the English language within the plugin; to see how to make your plugin multilingual look at Basic Content Plugin.
Overall Design
As in the Basic Console Plugin there are 2 main classes:
- a console plugin class which handles the aspects associated with the Joomla plugin mechanism
- a command class which contains the code for the command
Console Plugin Class
Here's the core of our plugin class:
class SqlfileConsolePlugin extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
\Joomla\Application\ApplicationEvents::BEFORE_EXECUTE => 'registerCommands',
];
}
public function registerCommands(): void
{
$myCommand = new RunSqlfileCommand();
$myCommand->setParams($this->params);
$this->getApplication()->addCommand($myCommand);
}
}
When our plugin is initiated Joomla will call getSubscribedEvents()
to find out what plugin events we want to handle. Our response tells Joomla to call our registerCommands()
function when the ApplicationEvents::BEFORE_EXECUTE
event is triggered.
Within registerCommands()
we then do 3 things
- instantiate our command class
- inject into our command class the plugin params (we'll look at this in more detail shortly)
- add our command class instance to the core Joomla console application.
Plugin Params
We define a configurable parameter for the plugin by including in the manifest file:
<config>
<fields name="params">
<fieldset name="basic">
<field
name="txn"
type="list"
label="Use Transaction Control?"
default="1" >
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
</fields>
</config>
Then when the plugin is installed we can navigate in the back end to System / Plugins, click on our Execute SQL file console command
plugin and we will be shown the option to set transaction control on or off.
Because our plugin extends Joomla\CMS\Plugin\CMSPlugin
the values of params are made available via $this->params
. We want to use the value within our command class, so we define a setter setParams()
and getter getParams()
there, and inject the parameters into the class via:
$myCommand->setParams($this->params);
Then in our command class we can get the value using:
$transactionControl = $this->getParams()->get('txn', 1);
The string 'txn' has to match the name
attribute of our field in the <config>
section in the manifest file.
Command Class
The command class extends Joomla\Console\Command\AbstractCommand
and the APIs associated with this class are listed in the API docs. We used a number of these APIs in the Basic Helloworld Console Plugin, and here we explore several more.
Defining an argument
You define in your command class's configure()
method what arguments you want your command to have . To define an argument you use eg:
$this->addArgument('sqlfile', InputArgument::REQUIRED, 'file of joomla sql commands', null);
where the parameters are:
- Argument name - you'll use this to retrieve the value of your argument
InputArgument::REQUIRED
orInputArgument::OPTIONAL
. These are defined in the classSymfony\Component\Console\Input\InputArgument
inlibraries/vendor/symfony/console/Input/InputArgument.php
.- Argument description - you'll see this displayed when you display the help text using
php cli/joomla.cli sql:execute-file -h
- Default value of argument (if it's optional)
When the command is executed then you get the value of the argument using
protected function doExecute(InputInterface $input, OutputInterface $output): int
{
$sqlfile = $input->getArgument('sqlfile');
...