AbstractApplication implements an initialise method that is called at the end of the constructor. This method is intended to be overridden in derived classes as needed by the developer.
If you are overriding the __construct method in your application class, remember to call the parent constructor last.
useJoomla\Application\AbstractApplication;
useJoomla\Input\Input;
useJoomla\Registry\Registry;
class MyApplication extends AbstractApplication
{
/** * Customer constructor for my application class. * * @param Input $input * @param Registry $config * * @since 1.0 */publicfunction__construct(Input$input = null, Registry$config = null, Foo$foo)
{
// Do some extra assignment.$this->foo = $foo;
// Call the parent constructor last of all.parent::__construct($input, $config);
}
/** * Method to run the application routines. * * @return void * * @since 1.0 */protectedfunctiondoExecute()
{
try
{
// Do stuff.
}
catch(\Exception$e)
{
// Set status header of exception code and response body of exception message$this->setHeader('status', $e->getCode() ?: 500);
$this->setBody($e->getMessage());
}
}
/** * Custom initialisation for my application. * * @return void * * @since 1.0 */protectedfunctioninitialise()
{
// Do stuff.// Note that configuration has been loaded.
}
}AbstractApplication implements the Psr\Log\LoggerAwareInterface so is ready for integrating with an logging package that supports that standard.
The following example shows how you could set up logging in your application using initialise method from AbstractApplication.
useJoomla\Application\AbstractApplication;
useMonolog\Logger;
useMonolog\Handler\NullHandler;
useMonolog\Handler\StreamHandler;
class MyApplication extends AbstractApplication
{
/** * Custom initialisation for my application. * * Note that configuration has been loaded. * * @return void * * @since 1.0 */protectedfunctioninitialise()
{
// Get the file logging path from configuration.$logPath = $this->get('logger.path');
$log = newLogger('MyApp');
if ($logPath)
{
// If the log path is set, configure a file logger.$log->pushHandler(newStreamHandler($logPath, Logger::WARNING);
}
else
{
// If the log path is not set, just use a null logger.$log->pushHandler(newNullHandler, Logger::WARNING);
}
$this->setLogger($logger);
}
}The logger variable is private so you must use the getLogger method to access it. If a logger has not been initialised, the getLogger method will throw an exception.
To check if the logger has been set, use the hasLogger method. This will return true if the logger has been set.
Consider the following example:
useJoomla\Application\AbstractApplication;
class MyApplication extends AbstractApplication
{
protectedfunctiondoExecute()
{
// In this case, we always want the logger set.$this->getLogger()->logInfo('Performed this {task}', array('task' => $task));
// Or, in this case logging is optional, so we check if the logger is set first.if ($this->get('debug') && $this->hasLogger())
{
$this->getLogger()->logDebug('Performed {task}', array('task' => $task));
}
}
}For more complicated mocking where you need to similate real behaviour, you can use the Application\Tests\Mocker class to create robust mock objects.
There are three mocking methods available:
createMockBasewill create a mock forAbstractApplication.createMockCliwill create a mock forAbstractCliApplication.createMockWebwill create a mock forAbstractWebApplication.
useJoomla\Application\Tests\MockerasAppMocker;
class MyTest extends \PHPUnit_Framework_TestCase
{
private$instance;
protectedfunctionsetUp()
{
parent::setUp();
// Create the mock input object.$appMocker = newAppMocker($this);
$mockApp = $appMocker->createMockWeb();
// Create the test instance injecting the mock dependency.$this->instance = newMyClass($mockApp);
}
}The createMockWeb method will return a mock with the following methods mocked to roughly simulate real behaviour albeit with reduced functionality:
appendBody($content)get($name [, $default])getBody([$asArray])getHeaders()prependBody($content)set($name, $value)setBody($content)setHeader($name, $value [, $replace])
You can provide customised implementations these methods by creating the following methods in your test class respectively:
mockWebAppendBodymockWebGetmockWebGetBodymockWebGetHeadersmockWebSetmockWebSetBodymockWebSetHeader
The AbstractWebApplication sets following application configuration:
Execution datetime and timestamp
execution.datetime- Execution datetimeexecution.timestamp- Execution timestamp
URIs
uri.request- The request URIuri.base.full- full URIuri.base.host- URI hosturi.base.path- URI pathuri.route- Extended (non-base) part of the request URIuri.media.full- full media URIuri.media.path- relative media URI
and uses following ones during object construction:
gzipto compress the outputsite_urito see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)media_urito get an explicitly set media URI (relative values are appended touri.base). If it's not set explicitly, it defaults to amedia/path ofuri.base.
Accepted parameters
$name- The name of the header to set.$value- The value of the header to set.$replace- True to replace any headers with the same name.
Example: Using WebApplication::setHeader to set a status header.
$app->setHeader('status', '401 Auhtorization required', true);Will result in response containing header
Status Code: 401 Authorization required
The Joomla Framework provides an application class for making command line applications.
An example command line application skeleton:
useJoomla\Application\AbstractCliApplication;
// Bootstrap the autoloader (adjust path as appropriate to your situation).require_once__DIR__ . '/../vendor/autoload.php';
class MyCli extends AbstractCliApplication
{
protectedfunctiondoExecute()
{
// Output string$this->out('It works');
// Get user input$this->out('What is your name? ', false);
$userInput = $this->in();
$this->out('Hello ' . $userInput);
}
}
$app = newMyCli;
$app->execute();It is possible to use colors on an ANSI enabled terminal.
useJoomla\Application\AbstractCliApplication;
class MyCli extends AbstractCliApplication
{
protectedfunctiondoExecute()
{
// Green text$this->out('<info>foo</info>');
// Yellow text$this->out('<comment>foo</comment>');
// Black text on a cyan background$this->out('<question>foo</question>');
// White text on a red background$this->out('<error>foo</error>');
}
}You can also create your own styles.
useJoomla\Application\AbstractCliApplication;
useJoomla\Application\Cli\Colorstyle;
class MyCli extends AbstractCliApplication
{
/** * Override to initialise the colour styles. * * @return void * * @since 1.0 */protectedfunctioninitialise()
{
$style = newColorstyle('yellow', 'red', array('bold', 'blink'));
$this->getOutput()->addStyle('fire', $style);
}
protectedfunctiondoExecute()
{
$this->out('<fire>foo</fire>');
}
}Available foreground and background colors are: black, red, green, yellow, blue, magenta, cyan and white.
And available options are: bold, underscore, blink and reverse.
You can also set these colors and options inside the tagname:
useJoomla\Application\AbstractCliApplication;
class MyCli extends AbstractCliApplication
{
protectedfunctiondoExecute()
{
// Green text$this->out('<fg=green>foo</fg=green>');
// Black text on a cyan background$this->out('<fg=black;bg=cyan>foo</fg=black;bg=cyan>');
// Bold text on a yellow background$this->out('<bg=yellow;options=bold>foo</bg=yellow;options=bold>');
}
}Add "joomla/application": "~4.0" to the require block in your composer.json and then run composer install.
{
"require": {
"joomla/application": "~4.0"
}
}Alternatively, you can simply run the following from the command line:
composer require joomla/application "~4.0"If you want to include the test sources, use
composer require --prefer-source joomla/application "~4.0"