The Joomla 3.x Execution Cycle
When Joomla starts up it goes through a process to boot strap itself, gathers information it needs and classes it has to have to run. After getting its house in order at some point Joomla will execute the code for modules, plugins and components. The output of these extensions are held in a buffer until the data is needed. After running these, it back fills the data into the template which is also stored in a buffer. When finally all the processing is complete and the data gathered and assembled into the template, it is then sent to the end user as a webpage. This document discusses the process that Joomla goes through each time a page is brought up.
When we go the to front end with the URL, http://www.joom.dev, the web server sees that no specific page was passed to it to return to the calling browser. Since no specific page was requested, it looks at a list of pages that it would send in the absence of a specific request. The list of pages and the order that it will send them all depends on how the web server is set up and configured. In our case, the web server will send the index.php file located in the root of our web folder. Recall, that this is the “Site” application for Joomla. So with the index.php script loaded, let’s try to get an overview of what is happening.
The code listed below the paragraphs is part of the ‘site’ applications index.php file. Hopefully, the paragraph will adequately explain what is happening.
Joomla first defines the minimum version of PHP in which it will run. Then compares this defined version against the version of PHP that is actually installed on the server. If the servers version of PHP is less than the required version, then Joomla bails out with an error indicating that the server does not meet the minimum requirements for joomla to run.
/**
* Define the application's minimum supported PHP version as a constant so it can be referenced within the application.
*/
define('JOOMLA_MINIMUM_PHP', '5.3.10');
if (version_compare(PHP_VERSION, JOOMLA_MINIMUM_PHP, '<'))
{
die('Your host needs to use PHP ' . JOOMLA_MINIMUM_PHP . ' or higher to run this version of Joomla!');
}
Next Joomla grabs the start time and memory usage. This is used in profiling the script if debugging has been turned on.
// Saves the start time and memory usage.
$startTime = microtime(1);
$startMem = memory_get_usage();
Joomla then defines the _JEXEC constant. This constant is used in every page that joomla loads and executes. This is a safety feature the prevents a script from being run outside the joomla environment.
/**
* Constant that is checked in included files to prevent direct access.
* define() is used in the installation folder rather than "const" to not error for PHP 5.2 and lower
*/
define('_JEXEC', 1);
Next Joomla looks to see if a defines.php file exists in the current directory, if it does it will load the file. Under normal circumstances your install will not contain this file. It would be used if you were interested in moving the files from your default locations to somewhere else.
if (file_exists(__DIR__ . '/defines.php'))
{
include_once __DIR__ . '/defines.php';
}
Now we get to the start of the magic. Joomla loads the defines.php file located in the includes folder. This file defines a set of constants that point to the locations of files it needs to have in order to work. For example, it sets up a constant that points to the libraries folder so that it can find the library files.
if (!defined('_JDEFINES'))
{
define('JPATH_BASE', __DIR__);
require_once JPATH_BASE . '/includes/defines.php';
}
After the defines are loaded then Joomla loads the framework.php file from the includes folder. The framework.php file registers the classes Joomla needs to run using the JLoader class. Next, framwork.php sets some error handling, then checks to see if a configuration file exists. If it does not it will launch the installation application. In the event that the installation program does not exist, Joomla will throw an error and stop running. Framwork.php will then set the php error level reporting to what has been saved in the configuration file.
require_once JPATH_BASE . '/includes/framework.php';
If debug has been turned on, Joomla will start the profiler marking the start time and memory usage, marking it ‘afterload’.
// Set profiler start time and memory usage and mark afterLoad in the profiler.
JDEBUG ? $_PROFILER->setStart($startTime, $startMem)->mark('afterLoad') : null;
With the framework loaded, the index.php file will instantiate the site application, when the application has been created then index.php will execute the site application.
// Instantiate the application.
$app = JFactory::getApplication('site');
// Execute the application.
$app->execute();
That was a quick rundown of how Joomla starts up, but it would be helpful to know more about it. So lets take a look at what happens when joomla creates a site application object.
The Site Application
Joomla creates the Site Application with a call to JFactory::getApplication('site') from the index.php file.
JFactory looks to see if the application has already been created, and if not will instantiate a new application using the JApplicationCms::getInstance($id) static method call. This application object is stored in JFactory in the event it is needed again in a later script. This is a singleton pattern and prevents multiple application objects from being created. Finally, JFactory returns the application object to the caller. In our index.php file this is assigned to a variable called $app. Just as a side note, in this case, the parameter $id being passed in the JApplicationCms::getInstance($id) would contain the value of ‘site’.
When the JApplicationCms::getInstance($id) method executes, it will create a class name composing of JApplication and concatenate to it the $id parameter passed to it. In our case it turns out to be JApplicationSite. Once the classname is determined, the method will create an instance of this class, JApplicationSite, store it and then return a copy to the caller, JFactory::getApplication('site').
When the JapplicationSite object is created, all the associated objects and properties that are needed to define what a site application is, are created and populated. This would include the Input (POST and GET variables for example), configuration, the system URI, etcetera.The code below is the getApplication() method of the JFactory class.
public static function getApplication($id = null, array $config = array(), $prefix = 'J')
{
if (!self::$application)
{
if (!$id)
{
throw new Exception('Application Instantiation Error', 500);
}
self::$application = JApplicationCms::getInstance($id);
}
return self::$application;
}
To sum up so far, the index.php file does the following
- Loads the includes and classes needed to run
-
Get’s an instance of the application, JapplicationSite
With the site application object created, the index.php file calls the execute() method of the object to finally start running the application with the line $app->execute().
Executing the Application
Recall from above that $app is a JApplicationSite object. Many of JApplicationSite methods and properties are inherited from the its parent classes above it. Rather than getting caught up in the weeds of the code with how and what gets executed, I will instead outline what is happening as the code runs.
To start, the application is initialized with the following call.
$this->initialiseApp();
Initializing the application will do the following:
- Gets the User
- Loads language strings for translation
- Sets the configuration of the API
- Gets the user’s editor
After the application is initialized a call is made to route the application with the code:
$this->route();
When the application’s route method is called, the following happens:
- Gets a copy of the JURI object (The URI broken down into individual components uri, scheme, host, port, user, pass, path, query, fragment and vars)
- Gets the JRouterSite (router class)
- Parses the URI (gets the query variables, option, Itemid, View etc) It should be noted that if a component was not supplied in the URL, that Joomla will set the component to whatever is set to the HOME link. If you have made no changes to Joomla, this will end up being the com_content component with the view set to featured.
With the routing completed, the application is dispatched with the following code.
$this->dispatch();
The dispatch method does the lions share of the work to get the application ready for the end user. When this method runs the following happens:
- Gets the component name from the parsed URL (component will be the option variable if it is set for example com_content. Otherwise it returns null)
- Gets a copy of the document
- Gets a copy of the Router
- Gets the component parameters
- Sets the metadata in the document if an html document
- Gets the template if an html document
- Sets the document title and description
- Sets the generator to Joomla
- runs the component
- Stores the output of the component to the $document component buffer
- loads and triggers system plugins
With the above completed and the main component having been run and sitting in the component buffer, the application can be rendered. It is done with the following call.
$this->render();
When the document is rendered, the following things happen:
- Gets the template
- Calls the document->parse()1 method
- Loads system plugins and executes onBeforeRender event.
- Caches the page if caching is turned on
1The parse() method looks at the template, fills in the component and runs the modules that are assigned to the positions available if they are set to show in the current menu link.
If compression has been enabled, then the application will be compressed with a call to
$this->compress();
With all the document rendering complete, Joomla can finally send the application output to the end user. This is done with the following method call.
$this->respond();
This method does the following:
- Sets the document headers
- Sends the headers
- Sends the document
What to take away from all this?
Joomla does a lot of work to send information to the end user, but having a bird’s eye view of what Joomla does to perform this will give you respect for all the work that has went into creating the platform and give you a good understanding of how your extension gets processed and rendered by Joomla. Although knowing this stuff isn’t strictly necessary to write extensions for Joomla it does help to know where your extension fits in the process of things.
END OF TUTORIAL