Skip to content

The Application Package Build Status

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicense

Initialising Applications

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.
}
}

Logging within Applications

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));
}
}
}

Mocking the Application Package

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:

  1. createMockBase will create a mock for AbstractApplication.
  2. createMockCli will create a mock for AbstractCliApplication.
  3. createMockWeb will create a mock for AbstractWebApplication.
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:

  • mockWebAppendBody
  • mockWebGet
  • mockWebGetBody
  • mockWebGetHeaders
  • mockWebSet
  • mockWebSetBody
  • mockWebSetHeader

Web Application

Configuration options

The AbstractWebApplication sets following application configuration:

  • Execution datetime and timestamp

    • execution.datetime - Execution datetime
    • execution.timestamp - Execution timestamp
  • URIs

    • uri.request - The request URI
    • uri.base.full - full URI
    • uri.base.host - URI host
    • uri.base.path - URI path
    • uri.route - Extended (non-base) part of the request URI
    • uri.media.full - full media URI
    • uri.media.path - relative media URI

and uses following ones during object construction:

  • gzip to compress the output
  • site_uri to see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)
  • media_uri to get an explicitly set media URI (relative values are appended to uri.base ). If it's not set explicitly, it defaults to a media/ path of uri.base.

The setHeader method

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

Command Line Applications

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();

Colors for CLI Applications

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>');
}
}

Installation via Composer

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"

About

Joomla Framework Application Package

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

23 stars

Watchers

19 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - joomla-framework/application: Joomla Framework Application Package · GitHub
Skip to content

The Application Package Build Status

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicense

Initialising Applications

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.
}
}

Logging within Applications

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));
}
}
}

Mocking the Application Package

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:

  1. createMockBase will create a mock for AbstractApplication.
  2. createMockCli will create a mock for AbstractCliApplication.
  3. createMockWeb will create a mock for AbstractWebApplication.
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:

  • mockWebAppendBody
  • mockWebGet
  • mockWebGetBody
  • mockWebGetHeaders
  • mockWebSet
  • mockWebSetBody
  • mockWebSetHeader

Web Application

Configuration options

The AbstractWebApplication sets following application configuration:

  • Execution datetime and timestamp

    • execution.datetime - Execution datetime
    • execution.timestamp - Execution timestamp
  • URIs

    • uri.request - The request URI
    • uri.base.full - full URI
    • uri.base.host - URI host
    • uri.base.path - URI path
    • uri.route - Extended (non-base) part of the request URI
    • uri.media.full - full media URI
    • uri.media.path - relative media URI

and uses following ones during object construction:

  • gzip to compress the output
  • site_uri to see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)
  • media_uri to get an explicitly set media URI (relative values are appended to uri.base ). If it's not set explicitly, it defaults to a media/ path of uri.base.

The setHeader method

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

Command Line Applications

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();

Colors for CLI Applications

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>');
}
}

Installation via Composer

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"

About

Joomla Framework Application Package

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

23 stars

Watchers

19 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - joomla-framework/application: Joomla Framework Application Package · GitHub
Skip to content

The Application Package Build Status

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicense

Initialising Applications

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.
}
}

Logging within Applications

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));
}
}
}

Mocking the Application Package

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:

  1. createMockBase will create a mock for AbstractApplication.
  2. createMockCli will create a mock for AbstractCliApplication.
  3. createMockWeb will create a mock for AbstractWebApplication.
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:

  • mockWebAppendBody
  • mockWebGet
  • mockWebGetBody
  • mockWebGetHeaders
  • mockWebSet
  • mockWebSetBody
  • mockWebSetHeader

Web Application

Configuration options

The AbstractWebApplication sets following application configuration:

  • Execution datetime and timestamp

    • execution.datetime - Execution datetime
    • execution.timestamp - Execution timestamp
  • URIs

    • uri.request - The request URI
    • uri.base.full - full URI
    • uri.base.host - URI host
    • uri.base.path - URI path
    • uri.route - Extended (non-base) part of the request URI
    • uri.media.full - full media URI
    • uri.media.path - relative media URI

