print Migrating from 0.1.4 to 0.2.0

Migrating CLI Apps

The most difficult challenge will be migrating CLI applications or tools. The CLI system has been completely re-developed to be based on a pseudo Front Controller system. This allows for a single entry point for any command and means you no longer have to code for each parameters, switch or argument you want to support. You immediately get access to them via the cliRequest object. The downside to this, is that CLI apps have a very prescriptive design.

Now when creating a cliApplication you no longer extend the cliApplication class. Instead you use this and add your commands to the command stack. A command generally performs a single function and can re-route to additional commands upon error, completion etc. Error handling has been centralised and all commands should through the cliApplicationCommandException class which always carriers an instance of the command that triggered the error.

Other changes include revised signal handling, help system and a response system where cliApp responses can be aggregated to a single cliResponse object, or flushed as the command sees fit.

There are many built-in commands for handling common tasks and providing support to other commands, some of the more important and useful ones are:

Command ClassLocationDescription
cliCommandChain /libraries/cli/commands Used internal to hold other command objects and allow iteration over them
cliCommandNull /libraries/cli/commands A 'null' command, it has no execute body allowing it to act as a place-holder during app building, or to provide help messages
cliCommandSwitch /libraries/cli/commands Creates a 'switch' command and allows for aliases to it. Switch commands are always processed before arguments or parameters
cliCommandHelp /libraries/cli/commands Provides a help system that formats command options, names and messages into a friendly format. Also adds the -h switch.
cliCommandLog /libraries/cli/commands Adds verbose and very verbose log options as switches.
cliCommandLogToConsole /libraries/cli/commands Outputs log messages to the console as well as a log file
cliCommandConfig /libraries/cli/commands Adds support for --config to allow other config files to be loaded before commands are processed
systemCommandExtract /libraries/system/command Provides a container for aggregating extraction tools e.g. the i18n and autoload commands.
dbUpdateCommandUpdate /libraries/db/update/command Provides a CLI interface to the dbUpdate system allowing dbUpdate class files to be executed.

There are other commands including pre-built command chains for new, delete and list commands.

In cliApplication the order of the commands is important. All switches (anything starting with a single hyphen, that is one character long) are processed before any other command. Therefore, switches can occur anywhere in the arguments.

Once all the switches have been processed, the arguments are then worked on. An argument can be either a --param=value pair, or a chain such as: new dao MyObject. The cliApplication will work through the arguments IN THE ORDER THEY ARE SET and dispatch each one to the first matching command. Commands must therefore have unique signatures and should not be repeated.

A basic cliApplication can look like:

require_once(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'libraries'.DIRECTORY_SEPARATOR.'system.inc');
$oApp = new cliApplication('cliUtils', 'A simple script file that has some useful functions without the whole application framework behind it.');
$oRequest = cliRequest::getInstance()->setApplication($oApp);
$oApp->getCommandChain()
	->addCommand(new cliCommandHelp($oRequest))
	->addCommand(new cliCommandPassword($oRequest))
	->addCommand(new cliCommandSerialise($oRequest));
$oApp->getListeners()->attachListener(new cliApplicationListenerLog());
$oApp->execute($oRequest);

This is the cliUtils.php script from /tools. It allows for help, hashing passwords and serialising data. It is very simple to put together and each command can be re-used by any other cliApplication.

The final change to the cliApplication system is the addition of cliApplicationListener objects. This system allows various listeners to be attached to the application and events notified to them. Currently only a logging listener is complete, however anything can be added so long as it implements the interface.

Listeners take a cliApplicationEvent object. This records the event information and can include additional information depending on where the event was fired. Some parameters are reserved for the logging system (e.g. log.source, app.command, app.name) but anything can be registered, including additional objects, though you should code to handle if they are not present.

cliApplications can be very advanced, for an example look at the scorpio.php tool in /tools. This has many sub-commands, uses the listener system as well as command redirection.

Finally, cliDaemons use the revised system, however these are still extended into your own daemon. They now use the method execute() to needs to be overloaded with an implementation - the default is to throw an exception. Custom terminate is still supported, and now listeners can be configured to receive events from cliDaemon termination.