Anatomy of a Joomla! Command Cycle
Now let's look at a typical Joomla command cycle in more detail.
Important note: You do NOT need to understand all of this in order to write Joomla programs. However, this section will give you an insider's view of how Joomla works and help you better understand the various parts of the core code base. In this section we will be looking at specific blocks of code. If you are not familiar with PHP and object-oriented programming (OOP), you have some options. You could:
- read along and not worry about the specifics of the code for now. We will introduce specific PHP and OOP topics as needed in the following chapters.
- refer to Appendix B: Crash Course on PHP and OOP as you look at the code blocks to help you figure out what each line of code is doing.
- skip this section for now and come back to it once you are more familiar with PHP code.
Load the Index.php File
Let's start our session by typing in a URL that points to an article in the front page of our site – something like "http://myjoomlasite.org/index.php/my-article-name".
The first thing that happens depends on the web server (Apache or IIS), not Joomla. The web server doesn't know that we are pointing to a dynamic Joomla web site. It first tries first to find a file or folder called "my-article-name" in a folder called "index.php". Failing that, it goes up to the next segment of the URL and tries to find a file called "index.php". Since that file exists, that is the file that get executed. Since all URL's for the front end will start the same way, every front-end command cycle starts with the web server loading the "index.php" file.
If we have our site configured to use Apache's "mod_rewrite" module, we can leave out the "index.php" in the URL and it still takes us to that same file. In this case, Apache still executes the front-end "index.php" file for any URL starting with our base URL (in this case "http://myjoomlasite.org").
The same process applies to the back-end URL's, except that these point to the "index.php" file in the "adminsitrator" folder. Any URL that starts with "http://myjoomlasite.org/administrator" will execute the back-end "index.php" file, since that will be the first file it finds that it can execute.
In short, any URL we enter that begins with our home page URL will cause the web server to load the site's "index.php" file, which is the common starting point for any front-end command cycle.
Check the Execution Environment
So, now the web server has loaded our front-end "index.php" file. Let's take a look at this file. The first section of this code is shown below.
<?php /** * @version $Id: index.php 20196 2011-01-09 02:40:25Z ian $ * @package Joomla.Site * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Set flag that this is a parent file. define('_JEXEC', 1); |
Figure 18: Start of Front-end "index.php" file
The first comment section is called the "doc block". These lines are (or should be!) present in every core PHP file in Joomla. The @version is a special line that is maintained automatically by the SVN source code control program. It shows the SVN revision number that corresponds to the last change in the file. It also shows the date and the user id who committed this change.
The @package is the name of the file package. The package is normally "Joomla.Site" for front-end files and "Joomla.Administrator" for back-end files.
The @copyright and @license lines are the same for every file.
The next line, "define('_JEXEC', 1);", is very important. This line defines a constant called '_JEXEC'. Every other PHP file in the system (except for the administrator "index.php" file) contains a line at the beginning like this: 'defined('_JEXEC') or die;'. This checks that the "_JEXEC" constant is defined, which means that we entered the application from the "index.php" file.
If someone tries to run a PHP file directly, outside of the application, the '_JEXEC' constant won't be defined and the file will not be executed. If you include a PHP file in the application that does not have the "defined" line at the start, someone could enter the path to the file directly in the browser. In many cases, if you execute a Joomla PHP file outside of the CMS, you will get a PHP error (for example, because a constant or class is not defined). In the PHP error message, the full path to the PHP file will show. This is considered a security breach, since it gives a would-be attacker information about your server and folders.
If you want to see an example, remove the 'defined('_JEXEC') or die;' from the file "components/com_banners/banners.php". Then, enter this URL into your browser: "http:<your-joomla-site>/components/com_banners/banners.php". You should get an error message similar to the following:
Figure 19: Full Path Disclosure Example
Notice that in the error message it shows the full path to my Joomla installation. If we restore the "defined" line to that file and try it again, we just get a blank screen that doesn't reveal any information about our site.
Define the File Locations
The next section of the "index.php" file defines a number of constants that we need to find our way around.
define('DS', DIRECTORY_SEPARATOR); if (file_exists(dirname(__FILE__) . '/defines.php')) { include_once dirname(__FILE__) . '/defines.php'; } if (!defined('_JDEFINES')) { define('JPATH_BASE', dirname(__FILE__)); require_once JPATH_BASE.DS.'includes'.DS.'defines.php'; } |
Figure 20: Loading of "defines.php" File
First we define the "DS" constant. This is actually being phased out, since it is no longer needed. It defines the directory separator character, which is the forward slash ('/') for Linux and Mac systems and the back slash ('\') for Windows systems. However, since Windows can now work correctly with the forward slash, the "DS" constant will be removed.
The next two if code blocks give us two possible ways to define a set of constants. Joomla includes a standard file called "includes/defines.php". In the "index.php" file, the first if block looks for a "defines.php" file in the top-level folder. In a standard installation, there is no such file. So the first if block is not executed and, since the constant 'JPATH_BASE' is not yet defined, the standard "includes/defines.php" file is executed using the PHP "require_once" command.
The "includes/defines.php" file defines the following constants:
//Global definitions. //Joomla framework path definitions. $parts = explode(DS, JPATH_BASE); //Defines. define('JPATH_ROOT', implode(DS, $parts)); define('JPATH_SITE', JPATH_ROOT); define('JPATH_CONFIGURATION', JPATH_ROOT); define('JPATH_ADMINISTRATOR', JPATH_ROOT.DS.'administrator'); define('JPATH_LIBRARIES', JPATH_ROOT.DS.'libraries'); define('JPATH_PLUGINS', JPATH_ROOT.DS.'plugins' ); define('JPATH_INSTALLATION', JPATH_ROOT.DS.'installation'); define('JPATH_THEMES', JPATH_BASE.DS.'templates'); define('JPATH_CACHE', JPATH_BASE.DS.'cache'); define('JPATH_MANIFESTS', JPATH_ADMINISTRATOR.DS.'manifests'); |
Figure 21: Standard Defines.php File
Each of these constants is used to find the folder where the various types of core Joomla files can be found. If you want to override the standard "defines.php", you can simply create a file called "defines.php" at the top-level and make sure it defines the required constants. If this file is executed and defines the "JPATH_BASE" constant, then the standard "indludes/defines.php" file won't be executed.
This is our first example where Joomla gives you a simple way to override the standard setup. If you wanted to move the files to different folders in your installation, you could easily do that and just create your own custom "defines.php" file to point to the new folders.
The use of PHP constants allows us to define each of these locations once for the entire application. When we need to find these files in other parts of the application, we can refer to the constant and be confident that it will point to the correct location for our setup.