and uses following ones during object construction:

  • gzip to compress the output
  • site_uri to see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)
  • media_uri to get an explicitly set media URI (relative values are appended to uri.base ). If it's not set explicitly, it defaults to a media/ path of uri.base.

The setHeader method

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

Command Line Applications

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();

Colors for CLI Applications

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>');
}
}

Installation via Composer

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"

About

Joomla Framework Application Package

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

23 stars

Watchers

19 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - joomla-framework/application: Joomla Framework Application Package · GitHub
Skip to content

The Application Package Build Status

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicense

Initialising Applications

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.
}
}

Logging within Applications

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));
}
}
}

Mocking the Application Package

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:

  1. createMockBase will create a mock for AbstractApplication.
  2. createMockCli will create a mock for AbstractCliApplication.
  3. createMockWeb will create a mock for AbstractWebApplication.
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:

  • mockWebAppendBody
  • mockWebGet
  • mockWebGetBody
  • mockWebGetHeaders
  • mockWebSet
  • mockWebSetBody
  • mockWebSetHeader

Web Application

Configuration options

The AbstractWebApplication sets following application configuration:

  • Execution datetime and timestamp

    • execution.datetime - Execution datetime
    • execution.timestamp - Execution timestamp
  • URIs

    • uri.request - The request URI
    • uri.base.full - full URI
    • uri.base.host - URI host
    • uri.base.path - URI path
    • uri.route - Extended (non-base) part of the request URI
    • uri.media.full - full media URI
    • uri.media.path - relative media URI

and uses following ones during object construction:

  • gzip to compress the output
  • site_uri to see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)
  • media_uri to get an explicitly set media URI (relative values are appended to uri.base ). If it's not set explicitly, it defaults to a media/ path of uri.base.

The setHeader method

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

Command Line Applications

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();

Colors for CLI Applications

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>');
}
}

Installation via Composer

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"

About

Joomla Framework Application Package

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

23 stars

Watchers

19 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - joomla-framework/application: Joomla Framework Application Package · GitHub
Skip to content

The Application Package Build Status

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicense

Initialising Applications

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.
}
}

Logging within Applications

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));
}
}
}

Mocking the Application Package

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:

  1. createMockBase will create a mock for AbstractApplication.
  2. createMockCli will create a mock for AbstractCliApplication.
  3. createMockWeb will create a mock for AbstractWebApplication.
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:

  • mockWebAppendBody
  • mockWebGet
  • mockWebGetBody
  • mockWebGetHeaders
  • mockWebSet
  • mockWebSetBody
  • mockWebSetHeader

Web Application

Configuration options

The AbstractWebApplication sets following application configuration:

  • Execution datetime and timestamp

    • execution.datetime - Execution datetime
    • execution.timestamp - Execution timestamp
  • URIs

    • uri.request - The request URI
    • uri.base.full - full URI
    • uri.base.host - URI host
    • uri.base.path - URI path
    • uri.route - Extended (non-base) part of the request URI
    • uri.media.full - full media URI
    • uri.media.path - relative media URI

and uses following ones during object construction:

  • gzip to compress the output
  • site_uri to see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)
  • media_uri to get an explicitly set media URI (relative values are appended to uri.base ). If it's not set explicitly, it defaults to a media/ path of uri.base.

The setHeader method

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

Command Line Applications

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();

Colors for CLI Applications

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>');
}
}

Installation via Composer

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"

About

Joomla Framework Application Package

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

23 stars

Watchers

19 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - joomla-framework/application: Joomla Framework Application Package · GitHub
Skip to content

The Application Package Build Status

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicense

Initialising Applications

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.
}
}

Logging within Applications

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));
}
}
}

Mocking the Application Package

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:

  1. createMockBase will create a mock for AbstractApplication.
  2. createMockCli will create a mock for AbstractCliApplication.
  3. createMockWeb will create a mock for AbstractWebApplication.
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:

  • mockWebAppendBody
  • mockWebGet
  • mockWebGetBody
  • mockWebGetHeaders
  • mockWebSet
  • mockWebSetBody
  • mockWebSetHeader

