Working on creating my first couple of line command applications using the Joomla Application CLI was an exercise and after lots of reading and breaking things I manged to get two applications up and working so here are a few of the things I learnt along the way.
Where to put your CliApplication.
My two command line applications are part of a component I am building for a client and I really would like to save them in a /cli directory within my components admin structure, however I haven't yet managed to do that due to some limitations they possibly includes my lack of knowledge at this point in time.
Joomla expects to find all the command line applications in the /cli directory of the Joomla root folder in most examples you will find of cli applications for Joomla because to get the Joomla platform established it needs to load up /includes/defines.php so it can find the rest of the Joomla libraries. With few exceptions you see it coded like this;
require_once JPATH_BASE . '/includes/defines.php';
//or sometimes just as
JPATH_BASE is a constant set in the /index.php of all Joomla installations using the current directory of the script you are executing. The second example shown there doesn't work unless your /cli is at the same level as the /includes directory. The first option didn't work for me as my development environment uses symbolic links to keep the related code together so JPATH_BASE never got set correctly.
For a temporary solution I am using the default /cli directory but somewhere in the not too distant future I will have to work out how to get my two applications working from /administrator/componenets/com_example/cli
Tricking Joomla into thinking it is in the Admin or Site application.
When running a command line application under Joomla you don't always have or need to have all the features of Joomla available for example templates and visual aspects of the website are not needed. However looking at lots of code and people raising issues trying to get their CLI apps to work I came across this little snippet of code that is used to solve problems for people.
// Fool the system into thinking we are running as JSite.
// $_SERVER['HTTP_HOST'] = 'domain.com';
Eventually I hit a an issue and the only solution at the time was to un-comment that little bit of code and keep moving on, however I wanted to know why I need to trick Joomla into thinking anything so I had to investigate and resolve my issue without that code being required.
In my case I wanted to use a Model out of my component so I had added these two lines to my cli;
BaseDatabaseModel::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_harmony/models', 'Harmony');
$this->model = BaseDatabaseModel::getInstance('Harmony', 'HarmonyModel');
And the messages i was getting were saying I needed the Administrator template or my application would just fail with no reason.
To resolve the issue I went into the model called Harmony and copied it with a new name of HarmonyCli and proceeded to remove the methods and stuff I didn't need for my application and in particular any references to factory::getApplication() and anything dependant on the Factory class. It is those references to the other aspects of the Joomla Admin or Site applications that require you trick Joomla into thinking it is all there.
$this->model = BaseDatabaseModel::getInstance('HarmonyCli', 'HarmonyModel');
So the moral to the story is that while it might be convenient and less code to manage if you can use the existing classes from your Joomla site it can also be nice to have classes that work specifically with your command line application and not be subject to breaking because someone included an element not available to the CLI environment. Or maybe I just have to write better code.