Web Application

Configuration options

The AbstractWebApplication sets following application configuration:

  • Execution datetime and timestamp

    • execution.datetime - Execution datetime
    • execution.timestamp - Execution timestamp
  • URIs

    • uri.request - The request URI
    • uri.base.full - full URI
    • uri.base.host - URI host
    • uri.base.path - URI path
    • uri.route - Extended (non-base) part of the request URI
    • uri.media.full - full media URI
    • uri.media.path - relative media URI

and uses following ones during object construction:

  • gzip to compress the output
  • site_uri to see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)
  • media_uri to get an explicitly set media URI (relative values are appended to uri.base ). If it's not set explicitly, it defaults to a media/ path of uri.base.

The setHeader method

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

Command Line Applications

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();

Colors for CLI Applications

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>');
}
}

Installation via Composer

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"

About

Joomla Framework Application Package

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

23 stars

Watchers

19 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - joomla-framework/application: Joomla Framework Application Package · GitHub
Skip to content

The Application Package Build Status

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicense

Initialising Applications

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.
}
}

Logging within Applications

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));
}
}
}

Mocking the Application Package

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:

  1. createMockBase will create a mock for AbstractApplication.
  2. createMockCli will create a mock for AbstractCliApplication.
  3. createMockWeb will create a mock for AbstractWebApplication.
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:

  • mockWebAppendBody
  • mockWebGet
  • mockWebGetBody
  • mockWebGetHeaders
  • mockWebSet
  • mockWebSetBody
  • mockWebSetHeader

Web Application

Configuration options

The AbstractWebApplication sets following application configuration:

  • Execution datetime and timestamp

    • execution.datetime - Execution datetime
    • execution.timestamp - Execution timestamp
  • URIs

    • uri.request - The request URI
    • uri.base.full - full URI
    • uri.base.host - URI host
    • uri.base.path - URI path
    • uri.route - Extended (non-base) part of the request URI
    • uri.media.full - full media URI
    • uri.media.path - relative media URI

and uses following ones during object construction:

  • gzip to compress the output
  • site_uri to see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)
  • media_uri to get an explicitly set media URI (relative values are appended to uri.base ). If it's not set explicitly, it defaults to a media/ path of uri.base.

The setHeader method

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

Command Line Applications

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();

Colors for CLI Applications

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>');
}
}

Installation via Composer

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"

About

Joomla Framework Application Package

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

23 stars

Watchers

19 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - joomla-framework/application: Joomla Framework Application Package · GitHub
Skip to content

The Application Package Build Status

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicense

Initialising Applications

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.
}
}

Logging within Applications

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));
}
}
}

Mocking the Application Package

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:

  1. createMockBase will create a mock for AbstractApplication.
  2. createMockCli will create a mock for AbstractCliApplication.
  3. createMockWeb will create a mock for AbstractWebApplication.
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:

  • mockWebAppendBody
  • mockWebGet
  • mockWebGetBody
  • mockWebGetHeaders
  • mockWebSet
  • mockWebSetBody
  • mockWebSetHeader

Web Application

Configuration options

The AbstractWebApplication sets following application configuration:

  • Execution datetime and timestamp

    • execution.datetime - Execution datetime
    • execution.timestamp - Execution timestamp
  • URIs

    • uri.request - The request URI
    • uri.base.full - full URI
    • uri.base.host - URI host
    • uri.base.path - URI path
    • uri.route - Extended (non-base) part of the request URI
    • uri.media.full - full media URI
    • uri.media.path - relative media URI

and uses following ones during object construction:

  • gzip to compress the output
  • site_uri to see if an explicit base URI has been set (helpful when chaining request uri using mod_rewrite)
  • media_uri to get an explicitly set media URI (relative values are appended to uri.base ). If it's not set explicitly, it defaults to a media/ path of uri.base.

The setHeader method

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

Command Line Applications

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();

Colors for CLI Applications

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>');
}
}

Installation via Composer

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"

About

Joomla Framework Application Package

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

23 stars

Watchers

19 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages