<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ian</id>
	<title>Joomla! Documentation - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ian"/>
	<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/Special:Contributions/Ian"/>
	<updated>2026-06-18T00:12:45Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:Developing_a_MVC_Component/Introduction&amp;diff=71457</id>
		<title>J1.5:Developing a MVC Component/Introduction</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:Developing_a_MVC_Component/Introduction&amp;diff=71457"/>
		<updated>2012-08-15T23:58:25Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Joomla! MVC Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Chunk:Developing a Model-View-Controller (MVC) Component for Joomla!1.5 - Contents}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
A software framework is the base of an application that can be used by a developer. The framework in Joomla! 1.5 unleashes a great deal of power for them. The Joomla! code has been designed for extensibility. This tutorial will guide you through the process of developing a component using the framework.&lt;br /&gt;
&lt;br /&gt;
The scope of this project will be to develop a simple Hello World! component. In future tutorials, this simple framework will be built upon to show the full power and versatility of the MVC design pattern in Joomla!&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
You need Joomla! 1.5 for this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Introduction to Model-View-Controller ==&lt;br /&gt;
{|&lt;br /&gt;
| colspan=2|While the idea behind a component may seem extremely simple, code can quickly become very complex as additional features are added or the interface is customized.&lt;br /&gt;
|-&lt;br /&gt;
|Model-View-Controller (herein referred to as MVC) is a software design pattern that can be used to organize code in such a way that the business logic and data presentation are separate. The premise behind this approach is that if the business logic is grouped into one section, then the interface and user interaction that surrounds the data can be revised and customized without having to reprogram the business logic. MVC was originally developed to map the traditional input, processing, output roles into a logical GUI architecture.&lt;br /&gt;
|[[Image:MVC basics.png|180px|right]]&lt;br /&gt;
|-&lt;br /&gt;
| colspan=2|These three main roles are the basis for the Joomla MVC. They are described here in brief, but for a more thorough explanation, please refer to the links provided at the end of this tutorial.&lt;br /&gt;
|}&lt;br /&gt;
=== Model ===&lt;br /&gt;
The model is the part of the component that encapsulates the application&#039;s data. It will often provide routines to manage and manipulate this data in a meaningful way in addition to routines that retrieve the data from the model. In our case, the model will contain methods to add, remove and update information about the greetings in the database. It will also contain methods to retrieve the list of greetings from the database. In general, the underlying data access technique should be encapsulated in the model. In this way, if an application is to be moved from a system that utilizes a flat file to store its information to a system that uses a database, the model is the only element that needs to be changed, not the view or the controller.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
The view is the part of the component that is used to render the data from the model in a manner that is suitable for interaction. For a web-based application, the view would generally be an HTML page that is returned to the user. The view pulls data from the model (which is passed to it from the controller) and feeds the data into a template which is populated and presented to the user. The view does not cause the data to be modified in any way, it only displays data retrieved from the model.&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
The controller is responsible for responding to user actions. In the case of a web application, a user action is (generally) a page request. The controller will determine what request is being made by the user and respond appropriately by triggering the model to manipulate the data appropriately and passing the model into the view. The controller does not display the data in the model, it only triggers methods in the model which modify the data, and then pass the model into the view which displays the data.&lt;br /&gt;
&lt;br /&gt;
=== MVC connection ===&lt;br /&gt;
[[image:MVC joomla.png|frameless|right]]The simplified picture on the right depicts the basic components being used within Joomla. Besides the Model, the View and the Controller, an Entry Point has been added that is depicted as a small circle. Attached to the viewer (view) a Template has been added. With these five components you should be able to understand this tutorial about making a basic Joomla! MVC component.&lt;br /&gt;
&lt;br /&gt;
Part 1 of the tutorial only focuses on the Controller and the View (with the use of the Template); these are marked with the blue colour in the picture. Part 2 adds and Part 3 extends the model functionality for the data manipulation abstraction; marked with the green colour in the picture. &lt;br /&gt;
&lt;br /&gt;
Keep in mind that this simplified picture only applies for the site section (i.e the front-end). An identical picture is applicable for the admin section (i.e. the back-end). The administrative section is taken care of in Parts 4 through 6 of this component development tutorial. Both the site and the admin section are maintained and configured in an XML based installation file (typically termed a manifest file).&lt;br /&gt;
&lt;br /&gt;
== Joomla! MVC Implementation ==&lt;br /&gt;
In Joomla!, the MVC pattern is implemented using three classes: [http://api.joomla.org/1.5/Joomla-Framework/Application/JModel.html JModel], [http://api.joomla.org/1.5/Joomla-Framework/Application/JView.html JView] and [http://api.joomla.org/1.5/Joomla-Framework/Application/JController.html JController]. For more detailed information about these classes, please refer to the API reference documentation (WIP).&lt;br /&gt;
&lt;br /&gt;
For learning purposes and debugging, adding a run-time debugger to your Joomla! site might be a good extension especially during development of your (tutorial) component. A good example is the community project [http://extensions.joomla.org/extensions/miscellaneous/development/1509/details J!Dump] that has the advantage of being a pop-up which leaves the view output unchanged. The J!Dump system allows you to view not only your development properties but also the methods.&lt;br /&gt;
&lt;br /&gt;
== Creating a Component ==&lt;br /&gt;
For our basic component, we only require five files:&lt;br /&gt;
&lt;br /&gt;
* site/hello.php - this is the entry point to our component&lt;br /&gt;
* site/controller.php - this file contains our base controller&lt;br /&gt;
* site/views/hello/view.html.php - this file retrieves the necessary data and pushes it into the template&lt;br /&gt;
* site/views/hello/tmpl/default.php - this is the template for our output&lt;br /&gt;
* hello.xml - this is an XML (manifest) file that tells Joomla! how to install our component.&lt;br /&gt;
&lt;br /&gt;
Remember that the filename for the entry point must have the same name of the component. For example, if you call your component &amp;quot;Very Intricate Name Component&amp;quot;, at install time (see below in the hello.xml section) Joomla! will create the folder com_veryintricatenamecomponent and the entry point php file must be named veryintricatenamecomponent.php otherwise it will not work. Be aware that use of some special characters, notibly the underscore &#039;_&#039;, may have special meaning in Joomla and should be avoided in component names or files.&lt;br /&gt;
&lt;br /&gt;
The site directory here is for the parts of the component which are installed in the front end site.&lt;br /&gt;
&lt;br /&gt;
=== Naming conventions ===&lt;br /&gt;
&lt;br /&gt;
Main article: [[Naming conventions]]&lt;br /&gt;
&lt;br /&gt;
At this point it is important to say that some words are reserved for using in component or its class names, and violating some of that will produce a hard for debugging error. One of them is &amp;quot;view&amp;quot; (in any character case) for view class (subclass of JView) and controller class (subclass of JController), because view class need to have first part of name the same as controller class name, and component name (although violating of last one won&#039;t produce an error, it&#039;s just a useful convention).&lt;br /&gt;
&lt;br /&gt;
All filenames and foldernames for models, views and controllers must be lower-case in order to operate well on Unix/Linux-systems.&lt;br /&gt;
&lt;br /&gt;
=== Creating the Entry Point ===&lt;br /&gt;
{{review}}&lt;br /&gt;
Joomla! is always accessed through a single point of entry: index.php for the Site Application or administrator/index.php for the Administrator Application. The application will then load the required component, based on the value of &#039;option&#039; in the URL or in the POST data. For our component, the URL would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;index.php?option=com_hello&amp;amp;view=hello&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will load our main file, which can be seen as the single point of entry for our component: components/com_hello/hello.php.&lt;br /&gt;
&lt;br /&gt;
The code for this file is fairly typical across components. &lt;br /&gt;
 &lt;br /&gt;
site/hello.php:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    Joomla.Tutorials&lt;br /&gt;
 * @subpackage Components&lt;br /&gt;
 * components/com_hello/hello.php&lt;br /&gt;
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1&lt;br /&gt;
 * @license    GNU/GPL&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// No direct access&lt;br /&gt;
defined( &#039;_JEXEC&#039; ) or die( &#039;Restricted access&#039; );&lt;br /&gt;
&lt;br /&gt;
// Require the base controller&lt;br /&gt;
&lt;br /&gt;
require_once( JPATH_COMPONENT.DS.&#039;controller.php&#039; );&lt;br /&gt;
&lt;br /&gt;
// Require specific controller if requested&lt;br /&gt;
if($controller = JRequest::getWord(&#039;controller&#039;)) {&lt;br /&gt;
    $path = JPATH_COMPONENT.DS.&#039;controllers&#039;.DS.$controller.&#039;.php&#039;;&lt;br /&gt;
    if (file_exists($path)) {&lt;br /&gt;
        require_once $path;&lt;br /&gt;
    } else {&lt;br /&gt;
        $controller = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Create the controller&lt;br /&gt;
$classname    = &#039;HelloController&#039;.$controller;&lt;br /&gt;
$controller   = new $classname( );&lt;br /&gt;
&lt;br /&gt;
// Perform the Request task&lt;br /&gt;
$controller-&amp;gt;execute( JRequest::getWord( &#039;task&#039; ) );&lt;br /&gt;
&lt;br /&gt;
// Redirect if set by the controller&lt;br /&gt;
$controller-&amp;gt;redirect();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first statement is a security check.&lt;br /&gt;
&lt;br /&gt;
JPATH_COMPONENT is the absolute path to the current component, in our case components/com_hello. If you specifically need either the Site component or the Administrator component, you can use JPATH_COMPONENT_SITE or JPATH_COMPONENT_ADMINISTRATOR.&lt;br /&gt;
&lt;br /&gt;
DS is the directory separator of your system: either &#039;/&#039; or &#039;\&#039;. This is automatically set by the framework so the developer doesn&#039;t have to worry about developing different versions for different server OSs. The &#039;DS&#039; constant should always be used when referring to files on the local server.&lt;br /&gt;
&lt;br /&gt;
After loading the base controller, we check if a specific controller is needed. In this component, the base controller is the only controller, but we will leave this conditional check &amp;quot;in place&amp;quot; for future use.&lt;br /&gt;
&lt;br /&gt;
JRequest::getWord() finds a word variable in the URL or the POST data. So if our URL is index.php?option=com_hello&amp;amp;controller=controller_name, then we can retrieve our controller name in our component using: echo JRequest::getWord(&#039;controller&#039;);&lt;br /&gt;
&lt;br /&gt;
Now we have our base controller &#039;HelloController&#039; in com_hello/controller.php, and, if needed, additional controllers like &#039;HelloControllerController1&#039; in com_hello/controllers/controller1.php. Using this standard naming scheme will make things easy later on: &#039;{Componentname}{Controller}{Controllername}&#039;&lt;br /&gt;
&lt;br /&gt;
After the controller is created, we instruct the controller to execute the task, as defined in the URL: index.php?option=com_hello&amp;amp;task=sometask. If no task is set, the default task &#039;display&#039; will be assumed. When display is used, the &#039;view&#039; variable will decide what will be displayed. Other common tasks are save, edit, new...&lt;br /&gt;
&lt;br /&gt;
The controller might decide to redirect the page, usually after a task like &#039;save&#039; has been completed. This last statement takes care of the actual redirection.&lt;br /&gt;
&lt;br /&gt;
The main entry point (hello.php) essentially passes control to the controller, which handles performing the task that was specified in the request.&lt;br /&gt;
&lt;br /&gt;
Note that we don&#039;t use a closing php tag in this file: ?&amp;gt;. The reason for this is that we will not have any unwanted whitespace in the output code. This is default practice since Joomla! 1.5, and will be used for all php-only files.&lt;br /&gt;
&lt;br /&gt;
=== Creating the Controller ===&lt;br /&gt;
Our component only has one task - greet the world. Therefore, the controller will be very simple. No data manipulation is required. All that needs to be done is the appropriate view loaded. We will have only one method in our controller: display(). Most of the required functionality is built into the JController class, so all that we need to do is invoke the JController::display() method.&lt;br /&gt;
&lt;br /&gt;
The code for the base controller site/controller.php is:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    Joomla.Tutorials&lt;br /&gt;
 * @subpackage Components&lt;br /&gt;
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1&lt;br /&gt;
 * @license    GNU/GPL&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// No direct access&lt;br /&gt;
&lt;br /&gt;
defined( &#039;_JEXEC&#039; ) or die( &#039;Restricted access&#039; );&lt;br /&gt;
&lt;br /&gt;
jimport(&#039;joomla.application.component.controller&#039;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Hello World Component Controller&lt;br /&gt;
 *&lt;br /&gt;
 * @package    Joomla.Tutorials&lt;br /&gt;
 * @subpackage Components&lt;br /&gt;
 */&lt;br /&gt;
class HelloController extends JController&lt;br /&gt;
{&lt;br /&gt;
    /**&lt;br /&gt;
     * Method to display the view&lt;br /&gt;
     *&lt;br /&gt;
     * @access    public&lt;br /&gt;
     */&lt;br /&gt;
    function display()&lt;br /&gt;
    {&lt;br /&gt;
        parent::display();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The JController constructor will always register a display() task and unless otherwise specified (using the registerDefaultTask() method), it will set it as the default task.&lt;br /&gt;
&lt;br /&gt;
This barebones display() method isn&#039;t really even necessary since all it does is invoke the parent constructor. However, it is a good visual clue to indicate what is happening in the controller.&lt;br /&gt;
&lt;br /&gt;
The JController::display() method will determine the name of the view and layout from the request and load that view and set the layout. When you create a menu item for your component, the menu manager will allow the administrator to select the view that they would like the menu link to display and to specify the layout. A view usually refers to a view of a certain set of data (i.e. a list of cars, a list of events, a single car, a single event). A layout is a way that that view is organized.&lt;br /&gt;
&lt;br /&gt;
In our component, we will have a single view called hello, and a single layout (default).&lt;br /&gt;
&lt;br /&gt;
=== Creating the View ===&lt;br /&gt;
The task of the view is very simple: It retrieves the data to be displayed and pushes it into the template. Data is pushed into the template using the JView::assignRef method.&lt;br /&gt;
&amp;lt;small&amp;gt;(Note: The key (the first argument) passed to the assignRef method cannot be preceded by an underscore i.e. $this-&amp;gt;assignRef(&#039;_greeting&#039;,$greeting). Doing so will cause the assignRef method to return false and your variable will not be pushed into the template.)&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code for the view at site/views/hello/view.html.php:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    Joomla.Tutorials&lt;br /&gt;
 * @subpackage Components&lt;br /&gt;
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1&lt;br /&gt;
 * @license    GNU/GPL&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// no direct access&lt;br /&gt;
&lt;br /&gt;
defined( &#039;_JEXEC&#039; ) or die( &#039;Restricted access&#039; );&lt;br /&gt;
&lt;br /&gt;
jimport( &#039;joomla.application.component.view&#039;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * HTML View class for the HelloWorld Component&lt;br /&gt;
 *&lt;br /&gt;
 * @package    HelloWorld&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
class HelloViewHello extends JView&lt;br /&gt;
{&lt;br /&gt;
    function display($tpl = null)&lt;br /&gt;
    {&lt;br /&gt;
        $greeting = &amp;quot;Hello World!&amp;quot;;&lt;br /&gt;
        $this-&amp;gt;assignRef( &#039;greeting&#039;, $greeting );&lt;br /&gt;
&lt;br /&gt;
        parent::display($tpl);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Creating the Template ====&lt;br /&gt;
&lt;br /&gt;
Joomla! templates/layouts are regular PHP files that are used to layout the data from the view in a particular manner. The variables assigned by the JView::assignRef method can be accessed from the template using $this-&amp;gt;{propertyname} (see the template code below for an example).&lt;br /&gt;
&lt;br /&gt;
Our template is very simple: we only want to display the greeting that was passed in from the view - this file is:&amp;lt;br&amp;gt;site/views/hello/tmpl/default.php:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// No direct access&lt;br /&gt;
&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die(&#039;Restricted access&#039;); ?&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;&amp;lt;?php echo $this-&amp;gt;greeting; ?&amp;gt;&amp;lt;/h1&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wrapping It All Up - Creating the hello.xml File ===&lt;br /&gt;
It is possible to install a component manually by copying the files using an FTP client and modifying the database tables. It is more efficient to create a package file that will allow the Joomla! Installer to do this for you. This package file contains a variety of information:&lt;br /&gt;
&lt;br /&gt;
* basic descriptive details about your component (i.e. name), and optionally, a description, copyright and license information.&lt;br /&gt;
* a list of files that need to be copied.&lt;br /&gt;
* optionally, a PHP file that performs additional install and uninstall operations.&lt;br /&gt;
* optionally, an SQL file which contains database queries that should be executed upon install/uninstall&lt;br /&gt;
&lt;br /&gt;
The format of the XML file at hello.xml is as follows:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;install type=&amp;quot;component&amp;quot; version=&amp;quot;1.5.0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;name&amp;gt;Hello&amp;lt;/name&amp;gt;&lt;br /&gt;
 &amp;lt;!-- The following elements are optional and free of formatting constraints --&amp;gt;&lt;br /&gt;
 &amp;lt;creationDate&amp;gt;2007-02-22&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
 &amp;lt;author&amp;gt;John Doe&amp;lt;/author&amp;gt;&lt;br /&gt;
 &amp;lt;authorEmail&amp;gt;john.doe@example.org&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
 &amp;lt;authorUrl&amp;gt;http://www.example.org&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
 &amp;lt;copyright&amp;gt;Copyright Info&amp;lt;/copyright&amp;gt;&lt;br /&gt;
 &amp;lt;license&amp;gt;License Info&amp;lt;/license&amp;gt;&lt;br /&gt;
 &amp;lt;!--  The version string is recorded in the components table --&amp;gt;&lt;br /&gt;
 &amp;lt;version&amp;gt;1.01&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;!-- The description is optional and defaults to the name --&amp;gt;&lt;br /&gt;
 &amp;lt;description&amp;gt;Description of the component ...&amp;lt;/description&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!-- Site Main File Copy Section --&amp;gt;&lt;br /&gt;
 &amp;lt;!-- Note the folder attribute: This attribute describes the folder&lt;br /&gt;
      to copy FROM in the package to install therefore files copied&lt;br /&gt;
      in this section are copied from /site/ in the package --&amp;gt;&lt;br /&gt;
 &amp;lt;files folder=&amp;quot;site&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;controller.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;hello.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/hello/index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/hello/view.html.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/hello/tmpl/default.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/hello/tmpl/index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
 &amp;lt;/files&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;administration&amp;gt;&lt;br /&gt;
  &amp;lt;!-- Administration Menu Section --&amp;gt;&lt;br /&gt;
  &amp;lt;menu&amp;gt;Hello World!&amp;lt;/menu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;!-- Administration Main File Copy Section --&amp;gt;&lt;br /&gt;
  &amp;lt;files folder=&amp;quot;admin&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;filename&amp;gt;hello.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
   &amp;lt;filename&amp;gt;index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;/files&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/administration&amp;gt;&lt;br /&gt;
&amp;lt;/install&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{notice|&lt;br /&gt;
Put this xml file, also called manifest, in the root of your package (because the installer will take its path as the root path for all other files).{{1}}Don&#039;t include itself under &amp;lt;files&amp;gt;...}}&lt;br /&gt;
&lt;br /&gt;
You may have noticed the manifest source above mentioned files we have not discussed. These are the index.html files and the admin files. An index.html file is placed in each directory to prevent prying users from getting a directory listing. If there is no index.html file, some web servers will list the directory contents. This is often undesirable. These files have the simple line:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;html&amp;gt;&amp;lt;body bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will simply display a blank page.&lt;br /&gt;
&lt;br /&gt;
The hello.php file in the admin folder is the entry point for the our component&#039;s admin section. Since our component has no administrator needs (yet), this file will have the same content as the index.html files for now.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve followed along, you can visit URL index.php?option=com_hello to see your work.  To do this, zip up the main folder and install via the extensions manager.  If it still does not work, download the package at the bottom of this page and install for a working example.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
* mjaz&lt;br /&gt;
* staalanden&lt;br /&gt;
* dannystaple&lt;br /&gt;
* Stilgar&lt;br /&gt;
* presto&lt;br /&gt;
&lt;br /&gt;
== Download ==&lt;br /&gt;
The component can be downloaded at: [http://joomlacode.org/gf/download/frsrelease/8108/29433/com_hello1_01.zip com_hello1_01]&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:Component Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:Developing_a_MVC_Component/Introduction&amp;diff=71456</id>
		<title>J1.5:Developing a MVC Component/Introduction</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:Developing_a_MVC_Component/Introduction&amp;diff=71456"/>
		<updated>2012-08-15T23:55:40Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Chunk:Developing a Model-View-Controller (MVC) Component for Joomla!1.5 - Contents}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
A software framework is the base of an application that can be used by a developer. The framework in Joomla! 1.5 unleashes a great deal of power for them. The Joomla! code has been designed for extensibility. This tutorial will guide you through the process of developing a component using the framework.&lt;br /&gt;
&lt;br /&gt;
The scope of this project will be to develop a simple Hello World! component. In future tutorials, this simple framework will be built upon to show the full power and versatility of the MVC design pattern in Joomla!&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
You need Joomla! 1.5 for this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Introduction to Model-View-Controller ==&lt;br /&gt;
{|&lt;br /&gt;
| colspan=2|While the idea behind a component may seem extremely simple, code can quickly become very complex as additional features are added or the interface is customized.&lt;br /&gt;
|-&lt;br /&gt;
|Model-View-Controller (herein referred to as MVC) is a software design pattern that can be used to organize code in such a way that the business logic and data presentation are separate. The premise behind this approach is that if the business logic is grouped into one section, then the interface and user interaction that surrounds the data can be revised and customized without having to reprogram the business logic. MVC was originally developed to map the traditional input, processing, output roles into a logical GUI architecture.&lt;br /&gt;
|[[Image:MVC basics.png|180px|right]]&lt;br /&gt;
|-&lt;br /&gt;
| colspan=2|These three main roles are the basis for the Joomla MVC. They are described here in brief, but for a more thorough explanation, please refer to the links provided at the end of this tutorial.&lt;br /&gt;
|}&lt;br /&gt;
=== Model ===&lt;br /&gt;
The model is the part of the component that encapsulates the application&#039;s data. It will often provide routines to manage and manipulate this data in a meaningful way in addition to routines that retrieve the data from the model. In our case, the model will contain methods to add, remove and update information about the greetings in the database. It will also contain methods to retrieve the list of greetings from the database. In general, the underlying data access technique should be encapsulated in the model. In this way, if an application is to be moved from a system that utilizes a flat file to store its information to a system that uses a database, the model is the only element that needs to be changed, not the view or the controller.&lt;br /&gt;
&lt;br /&gt;
=== View ===&lt;br /&gt;
The view is the part of the component that is used to render the data from the model in a manner that is suitable for interaction. For a web-based application, the view would generally be an HTML page that is returned to the user. The view pulls data from the model (which is passed to it from the controller) and feeds the data into a template which is populated and presented to the user. The view does not cause the data to be modified in any way, it only displays data retrieved from the model.&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
The controller is responsible for responding to user actions. In the case of a web application, a user action is (generally) a page request. The controller will determine what request is being made by the user and respond appropriately by triggering the model to manipulate the data appropriately and passing the model into the view. The controller does not display the data in the model, it only triggers methods in the model which modify the data, and then pass the model into the view which displays the data.&lt;br /&gt;
&lt;br /&gt;
=== MVC connection ===&lt;br /&gt;
[[image:MVC joomla.png|frameless|right]]The simplified picture on the right depicts the basic components being used within Joomla. Besides the Model, the View and the Controller, an Entry Point has been added that is depicted as a small circle. Attached to the viewer (view) a Template has been added. With these five components you should be able to understand this tutorial about making a basic Joomla! MVC component.&lt;br /&gt;
&lt;br /&gt;
Part 1 of the tutorial only focuses on the Controller and the View (with the use of the Template); these are marked with the blue colour in the picture. Part 2 adds and Part 3 extends the model functionality for the data manipulation abstraction; marked with the green colour in the picture. &lt;br /&gt;
&lt;br /&gt;
Keep in mind that this simplified picture only applies for the site section (i.e the front-end). An identical picture is applicable for the admin section (i.e. the back-end). The administrative section is taken care of in Parts 4 through 6 of this component development tutorial. Both the site and the admin section are maintained and configured in an XML based installation file (typically termed a manifest file).&lt;br /&gt;
&lt;br /&gt;
== Joomla! MVC Implementation ==&lt;br /&gt;
In Joomla!, the MVC pattern is implemented using three classes: [http://api.joomla.org/Joomla-Framework/Application/JModel.html JModel], [http://api.joomla.org/Joomla-Framework/Application/JView.html JView] and [http://api.joomla.org/Joomla-Framework/Application/JController.html JController]. For more detailed information about these classes, please refer to the API reference documentation (WIP).&lt;br /&gt;
&lt;br /&gt;
For learning purposes and debugging, adding a run-time debugger to your Joomla! site might be a good extension especially during development of your (tutorial) component. A good example is the community project [http://extensions.joomla.org/extensions/miscellaneous/development/1509/details J!Dump] that has the advantage of being a pop-up which leaves the view output unchanged. The J!Dump system allows you to view not only your development properties but also the methods.&lt;br /&gt;
&lt;br /&gt;
== Creating a Component ==&lt;br /&gt;
For our basic component, we only require five files:&lt;br /&gt;
&lt;br /&gt;
* site/hello.php - this is the entry point to our component&lt;br /&gt;
* site/controller.php - this file contains our base controller&lt;br /&gt;
* site/views/hello/view.html.php - this file retrieves the necessary data and pushes it into the template&lt;br /&gt;
* site/views/hello/tmpl/default.php - this is the template for our output&lt;br /&gt;
* hello.xml - this is an XML (manifest) file that tells Joomla! how to install our component.&lt;br /&gt;
&lt;br /&gt;
Remember that the filename for the entry point must have the same name of the component. For example, if you call your component &amp;quot;Very Intricate Name Component&amp;quot;, at install time (see below in the hello.xml section) Joomla! will create the folder com_veryintricatenamecomponent and the entry point php file must be named veryintricatenamecomponent.php otherwise it will not work. Be aware that use of some special characters, notibly the underscore &#039;_&#039;, may have special meaning in Joomla and should be avoided in component names or files.&lt;br /&gt;
&lt;br /&gt;
The site directory here is for the parts of the component which are installed in the front end site.&lt;br /&gt;
&lt;br /&gt;
=== Naming conventions ===&lt;br /&gt;
&lt;br /&gt;
Main article: [[Naming conventions]]&lt;br /&gt;
&lt;br /&gt;
At this point it is important to say that some words are reserved for using in component or its class names, and violating some of that will produce a hard for debugging error. One of them is &amp;quot;view&amp;quot; (in any character case) for view class (subclass of JView) and controller class (subclass of JController), because view class need to have first part of name the same as controller class name, and component name (although violating of last one won&#039;t produce an error, it&#039;s just a useful convention).&lt;br /&gt;
&lt;br /&gt;
All filenames and foldernames for models, views and controllers must be lower-case in order to operate well on Unix/Linux-systems.&lt;br /&gt;
&lt;br /&gt;
=== Creating the Entry Point ===&lt;br /&gt;
{{review}}&lt;br /&gt;
Joomla! is always accessed through a single point of entry: index.php for the Site Application or administrator/index.php for the Administrator Application. The application will then load the required component, based on the value of &#039;option&#039; in the URL or in the POST data. For our component, the URL would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;index.php?option=com_hello&amp;amp;view=hello&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will load our main file, which can be seen as the single point of entry for our component: components/com_hello/hello.php.&lt;br /&gt;
&lt;br /&gt;
The code for this file is fairly typical across components. &lt;br /&gt;
 &lt;br /&gt;
site/hello.php:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    Joomla.Tutorials&lt;br /&gt;
 * @subpackage Components&lt;br /&gt;
 * components/com_hello/hello.php&lt;br /&gt;
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1&lt;br /&gt;
 * @license    GNU/GPL&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// No direct access&lt;br /&gt;
defined( &#039;_JEXEC&#039; ) or die( &#039;Restricted access&#039; );&lt;br /&gt;
&lt;br /&gt;
// Require the base controller&lt;br /&gt;
&lt;br /&gt;
require_once( JPATH_COMPONENT.DS.&#039;controller.php&#039; );&lt;br /&gt;
&lt;br /&gt;
// Require specific controller if requested&lt;br /&gt;
if($controller = JRequest::getWord(&#039;controller&#039;)) {&lt;br /&gt;
    $path = JPATH_COMPONENT.DS.&#039;controllers&#039;.DS.$controller.&#039;.php&#039;;&lt;br /&gt;
    if (file_exists($path)) {&lt;br /&gt;
        require_once $path;&lt;br /&gt;
    } else {&lt;br /&gt;
        $controller = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Create the controller&lt;br /&gt;
$classname    = &#039;HelloController&#039;.$controller;&lt;br /&gt;
$controller   = new $classname( );&lt;br /&gt;
&lt;br /&gt;
// Perform the Request task&lt;br /&gt;
$controller-&amp;gt;execute( JRequest::getWord( &#039;task&#039; ) );&lt;br /&gt;
&lt;br /&gt;
// Redirect if set by the controller&lt;br /&gt;
$controller-&amp;gt;redirect();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first statement is a security check.&lt;br /&gt;
&lt;br /&gt;
JPATH_COMPONENT is the absolute path to the current component, in our case components/com_hello. If you specifically need either the Site component or the Administrator component, you can use JPATH_COMPONENT_SITE or JPATH_COMPONENT_ADMINISTRATOR.&lt;br /&gt;
&lt;br /&gt;
DS is the directory separator of your system: either &#039;/&#039; or &#039;\&#039;. This is automatically set by the framework so the developer doesn&#039;t have to worry about developing different versions for different server OSs. The &#039;DS&#039; constant should always be used when referring to files on the local server.&lt;br /&gt;
&lt;br /&gt;
After loading the base controller, we check if a specific controller is needed. In this component, the base controller is the only controller, but we will leave this conditional check &amp;quot;in place&amp;quot; for future use.&lt;br /&gt;
&lt;br /&gt;
JRequest::getWord() finds a word variable in the URL or the POST data. So if our URL is index.php?option=com_hello&amp;amp;controller=controller_name, then we can retrieve our controller name in our component using: echo JRequest::getWord(&#039;controller&#039;);&lt;br /&gt;
&lt;br /&gt;
Now we have our base controller &#039;HelloController&#039; in com_hello/controller.php, and, if needed, additional controllers like &#039;HelloControllerController1&#039; in com_hello/controllers/controller1.php. Using this standard naming scheme will make things easy later on: &#039;{Componentname}{Controller}{Controllername}&#039;&lt;br /&gt;
&lt;br /&gt;
After the controller is created, we instruct the controller to execute the task, as defined in the URL: index.php?option=com_hello&amp;amp;task=sometask. If no task is set, the default task &#039;display&#039; will be assumed. When display is used, the &#039;view&#039; variable will decide what will be displayed. Other common tasks are save, edit, new...&lt;br /&gt;
&lt;br /&gt;
The controller might decide to redirect the page, usually after a task like &#039;save&#039; has been completed. This last statement takes care of the actual redirection.&lt;br /&gt;
&lt;br /&gt;
The main entry point (hello.php) essentially passes control to the controller, which handles performing the task that was specified in the request.&lt;br /&gt;
&lt;br /&gt;
Note that we don&#039;t use a closing php tag in this file: ?&amp;gt;. The reason for this is that we will not have any unwanted whitespace in the output code. This is default practice since Joomla! 1.5, and will be used for all php-only files.&lt;br /&gt;
&lt;br /&gt;
=== Creating the Controller ===&lt;br /&gt;
Our component only has one task - greet the world. Therefore, the controller will be very simple. No data manipulation is required. All that needs to be done is the appropriate view loaded. We will have only one method in our controller: display(). Most of the required functionality is built into the JController class, so all that we need to do is invoke the JController::display() method.&lt;br /&gt;
&lt;br /&gt;
The code for the base controller site/controller.php is:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    Joomla.Tutorials&lt;br /&gt;
 * @subpackage Components&lt;br /&gt;
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1&lt;br /&gt;
 * @license    GNU/GPL&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// No direct access&lt;br /&gt;
&lt;br /&gt;
defined( &#039;_JEXEC&#039; ) or die( &#039;Restricted access&#039; );&lt;br /&gt;
&lt;br /&gt;
jimport(&#039;joomla.application.component.controller&#039;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Hello World Component Controller&lt;br /&gt;
 *&lt;br /&gt;
 * @package    Joomla.Tutorials&lt;br /&gt;
 * @subpackage Components&lt;br /&gt;
 */&lt;br /&gt;
class HelloController extends JController&lt;br /&gt;
{&lt;br /&gt;
    /**&lt;br /&gt;
     * Method to display the view&lt;br /&gt;
     *&lt;br /&gt;
     * @access    public&lt;br /&gt;
     */&lt;br /&gt;
    function display()&lt;br /&gt;
    {&lt;br /&gt;
        parent::display();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The JController constructor will always register a display() task and unless otherwise specified (using the registerDefaultTask() method), it will set it as the default task.&lt;br /&gt;
&lt;br /&gt;
This barebones display() method isn&#039;t really even necessary since all it does is invoke the parent constructor. However, it is a good visual clue to indicate what is happening in the controller.&lt;br /&gt;
&lt;br /&gt;
The JController::display() method will determine the name of the view and layout from the request and load that view and set the layout. When you create a menu item for your component, the menu manager will allow the administrator to select the view that they would like the menu link to display and to specify the layout. A view usually refers to a view of a certain set of data (i.e. a list of cars, a list of events, a single car, a single event). A layout is a way that that view is organized.&lt;br /&gt;
&lt;br /&gt;
In our component, we will have a single view called hello, and a single layout (default).&lt;br /&gt;
&lt;br /&gt;
=== Creating the View ===&lt;br /&gt;
The task of the view is very simple: It retrieves the data to be displayed and pushes it into the template. Data is pushed into the template using the JView::assignRef method.&lt;br /&gt;
&amp;lt;small&amp;gt;(Note: The key (the first argument) passed to the assignRef method cannot be preceded by an underscore i.e. $this-&amp;gt;assignRef(&#039;_greeting&#039;,$greeting). Doing so will cause the assignRef method to return false and your variable will not be pushed into the template.)&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code for the view at site/views/hello/view.html.php:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    Joomla.Tutorials&lt;br /&gt;
 * @subpackage Components&lt;br /&gt;
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1&lt;br /&gt;
 * @license    GNU/GPL&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// no direct access&lt;br /&gt;
&lt;br /&gt;
defined( &#039;_JEXEC&#039; ) or die( &#039;Restricted access&#039; );&lt;br /&gt;
&lt;br /&gt;
jimport( &#039;joomla.application.component.view&#039;);&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * HTML View class for the HelloWorld Component&lt;br /&gt;
 *&lt;br /&gt;
 * @package    HelloWorld&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
class HelloViewHello extends JView&lt;br /&gt;
{&lt;br /&gt;
    function display($tpl = null)&lt;br /&gt;
    {&lt;br /&gt;
        $greeting = &amp;quot;Hello World!&amp;quot;;&lt;br /&gt;
        $this-&amp;gt;assignRef( &#039;greeting&#039;, $greeting );&lt;br /&gt;
&lt;br /&gt;
        parent::display($tpl);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Creating the Template ====&lt;br /&gt;
&lt;br /&gt;
Joomla! templates/layouts are regular PHP files that are used to layout the data from the view in a particular manner. The variables assigned by the JView::assignRef method can be accessed from the template using $this-&amp;gt;{propertyname} (see the template code below for an example).&lt;br /&gt;
&lt;br /&gt;
Our template is very simple: we only want to display the greeting that was passed in from the view - this file is:&amp;lt;br&amp;gt;site/views/hello/tmpl/default.php:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// No direct access&lt;br /&gt;
&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die(&#039;Restricted access&#039;); ?&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;&amp;lt;?php echo $this-&amp;gt;greeting; ?&amp;gt;&amp;lt;/h1&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wrapping It All Up - Creating the hello.xml File ===&lt;br /&gt;
It is possible to install a component manually by copying the files using an FTP client and modifying the database tables. It is more efficient to create a package file that will allow the Joomla! Installer to do this for you. This package file contains a variety of information:&lt;br /&gt;
&lt;br /&gt;
* basic descriptive details about your component (i.e. name), and optionally, a description, copyright and license information.&lt;br /&gt;
* a list of files that need to be copied.&lt;br /&gt;
* optionally, a PHP file that performs additional install and uninstall operations.&lt;br /&gt;
* optionally, an SQL file which contains database queries that should be executed upon install/uninstall&lt;br /&gt;
&lt;br /&gt;
The format of the XML file at hello.xml is as follows:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;install type=&amp;quot;component&amp;quot; version=&amp;quot;1.5.0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;name&amp;gt;Hello&amp;lt;/name&amp;gt;&lt;br /&gt;
 &amp;lt;!-- The following elements are optional and free of formatting constraints --&amp;gt;&lt;br /&gt;
 &amp;lt;creationDate&amp;gt;2007-02-22&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
 &amp;lt;author&amp;gt;John Doe&amp;lt;/author&amp;gt;&lt;br /&gt;
 &amp;lt;authorEmail&amp;gt;john.doe@example.org&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
 &amp;lt;authorUrl&amp;gt;http://www.example.org&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
 &amp;lt;copyright&amp;gt;Copyright Info&amp;lt;/copyright&amp;gt;&lt;br /&gt;
 &amp;lt;license&amp;gt;License Info&amp;lt;/license&amp;gt;&lt;br /&gt;
 &amp;lt;!--  The version string is recorded in the components table --&amp;gt;&lt;br /&gt;
 &amp;lt;version&amp;gt;1.01&amp;lt;/version&amp;gt;&lt;br /&gt;
 &amp;lt;!-- The description is optional and defaults to the name --&amp;gt;&lt;br /&gt;
 &amp;lt;description&amp;gt;Description of the component ...&amp;lt;/description&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!-- Site Main File Copy Section --&amp;gt;&lt;br /&gt;
 &amp;lt;!-- Note the folder attribute: This attribute describes the folder&lt;br /&gt;
      to copy FROM in the package to install therefore files copied&lt;br /&gt;
      in this section are copied from /site/ in the package --&amp;gt;&lt;br /&gt;
 &amp;lt;files folder=&amp;quot;site&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;controller.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;hello.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/hello/index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/hello/view.html.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/hello/tmpl/default.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;filename&amp;gt;views/hello/tmpl/index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
 &amp;lt;/files&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;administration&amp;gt;&lt;br /&gt;
  &amp;lt;!-- Administration Menu Section --&amp;gt;&lt;br /&gt;
  &amp;lt;menu&amp;gt;Hello World!&amp;lt;/menu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;!-- Administration Main File Copy Section --&amp;gt;&lt;br /&gt;
  &amp;lt;files folder=&amp;quot;admin&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;filename&amp;gt;hello.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
   &amp;lt;filename&amp;gt;index.html&amp;lt;/filename&amp;gt;&lt;br /&gt;
  &amp;lt;/files&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/administration&amp;gt;&lt;br /&gt;
&amp;lt;/install&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{notice|&lt;br /&gt;
Put this xml file, also called manifest, in the root of your package (because the installer will take its path as the root path for all other files).{{1}}Don&#039;t include itself under &amp;lt;files&amp;gt;...}}&lt;br /&gt;
&lt;br /&gt;
You may have noticed the manifest source above mentioned files we have not discussed. These are the index.html files and the admin files. An index.html file is placed in each directory to prevent prying users from getting a directory listing. If there is no index.html file, some web servers will list the directory contents. This is often undesirable. These files have the simple line:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;html&amp;gt;&amp;lt;body bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will simply display a blank page.&lt;br /&gt;
&lt;br /&gt;
The hello.php file in the admin folder is the entry point for the our component&#039;s admin section. Since our component has no administrator needs (yet), this file will have the same content as the index.html files for now.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve followed along, you can visit URL index.php?option=com_hello to see your work.  To do this, zip up the main folder and install via the extensions manager.  If it still does not work, download the package at the bottom of this page and install for a working example.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
* mjaz&lt;br /&gt;
* staalanden&lt;br /&gt;
* dannystaple&lt;br /&gt;
* Stilgar&lt;br /&gt;
* presto&lt;br /&gt;
&lt;br /&gt;
== Download ==&lt;br /&gt;
The component can be downloaded at: [http://joomlacode.org/gf/download/frsrelease/8108/29433/com_hello1_01.zip com_hello1_01]&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:Component Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Accessing_the_database_using_JDatabase&amp;diff=68469</id>
		<title>Accessing the database using JDatabase</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Accessing_the_database_using_JDatabase&amp;diff=68469"/>
		<updated>2012-07-20T14:53:41Z</updated>

		<summary type="html">&lt;p&gt;Ian: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Joomla provides a sophisticated database abstraction layer to simplify the usage for third party developers. This guide will help you use this layer.&lt;br /&gt;
&lt;br /&gt;
==Why should I use the Joomla database class?==&lt;br /&gt;
Joomla can use different kinds of SQL database systems and run in a variety of environments with different table-prefixes. In addition to these functions, the class automatically creates the database connection. Besides instantiating the object you need just two lines of code to get a result from the database in a variety of formats. Using the Joomla database layer ensures a maximum of compatibility and flexibility for your extension.&lt;br /&gt;
&lt;br /&gt;
==Preparing the query==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Get a database object&lt;br /&gt;
$db = JFactory::getDBO();&lt;br /&gt;
&lt;br /&gt;
$query = &amp;quot;SELECT * FROM #__example_table WHERE id = 999999;&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First we instantiate the database object; then we prepare the query. You can use the normal SQL syntax. The only thing you have to change is the table prefix. To make this as flexible as possible, Joomla uses a placeholder for the prefix, the &amp;amp;ldquo;#__&amp;amp;rdquo;. In the next step, the $db-&amp;gt;setQuery(), this string is replaced with the correct prefix.&lt;br /&gt;
&lt;br /&gt;
Now, if we don&#039;t want to get information from the database, but rather insert a row into it, we need one more function. Every string value in the SQL syntax should be quoted. For example, MySQL uses backticks &amp;amp;#096;&amp;amp;#096; for names and single quotes &amp;amp;lsquo;&amp;amp;lsquo; for values. Joomla has some functions to do this for us and to ensure code compatibility between different databases. We can pass the names to the function $db-&amp;gt;nameQuote($name) and the values to the function $db-&amp;gt;Quote($value). &lt;br /&gt;
&lt;br /&gt;
A fully quoted query example is:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT * &lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__example_table&#039;).&amp;quot;  &lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;id&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote(&#039;999999&#039;).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whatever we want to do, we have to set the query with the $db-&amp;gt;setQuery() function. Although you could write the query directly as a parameter for $db-&amp;gt;setQuery(), it&#039;s commonly done by first saving it in a variable, normally $query, and then handing this variable over. This results in clean, readable code.&lt;br /&gt;
&lt;br /&gt;
==== setQuery($query) ====&lt;br /&gt;
The &#039;&#039;setQuery($query)&#039;&#039; method sets up a database query for later execution either by the query() method or one of the Load result methods.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$db = JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;/* some valid sql string */&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
The parameter $query must be a valid SQL string. It can either be added as a string parameter or as a variable. Generally a variable is preferred; it leads to more legible code and can help in debugging.&lt;br /&gt;
&lt;br /&gt;
setQuery() also takes three other parameters: $offset, $limit (both used in list pagination) and $prefix, an alternative table prefix. All three variables have default values set and can usually be ignored.&lt;br /&gt;
&lt;br /&gt;
==Executing the Query==&lt;br /&gt;
To execute the query, Joomla provides several functions, which differ in their return value.&lt;br /&gt;
&lt;br /&gt;
=== Basic Query Execution ===&lt;br /&gt;
==== query() ====&lt;br /&gt;
The &#039;&#039;query()&#039;&#039; method is the basic tool for executing SQL queries on a database. In Joomla it is most often used for updating or administering the database simply because the various load methods detailed on this page have the query step built into them.&lt;br /&gt;
&lt;br /&gt;
The syntax is very straightforward:&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$db = JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;/* some valid sql string */&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;query();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $query() returns an appropriate database resource if successful, or FALSE if not.&lt;br /&gt;
&lt;br /&gt;
=== Query Execution Information ===&lt;br /&gt;
* getAffectedRows()&lt;br /&gt;
* explain()&lt;br /&gt;
&lt;br /&gt;
==== insertid() ====&lt;br /&gt;
If you insert a record into a table that contains an AUTO_INCREMENT column, you can obtain the value stored into that column by calling the insertid() function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query = &amp;quot;INSERT INTO &#039;#__example_table&#039; (&#039;name&#039;,&#039;email&#039;,&#039;username&#039;)&lt;br /&gt;
        VALUES (&#039;John Smith&#039;,&#039;johnsmith@domain.example&#039;,&#039;johnsmith&#039;)&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$db-&amp;gt;query();&lt;br /&gt;
$user_id = $db-&amp;gt;insertid();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Query Execution ===&lt;br /&gt;
* insertObject()&lt;br /&gt;
&lt;br /&gt;
==Query Results ==&lt;br /&gt;
The database class contains many methods for working with a query&#039;s result set.&lt;br /&gt;
&lt;br /&gt;
=== Single Value Result ===&lt;br /&gt;
==== loadResult() ====&lt;br /&gt;
Use &#039;&#039;&#039;loadResult()&#039;&#039;&#039; when you expect just a single value back from your database query. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- &lt;br /&gt;
| 1 || style=&amp;quot;background:yellow&amp;quot; | John Smith || johnsmith@domain.example || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Magda Hellman || magda_h@domain.example || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@domain.example || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is often the result of a &#039;count&#039; query to get a number of records:&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$db = JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT COUNT(*)&lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__my_table&#039;).&amp;quot;&lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;name&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote($value).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$count = $db-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or where you are just looking for a single field from a single row of the table (or possibly a single field from the first row returned).&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$db = JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT &amp;quot;.$db-&amp;gt;nameQuote(&#039;field_name&#039;).&amp;quot;&lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__my_table&#039;).&amp;quot;&lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;some_name&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote($some_value).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Single Row Results ===&lt;br /&gt;
Each of these results functions will return a single record from the database even though there may be several records that meet the criteria that you have set. To get more records you need to call the function again.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 1 || John Smith || johnsmith@domain.example || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Magda Hellman || magda_h@domain.example || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@domain.example || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadRow() ====&lt;br /&gt;
loadRow() returns an indexed array from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadRow();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; 1 [1] =&amp;gt; John Smith [2] =&amp;gt; johnsmith@domain.example [3] =&amp;gt; johnsmith ) &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful.&lt;br /&gt;
&lt;br /&gt;
==== loadAssoc() ====&lt;br /&gt;
loadAssoc() returns an associated array from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadAssoc();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@domain.example [username] =&amp;gt; johnsmith )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;name&#039;] // e.g. $row[&#039;name&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful.&lt;br /&gt;
&lt;br /&gt;
==== loadObject() ====&lt;br /&gt;
loadObject returns a PHP object from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadObject();&lt;br /&gt;
print_r($result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@domain.example [username] =&amp;gt; johnsmith )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$result-&amp;gt;index // e.g. $result-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful.&lt;br /&gt;
&lt;br /&gt;
===Single Column Results ===&lt;br /&gt;
Each of these results functions will return a single column from the database. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- &lt;br /&gt;
| 1 || style=&amp;quot;background:yellow&amp;quot; | John Smith || johnsmith@domain.example || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || style=&amp;quot;background:yellow&amp;quot; | Magda Hellman || magda_h@domain.example || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || style=&amp;quot;background:yellow&amp;quot; | Yvonne de Gaulle || ydg@domain.example || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadResultArray() ====&lt;br /&gt;
loadResultArray() returns an indexed array from a single column in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT name, email, username&lt;br /&gt;
    FROM . . . &amp;quot;;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$column= $db-&amp;gt;loadResultArray();&lt;br /&gt;
print_r($column);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; John Smith [1] =&amp;gt; Magda Hellman [2] =&amp;gt; Yvonne de Gaulle )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$column[&#039;index&#039;] // e.g. $column[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
# loadResultArray() is equivalent to loadResultArray(0).&lt;br /&gt;
&lt;br /&gt;
==== loadResultArray($index) ====&lt;br /&gt;
loadResultArray($index) returns an indexed array from a single column in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT name, email, username&lt;br /&gt;
    FROM . . . &amp;quot;;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$column= $db-&amp;gt;loadResultArray(1);&lt;br /&gt;
print_r($column);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; johnsmith@domain.example [1] =&amp;gt; magda_h@domain.example [2] =&amp;gt; ydg@domain.example )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$column[&#039;index&#039;] // e.g. $column[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
loadResultArray($index) allows you to iterate through a series of columns in the results&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
for ( $i = 0; $i &amp;lt;= 2; $i++ ) {&lt;br /&gt;
  $column= $db-&amp;gt;loadResultArray($i);&lt;br /&gt;
  print_r($column);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; John Smith [1] =&amp;gt; Magda Hellman [2] =&amp;gt; Yvonne de Gaulle )&lt;br /&gt;
Array ( [0] =&amp;gt; johnsmith@domain.example [1] =&amp;gt; magda_h@domain.example [2] =&amp;gt; ydg@domain.example )&lt;br /&gt;
Array ( [0] =&amp;gt; johnsmith [1] =&amp;gt; magdah [2] =&amp;gt; ydegaulle )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
&lt;br /&gt;
=== Multi-Row Results ===&lt;br /&gt;
Each of these results functions will return multiple records from the database. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 1 || John Smith || johnsmith@domain.example || johnsmith&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 2 || Magda Hellman || magda_h@domain.example || magdah&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@domain.example || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadRowList() ====&lt;br /&gt;
loadRowList() returns an indexed array of indexed arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadRowList();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; Array ( [0] =&amp;gt; 1 [1] =&amp;gt; John Smith [2] =&amp;gt; johnsmith@domain.example [3] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; Array ( [0] =&amp;gt; 2 [1] =&amp;gt; Magda Hellman [2] =&amp;gt; magda_h@domain.example [3] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; Array ( [0] =&amp;gt; 3 [1] =&amp;gt; Yvonne de Gaulle [2] =&amp;gt; ydg@domain.example [3] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;][&#039;index&#039;] // e.g. $row[&#039;2&#039;][&#039;3&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
&lt;br /&gt;
==== loadAssocList() ====&lt;br /&gt;
loadAssocList() returns an indexed array of associated arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadAssocList();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@domain.example [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; Array ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman [email] =&amp;gt; magda_h@domain.example [username] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; Array ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle [email] =&amp;gt; ydg@domain.example [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
) &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;][&#039;column_name&#039;] // e.g. $row[&#039;2&#039;][&#039;email&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadAssocList($key) ====&lt;br /&gt;
loadAssocList(&#039;key&#039;) returns an associated array - indexed on &#039;key&#039; - of associated arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadAssocList(&#039;username&#039;);&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[johnsmith] =&amp;gt; Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@domain.example [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[magdah] =&amp;gt; Array ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman [email] =&amp;gt; magda_h@domain.example [username] =&amp;gt; magdah ) &lt;br /&gt;
[ydegaulle] =&amp;gt; Array ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle [email] =&amp;gt; ydg@domain.example [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;] // e.g. $row[&#039;johnsmith&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;][&#039;column_name&#039;] // e.g. $row[&#039;johnsmith&#039;][&#039;email&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.&lt;br /&gt;
&lt;br /&gt;
==== loadObjectList() ====&lt;br /&gt;
loadObjectList() returns an indexed array of PHP objects from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadObjectList();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith &lt;br /&gt;
    [email] =&amp;gt; johnsmith@domain.example [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; stdClass Object ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman &lt;br /&gt;
    [email] =&amp;gt; magda_h@domain.example [username] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; stdClass Object ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle &lt;br /&gt;
    [email] =&amp;gt; ydg@domain.example [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;]-&amp;gt;name // e.g. $row[&#039;2&#039;]-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadObjectList(&#039;key&#039;) ====&lt;br /&gt;
loadObjectList($key) returns an associated array - indexed on &#039;key&#039; - of objects from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadObjectList(&#039;username&#039;);&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[johnsmith] =&amp;gt; stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith &lt;br /&gt;
    [email] =&amp;gt; johnsmith@domain.example [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[magdah] =&amp;gt; stdClass Object ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman &lt;br /&gt;
    [email] =&amp;gt; magda_h@domain.example [username] =&amp;gt; magdah ) &lt;br /&gt;
[ydegaulle] =&amp;gt; stdClass Object ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle &lt;br /&gt;
    [email] =&amp;gt; ydg@domain.example [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;] // e.g. $row[&#039;johnsmith&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;]-&amp;gt;column_name // e.g. $row[&#039;johnsmith&#039;]-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous Result Set Methods ===&lt;br /&gt;
==== getNumRows() ====&lt;br /&gt;
getNumRows() will return the number of result rows found by the last query and waiting to be read. To get a result from getNumRows() you have to run it &#039;&#039;&#039;after&#039;&#039;&#039; the query and &#039;&#039;&#039;before&#039;&#039;&#039; you have retrieved any results.  &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$db-&amp;gt;query();&lt;br /&gt;
$num_rows = $db-&amp;gt;getNumRows();&lt;br /&gt;
print_r($num_rows);&lt;br /&gt;
$result = $db-&amp;gt;loadRowList();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will return &amp;lt;pre&amp;gt;3&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: if you run getNumRows() after loadRowList() - or any other retrieval method - you may get a PHP Warning:&lt;br /&gt;
&amp;lt;pre&amp;gt;Warning: mysql_num_rows(): 80 is not a valid MySQL result resource &lt;br /&gt;
in D:\xampp\htdocs\joomla1.5a\libraries\joomla\database\database\mysql.php on line 344&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tips, Tricks &amp;amp; FAQ==&lt;br /&gt;
===Subqueries===&lt;br /&gt;
Subqueries should be written as follows:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;SQL&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM #__example WHERE id IN (SELECT id FROM #__example2);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
These kinds of queries are supported since MySQL 4.1. If this method fails, you can split the query into two as demonstrated below. Please note that this will (often unnecessarily) increase the load on the database server.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = &amp;quot;SELECT id FROM #__example2&amp;quot;;&lt;br /&gt;
$database-&amp;gt;setQuery($query);&lt;br /&gt;
$query = &amp;quot;SELECT * FROM #__example WHERE id IN (&amp;quot;. implode(&amp;quot;,&amp;quot;, $database-&amp;gt;loadResultArray()) .&amp;quot;)&amp;quot;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using MySQL User-Defined Variables===&lt;br /&gt;
MySQL User-Defined Variables are created and maintained for the lifespan of a connection. In Joomla terms this is usually the lifespan of a page request. They can be used in consecutive queries, retaining their value, as long as each query is inside the same connection lifespan.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$database = JFactory::getDBO();&lt;br /&gt;
$database-&amp;gt;setQuery(&amp;quot;SET @num := 0&amp;quot;);&lt;br /&gt;
$database-&amp;gt;query();&lt;br /&gt;
$database-&amp;gt;setQuery(&amp;quot;SET @num := @num + 5&amp;quot;);&lt;br /&gt;
$database-&amp;gt;query();&lt;br /&gt;
$database-&amp;gt;setQuery(&amp;quot;SELECT @num&amp;quot;);&lt;br /&gt;
$result = $localDB-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The first query defines the MySQL User-Defined Variable, the second one increments it by 5, the third one retrieves it&#039;s value and will in this case return a value of 5.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
The fact that they retain their value can be quite useful, however there is also a little risk. If you use the same User-Defined Variable, in this case @num, in another query, make sure you reset it first. If that other query runs within the same connection lifespan, @num will have remembered its value of 5. You may expect it to start at null or 0.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
For details on working with MySQL&#039;s User-Defined Variables, please refer to the MySQL documentation at [http://dev.mysql.com/doc/ http://dev.mysql.com/doc/]&lt;br /&gt;
&lt;br /&gt;
===Developer-Friendly Tips===&lt;br /&gt;
Here is a quick way to do four developer-friendly things at once:&lt;br /&gt;
* Use a simple constant as an SQL seperator (which can probably be used in many queries).&lt;br /&gt;
* Make your SQL-in-PHP code easy to read (for yourself and possibly other developers later on).&lt;br /&gt;
* Give an error inside your (component-) content without really setting debugging on.&lt;br /&gt;
* Have a visibly nice SQL by splitting SQL groups with linebreaks in your error.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$db = JFactory::getDBO();&lt;br /&gt;
$jAp = JFactory::getApplication();&lt;br /&gt;
    //We define a linebreak constant&lt;br /&gt;
define(&#039;L&#039;, chr(10));&lt;br /&gt;
    //Here is the most magic&lt;br /&gt;
$db-&amp;gt;setQuery(&lt;br /&gt;
	&#039;SELECT * FROM #__table&#039;.L.&lt;br /&gt;
	&#039;WHERE something=&amp;quot;something else&amp;quot;)&#039;.L.&lt;br /&gt;
	&#039;ORDER BY date desc&#039;&lt;br /&gt;
); &lt;br /&gt;
$db-&amp;gt;query();&lt;br /&gt;
    //display and convert to HTML when SQL error&lt;br /&gt;
if (is_null($posts=$db-&amp;gt;loadRowList())) {$jAp-&amp;gt;enqueueMessage(nl2br($db-&amp;gt;getErrorMsg()),&#039;error&#039;); return;} &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Tutorials]][[Category:Development]][[Category:Database]]&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===See your resulting query===&lt;br /&gt;
when building an extension, if you want to see the resulting query you can use:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
echo nl2br(str_replace(&#039;#__&#039;,&#039;jos_&#039;,$query));die; //Where &#039;jos_&#039; is your database prefix &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Retrieving_request_data_using_JInput&amp;diff=68303</id>
		<title>Retrieving request data using JInput</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Retrieving_request_data_using_JInput&amp;diff=68303"/>
		<updated>2012-07-15T01:24:08Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Getting Multiple Values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{JVer|11.1}} {{JVer|1.7}}&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
To be able to use JInput as described here, you must be using Joomla 1.7.1 or above.&lt;br /&gt;
&lt;br /&gt;
==Starting JInput==&lt;br /&gt;
To use JInput you must first create the object by using this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$jinput = JFactory::getApplication()-&amp;gt;input;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting values===&lt;br /&gt;
To get a value from JInput you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filter defaults to cmd&lt;br /&gt;
&lt;br /&gt;
Available filters are:&lt;br /&gt;
&lt;br /&gt;
*INT&lt;br /&gt;
*INTEGER&lt;br /&gt;
*UINT&lt;br /&gt;
*FLOAT&lt;br /&gt;
*DOUBLE&lt;br /&gt;
*BOOL&lt;br /&gt;
*BOOLEAN&lt;br /&gt;
*WORD&lt;br /&gt;
*ALNUM&lt;br /&gt;
*CMD&lt;br /&gt;
*BASE64&lt;br /&gt;
*STRING&lt;br /&gt;
*HTML&lt;br /&gt;
*ARRAY&lt;br /&gt;
*PATH&lt;br /&gt;
*USERNAME&lt;br /&gt;
&lt;br /&gt;
===Getting Multiple Values===&lt;br /&gt;
&lt;br /&gt;
To retrieve a number of values you can use the getArray() method like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$fooarray = array();&lt;br /&gt;
$fooarray[] = &#039;var1&#039;;&lt;br /&gt;
$fooarray[] = &#039;var2&#039;;&lt;br /&gt;
$fooarray[] = &#039;var3&#039;;&lt;br /&gt;
$foovalues = $jinput-&amp;gt;getArray($fooarray);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The $foovalues will be an array that consists of the same keys as used in $fooarray.&lt;br /&gt;
&lt;br /&gt;
You can also get specify a more complex hierarchy of values to retrieve:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;gt;&lt;br /&gt;
$fooValues = $jinput-&amp;gt;getArray(array(&lt;br /&gt;
    &#039;var1&#039; =&amp;gt; &#039;int&#039;,&lt;br /&gt;
    &#039;var2&#039; =&amp;gt; &#039;float&#039;,&lt;br /&gt;
    &#039;var3&#039; =&amp;gt; &#039;word&#039;&lt;br /&gt;
));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also nest arrays to get more complicated hierarchies of values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$fooValues = $jinput-&amp;gt;getArray(array(&lt;br /&gt;
    &#039;jform&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;title&#039; =&amp;gt; &#039;string&#039;,&lt;br /&gt;
        &#039;quantity&#039; =&amp;gt; &#039;int&#039;,&lt;br /&gt;
        &#039;state&#039; =&amp;gt; &#039;int&#039;&lt;br /&gt;
    )&lt;br /&gt;
));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting Values from a Specific Super Global===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;post-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;server-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To retrieve an object you can use:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get(&#039;varname&#039;, null, null);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting values===&lt;br /&gt;
To set a value via JInput you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$jinput-&amp;gt;set(&#039;varname&#039;, $foo);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is based on an email discussion: [https://groups.google.com/d/msg/joomla-dev-framework/LbALkK1ifMo/5waSiIlb21gJ Framework List 23 July 2011]&lt;br /&gt;
&lt;br /&gt;
The idea behind JInput is to abstract out the input source to allow code to be reused in different applications and in different contexts.  What I mean by this is that you could have a controller that grabs data from an input source.  Instead of always getting it from the request (i.e. get and post variables), you get it from JInput.  So say for instance you have a MVC triad in your component that is meant to get data from the browser as a client (a typical web application).  Now suppose you want to reuse that same code but interface with it using JSON.  Instead of rewriting your triad, you just extend JInput and have it grab it data from a parsed json object and perform any translation that you need to perform.&lt;br /&gt;
&lt;br /&gt;
The plan is to have JApplication instantiate JInput in its constructor.  Then in your code you get the input object from the application and get your input from there.  It will be a public property in Japplication so that it can be swapped out of that is appropriate.&lt;br /&gt;
&lt;br /&gt;
We get the added benefit that we get rid of the static JRequest which makes a whole bunch the code a whole lot easier to test because you can inject mock inputs directly instead of trying to fudge with hackish dependencies.&lt;br /&gt;
&lt;br /&gt;
The end result will be that your code will get the input object from the application (we will probably add something to JController at some point to make it more convenient to use there as well).&lt;br /&gt;
&lt;br /&gt;
Once you have your JInput object, you use it fairly in a fairly similar manner to how JRequest is used:&lt;br /&gt;
$input-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&lt;br /&gt;
&lt;br /&gt;
Where filter is a filter that is supported by JFilterInput.  JInput::clean proxies to JFilter.  We&#039;ll have to tweak JFilter a little bit so that it is more extensible.  It defaults to cmd so that developers have to be intentional about things if they want to have more lenient filtering.&lt;br /&gt;
&lt;br /&gt;
There is also a getArray method that allows you to specify an array of key and filter pairs so that you can get a whole array of filtered input.&lt;br /&gt;
&lt;br /&gt;
If you want to get data from a specific super global array, you can do $input-&amp;gt;get-&amp;gt;get(...) or $input-&amp;gt;post-&amp;gt;get(...).&lt;br /&gt;
&lt;br /&gt;
So that&#039;s the basic idea.  Feel free to post more questions if you have any.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be adding input as a public property to JApplication in the near future.  It might be an idea if the CMS folks so chose to release a 1.7.1 that included this so developers can use it now.  Otherwise, at this point in time, it is best to still use JRequest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Retrieving File Data===&lt;br /&gt;
&lt;br /&gt;
The format that PHP returns file data in for arrays can at times be awkward, especially when dealing with arrays of files. JInputFiles provides a convenient interface for making life a little easier.&lt;br /&gt;
&lt;br /&gt;
Suppose a form like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;lt;?php echo JRoute::_(&#039;index.php?option=com_example&amp;amp;task=file.submit&#039;); ?&amp;gt;&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;jform1[test][]&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;jform1[test][]&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;submit&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, PHP would put these in an array called $_FILES that looked like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Array&lt;br /&gt;
(&lt;br /&gt;
    [jform1] =&amp;gt; Array&lt;br /&gt;
        (&lt;br /&gt;
            [name] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; youtube_icon.png&lt;br /&gt;
                            [1] =&amp;gt; Younger_Son_2.jpg&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [type] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; image/png&lt;br /&gt;
                            [1] =&amp;gt; image/jpeg&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [tmp_name] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; /tmp/phpXoIpSD&lt;br /&gt;
                            [1] =&amp;gt; /tmp/phpWDE7ye&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [error] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; 0&lt;br /&gt;
                            [1] =&amp;gt; 0&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [size] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; 34409&lt;br /&gt;
                            [1] =&amp;gt; 99529&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JInputFiles produces a result that is cleaner and easier to work with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$files = $input-&amp;gt;files-&amp;gt;get(&#039;jform1&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
$files then becomes:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Array&lt;br /&gt;
(&lt;br /&gt;
    [test] =&amp;gt; Array&lt;br /&gt;
        (&lt;br /&gt;
            [0] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [name] =&amp;gt; youtube_icon.png&lt;br /&gt;
                    [type] =&amp;gt; image/png&lt;br /&gt;
                    [tmp_name] =&amp;gt; /tmp/phpXoIpSD&lt;br /&gt;
                    [error] =&amp;gt; 0&lt;br /&gt;
                    [size] =&amp;gt; 34409&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [1] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [name] =&amp;gt; Younger_Son_2.jpg&lt;br /&gt;
                    [type] =&amp;gt; image/jpeg&lt;br /&gt;
                    [tmp_name] =&amp;gt; /tmp/phpWDE7ye&lt;br /&gt;
                    [error] =&amp;gt; 0&lt;br /&gt;
                    [size] =&amp;gt; 99529&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this way, the data from each file element is consolidated into a single array and can be indexed in a more straightforward manner.&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Retrieving_request_data_using_JInput&amp;diff=68302</id>
		<title>Retrieving request data using JInput</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Retrieving_request_data_using_JInput&amp;diff=68302"/>
		<updated>2012-07-15T01:22:40Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Setting values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{JVer|11.1}} {{JVer|1.7}}&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
To be able to use JInput as described here, you must be using Joomla 1.7.1 or above.&lt;br /&gt;
&lt;br /&gt;
==Starting JInput==&lt;br /&gt;
To use JInput you must first create the object by using this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$jinput = JFactory::getApplication()-&amp;gt;input;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting values===&lt;br /&gt;
To get a value from JInput you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filter defaults to cmd&lt;br /&gt;
&lt;br /&gt;
Available filters are:&lt;br /&gt;
&lt;br /&gt;
*INT&lt;br /&gt;
*INTEGER&lt;br /&gt;
*UINT&lt;br /&gt;
*FLOAT&lt;br /&gt;
*DOUBLE&lt;br /&gt;
*BOOL&lt;br /&gt;
*BOOLEAN&lt;br /&gt;
*WORD&lt;br /&gt;
*ALNUM&lt;br /&gt;
*CMD&lt;br /&gt;
*BASE64&lt;br /&gt;
*STRING&lt;br /&gt;
*HTML&lt;br /&gt;
*ARRAY&lt;br /&gt;
*PATH&lt;br /&gt;
*USERNAME&lt;br /&gt;
&lt;br /&gt;
===Getting Multiple Values===&lt;br /&gt;
&lt;br /&gt;
To retrieve a number of values you can use the getArray() method like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$fooarray = array();&lt;br /&gt;
$fooarray[] = &#039;var1&#039;;&lt;br /&gt;
$fooarray[] = &#039;var2&#039;;&lt;br /&gt;
$fooarray[] = &#039;var3&#039;;&lt;br /&gt;
$foovalues = $jinput-&amp;gt;getArray($fooarray);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The $foovalues will be an array that consists of the same keys as used in $fooarray.&lt;br /&gt;
&lt;br /&gt;
You can also get specify a more complex hierarchy of values to retrieve:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;gt;&lt;br /&gt;
$fooValues = $jinput-&amp;gt;getArray(&lt;br /&gt;
    &#039;var1&#039; =&amp;gt; &#039;int&#039;,&lt;br /&gt;
    &#039;var2&#039; =&amp;gt; &#039;float&#039;,&lt;br /&gt;
    &#039;var3&#039; =&amp;gt; &#039;word&#039;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also nest arrays to get more complicated hierarchies of values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$fooValues = $jinput-&amp;gt;getArray(&lt;br /&gt;
    &#039;jform&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;title&#039; =&amp;gt; &#039;string&#039;,&lt;br /&gt;
        &#039;quantity&#039; =&amp;gt; &#039;int&#039;,&lt;br /&gt;
        &#039;state&#039; =&amp;gt; &#039;int&#039;&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Getting Values from a Specific Super Global===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;post-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;server-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To retrieve an object you can use:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get(&#039;varname&#039;, null, null);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting values===&lt;br /&gt;
To set a value via JInput you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$jinput-&amp;gt;set(&#039;varname&#039;, $foo);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is based on an email discussion: [https://groups.google.com/d/msg/joomla-dev-framework/LbALkK1ifMo/5waSiIlb21gJ Framework List 23 July 2011]&lt;br /&gt;
&lt;br /&gt;
The idea behind JInput is to abstract out the input source to allow code to be reused in different applications and in different contexts.  What I mean by this is that you could have a controller that grabs data from an input source.  Instead of always getting it from the request (i.e. get and post variables), you get it from JInput.  So say for instance you have a MVC triad in your component that is meant to get data from the browser as a client (a typical web application).  Now suppose you want to reuse that same code but interface with it using JSON.  Instead of rewriting your triad, you just extend JInput and have it grab it data from a parsed json object and perform any translation that you need to perform.&lt;br /&gt;
&lt;br /&gt;
The plan is to have JApplication instantiate JInput in its constructor.  Then in your code you get the input object from the application and get your input from there.  It will be a public property in Japplication so that it can be swapped out of that is appropriate.&lt;br /&gt;
&lt;br /&gt;
We get the added benefit that we get rid of the static JRequest which makes a whole bunch the code a whole lot easier to test because you can inject mock inputs directly instead of trying to fudge with hackish dependencies.&lt;br /&gt;
&lt;br /&gt;
The end result will be that your code will get the input object from the application (we will probably add something to JController at some point to make it more convenient to use there as well).&lt;br /&gt;
&lt;br /&gt;
Once you have your JInput object, you use it fairly in a fairly similar manner to how JRequest is used:&lt;br /&gt;
$input-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&lt;br /&gt;
&lt;br /&gt;
Where filter is a filter that is supported by JFilterInput.  JInput::clean proxies to JFilter.  We&#039;ll have to tweak JFilter a little bit so that it is more extensible.  It defaults to cmd so that developers have to be intentional about things if they want to have more lenient filtering.&lt;br /&gt;
&lt;br /&gt;
There is also a getArray method that allows you to specify an array of key and filter pairs so that you can get a whole array of filtered input.&lt;br /&gt;
&lt;br /&gt;
If you want to get data from a specific super global array, you can do $input-&amp;gt;get-&amp;gt;get(...) or $input-&amp;gt;post-&amp;gt;get(...).&lt;br /&gt;
&lt;br /&gt;
So that&#039;s the basic idea.  Feel free to post more questions if you have any.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be adding input as a public property to JApplication in the near future.  It might be an idea if the CMS folks so chose to release a 1.7.1 that included this so developers can use it now.  Otherwise, at this point in time, it is best to still use JRequest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Retrieving File Data===&lt;br /&gt;
&lt;br /&gt;
The format that PHP returns file data in for arrays can at times be awkward, especially when dealing with arrays of files. JInputFiles provides a convenient interface for making life a little easier.&lt;br /&gt;
&lt;br /&gt;
Suppose a form like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;&amp;lt;?php echo JRoute::_(&#039;index.php?option=com_example&amp;amp;task=file.submit&#039;); ?&amp;gt;&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;jform1[test][]&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;jform1[test][]&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;submit&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, PHP would put these in an array called $_FILES that looked like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Array&lt;br /&gt;
(&lt;br /&gt;
    [jform1] =&amp;gt; Array&lt;br /&gt;
        (&lt;br /&gt;
            [name] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; youtube_icon.png&lt;br /&gt;
                            [1] =&amp;gt; Younger_Son_2.jpg&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [type] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; image/png&lt;br /&gt;
                            [1] =&amp;gt; image/jpeg&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [tmp_name] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; /tmp/phpXoIpSD&lt;br /&gt;
                            [1] =&amp;gt; /tmp/phpWDE7ye&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [error] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; 0&lt;br /&gt;
                            [1] =&amp;gt; 0&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [size] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [test] =&amp;gt; Array&lt;br /&gt;
                        (&lt;br /&gt;
                            [0] =&amp;gt; 34409&lt;br /&gt;
                            [1] =&amp;gt; 99529&lt;br /&gt;
                        )&lt;br /&gt;
&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JInputFiles produces a result that is cleaner and easier to work with:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$files = $input-&amp;gt;files-&amp;gt;get(&#039;jform1&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
$files then becomes:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Array&lt;br /&gt;
(&lt;br /&gt;
    [test] =&amp;gt; Array&lt;br /&gt;
        (&lt;br /&gt;
            [0] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [name] =&amp;gt; youtube_icon.png&lt;br /&gt;
                    [type] =&amp;gt; image/png&lt;br /&gt;
                    [tmp_name] =&amp;gt; /tmp/phpXoIpSD&lt;br /&gt;
                    [error] =&amp;gt; 0&lt;br /&gt;
                    [size] =&amp;gt; 34409&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
            [1] =&amp;gt; Array&lt;br /&gt;
                (&lt;br /&gt;
                    [name] =&amp;gt; Younger_Son_2.jpg&lt;br /&gt;
                    [type] =&amp;gt; image/jpeg&lt;br /&gt;
                    [tmp_name] =&amp;gt; /tmp/phpWDE7ye&lt;br /&gt;
                    [error] =&amp;gt; 0&lt;br /&gt;
                    [size] =&amp;gt; 99529&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this way, the data from each file element is consolidated into a single array and can be indexed in a more straightforward manner.&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Retrieving_request_data_using_JInput&amp;diff=68300</id>
		<title>Retrieving request data using JInput</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Retrieving_request_data_using_JInput&amp;diff=68300"/>
		<updated>2012-07-15T00:43:09Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Getting values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{JVer|11.1}} {{JVer|1.7}}&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
To be able to use JInput as described here, you must be using Joomla 1.7.1 or above.&lt;br /&gt;
&lt;br /&gt;
==Starting JInput==&lt;br /&gt;
To use JInput you must first create the object by using this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$jinput = JFactory::getApplication()-&amp;gt;input;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting values===&lt;br /&gt;
To get a value from JInput you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filter defaults to cmd&lt;br /&gt;
&lt;br /&gt;
Available filters are:&lt;br /&gt;
&lt;br /&gt;
*INT&lt;br /&gt;
*INTEGER&lt;br /&gt;
*UINT&lt;br /&gt;
*FLOAT&lt;br /&gt;
*DOUBLE&lt;br /&gt;
*BOOL&lt;br /&gt;
*BOOLEAN&lt;br /&gt;
*WORD&lt;br /&gt;
*ALNUM&lt;br /&gt;
*CMD&lt;br /&gt;
*BASE64&lt;br /&gt;
*STRING&lt;br /&gt;
*HTML&lt;br /&gt;
*ARRAY&lt;br /&gt;
*PATH&lt;br /&gt;
*USERNAME&lt;br /&gt;
&lt;br /&gt;
===Getting Multiple Values===&lt;br /&gt;
&lt;br /&gt;
To retrieve a number of values you can use the getArray() method like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$fooarray = array();&lt;br /&gt;
$fooarray[] = &#039;var1&#039;;&lt;br /&gt;
$fooarray[] = &#039;var2&#039;;&lt;br /&gt;
$fooarray[] = &#039;var3&#039;;&lt;br /&gt;
$foovalues = $jinput-&amp;gt;getArray($fooarray);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The $foovalues will be an array that consists of the same keys as used in $fooarray.&lt;br /&gt;
&lt;br /&gt;
You can also get specify a more complex hierarchy of values to retrieve:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;gt;&lt;br /&gt;
$fooValues = $jinput-&amp;gt;getArray(&lt;br /&gt;
    &#039;var1&#039; =&amp;gt; &#039;int&#039;,&lt;br /&gt;
    &#039;var2&#039; =&amp;gt; &#039;float&#039;,&lt;br /&gt;
    &#039;var3&#039; =&amp;gt; &#039;word&#039;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also nest arrays to get more complicated hierarchies of values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$fooValues = $jinput-&amp;gt;getArray(&lt;br /&gt;
    &#039;jform&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;title&#039; =&amp;gt; &#039;string&#039;,&lt;br /&gt;
        &#039;quantity&#039; =&amp;gt; &#039;int&#039;,&lt;br /&gt;
        &#039;state&#039; =&amp;gt; &#039;int&#039;&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Getting Values from a Specific Super Global===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;post-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;server-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To retrieve an object you can use:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$foo = $jinput-&amp;gt;get(&#039;varname&#039;, null, null);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting values===&lt;br /&gt;
To set a value via JInput you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$jinput-&amp;gt;set(&#039;varname&#039;, $foo);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is based on an email discussion: [https://groups.google.com/d/msg/joomla-dev-framework/LbALkK1ifMo/5waSiIlb21gJ Framework List 23 July 2011]&lt;br /&gt;
&lt;br /&gt;
The idea behind JInput is to abstract out the input source to allow code to be reused in different applications and in different contexts.  What I mean by this is that you could have a controller that grabs data from an input source.  Instead of always getting it from the request (i.e. get and post variables), you get it from JInput.  So say for instance you have a MVC triad in your component that is meant to get data from the browser as a client (a typical web application).  Now suppose you want to reuse that same code but interface with it using JSON.  Instead of rewriting your triad, you just extend JInput and have it grab it data from a parsed json object and perform any translation that you need to perform.&lt;br /&gt;
&lt;br /&gt;
The plan is to have JApplication instantiate JInput in its constructor.  Then in your code you get the input object from the application and get your input from there.  It will be a public property in Japplication so that it can be swapped out of that is appropriate.&lt;br /&gt;
&lt;br /&gt;
We get the added benefit that we get rid of the static JRequest which makes a whole bunch the code a whole lot easier to test because you can inject mock inputs directly instead of trying to fudge with hackish dependencies.&lt;br /&gt;
&lt;br /&gt;
The end result will be that your code will get the input object from the application (we will probably add something to JController at some point to make it more convenient to use there as well).&lt;br /&gt;
&lt;br /&gt;
Once you have your JInput object, you use it fairly in a fairly similar manner to how JRequest is used:&lt;br /&gt;
$input-&amp;gt;get(&#039;varname&#039;, &#039;default_value&#039;, &#039;filter&#039;);&lt;br /&gt;
&lt;br /&gt;
Where filter is a filter that is supported by JFilterInput.  JInput::clean proxies to JFilter.  We&#039;ll have to tweak JFilter a little bit so that it is more extensible.  It defaults to cmd so that developers have to be intentional about things if they want to have more lenient filtering.&lt;br /&gt;
&lt;br /&gt;
There is also a getArray method that allows you to specify an array of key and filter pairs so that you can get a whole array of filtered input.&lt;br /&gt;
&lt;br /&gt;
If you want to get data from a specific super global array, you can do $input-&amp;gt;get-&amp;gt;get(...) or $input-&amp;gt;post-&amp;gt;get(...).&lt;br /&gt;
&lt;br /&gt;
So that&#039;s the basic idea.  Feel free to post more questions if you have any.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be adding input as a public property to JApplication in the near future.  It might be an idea if the CMS folks so chose to release a 1.7.1 that included this so developers can use it now.  Otherwise, at this point in time, it is best to still use JRequest.&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Archived:Vulnerable_Extensions_List&amp;diff=37534</id>
		<title>Archived:Vulnerable Extensions List</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Archived:Vulnerable_Extensions_List&amp;diff=37534"/>
		<updated>2011-02-24T14:10:25Z</updated>

		<summary type="html">&lt;p&gt;Ian: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{RightTOC}}&lt;br /&gt;
&#039;&#039;&#039;List prior to January 2010 ([[Archived vel|now archived]])&#039;&#039;&#039; Please check here also. &lt;br /&gt;
&lt;br /&gt;
Please also check the [[Investigation of exploits|Extension Investigation List]].&lt;br /&gt;
 &lt;br /&gt;
== Check and Report.  ==&lt;br /&gt;
&#039;&#039;&#039;Please check with the extension publisher in case of any questions over the security of their product.&#039;&#039;&#039;&lt;br /&gt;
Report Vulnerable extensions either in the [[jforum:432|security forum]] or the [[jforum:470|extensions forum]] clearly marked with the first word in the title being &#039;&#039;Vulnerable&#039;&#039; where the security moderators or JSST team will respond. &lt;br /&gt;
This list is change protected,&#039;&#039;&#039; for additions or updates email&#039;&#039;&#039; &#039;&#039;vel @ joomla.org&#039;&#039; [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=28000 Mandville] or [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=87230 lafrance] are the main editors&lt;br /&gt;
*If you are seeing this page on any site other than [http://docs.joomla.org/Vulnerable_Extensions_List the Offical Joomla Documentation] you may be seeing an out of date version or experiencing [http://en.wikipedia.org/wiki/Plagiarism plagiary] and the links may not work properly&lt;br /&gt;
&lt;br /&gt;
== How to use this list ==&lt;br /&gt;
&#039;&#039;&#039;Items will be removed after a suitable period and not on resolution&#039;&#039;&#039;&lt;br /&gt;
All known vulnerable extensions are the listed in the first column. Any in &amp;lt;span style=&amp;quot;background:red; color:white&amp;quot;&amp;gt;a red box &amp;lt;/span&amp;gt;are high where we have not been given a fix for. Alert Advisory details in the centre column . &lt;br /&gt;
The link to the advisory notice. &lt;br /&gt;
Finally a link to the notice about any &amp;lt;span style=&amp;quot;background:#cef2e0; color:black&amp;quot;&amp;gt;update with link&amp;lt;/span&amp;gt; or &amp;lt;span style=&amp;quot;background:red; color:white&amp;quot;&amp;gt;&#039;&#039;&#039;Not Known&#039;&#039;&#039; &amp;lt;/span&amp;gt; where none is known.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This list is compiled from found information and may not be an up to date accurate list&#039;&#039;&#039; &#039;&#039;We do &#039;&#039;&#039;NOT&#039;&#039;&#039; promise to test or validate these reports. We do &#039;&#039;&#039;NOT&#039;&#039;&#039; guarantee the quality or effectiveness of any updates reported to us or listed here.&#039;&#039;&lt;br /&gt;
To sign up for the feed please [http://feeds.joomla.org/JoomlaSecurityVulnerableExtensions follow this link]&lt;br /&gt;
* We do not list BETA products, or extensions for J1.0.x&lt;br /&gt;
&lt;br /&gt;
== Developers - How to get yourself removed from the VEL ==&lt;br /&gt;
&lt;br /&gt;
Resolved items will be removed after a suitable period and not on resolution&lt;br /&gt;
&lt;br /&gt;
Please solve the issues and:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;If JED listed&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
To have your extension republished, please follow these steps:&lt;br /&gt;
&lt;br /&gt;
1- Solve the issues.&lt;br /&gt;
&lt;br /&gt;
2- Attach the new zip file at your actual JED listing.&lt;br /&gt;
&lt;br /&gt;
3- Change the extension version at JED listing.&lt;br /&gt;
&lt;br /&gt;
4- Make sure to include a notice in the JED description to the fact that the new release is a &amp;quot;Security Release&amp;quot; and those who use the extension should upgrade immediately.&lt;br /&gt;
&lt;br /&gt;
5- Email to the JED with a notice and ask that your listing be republished.&lt;br /&gt;
&lt;br /&gt;
6- Email the VEL team with a notice of resolution, and a link to the security release statement on your website&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
VEL email can be found above and the JED email is in your notice of &amp;quot;unpublication&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;If not JED listed.&#039;&#039;&#039; &lt;br /&gt;
Inform us by &#039;&#039;&#039;email&#039;&#039;&#039; of the link to your resolution notice on your website.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== New format Feed Starts Here ==&lt;br /&gt;
Please do not change your [http://feeds.joomla.org/JoomlaSecurityVulnerableExtensions feed url], only the feed format has changed.&lt;br /&gt;
&#039;&#039;&#039;Please check with the extension publisher in case of any questions over the security of their product.&#039;&#039;&#039;&lt;br /&gt;
Report Vulnerable extensions either in the [[jforum:432]] security topic or the [http://forum.joomla.org/viewforum.php?f=470 extensions] topic clearly marked with the first word in the title being &#039;&#039;Vulnerable&#039;&#039; where the security moderators or JSST team will respond. &lt;br /&gt;
&#039;&#039;This list is change protected, for updates or editing requests [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=28000 Mandville] or [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=87230 lafrance]&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[http://docs.joomla.org/Vulnerable_Extensions_List Back To Top]&lt;br /&gt;
&lt;br /&gt;
== February 2010 and onwards Reported Vulnerable Extensions ==&lt;br /&gt;
&amp;lt;startFeed /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please check with the extension publisher in case of any questions over the security of their product.&#039;&#039;&#039;&lt;br /&gt;
Report Vulnerable extensions either in the [[jforum:432]] security topic clearly marked with the first word in the title being &#039;&#039;Vulnerable Report&#039;&#039; where the security moderators or JSST team will respond. For a guide to the [http://docs.joomla.org/Vulnerable_Extensions_List_0210#Codes_used codes]&lt;br /&gt;
&lt;br /&gt;
[http://docs.joomla.org/Vulnerable_Extensions_List Previous Reports]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  &#039;&#039;&#039;Extension&#039;&#039;&#039;&lt;br /&gt;
! class=&amp;quot;unsortable&amp;quot;| &#039;&#039;&#039;Details&#039;&#039;&#039;&lt;br /&gt;
!  &#039;&#039;&#039;Date Added&#039;&#039;&#039;&lt;br /&gt;
! class=&amp;quot;unsortable&amp;quot; |&#039;&#039;&#039;Extension Update Link &amp;amp; Date&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== smartformer    ==&lt;br /&gt;
|RFI&lt;br /&gt;
|230211 (repeat of 041110)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== xmap 1.2.10    ==&lt;br /&gt;
|Malicious payload in zip&lt;br /&gt;
|230211&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==   Frontend-User-Access 3.4.1  ==&lt;br /&gt;
|Frontend-User-Access 3.4.1 from http://www.pages-and-items.com LFI&lt;br /&gt;
|030211&lt;br /&gt;
|update to [http://extensions.joomla.org/extensions/access-a-security/frontend-access-control/6874 Frontend-User-Access 3.4.2]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
==  com properties 7134   ==&lt;br /&gt;
| http://com-property.com/ malicious files in script&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  B2 Portfolio ==&lt;br /&gt;
|B2 portfolio 1.0 SQLi pulseextensions.com&lt;br /&gt;
|250111&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  allcinevid   ==&lt;br /&gt;
|SQLI http://extensions.joomla.org/extensions/multimedia/multimedia-players/video-players-a-gallery/15367&lt;br /&gt;
|220111&lt;br /&gt;
|[http://www.joomtraders.com/our-blog/allcinevid-1.0-sql-injection.html Developers resolution notice]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== People Component    ==&lt;br /&gt;
|People component http://www.ptt-solution.com/vmchk/people-component.html sqli&lt;br /&gt;
|150111&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==   J!Dump v1.1.2  ==&lt;br /&gt;
| LFI in J!Dump v1.1.2 and before&lt;br /&gt;
|060111&lt;br /&gt;
|The extension is fixed in &lt;br /&gt;
[http://joomlacode.org/gf/project/jdump/frs  version 1.1.3]  070111&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==   xmovie 1.0  ==&lt;br /&gt;
|xmovie 1.0 LFi&lt;br /&gt;
|010111&lt;br /&gt;
|[http://www.optikool.com/news/xmovie-news/45-xmovie-11-udpate v1.1 is a security release.] &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  Easy File Uploader    ==&lt;br /&gt;
|LFI - http://extensions.joomla.org/extensions/core-enhancements/file-management/11909&lt;br /&gt;
|090111&lt;br /&gt;
| Fixed MIME type tamper vulnerability http://michaelgilkes.info/joomla-plugin-easy-file-uploader 2011-01-10&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  akeebabackup admin tools   ==&lt;br /&gt;
|xss&lt;br /&gt;
|181210&lt;br /&gt;
|http://www.akeebabackup.com/home/item/929-security-release-admin-tools-1-1.html devs update statement&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
== aicontactsafe    ==&lt;br /&gt;
|XSS for versions 2.0.13 and below&lt;br /&gt;
|161210&lt;br /&gt;
|[http://www.algisinfo.com/joomla/aicontactsafe-change-log.html dev release 2.0.14]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  JRadio    ==&lt;br /&gt;
|JRadio LFI/SID&lt;br /&gt;
|161210&lt;br /&gt;
|http://www.fxwebdesign.nl/index.php?option=com_content&amp;amp;view=article&amp;amp;id=20&amp;amp;Itemid=56 developer fix statement&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  JE Auto   ==&lt;br /&gt;
|JE Auto 1.0 SQL I&lt;br /&gt;
|091210&lt;br /&gt;
|[http://www.joomlaextensions.co.in/extensions/components/je-auto.html developers bug fix statement]&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==  jxtended comments   ==&lt;br /&gt;
|xss &lt;br /&gt;
|081210&lt;br /&gt;
|[http://jxtended.com/blog/releases/375-jxtended-comments-131-stable-released.html dev notice] update to 1.3.1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  sh404SEF   ==&lt;br /&gt;
|sqlI&lt;br /&gt;
|301110&lt;br /&gt;
|[http://dev.anything-digital.com/Blog/sh404SEF/Urgent-security-releases-now-available-for-all-version-of-sh404SEF.html dev post of resolution] &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  JE Ajax Event Calendar   ==&lt;br /&gt;
|SQL I (relist)&lt;br /&gt;
|251110&lt;br /&gt;
|[http://joomlaextensions.co.in/extensions/components/je-ajax-event-calender.html Dev states resolved,] &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Jimtawl    ==&lt;br /&gt;
|Jimtawl LFI &lt;br /&gt;
|251110&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  mosets tree    ==&lt;br /&gt;
|mosets tree various &lt;br /&gt;
|181110&lt;br /&gt;
|dev release 2.1.8 http://forum.mosets.com/showthread.php?t=17064&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   Maian Media SILVER  ==&lt;br /&gt;
|Maian Media SQLi&lt;br /&gt;
|151110&lt;br /&gt;
|Developer states unproven in free edition, paid/SILVER version is being upgraded. [http://www.aretimes.com/index.php?option=com_content&amp;amp;view=category&amp;amp;layout=blog&amp;amp;id=40&amp;amp;Itemid=113 dev article]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  alfurqan  ==&lt;br /&gt;
|alfurqan 1.5 sqli&lt;br /&gt;
|151110&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  ccboard   ==&lt;br /&gt;
|[http://extensions.joomla.org/extensions/communication/forum/6823 ccboard XSS and SQLi]&lt;br /&gt;
|131110&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   ProDesk v 1.5  ==&lt;br /&gt;
|LFI &lt;br /&gt;
|091110&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  JQuarks 4 survey 1.0.0   ==&lt;br /&gt;
|SQLi&lt;br /&gt;
|091110&lt;br /&gt;
| [http://www.iptechinside.com/labs/projects/list_files/jquarks-for-surveys developer statement updated to version 1.0.1] 101110&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
== RSform! 1.0.5    ==&lt;br /&gt;
|Multiple vulnerabilities - LFI, SQLi&lt;br /&gt;
|061110&lt;br /&gt;
| [http://www.rsjoomla.com/customer-support/documentations/12-general-overview-of-the-component/46-rsform-changelog.html developer announcement of security release]to 1.0.6 091110&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
== ccinvoices    ==&lt;br /&gt;
|SQLi for [http://www.chillcreations.com/ ccinvoices]&lt;br /&gt;
|051110&lt;br /&gt;
|Developer Upgrade release to ccInvoices_110RC3 061110&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  sponsorwall   ==&lt;br /&gt;
|SQL injection pulseextensions.com&lt;br /&gt;
|011110&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Flip wall   ==&lt;br /&gt;
|SQL injection pulseextensions.com&lt;br /&gt;
|011110&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
== K2 joomlaworks    ==&lt;br /&gt;
| http://getk2.org/ k2 xss&lt;br /&gt;
|&lt;br /&gt;
|[http://getk2.org/ version 2.4.1]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
== Mosets Tree 2.1.5     ==&lt;br /&gt;
|Mosets Tree http://www.mosets.com/tree/  2.1.5 LFI&lt;br /&gt;
|&lt;br /&gt;
|[http://forum.mosets.com/forumdisplay.php?f=2 developer relase statement and change log]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== Freestyle FAQ 1.5.6     ==&lt;br /&gt;
|http://freestyle-joomla.com/fssdownloads/viewcategory/2 Freestyle FAQ 1.5.6 ‎SQL Injection&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   JE FAQ Pro  ==&lt;br /&gt;
|[http://www.jextn.com/ Je faq pro] various reports&lt;br /&gt;
|090910&lt;br /&gt;
|[http://www.jextn.com/joomla-faq-component-extensions-downloads Developer update notice]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   iJoomla Magazine 3.0.1  ==&lt;br /&gt;
|iJoomla Magazine 3.0.1 RFI&lt;br /&gt;
|090910&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Clantools   ==&lt;br /&gt;
| &lt;br /&gt;
|http://www.joomla-clantools.de/downloads/doc_download/7-clantools-123.html clantool sqli&lt;br /&gt;
|090910&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  jphone   ==&lt;br /&gt;
|jphone LFI&lt;br /&gt;
|090910&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== Gantry Framework    ==&lt;br /&gt;
|SQli injection&lt;br /&gt;
|050910&lt;br /&gt;
|[http://www.gantry-framework.org/news Update to 3.0.11]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  PicSell    ==&lt;br /&gt;
|[http://vm.xmlswf.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=104&amp;amp;Itemid=131Picsell LFD, 777]&lt;br /&gt;
|020910&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  JE FAQ Pro   ==&lt;br /&gt;
|[http://www.jextn.com/joomla-faq-component-extensions-downloads/ SID]&lt;br /&gt;
|020910&lt;br /&gt;
|[http://www.jextn.com/joomla-faq-component-extensions-downloads Developer update notice]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   Zoom Portfolio   ==&lt;br /&gt;
|SID&lt;br /&gt;
|020910&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   zina   ==&lt;br /&gt;
|[http://www.pancake.org/zina/ SQL Injection]&lt;br /&gt;
|020910&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Team&#039;s   ==&lt;br /&gt;
|[http://www.joomlamo.com Teams extension] SQL Injection &lt;br /&gt;
|120810&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Amblog    ==&lt;br /&gt;
|[http://robitbt.hu/jm/index.php?option=com_amdownloader&amp;amp;task=showfiles&amp;amp;pathid=8 Amblog] SQLi&lt;br /&gt;
|120810&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==     ==&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Graffiti Wall   ==&lt;br /&gt;
|[http://extensions.joomla.org/extensions/extension-specific/jomsocial-extensions/13263 Graffiti Wall] for [http://www.joomplace.com/forum/jomsocial-plugins/jomsocial-plugins/graffiti-wall-permissions-777.html jomsocial silent 777]&lt;br /&gt;
|310710&lt;br /&gt;
|[http://extensions.joomla.org/extensions/extension-specific/jomsocial-extensions/13263 Dev statement 1.1 - is security release]. Folder permission was set by default as 777 that is unsecure.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Spielothek   ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/sports-a-games/games/11017 http://www.spielban.de/ silent 0777, unknown folder creation&lt;br /&gt;
|290710&lt;br /&gt;
|Dev states version 1.7.1 resolves issues 020810&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   Aardvertiser  ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/ads-a-affiliates/classified-ads/9454 silent 0777&lt;br /&gt;
|290710&lt;br /&gt;
|[http://sourceforge.net/projects/aardvertiser/forums/forum/989030/topic/3788365 dev announces silent 0777 fixed in Version 2.1 290710]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  FW Real Estate Light    ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/vertical-markets/real-estate/13376 http://www.fastw3b.net/fw-real-estate-light.html silent 777&lt;br /&gt;
|290710&lt;br /&gt;
|[http://www.fastw3b.net/fw-real-estate-light.html version 1.1 reported as fixed 777 issue]&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==     ==&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== jDownloads    ==&lt;br /&gt;
|http://www.jdownloads.com/ and http://extensions.joomla.org/extensions/directory-a-documentation/downloads/2849 silent 0777 setting&lt;br /&gt;
|2807110&lt;br /&gt;
|1.7.4 RC3 Build 771 update on Jul 29 to remove 0777&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  TTVideo   ==&lt;br /&gt;
|[http://www.toughtomato.com TTVideo 1.0 Joomla] SQL Injection Vulnerability&lt;br /&gt;
|270710&lt;br /&gt;
|[http://www.toughtomato.com/resources/downloads/joomla-1.5/components/ttvideo/ dev updated the component to prevent this]. 280710&lt;br /&gt;
Users are no longer able to download the previous version.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  frei-chat2.0   ==&lt;br /&gt;
|http://code.google.com/p/frei-chat/downloads/list xss vulnerability &lt;br /&gt;
|230710&lt;br /&gt;
|[http://code.google.com/p/frei-chat/downloads/list Dev announcement to fix] 2.1.2 for FreiChat [Those having CB installed]AND 1.2.2 for FreiChatPure [Extension Independent] 240710&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  QContacts    ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/contacts-and-feedback/contact-details/4811 &#039;&#039;&#039;Version: 1.0.4 reported, current version 1.0.6&#039;&#039;&#039;&lt;br /&gt;
|220710&lt;br /&gt;
|Devleoper states [http://www.latenight-coding.com/news/joomla/supposed-vulnerability-qcontacts-104.html unproven report and no POC]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== Jomtube    ==&lt;br /&gt;
|http://www.jomtube.com/ SID&lt;br /&gt;
|220710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  mysms   ==&lt;br /&gt;
|http://www.willcodejoomlaforfood.de/ Upload Vulnerability &lt;br /&gt;
|july 10,2010&lt;br /&gt;
|290710 [http://www.willcodejoomlaforfood.de/ released the version 1.5.12.] &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== Rapid Recipe    ==&lt;br /&gt;
|http://www.rapid-source.com Persistent XSS Vulnerability last known fix version 1.7.2 &lt;br /&gt;
|july 10,2010&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   Health &amp;amp; Fitness Stats   ==&lt;br /&gt;
|http://joomla-extensions.instantiate.co.uk/jcomponents/healthstats Persistent XSS Vulnerability july 10,2010 &lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  staticxt   ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/edition/custom-code-in-content/2184  no version number provided&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
==   EasyBlog  ==&lt;br /&gt;
|http://stackideas.com/products/easyblog.html xss (new report) july 10,2010&lt;br /&gt;
|&lt;br /&gt;
|[http://extensions.joomla.org/extensions/news-production/blog/12630 developer reported fix available on site ]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   redshop light   ==&lt;br /&gt;
|http://redcomponent.com/redshop http://extensions.joomla.org/extensions/e-commerce/shopping-cart/13184 silent 777 and sqli&lt;br /&gt;
|110710&lt;br /&gt;
|[http://redcomponent.com/forum/72-redshop-light/11261-redshop-light-rc2-released-security-release Developer reported fix and upgrade to RC2]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   quickfaq  ==&lt;br /&gt;
|http://www.schlu.net sqli&lt;br /&gt;
|090710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==    Minify4Joomla  ==&lt;br /&gt;
|http://waltercedric.com/ LFI and xss&lt;br /&gt;
|090710&lt;br /&gt;
|No longer available to download&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   IXXO Cart   ==&lt;br /&gt;
|http://www.php-shop-system.com/ SQLi LFI XSS Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== Music Manager    ==&lt;br /&gt;
|LFI [http://danieljamesscott.org/software/4-joomla-extensions/4-music-manager.html music manager]&lt;br /&gt;
|090710&lt;br /&gt;
|[http://danieljamesscott.org/software/4-joomla-extensions/4-music-manager.html Version 0.13 released]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  PaymentsPlus   ==&lt;br /&gt;
|http://paymentsplus.com.au/ 2.1.5 Blind SQL Injection Vulnerability&lt;br /&gt;
|090710 &lt;br /&gt;
|current version 2.20, 2.1.5 not listed on dev site&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  ArtForms   ==&lt;br /&gt;
|http://joomlacode.org/gf/project/jartforms/ ArtForms 2.1b7.2 RC2 Multiple Remote Vulnerabilities&lt;br /&gt;
|090710&lt;br /&gt;
| Old beta extension &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==    NeoRecruit  ==&lt;br /&gt;
|neojoomla.com SQL Injection &lt;br /&gt;
| neorecruit vers 1.4 060710&lt;br /&gt;
|[http://www.neojoomla.com/index.php?lang=en dev statement of fix in 1.4.1 and safe 2.0.5] &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  autartimonial   ==&lt;br /&gt;
|autartica.be Sqli Vulnerability&lt;br /&gt;
|060710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   Jobs Pro  ==&lt;br /&gt;
|instantphp.com/ Sqli&lt;br /&gt;
|060710&lt;br /&gt;
|[http://www.instantphp.com/news/40-new-releases/153-jobs-133-is-published.html devs] announcement of fix 130710&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==  JPodium   ==&lt;br /&gt;
|http://www.jpodium.de/ SQL Injection &lt;br /&gt;
|060710&lt;br /&gt;
|[http://www.jpodium.de/index.php?option=com_content&amp;amp;view=article&amp;amp;id=135:jpodium-not-vulnerable-to-sql-injection&amp;amp;catid=2:newsrotator Devs statement as to not proven]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Front-End Article Manager System   ==&lt;br /&gt;
|http://b-elektro.no/ Upload Vulnerability&lt;br /&gt;
|040710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== addressbook    ==&lt;br /&gt;
|http://b-elektro.no/ Upload Vulnerability&lt;br /&gt;
|040710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==   NijnaMonials  ==&lt;br /&gt;
|http://ninjaforge.com/ Sqli Vulnerability&lt;br /&gt;
|040710&lt;br /&gt;
|070410 Discovered to be malicious/false report see [http://nekkidninjas.com/index.php/2010/07/05/there-is-no-sql-injection-vulnerability- devs notice]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== Phoca Gallery    ==&lt;br /&gt;
|SQL I  (wrong download location in report)&lt;br /&gt;
|040710&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;| deemed malicious report&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== socialads    ==&lt;br /&gt;
|techjoomla.com/ Xss Vulnerability &lt;br /&gt;
|040710&lt;br /&gt;
|[http://techjoomla.com/joomla-extension-news/socialads-v101-security-update-to-fix-xss-vulnerability-out.html Developers resolved statement]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== eventcal 1.6.4    ==&lt;br /&gt;
|http://joomlacode.org/gf/project/eventcal/frs/ SQL I  last update 2006-12-31 on joomlacode&lt;br /&gt;
|040710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== myblog controller    ==&lt;br /&gt;
|LFI  &lt;br /&gt;
http://www.azrul.com/ &lt;br /&gt;
|010710&lt;br /&gt;
|[http://www.azrul.com/  MyBlog 3.0.332] &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  joomanager    ==&lt;br /&gt;
|SQli Vulnerability&lt;br /&gt;
http://www.joomanager.com&lt;br /&gt;
|010710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  gamesbox   ==&lt;br /&gt;
|SQL Injection Vulnerability&lt;br /&gt;
http://www.jooforge.com/en/download/commercial/extensions/39-gamesbox&lt;br /&gt;
|010710&lt;br /&gt;
|upgrade to     1.0.10&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   wmtpic  ==&lt;br /&gt;
|www.webmaster-tips.net various&lt;br /&gt;
|010710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== date converter    ==&lt;br /&gt;
|http://sourceforge.net/projects/date-converter/ sqli&lt;br /&gt;
|010710&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
== Remository    ==&lt;br /&gt;
|http://remository.com/ LFI (proc)&lt;br /&gt;
|010710&lt;br /&gt;
|Developer states not proven and possibly malicious. Unable to reproduce without proc/environ security. 260710&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   RokBridge 1.0rc12   ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/communication/forum-bridges/9012 SDI&lt;br /&gt;
|090810&lt;br /&gt;
|[http://www.rockettheme.com/extensions-updates/834-rokbridge-10rc13-released RokBridge has been updated to version 1.0rc13.] 120810&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== real estate    ==&lt;br /&gt;
|http://www.opensourcetechnologies.com/demos/real-estate.html RFI&lt;br /&gt;
|210610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  jomsocial   ==&lt;br /&gt;
|Version: 1.6.288 Multiple XSS&lt;br /&gt;
|210610&lt;br /&gt;
|[http://www.jomsocial.com/blog/security-patch-for-jomsocial-16x.html 1.6.291 released] 220610&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  DOCman    ==&lt;br /&gt;
|DOCman 1.5.7 DOCman 1.4.0 none specific exploit&lt;br /&gt;
|210610&lt;br /&gt;
|[http://blog.joomlatools.eu/2010/06/docman-security-announcement.html developer announcement]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== eportfolio    ==&lt;br /&gt;
|http://www.joomplace.com/e-portfolio/e-portfolio-description.html Upload  Vulnerability&lt;br /&gt;
|200610&lt;br /&gt;
|Developer [http://www.joomplace.com/e-portfolio/e-portfolio-description.html announcement ] 270810&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  cinema   ==&lt;br /&gt;
|SQL injection&lt;br /&gt;
|190610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   Jreservation  ==&lt;br /&gt;
|http://jforjoomla.com/ SQLi Vulnerability&lt;br /&gt;
|190610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Super Messenger   ==&lt;br /&gt;
|axxis.gr xss &lt;br /&gt;
|190610&lt;br /&gt;
|[http://axxis.gr/forum/viewtopic.php?f=6&amp;amp;t=641 developer release statement 1.4.6]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   joomdocs  ==&lt;br /&gt;
|http://joomclan.com/index.php/JoomDocs/ xss vulnerability&lt;br /&gt;
|190610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  RSComments 1.0.0   ==&lt;br /&gt;
|Persistent XSS NOTE: ONLY executes in backend!&lt;br /&gt;
|190610&lt;br /&gt;
|[http://www.rsjoomla.com/customer-support/documentations/96--general-overview-of-the-component/393-changelog.html Developer update announcement] 210610&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   Live Chat    ==&lt;br /&gt;
|http://www.joompolitan.com/livechat.html Multiple Remote Vulnerabilities &lt;br /&gt;
|190610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== Turtushout 0.11    ==&lt;br /&gt;
| http://www.turtus.org.ua/files?func=fileinfo&amp;amp;id=13 SQL Injection (again)&lt;br /&gt;
|190610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  BF Survey Pro Free   ==&lt;br /&gt;
|BF Survey Pro Free SQL Injection Exploit &lt;br /&gt;
|190610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  MisterEstate   ==&lt;br /&gt;
|http://www.misterestate.com/ Blind SQL Injection Exploit &lt;br /&gt;
|190610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  RSMonials    ==&lt;br /&gt;
|http://www.rswebsols.com/downloads/category/14-download-rsmonials-all?download=23%3Adownload-rsmonials-component XSS Exploit&lt;br /&gt;
|190610&lt;br /&gt;
|Believed to be 1.5.1 version&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  RSComments 1.0.0   ==&lt;br /&gt;
|RS Comments 1.0.0 Multiple XSS Vulnerabilities http://www.rsjoomla.com (relisted)&lt;br /&gt;
|180610&lt;br /&gt;
|[http://www.rsjoomla.com/customer-support/documentations/96--general-overview-of-the-component/393-changelog.html Developer update announcement] 210610&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Answers v2.3beta   ==&lt;br /&gt;
|Multiple Vulnerabilities http://extensions.joomla.org/extensions/communication/forum/12652&lt;br /&gt;
|180610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Gallery XML 1.1   ==&lt;br /&gt;
|Multiple Vulnerabilities&lt;br /&gt;
http://extensions.joomla.org/extensions/photos-a-images/photo-gallery/12504&lt;br /&gt;
|180610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  JFaq 1.2   ==&lt;br /&gt;
|JFaq 1.2 Multiple Vulnerabilities&lt;br /&gt;
|180610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Listbingo 1.3   ==&lt;br /&gt;
|Multiple Vulnerabilities&lt;br /&gt;
http://extensions.joomla.org/extensions/ads-a-affiliates/classified-ads/12062&lt;br /&gt;
|180610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== PowerMail Pro    ==&lt;br /&gt;
| PowerMail Pro Local File Inclusion Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|[http://powermail4joomla.com/forum/showthread.php?tid=163 Dev upadte statement] 151010&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== Alpha User Points    ==&lt;br /&gt;
|www.alphaplug.com LFI&lt;br /&gt;
|180610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Magic Updater   ==&lt;br /&gt;
|http://software.realtyna.com/ RFI&lt;br /&gt;
|170610&lt;br /&gt;
|[http://software.realtyna.com/component/content/article/64-security-patch-for-magic-updater-and-translator.html] developer update statement&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   recruitmentmanager  ==&lt;br /&gt;
|http://recruitment.focusdev.co.uk Upload Vulnerability&lt;br /&gt;
|130610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Info Line (MT_ILine)    ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/news-display/news-tickers-a-scrollers/8425 reports of shell scripts in download file&lt;br /&gt;
|120610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Search Log   ==&lt;br /&gt;
|http://www.kanich.net/radio/site/searchlog/searchlog-download SQLi&lt;br /&gt;
|080610&lt;br /&gt;
|[http://www.kanich.net/radio/site/searchlog/searchlog-download Developer cited update to version 3.1.1 100710]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==  iJoobi   ==&lt;br /&gt;
|jtickets, jsubscription SQL Injection Vulnerability, &lt;br /&gt;
jstore SQL Injection Vulnerability, jnewsletter SQL Injection, jmarket SQL Injection Vulnerability, jcommunity SQL Injection, jsubscription SQL Injection,   &lt;br /&gt;
|090610&lt;br /&gt;
|developer states unproven&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Ads manager  Annonce   ==&lt;br /&gt;
|http://joomla.clubnautiquemarine.fr/ &lt;br /&gt;
Upload Vulnerability&lt;br /&gt;
| 05/06/10&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  lead article    ==&lt;br /&gt;
|http://www.leadya.co.il/ SQLi&lt;br /&gt;
|050610&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  djartgallery   ==&lt;br /&gt;
|http://www.design-joomla.eu Multiple Vul&lt;br /&gt;
|05/06/10&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
== Gallery 2 Bridge    ==&lt;br /&gt;
|[http://trac.4theweb.nl/g2bridge g2bridge] LFI vulnerability&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  jsjobs   ==&lt;br /&gt;
|[http://www.joomsky.com jsjobs] SQL Injection Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==     ==&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   JE Poll  ==&lt;br /&gt;
|http://slideshow.joomlaextensions.co.in/ SQL Injection Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  MyCar   ==&lt;br /&gt;
|http://www.unisoft.me/extensions/ sqli ID&lt;br /&gt;
|&lt;br /&gt;
|[http://www.unisoft.me/mycar/index.php?option=com_smallchat&amp;amp;Itemid=5 Dev announcement update to 1.1]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  MediQnA   ==&lt;br /&gt;
|MediQnA LFI vulnerability version : v1.1&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==   JE Job  ==&lt;br /&gt;
|http://joomlaextensions.co.in/ LFI SQLi&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  BF Quiz   ==&lt;br /&gt;
|SQL Injection Exploit Version(s) = 1.3.0&lt;br /&gt;
|&lt;br /&gt;
|[http://www.tamlyncreative.com.au/software/forum/index.php?topic=729.0 Developer update to BF Quiz v1.3.1]&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==     ==&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   Ozio Gallery 2  ==&lt;br /&gt;
|DT and open email relay&lt;br /&gt;
|280510&lt;br /&gt;
|[http://oziogallery.joomla.it/index.php?option=com_content&amp;amp;view=article&amp;amp;id=65:rilasciata-la-versione-ozio-gallery-25&amp;amp;catid=2:notizie&amp;amp;Itemid=13&amp;amp;lang=en Developer update and security release] 010610&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  SectionEx   ==&lt;br /&gt;
|Stack Ideas section Ex LFI&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  ActiveHelper LiveHelp    ==&lt;br /&gt;
|XSS in [http://extensions.joomla.org/extensions/communication/chat/12492 LiveHelp] &lt;br /&gt;
|200510&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
==  RS Comments   ==&lt;br /&gt;
|XSS Vulnerability &lt;br /&gt;
|&lt;br /&gt;
|[http://www.rsjoomla.com/customer-support/documentations/96--general-overview-of-the-component/393-changelog.html - fix posted 210510]&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==  BCA RSS Feed   ==&lt;br /&gt;
|LFI and other vulnerabilities&lt;br /&gt;
|&lt;br /&gt;
|Upgrade to [http://ninjaforge.com/index.php?option=com_ninjacentral&amp;amp;page=show_package&amp;amp;id=74&amp;amp;Itemid=236 Ninja RSS Syndicator 1.0.9 or later]&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
== SimpleDownload    ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/directory-a-documentation/downloads/10717 various exploits&lt;br /&gt;
|160510&lt;br /&gt;
|updated version (version 0.9.6)&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
==  JE Quotation Form   ==&lt;br /&gt;
|http://joomlaextensions.co.in/free-download/doc_download/11-je-quotation-form.html  LFI&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  konsultasi   ==&lt;br /&gt;
|SQL Injection Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== Aardvertiser    ==&lt;br /&gt;
|Local File Inclusion Vulnerability	&lt;br /&gt;
http://extensions.joomla.org/extensions/ads-a-affiliates/classified-ads/9454&lt;br /&gt;
|&lt;br /&gt;
|see [http://docs.joomla.org/Vulnerable_Extensions_List#Aardvertiser resolved notice 040810]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;  |&lt;br /&gt;
&lt;br /&gt;
==  Seber Cart    ==&lt;br /&gt;
|Local File Disclosure Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|[http://www.sebercart.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=158 Developer Update 140510]&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  FDione Form Wizard   ==&lt;br /&gt;
|lfi vulnerability	&lt;br /&gt;
|140510 200510&lt;br /&gt;
|[http://dionesoft.com Update to Dione Form Wizard (v. 1.0.4)].&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   Custom PHP Pages  ==&lt;br /&gt;
|http://extensions.joomla.org/extensions/edition/custom-code-in-content/5057 LFI Vulnerability		&lt;br /&gt;
|&lt;br /&gt;
|[http://fijiwebdesign.com Developer declares not vulnerable 140510]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  Camp26 Visitor    ==&lt;br /&gt;
|RFI www.camp26.biz&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==    iJoomla News Portal  ==&lt;br /&gt;
|RFI SID&lt;br /&gt;
|&lt;br /&gt;
|[http://www.ijoomla.com/forum/index.php/topic,4480.0.html Update to 1.5.10]&lt;br /&gt;
|-&lt;br /&gt;
|  &lt;br /&gt;
==  article Factory Manager   ==&lt;br /&gt;
|RFI &amp;amp; Input Validation Error http://www.thefactory.ro/shop/joomla-components/article-manager.html&lt;br /&gt;
|may 2010&lt;br /&gt;
|can not reproduce and unproven, http://www.thefactory.ro&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Table JX Component    ==&lt;br /&gt;
|http://www.toolsjx.com/ Table JX Component XSS&lt;br /&gt;
|060510 - update 130510&lt;br /&gt;
|Version: 1.5.5 considered unsafe, [http://www.toolsjx.com update to 1.5.7]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==   JE Property  ==&lt;br /&gt;
|JE Property Finder Upload Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==   Noticeboard  ==&lt;br /&gt;
|Noticeboard for Joomla &amp;quot;controller&amp;quot; Local File Inclusion Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==SmartSite     ==&lt;br /&gt;
|SmartSite com_smartsite Local File Inclusion Vulnerability &lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  ABC    ==&lt;br /&gt;
|ABC SQL Injection Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|reported as updated to JED 290410&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  htmlcoderhelper graphics   ==&lt;br /&gt;
|htmlcoderhelper graphics v1.0.6 LFI Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
== Ultimate Portfolio    ==&lt;br /&gt;
|Ultimate Portfolio  Local File Inclusion Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  huruhelpdesk   ==&lt;br /&gt;
|http://www.huruhelpdesk.net sqli injection &lt;br /&gt;
|&lt;br /&gt;
|[http://www.huruhelpdesk.net/forums/8-announcements/392--sql-injection-reveals-user-md5-password-hash Reported fix]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  Archery Scores   ==&lt;br /&gt;
| [http://lispeltuut.org/ Archery Scores (com_archeryscores) v1.0.6 LFI Vulnerability]&lt;br /&gt;
&lt;br /&gt;
|210410&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  ZiMB Manager   ==&lt;br /&gt;
|Joomla Component ZiMB Manager Local File Inclusion Vulnerability&lt;br /&gt;
|210410&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  Matamko   ==&lt;br /&gt;
|Matamko Local File Inclusion Vulnerability&lt;br /&gt;
|210410&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  Multiple Root   ==&lt;br /&gt;
|Multiple Root Local File Inclusion Vulnerability http://joomlacomponent.inetlanka.com/&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  Multiple Map   ==&lt;br /&gt;
|Multiple Map Local File Inclusion Vulnerability joomlacomponent.inetlanka.com&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==   Contact Us Draw Root Map  ==&lt;br /&gt;
|Draw Root Map Local File Inclusion Vulnerability joomlacomponent.inetlanka.com&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  iF surfALERT   ==&lt;br /&gt;
|[http://www.inertialfate.za.net/ iF surfALERT] Local File Inclusion Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==   GBU FACEBOOK  ==&lt;br /&gt;
|GBU FACEBOOK SQL injection vulnerability http://www.gbugrafici.nl/gbufacebook/&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==   jnewspaper  ==&lt;br /&gt;
|jnewspaper (cid) SQL Injection Vulnerability&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  JTM Reseller   ==&lt;br /&gt;
|TM Reseller SQL injection vulnerability&lt;br /&gt;
|&lt;br /&gt;
|[http://jtmreseller.com/ Developer Update] &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;   |&lt;br /&gt;
&lt;br /&gt;
==  media Mall Factory   ==&lt;br /&gt;
|SQLi&lt;br /&gt;
|200410&lt;br /&gt;
| [http://www.thefactory.ro/contact-us/product-update-request.html Solution: update to 1.0.5] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   Gadget Factory  ==&lt;br /&gt;
|LFi&lt;br /&gt;
|200410&lt;br /&gt;
|[http://www.thefactory.ro/contact-us/product-update-request.html Solution: update to 1.5.1]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Deluxe Blog Factory   ==&lt;br /&gt;
|SQLi&lt;br /&gt;
|200410&lt;br /&gt;
|[http://www.thefactory.ro/contact-us/product-update-request.html update to 1.1.2]&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==     ==&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;   |&lt;br /&gt;
== MT Fire Eagle ==&lt;br /&gt;
&lt;br /&gt;
|LFI http://joomlacode.org/gf/project/jfireeagle/frs/ http://www.moto-treks.com&lt;br /&gt;
| 190410&lt;br /&gt;
| product considered retired and to be replaced by dev&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
==  com properties   ==&lt;br /&gt;
| http://com-property.com/ SQL I&lt;br /&gt;
|&lt;br /&gt;
|[http://www.com-property.com/images/fbfiles/files/properties-20100413.txt developer announced fix]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Sweetykeeper   ==&lt;br /&gt;
|Sweetykeeper Local File Inclusion Vulnerability  http://www.joomlacorner.com/&lt;br /&gt;
|120410&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  jvehicles   ==&lt;br /&gt;
|SQL Injection http://jvehicles.com&lt;br /&gt;
|120410&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  worldrates   ==&lt;br /&gt;
|http://dev.pucit.edu.pk/&lt;br /&gt;
|120410&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  cvmaker   ==&lt;br /&gt;
|http://dev.pucit.edu.pk/&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  advertising   ==&lt;br /&gt;
|http://dev.pucit.edu.pk/&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   horoscope  ==&lt;br /&gt;
|http://dev.pucit.edu.pk/&lt;br /&gt;
|120410&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   webtv  ==&lt;br /&gt;
|http://dev.pucit.edu.pk/&lt;br /&gt;
|120410&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  diary   ==&lt;br /&gt;
|http://dev.pucit.edu.pk/&lt;br /&gt;
|120410&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   Multi-Venue Restaurant Menu Manager (MVRMM)  ==&lt;br /&gt;
|http://www.focusdev.co.uk/ &lt;br /&gt;
|120410 &lt;br /&gt;
||[http://extensions.joomla.org/extensions/vertical-markets/food-a-beverage/10015 Version 1.5.2 Stable Update 4]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Memory Book   ==&lt;br /&gt;
|http://dev.pucit.edu.pk/&lt;br /&gt;
|120410&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   TRAVELbook  ==&lt;br /&gt;
| http://www.demo-page.de/&lt;br /&gt;
|120410&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
== AlphaUserPoints    ==&lt;br /&gt;
|&lt;br /&gt;
|[http://www.alphaplug.com/index.php/downloads.html?func=fileinfo&amp;amp;id=31 developer upgrade]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  JprojectMan   ==&lt;br /&gt;
|LFI http://extensions.joomla.org/extensions/communities-a-groupware/project-a-task-management/5676&lt;br /&gt;
|110410&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   CKForms  ==&lt;br /&gt;
|1.3.4 release - Important LFI security fix [http://joomlacode.org/gf/project/ckforms/news/?action=NewsThreadView&amp;amp;id=2814 ]&lt;br /&gt;
|07-04-10 &lt;br /&gt;
|[http://ckforms.cookex.eu/download/download.php upgrade]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==   econtentsite  ==&lt;br /&gt;
|LFI&lt;br /&gt;
|040410&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==    Jvehicles ==&lt;br /&gt;
|ID&lt;br /&gt;
|040410&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==     ==&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  smestorage   ==&lt;br /&gt;
|[http://www.smestorage.com SMEStorage] LFI&lt;br /&gt;
&lt;br /&gt;
|Updated 29 March 10&lt;br /&gt;
|[http://gelembjuk.com/index.php?option=com_content&amp;amp;view=section&amp;amp;layout=blog&amp;amp;id=1&amp;amp;Itemid=55 developer fix] to 1.1&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  JE Tooltip   ==&lt;br /&gt;
|[http://joomlaextensions.co.in/formcreator/ JE Tooltip] LFI&lt;br /&gt;
|Updated 23 March &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  Gift Exchange Beta   ==&lt;br /&gt;
|[http://extensions.joomla.org/extensions/communities-a-groupware/membership/11680 Gift exchange] SQLi&lt;br /&gt;
|Updated 23 March &lt;br /&gt;
|[http://socialables.com/28-Jomsocial/Gift-Exchange/flypage.tpl.html upgrade beta 1.0.1]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==  RokDownloads  ==&lt;br /&gt;
|[[http://extensions.joomla.org/extensions/directory-a-documentation/downloads/7967 LFI]] &lt;br /&gt;
|15 march 2010&lt;br /&gt;
||upgrade to [http://www.rockettheme.com/extensions-updates/638-rokdownloads-10-released version 1.0]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==    gigcalender   ==&lt;br /&gt;
&lt;br /&gt;
|SQLi [http://extensions.joomla.org/extensions/calendars-a-events/events/97)http://extensions.joomla.org/extensions/calendars-a-events/events/97 gigcalender]&lt;br /&gt;
|13 march 2010&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
==    heza content   ==&lt;br /&gt;
|SQLi [http://extensions.joomla.org/extensions/structure-a-navigation/sections-a-categories/10427)http://extensions.joomla.org/extensions/structure-a-navigation/sections-a-categories/10427  heza content]&lt;br /&gt;
|13 march 2010&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==   juliaportfolio   ==&lt;br /&gt;
|LFI [http://extensions.joomla.org/extensions/directory-&amp;amp;-documentation/portfolio/8519/details juliaportfolio]&lt;br /&gt;
|13 march 2010&lt;br /&gt;
|[http://www.treidorinte.ro/joomla-extensions/19-joomla-components/467-juliaportfolio-security-upgrade-required withdrawal and update notice]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  Flash Magazine Deluxe   ==&lt;br /&gt;
|SQL Injection Vulnerability.&lt;br /&gt;
|Feb 25&lt;br /&gt;
|&#039;&#039;&#039;[http://www.joomplace.com/flash-magazine-deluxe/flash-magazine-deluxe-description.html Developer Update Version 2.0.11 09/03/10]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  SqlReport   ==&lt;br /&gt;
|Sqlreport has a sql/RFI exploit. awaiting confirmation on exact developer.&lt;br /&gt;
|Feb 20&lt;br /&gt;
|&#039;&#039;&#039;Not Known&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  Scriptegrator   ==&lt;br /&gt;
|Core Design [http://www.greatjoomla.com/extensions/plugins/core-design-scriptegrator-plugin.html Scriptegrator] RFI exploit&lt;br /&gt;
|Feb 20&lt;br /&gt;
|[http://www.greatjoomla.com/extensions/plugins/core-design-scriptegrator-plugin.html Dev Upgrade announcement]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  AllVideos 3.1  ==&lt;br /&gt;
|&lt;br /&gt;
A vulnerability discovered in versions 3.0. and 3.1 of the plugin can be exploited by malicious people to disclose potentially sensitive information. For security reasons we will not be providing further details to safeguard users of affected versions. http://www.joomlaworks.gr/content/view/77/34/]|&lt;br /&gt;
|17 Feb&lt;br /&gt;
| [http://joomlaworks.googlecode.com/files/plg_jw_allvideos-v3.3_j1.5.zip Version 3.3 release 18th]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  RW Cards   ==&lt;br /&gt;
| [http://extensions.joomla.org/extensions/3430/details RW Card] LFI and ID exploit [http://www.weberr.de/ Dev Site]&lt;br /&gt;
|180210&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&#039;&#039;&#039;  [http://www.weberr.de/index.php/forum.html?func=view&amp;amp;catid=5&amp;amp;id=1939&amp;amp;limit=6 developer update]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
== Yelp ==&lt;br /&gt;
| SQLi - Unable to locate developer. Possibly a custom extension.&lt;br /&gt;
|Feb 01 &lt;br /&gt;
|style=&amp;quot;background:red; color:white&amp;quot; | &#039;&#039;&#039;  Not Known&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  &#039;&#039;&#039;Autartitarot&#039;&#039;&#039;   ==&lt;br /&gt;
|Directory Traversal. Back end access required&lt;br /&gt;
| Feb 05&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; | &#039;&#039;&#039; Please upgrade to [http://www.autartica.be/en/autartitarot version 1.0.4]&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#cef2e0; color:black&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
==  communitypolls   ==&lt;br /&gt;
|LFI - [http://www.corejoomla.com/ community polls] &lt;br /&gt;
|Feb 17&lt;br /&gt;
||upgrade to [http://www.corejoomla.com/ version 1.5.3]&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
==     ==&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;endFeed /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This list is change protected, for updates or additions [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=28000 Mandville] or [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=87230 lafrance]&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Codes used ==&lt;br /&gt;
SQLi - SQL injection [http://en.wikipedia.org/wiki/Code_injection#SQL_injection wikipedia]&lt;br /&gt;
&lt;br /&gt;
LFI - Local File Inclusion [http://www.scribd.com/doc/6498408/Remote-and-Local-File-Inclusion-Explained scribd]&lt;br /&gt;
&lt;br /&gt;
RFI - Remote file inclusion [http://en.wikipedia.org/wiki/Remote_File_Inclusion wikipedia]&lt;br /&gt;
&lt;br /&gt;
DT - Directory Traversal [http://en.wikipedia.org/wiki/Directory_traversal wikipedia]&lt;br /&gt;
&lt;br /&gt;
ID = Information Disclosure: account information or sensitive information publicly viewable&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future Actions &amp;amp; WIP ==&lt;br /&gt;
&lt;br /&gt;
[http://feeds.joomla.org/JoomlaSecurityVulnerableExtensions RSS feed] completed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
to feed VEL direct to twitter&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
The RSS feed is currently fed by item entry order and not by date fixed. &lt;br /&gt;
List as discussed in  [[jtopic:455746]] by [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=67439 PhilD] editing by [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=28000 Mandville]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Category:Security]]&lt;br /&gt;
[[Category:Security_FAQ]]&lt;br /&gt;
[[Category:Component Management]]&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Moving_sensitive_files_outside_the_web_root_j16&amp;diff=32920</id>
		<title>Moving sensitive files outside the web root j16</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Moving_sensitive_files_outside_the_web_root_j16&amp;diff=32920"/>
		<updated>2010-12-16T03:35:23Z</updated>

		<summary type="html">&lt;p&gt;Ian: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overriding defines.php ==&lt;br /&gt;
&lt;br /&gt;
Starting with version 1.6, it is possible to provide a localized version of the files that reside in includes/defines.php (i.e. includes/defines.php and administrator/includes/defines.php).  This makes it possible to move a variety of files outside of document root.&lt;br /&gt;
&lt;br /&gt;
The actual process is quite simple, but it is advisable that you make sure you know what you&#039;re doing before proceeding.&lt;br /&gt;
&lt;br /&gt;
To start, copy the file {ROOT}/includes/defines.php to {ROOT}/defines.php and the file {ROOT}/administrator/includes/defines.php to {ROOT}/administrator/defines.php.&lt;br /&gt;
&lt;br /&gt;
Once you have copied the files, it is necessary to edit both new files and add the lines:&lt;br /&gt;
&lt;br /&gt;
define(&#039;_JDEFINES&#039;, 1);&lt;br /&gt;
&lt;br /&gt;
define(&#039;JPATH_BASE&#039;, dirname(__FILE__));&lt;br /&gt;
&lt;br /&gt;
underneath the defined(&#039;_JEXEC&#039;) or die; line.&lt;br /&gt;
&lt;br /&gt;
== Setting the path to configuration.php ==&lt;br /&gt;
&lt;br /&gt;
Now that you have created override files, you can edit them and provide new locations for various directories. The directory we&#039;re interested in is JPATH_CONFIGURATION.  The default value is defined as:&lt;br /&gt;
define(&#039;JPATH_CONFIGURATION&#039;,	JPATH_ROOT);&lt;br /&gt;
&lt;br /&gt;
To put the configuration file in another location, move the file to its new home and &lt;br /&gt;
specify the new path. As an example, if your files were in /home/exampleuser/public_html and you wanted to put configuration.php in /home/exampleuser/configuration.php, you would change the JPATH_CONFIGURATION define line to:&lt;br /&gt;
&lt;br /&gt;
define(&#039;JPATH_CONFIGURATION&#039;, &#039;/home/exampleuser&#039;);&lt;br /&gt;
&lt;br /&gt;
Make this change in both files, move the configuration.php file and you&#039;re done.&lt;br /&gt;
&lt;br /&gt;
== Other Possibilities ==&lt;br /&gt;
&lt;br /&gt;
The configuration.php file isn&#039;t the only thing you can move. I have done some amount of testing and was able to successfully move the JPATH_LIBRARIES directory, the JPATH_PLUGINS directory, the JPATH_MANIFESTS directory (which holds the XML manifests for some extensions and for core updates).&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Moving_sensitive_files_outside_the_web_root_j16&amp;diff=32879</id>
		<title>Moving sensitive files outside the web root j16</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Moving_sensitive_files_outside_the_web_root_j16&amp;diff=32879"/>
		<updated>2010-12-15T02:51:46Z</updated>

		<summary type="html">&lt;p&gt;Ian: New page: == Overriding defines.php ==  Starting with version 1.6, it is possible to provide a localized version of the files that reside in includes/defines.php (i.e. includes/defines.php and admin...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overriding defines.php ==&lt;br /&gt;
&lt;br /&gt;
Starting with version 1.6, it is possible to provide a localized version of the files that reside in includes/defines.php (i.e. includes/defines.php and administrator/includes/defines.php).  This makes it possible to move a variety of files outside of document root.&lt;br /&gt;
&lt;br /&gt;
The actual process is quite simple, but it is advisable that you make sure you know what you&#039;re doing before proceeding.&lt;br /&gt;
&lt;br /&gt;
To start, copy the file {ROOT}/includes/defines.php to {ROOT}/defines.php and the file {ROOT}/administrator/includes/defines.php to {ROOT}/administrator/defines.php.&lt;br /&gt;
&lt;br /&gt;
Once you have copied the files, it is necessary to edit both new files and add the lines:&lt;br /&gt;
&lt;br /&gt;
define(&#039;_JDEFINES&#039;, 1);&lt;br /&gt;
define(&#039;JPATH_BASE&#039;, dirname(__FILE__));&lt;br /&gt;
&lt;br /&gt;
underneath the defined(&#039;_JEXEC&#039;) or die; line.&lt;br /&gt;
&lt;br /&gt;
== Setting the path to configuration.php ==&lt;br /&gt;
&lt;br /&gt;
Now that you have created override files, you can edit them and provide new locations for various directories. The directory we&#039;re interested in is JPATH_CONFIGURATION.  The default value is defined as:&lt;br /&gt;
define(&#039;JPATH_CONFIGURATION&#039;,	JPATH_ROOT);&lt;br /&gt;
&lt;br /&gt;
To put the configuration file in another location, move the file to its new home and &lt;br /&gt;
specify the new path. As an example, if your files were in /home/exampleuser/public_html and you wanted to put configuration.php in /home/exampleuser/configuration.php, you would change the JPATH_CONFIGURATION define line to:&lt;br /&gt;
&lt;br /&gt;
define(&#039;JPATH_CONFIGURATION&#039;, &#039;/home/exampleuser&#039;);&lt;br /&gt;
&lt;br /&gt;
Make this change in both files, move the configuration.php file and you&#039;re done.&lt;br /&gt;
&lt;br /&gt;
== Other Possibilities ==&lt;br /&gt;
&lt;br /&gt;
The configuration.php file isn&#039;t the only thing you can move. I have done some amount of testing and was able to successfully move the JPATH_LIBRARIES directory, the JPATH_PLUGINS directory, the JPATH_MANIFESTS directory (which holds the XML manifests for some extensions and for core updates).&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=32003</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=32003"/>
		<updated>2010-11-20T03:27:21Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Keepalive */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
Ensure the switcher works in the Global Configuration and System Information&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
This is not used in core and should be deprecated.&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
Create an element with a class &#039;hasTip&#039;. Add an attribute title with the tooltip. The tooltip should popup when you mouseover the element.&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
Make sure the modals still work.&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
Test the uploader in the Media Manager, the Image Popup in the Article Manager and the frontend Image Popup.&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
Ensure the tree works in the media manager.&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
Calendar doesn&#039;t use Mootools, but test by selecting a date and ensuring that the proper date is inserted into the text field.&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
Ensure that a request is made to the server one minute before timeout. You can verify using the Apache logs.&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=32002</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=32002"/>
		<updated>2010-11-20T03:26:46Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Calendar */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
Ensure the switcher works in the Global Configuration and System Information&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
This is not used in core and should be deprecated.&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
Create an element with a class &#039;hasTip&#039;. Add an attribute title with the tooltip. The tooltip should popup when you mouseover the element.&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
Make sure the modals still work.&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
Test the uploader in the Media Manager, the Image Popup in the Article Manager and the frontend Image Popup.&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
Ensure the tree works in the media manager.&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
Calendar doesn&#039;t use Mootools, but test by selecting a date and ensuring that the proper date is inserted into the text field.&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=32001</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=32001"/>
		<updated>2010-11-20T03:24:19Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Tree */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
Ensure the switcher works in the Global Configuration and System Information&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
This is not used in core and should be deprecated.&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
Create an element with a class &#039;hasTip&#039;. Add an attribute title with the tooltip. The tooltip should popup when you mouseover the element.&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
Make sure the modals still work.&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
Test the uploader in the Media Manager, the Image Popup in the Article Manager and the frontend Image Popup.&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
Ensure the tree works in the media manager.&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=32000</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=32000"/>
		<updated>2010-11-20T03:23:57Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Uploader */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
Ensure the switcher works in the Global Configuration and System Information&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
This is not used in core and should be deprecated.&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
Create an element with a class &#039;hasTip&#039;. Add an attribute title with the tooltip. The tooltip should popup when you mouseover the element.&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
Make sure the modals still work.&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
Test the uploader in the Media Manager, the Image Popup in the Article Manager and the frontend Image Popup.&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31999</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31999"/>
		<updated>2010-11-20T03:23:10Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Modal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
Ensure the switcher works in the Global Configuration and System Information&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
This is not used in core and should be deprecated.&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
Create an element with a class &#039;hasTip&#039;. Add an attribute title with the tooltip. The tooltip should popup when you mouseover the element.&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
Make sure the modals still work.&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31998</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31998"/>
		<updated>2010-11-20T03:22:56Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Tooltip */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
Ensure the switcher works in the Global Configuration and System Information&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
This is not used in core and should be deprecated.&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
Create an element with a class &#039;hasTip&#039;. Add an attribute title with the tooltip. The tooltip should popup when you mouseover the element.&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31997</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31997"/>
		<updated>2010-11-20T03:20:31Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Combo Box */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
Ensure the switcher works in the Global Configuration and System Information&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
This is not used in core and should be deprecated.&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31996</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31996"/>
		<updated>2010-11-20T03:12:29Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Switcher */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
Ensure the switcher works in the Global Configuration and System Information&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31995</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31995"/>
		<updated>2010-11-20T03:11:27Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Form Validation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
Browse to a form in the backend and ensure that validation is working correctly.&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31994</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31994"/>
		<updated>2010-11-20T02:41:10Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Captions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
Create an image and insert it in an article. Set the title attribute to your caption.&lt;br /&gt;
Verify that the caption is inserted below the image.&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31993</id>
		<title>Mootools Testing Plan</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Mootools_Testing_Plan&amp;diff=31993"/>
		<updated>2010-11-20T02:34:51Z</updated>

		<summary type="html">&lt;p&gt;Ian: New page: This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.  == Captions ==   == Form Validation ==    == Switch...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will begin to define test procedures that can be used to ensure that all of the Mootools Behaviours are functioning properly.&lt;br /&gt;
&lt;br /&gt;
== Captions ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Form Validation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Switcher ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Combo Box ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tooltip ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modal ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uploader ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tree ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calendar ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Keepalive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== No Frames ==&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Category:Version_1.5.22_FAQ&amp;diff=31729</id>
		<title>Category:Version 1.5.22 FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Category:Version_1.5.22_FAQ&amp;diff=31729"/>
		<updated>2010-11-05T05:17:34Z</updated>

		<summary type="html">&lt;p&gt;Ian: New page: These FAQs are specific to the Joomla 1.5.22 release. Only issues that are specific to this release will be listed here, together with suggested resolutions. Please add information to this...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These FAQs are specific to the Joomla 1.5.22 release. Only issues that are specific to this release will be listed here, together with suggested resolutions. Please add information to this resource. The Joomla Bug Squad will watch over this page to ensure any new bugs are added to the tracker and resolved. Continue to use the Joomla forums for support requests as this is not a substitute for posting there, but rather a common location for the community to gather release issues.&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Help16:Content_Article_Manager&amp;diff=31707</id>
		<title>Help16:Content Article Manager</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Help16:Content_Article_Manager&amp;diff=31707"/>
		<updated>2010-11-01T16:37:10Z</updated>

		<summary type="html">&lt;p&gt;Ian: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==How to access==&lt;br /&gt;
Click the Article Manager icon in the [[Help16:Site_Control_Panel|Control Panel]], or click &#039;Article Manager&#039; in the &#039;Content&#039; menu in the back-end of your Joomla! installation.&lt;br /&gt;
&lt;br /&gt;
==Description==&lt;br /&gt;
The Article Manager is the place in the back-end where you can add and manage all of the articles for your web site.&lt;br /&gt;
&lt;br /&gt;
==Screenshot==&lt;br /&gt;
[[Image:Help16-content-article_manager-screen.png]]&lt;br /&gt;
&lt;br /&gt;
==Column Headers==&lt;br /&gt;
Click on the column heading to sort the list by that column&#039;s value.&lt;br /&gt;
{{colheader|Checkbox}}&lt;br /&gt;
{{colheader|Title}}&lt;br /&gt;
* &#039;&#039;&#039;Published&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Featured&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Category&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Ordering&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Access&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Created by&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Date&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Hits&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
{{colheader|Id}}&lt;br /&gt;
* &#039;&#039;&#039;Display #&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Toolbar==&lt;br /&gt;
At the top right you will see the following toolbar:&lt;br /&gt;
[[Image:Help16-content-article_manager-toolbar.png]]&lt;br /&gt;
&lt;br /&gt;
The functions are:&lt;br /&gt;
{{toolbaricon|New}}&lt;br /&gt;
{{toolbaricon|Edit}}&lt;br /&gt;
{{toolbaricon|Publish}}&lt;br /&gt;
{{toolbaricon|Unpublish}}&lt;br /&gt;
{{toolbaricon|Archive}} &lt;br /&gt;
* &#039;&#039;&#039;Check in&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
{{toolbaricon|Trash}}&lt;br /&gt;
*&#039;&#039;&#039;Options&#039;&#039;&#039; Click this button to open the Global Configuration window. This window allows you to set default parameters for Articles. This default parameter will take effect if the corresponding Menu Item parameter and Article parameter are both set to &#039;Use Global&#039;. See [[#Global Configuration|Global Configuration]] below.&lt;br /&gt;
{{toolbaricon|Help}}&lt;br /&gt;
&lt;br /&gt;
==List Filters==&lt;br /&gt;
&#039;&#039;&#039;Filter by Partial Title&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can filter the list of items either by entering in part of the title or the ID number. Or you can select a combination of Section, Category, Author, and Published State.&lt;br /&gt;
{{colheader|List Filter}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filter by Section, Category, Author, Published State&#039;&#039;&#039;&lt;br /&gt;
In the upper right area, above the column headings, are 4 drop-down list boxes as shown below:[[Image:article_manager_filter2.png|center]] The selections may be combined. Only items matching all selections will display in the list.&lt;br /&gt;
{{colheader|Select Section}}&lt;br /&gt;
{{colheader|Select Category}}&lt;br /&gt;
{{colheader|Select Author}}&lt;br /&gt;
{{colheader|Select State}}&lt;br /&gt;
&lt;br /&gt;
==Global Configuration==&lt;br /&gt;
This pop-up screen is shown when the User clicks the &#039;Parameters&#039; button on the Toolbar.&lt;br /&gt;
&lt;br /&gt;
===Screenshot===&lt;br /&gt;
[[Image:articles_global1.png|center]]&lt;br /&gt;
[[Image:articles_global2.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Column Headers===&lt;br /&gt;
&lt;br /&gt;
{{colheader|Global Show Unauthorized Links}}&lt;br /&gt;
{{colheader|Global Show Article Title}}&lt;br /&gt;
{{colheader|Global Title Linkable}}&lt;br /&gt;
{{colheader|Global Show Intro Text}}&lt;br /&gt;
{{colheader|Global Section Name}}&lt;br /&gt;
{{colheader|Global Section Title Linkable}}&lt;br /&gt;
{{colheader|Global Category Title}}&lt;br /&gt;
{{colheader|Global Category Title Linkable}}&lt;br /&gt;
{{colheader|Global Author Name}}&lt;br /&gt;
{{colheader|Global Created Date and Time}}&lt;br /&gt;
{{colheader|Global Modified Date and Time}}&lt;br /&gt;
{{colheader|Global Show Navigation}}&lt;br /&gt;
{{colheader|Global Read more... Link}}&lt;br /&gt;
{{colheader|Global Article Rating/Voting}}&lt;br /&gt;
{{colheader|Global Icons}}&lt;br /&gt;
{{colheader|Global PDF Icon}}&lt;br /&gt;
{{colheader|Global Print Icon}}&lt;br /&gt;
{{colheader|Global E-mail Icon}}&lt;br /&gt;
{{colheader|Hits}}&lt;br /&gt;
{{colheader|Global For each feed item show}}&lt;br /&gt;
&lt;br /&gt;
===Filtering Options (HTML)===&lt;br /&gt;
&lt;br /&gt;
Web sites can be attacked by users entering in special HTML code. Filtering is a way to protect your Joomla! web site. Joomla! 1.6 brings new filtering options to give you more control over the HTML that your content providers are allowed to submit. You can be as strict or as liberal as you desire, depending on your site&#039;s needs.&lt;br /&gt;
&lt;br /&gt;
It is important to understand that filtering occurs at the time an article is saved, &#039;&#039;after&#039;&#039; it has been written or edited. Depending on your editor and filter settings, it is possible for a user to add HTML to an article during the edit session only to have that HTML removed from the article when it is saved. This can sometimes cause confusion or frustration. If you have filtering set up on your site, make sure your users understand what types of HTML are allowed.&lt;br /&gt;
&lt;br /&gt;
The default setting, as of Joomla! version 1.6, is that all users will have &amp;quot;black list&amp;quot; filtering on by default. This is designed to protect against markup commonly associated with web site attacks. So, if you do not set any filtering options, all users will have &amp;quot;black list&amp;quot; filtering done using the default list of filtered items. If you create a filter here, this overrides the default, and the default filter is no longer in effect.&lt;br /&gt;
&lt;br /&gt;
To access the filtering settings, click on Options and select &#039;Text filters&#039;&lt;br /&gt;
&lt;br /&gt;
For each user group on your site you can specify what type of filtering is applied to their edits.&lt;br /&gt;
&lt;br /&gt;
====Filter Types====&lt;br /&gt;
There are four types of filters: Black List, White List, No HTML and No Filtering.&lt;br /&gt;
&lt;br /&gt;
=====Black List Filters=====&lt;br /&gt;
The default filter method in Joomla! is &#039;Black List&#039;. The default &#039;Black List&#039; contains the following tags to exclude:&lt;br /&gt;
&lt;br /&gt;
:&#039;applet&#039;, &#039;body&#039;, &#039;bgsound&#039;, &#039;base&#039;, &#039;basefont&#039;, &#039;embed&#039;, &#039;frame&#039;, &#039;frameset&#039;, &#039;head&#039;, &#039;html&#039;, &#039;id&#039;, &#039;iframe&#039;, &#039;ilayer&#039;, &#039;layer&#039;, &#039;link&#039;, &#039;meta&#039;, &#039;name&#039;, &#039;object&#039;, &#039;script&#039;, &#039;style&#039;, &#039;title&#039;, &#039;xml&#039;&lt;br /&gt;
&lt;br /&gt;
The default &#039;Black List&#039; contains the following attributes to exclude:&lt;br /&gt;
&lt;br /&gt;
:&#039;action&#039;, &#039;background&#039;, &#039;codebase&#039;, &#039;dynsrc&#039;, &#039;lowsrc&#039;&lt;br /&gt;
&lt;br /&gt;
You can &#039;Black List&#039; (disallow) additional tags and attributes by adding to the Filter tags and Filter attributes fields, separating each tag or attribute name with a space or comma. If you select a Filter Type of &amp;quot;Black List&amp;quot;, this list will always be used, plus any additional tags and attributes you add.&lt;br /&gt;
&lt;br /&gt;
=====White List Filters=====&lt;br /&gt;
White list filters allow you to specify that a given group can only use a specific list of HTML tags and attributes. You can &#039;White List&#039; (allow) tags and attributes by adding to the Filter tags and Filter attributes fields for the desired group, separating each tag or attribute name with a space or comma.&lt;br /&gt;
&lt;br /&gt;
=====No HTML Filters=====&lt;br /&gt;
No HTML filters are the strictest set of filters you can apply. Groups that are set to No HTML will not have permission to use any HTML.&lt;br /&gt;
&lt;br /&gt;
=====No Filtering=====&lt;br /&gt;
No filtering is the most permissive set of filters you can apply. Groups that are set to No Filtering will have permission to use any and all tags and attributes, including the default blacklisted tags and attributes.&lt;br /&gt;
&lt;br /&gt;
====Combining Filters====&lt;br /&gt;
If a user belongs to two different groups that have different filter settings, filters will combine in a permissive way. That is, the set of tags the user will be permitted to use will the combination of the tags that each group allows the user to use. So if the user is a member of one group that white lists a specific set of tags and another group that white lists a different set of tags, the user will be able to use both sets of white listed tags. White lists override blacklists, so if a user belongs to one group that black lists a tag and another group that white lists a tag, the user will be able to use that tag. A user that belongs to a group that has no filtering will be able to use any HTML regardless of filtering settings for other groups the user belongs to.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Filter Application====&lt;br /&gt;
&lt;br /&gt;
Please note that these settings work regardless of the editor that you are using.  Even if you are using a WYSIWYG editor, the filtering settings may strip additional tags and attributes prior to saving information in the database.&lt;br /&gt;
&lt;br /&gt;
====Filter Examples====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example One:&#039;&#039;&#039;&lt;br /&gt;
To allow people in a group to only submit content with basic HTML tags, use the following settings:&lt;br /&gt;
* Select White List as the Filter type&lt;br /&gt;
* Set the Filter tags to: p, b, i, em, br, a, ul, ol, li, img&lt;br /&gt;
* Set the Filter attributes to: href, target, src&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example Two:&#039;&#039;&#039;&lt;br /&gt;
To apply the default black-list filtering to a group, use the following settings:&lt;br /&gt;
* Select Black List as the Filter type.&lt;br /&gt;
* Leave the Filter Tags and Filter attributes fields empty.&lt;br /&gt;
&lt;br /&gt;
[[Image:Text_filters.png]]&lt;br /&gt;
&lt;br /&gt;
====Developers Notes====&lt;br /&gt;
&lt;br /&gt;
The filtering parameters in config.xml have the new parameter menu=&amp;quot;hide&amp;quot;.  This hides the filters from the Menu Item&#039;s Component pane as you do not want cascading overrides to occur at the menu item level.&lt;br /&gt;
&lt;br /&gt;
==Quick Tips==&lt;br /&gt;
*In Joomla! versions prior to 1.5, there were separate processes for creating a Static Content Item and normal Content Items. Both processes are now done just by adding Articles. Normal Content Items are now just called Articles, and Static Content Items are now called Uncategorized Articles.&lt;br /&gt;
&lt;br /&gt;
*To create a static content item, create a new Article in the same way as for normal content and assign it to the &#039;Uncategorized&#039; Section and Category. You can then use the Menu Item Type called Article Layout to show the Article in a page. &lt;br /&gt;
&lt;br /&gt;
*Joomla! 1.5 changes the method you must use to create the &#039;Read more...&#039; link. When you are adding or editing an article, just press the &#039;Read more...&#039; button located at the bottom of the screen, next to Image and Pagebreak buttons. This inserts a &#039;Read more...&#039; break in the Article. The text before the break will display as the Intro Text, and the text after the break will display when the &#039;Read more...&#039; link is pressed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Information==&lt;br /&gt;
* To add or edit Articles: [[screen.content.edit.15|Article Manager - New/Edit]]&lt;br /&gt;
* To manage Categories: [[screen.categories.15|Category Manager]]&lt;br /&gt;
* To manage Sections: [[screen.sections.15|Section Manager]]&lt;br /&gt;
* To manage Users: [[screen.users.15|User Manager]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{cathelp|1.6|Article Manager|Content}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=File:Text_filters.png&amp;diff=31706</id>
		<title>File:Text filters.png</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=File:Text_filters.png&amp;diff=31706"/>
		<updated>2010-11-01T16:35:38Z</updated>

		<summary type="html">&lt;p&gt;Ian: Screenshot of the text filters screen.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Screenshot of the text filters screen.&lt;br /&gt;
== Licensing: ==&lt;br /&gt;
{{JEDL}}&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Help16:Content_Article_Manager&amp;diff=31705</id>
		<title>Help16:Content Article Manager</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Help16:Content_Article_Manager&amp;diff=31705"/>
		<updated>2010-11-01T16:34:21Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Filtering Options (HTML) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==How to access==&lt;br /&gt;
Click the Article Manager icon in the [[Help16:Site_Control_Panel|Control Panel]], or click &#039;Article Manager&#039; in the &#039;Content&#039; menu in the back-end of your Joomla! installation.&lt;br /&gt;
&lt;br /&gt;
==Description==&lt;br /&gt;
The Article Manager is the place in the back-end where you can add and manage all of the articles for your web site.&lt;br /&gt;
&lt;br /&gt;
==Screenshot==&lt;br /&gt;
[[Image:Help16-content-article_manager-screen.png]]&lt;br /&gt;
&lt;br /&gt;
==Column Headers==&lt;br /&gt;
Click on the column heading to sort the list by that column&#039;s value.&lt;br /&gt;
{{colheader|Checkbox}}&lt;br /&gt;
{{colheader|Title}}&lt;br /&gt;
* &#039;&#039;&#039;Published&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Featured&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Category&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Ordering&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Access&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Created by&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Date&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Hits&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
{{colheader|Id}}&lt;br /&gt;
* &#039;&#039;&#039;Display #&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Toolbar==&lt;br /&gt;
At the top right you will see the following toolbar:&lt;br /&gt;
[[Image:Help16-content-article_manager-toolbar.png]]&lt;br /&gt;
&lt;br /&gt;
The functions are:&lt;br /&gt;
{{toolbaricon|New}}&lt;br /&gt;
{{toolbaricon|Edit}}&lt;br /&gt;
{{toolbaricon|Publish}}&lt;br /&gt;
{{toolbaricon|Unpublish}}&lt;br /&gt;
{{toolbaricon|Archive}} &lt;br /&gt;
* &#039;&#039;&#039;Check in&#039;&#039;&#039; &#039;&#039;(needs new 1.6 version)&#039;&#039;&lt;br /&gt;
{{toolbaricon|Trash}}&lt;br /&gt;
*&#039;&#039;&#039;Options&#039;&#039;&#039; Click this button to open the Global Configuration window. This window allows you to set default parameters for Articles. This default parameter will take effect if the corresponding Menu Item parameter and Article parameter are both set to &#039;Use Global&#039;. See [[#Global Configuration|Global Configuration]] below.&lt;br /&gt;
{{toolbaricon|Help}}&lt;br /&gt;
&lt;br /&gt;
==List Filters==&lt;br /&gt;
&#039;&#039;&#039;Filter by Partial Title&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can filter the list of items either by entering in part of the title or the ID number. Or you can select a combination of Section, Category, Author, and Published State.&lt;br /&gt;
{{colheader|List Filter}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filter by Section, Category, Author, Published State&#039;&#039;&#039;&lt;br /&gt;
In the upper right area, above the column headings, are 4 drop-down list boxes as shown below:[[Image:article_manager_filter2.png|center]] The selections may be combined. Only items matching all selections will display in the list.&lt;br /&gt;
{{colheader|Select Section}}&lt;br /&gt;
{{colheader|Select Category}}&lt;br /&gt;
{{colheader|Select Author}}&lt;br /&gt;
{{colheader|Select State}}&lt;br /&gt;
&lt;br /&gt;
==Global Configuration==&lt;br /&gt;
This pop-up screen is shown when the User clicks the &#039;Parameters&#039; button on the Toolbar.&lt;br /&gt;
&lt;br /&gt;
===Screenshot===&lt;br /&gt;
[[Image:articles_global1.png|center]]&lt;br /&gt;
[[Image:articles_global2.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Column Headers===&lt;br /&gt;
&lt;br /&gt;
{{colheader|Global Show Unauthorized Links}}&lt;br /&gt;
{{colheader|Global Show Article Title}}&lt;br /&gt;
{{colheader|Global Title Linkable}}&lt;br /&gt;
{{colheader|Global Show Intro Text}}&lt;br /&gt;
{{colheader|Global Section Name}}&lt;br /&gt;
{{colheader|Global Section Title Linkable}}&lt;br /&gt;
{{colheader|Global Category Title}}&lt;br /&gt;
{{colheader|Global Category Title Linkable}}&lt;br /&gt;
{{colheader|Global Author Name}}&lt;br /&gt;
{{colheader|Global Created Date and Time}}&lt;br /&gt;
{{colheader|Global Modified Date and Time}}&lt;br /&gt;
{{colheader|Global Show Navigation}}&lt;br /&gt;
{{colheader|Global Read more... Link}}&lt;br /&gt;
{{colheader|Global Article Rating/Voting}}&lt;br /&gt;
{{colheader|Global Icons}}&lt;br /&gt;
{{colheader|Global PDF Icon}}&lt;br /&gt;
{{colheader|Global Print Icon}}&lt;br /&gt;
{{colheader|Global E-mail Icon}}&lt;br /&gt;
{{colheader|Hits}}&lt;br /&gt;
{{colheader|Global For each feed item show}}&lt;br /&gt;
&lt;br /&gt;
===Filtering Options (HTML)===&lt;br /&gt;
&lt;br /&gt;
Web sites can be attacked by users entering in special HTML code. Filtering is a way to protect your Joomla! web site. Joomla! 1.6 brings new filtering options to give you more control over the HTML that your content providers are allowed to submit. You can be as strict or as liberal as you desire, depending on your site&#039;s needs.&lt;br /&gt;
&lt;br /&gt;
It is important to understand that filtering occurs at the time an article is saved, &#039;&#039;after&#039;&#039; it has been written or edited. Depending on your editor and filter settings, it is possible for a user to add HTML to an article during the edit session only to have that HTML removed from the article when it is saved. This can sometimes cause confusion or frustration. If you have filtering set up on your site, make sure your users understand what types of HTML are allowed.&lt;br /&gt;
&lt;br /&gt;
The default setting, as of Joomla! version 1.6, is that all users will have &amp;quot;black list&amp;quot; filtering on by default. This is designed to protect against markup commonly associated with web site attacks. So, if you do not set any filtering options, all users will have &amp;quot;black list&amp;quot; filtering done using the default list of filtered items. If you create a filter here, this overrides the default, and the default filter is no longer in effect.&lt;br /&gt;
&lt;br /&gt;
To access the filtering settings, click on Options and select &#039;Text filters&#039;&lt;br /&gt;
&lt;br /&gt;
For each user group on your site you can specify what type of filtering is applied to their edits.&lt;br /&gt;
&lt;br /&gt;
====Filter Types====&lt;br /&gt;
There are four types of filters: Black List, White List, No HTML and No Filtering.&lt;br /&gt;
&lt;br /&gt;
=====Black List Filters=====&lt;br /&gt;
The default filter method in Joomla! is &#039;Black List&#039;. The default &#039;Black List&#039; contains the following tags to exclude:&lt;br /&gt;
&lt;br /&gt;
:&#039;applet&#039;, &#039;body&#039;, &#039;bgsound&#039;, &#039;base&#039;, &#039;basefont&#039;, &#039;embed&#039;, &#039;frame&#039;, &#039;frameset&#039;, &#039;head&#039;, &#039;html&#039;, &#039;id&#039;, &#039;iframe&#039;, &#039;ilayer&#039;, &#039;layer&#039;, &#039;link&#039;, &#039;meta&#039;, &#039;name&#039;, &#039;object&#039;, &#039;script&#039;, &#039;style&#039;, &#039;title&#039;, &#039;xml&#039;&lt;br /&gt;
&lt;br /&gt;
The default &#039;Black List&#039; contains the following attributes to exclude:&lt;br /&gt;
&lt;br /&gt;
:&#039;action&#039;, &#039;background&#039;, &#039;codebase&#039;, &#039;dynsrc&#039;, &#039;lowsrc&#039;&lt;br /&gt;
&lt;br /&gt;
You can &#039;Black List&#039; (disallow) additional tags and attributes by adding to the Filter tags and Filter attributes fields, separating each tag or attribute name with a space or comma. If you select a Filter Type of &amp;quot;Black List&amp;quot;, this list will always be used, plus any additional tags and attributes you add.&lt;br /&gt;
&lt;br /&gt;
=====White List Filters=====&lt;br /&gt;
White list filters allow you to specify that a given group can only use a specific list of HTML tags and attributes. You can &#039;White List&#039; (allow) tags and attributes by adding to the Filter tags and Filter attributes fields for the desired group, separating each tag or attribute name with a space or comma.&lt;br /&gt;
&lt;br /&gt;
=====No HTML Filters=====&lt;br /&gt;
No HTML filters are the strictest set of filters you can apply. Groups that are set to No HTML will not have permission to use any HTML.&lt;br /&gt;
&lt;br /&gt;
=====No Filtering=====&lt;br /&gt;
No filtering is the most permissive set of filters you can apply. Groups that are set to No Filtering will have permission to use any and all tags and attributes, including the default blacklisted tags and attributes.&lt;br /&gt;
&lt;br /&gt;
====Combining Filters====&lt;br /&gt;
If a user belongs to two different groups that have different filter settings, filters will combine in a permissive way. That is, the set of tags the user will be permitted to use will the combination of the tags that each group allows the user to use. So if the user is a member of one group that white lists a specific set of tags and another group that white lists a different set of tags, the user will be able to use both sets of white listed tags. White lists override blacklists, so if a user belongs to one group that black lists a tag and another group that white lists a tag, the user will be able to use that tag. A user that belongs to a group that has no filtering will be able to use any HTML regardless of filtering settings for other groups the user belongs to.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Filter Application====&lt;br /&gt;
&lt;br /&gt;
Please note that these settings work regardless of the editor that you are using.  Even if you are using a WYSIWYG editor, the filtering settings may strip additional tags and attributes prior to saving information in the database.&lt;br /&gt;
&lt;br /&gt;
====Filter Examples====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example One:&#039;&#039;&#039;&lt;br /&gt;
To allow people in a group to only submit content with basic HTML tags, use the following settings:&lt;br /&gt;
* Select White List as the Filter type&lt;br /&gt;
* Set the Filter tags to: p, b, i, em, br, a, ul, ol, li, img&lt;br /&gt;
* Set the Filter attributes to: href, target, src&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example Two:&#039;&#039;&#039;&lt;br /&gt;
To apply the default black-list filtering to a group, use the following settings:&lt;br /&gt;
* Select Black List as the Filter type.&lt;br /&gt;
* Leave the Filter Tags and Filter attributes fields empty.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Developers Notes====&lt;br /&gt;
&lt;br /&gt;
The filtering parameters in config.xml have the new parameter menu=&amp;quot;hide&amp;quot;.  This hides the filters from the Menu Item&#039;s Component pane as you do not want cascading overrides to occur at the menu item level.&lt;br /&gt;
&lt;br /&gt;
==Quick Tips==&lt;br /&gt;
*In Joomla! versions prior to 1.5, there were separate processes for creating a Static Content Item and normal Content Items. Both processes are now done just by adding Articles. Normal Content Items are now just called Articles, and Static Content Items are now called Uncategorized Articles.&lt;br /&gt;
&lt;br /&gt;
*To create a static content item, create a new Article in the same way as for normal content and assign it to the &#039;Uncategorized&#039; Section and Category. You can then use the Menu Item Type called Article Layout to show the Article in a page. &lt;br /&gt;
&lt;br /&gt;
*Joomla! 1.5 changes the method you must use to create the &#039;Read more...&#039; link. When you are adding or editing an article, just press the &#039;Read more...&#039; button located at the bottom of the screen, next to Image and Pagebreak buttons. This inserts a &#039;Read more...&#039; break in the Article. The text before the break will display as the Intro Text, and the text after the break will display when the &#039;Read more...&#039; link is pressed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Information==&lt;br /&gt;
* To add or edit Articles: [[screen.content.edit.15|Article Manager - New/Edit]]&lt;br /&gt;
* To manage Categories: [[screen.categories.15|Category Manager]]&lt;br /&gt;
* To manage Sections: [[screen.sections.15|Section Manager]]&lt;br /&gt;
* To manage Users: [[screen.users.15|User Manager]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{cathelp|1.6|Article Manager|Content}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_1.5_version_history&amp;diff=31003</id>
		<title>Joomla 1.5 version history</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_1.5_version_history&amp;diff=31003"/>
		<updated>2010-09-23T15:50:40Z</updated>

		<summary type="html">&lt;p&gt;Ian: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Joomla! 1.5.20 ==&lt;br /&gt;
* 1.5.20 is the [http://www.joomla.org/announcements/release-news/5284-joomla-1520-released.html newest release]&lt;br /&gt;
* Senu takaa&lt;br /&gt;
* 18 July 2010&lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5284-joomla-1520-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=5325 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.19 ==&lt;br /&gt;
* Wojmamni ama batani&lt;br /&gt;
* 15 July 2010&lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5283-joomla-1519-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=5316 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla!  1.5.18 ==&lt;br /&gt;
* Wojmamni ama  wojnaiki&lt;br /&gt;
* 28 May 2010&lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5276-joomla-1518-released.html  Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=5241  Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.17 ==&lt;br /&gt;
* Wojmamni ama woobusani&lt;br /&gt;
* 23 April 2010&lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5268-joomla-1517-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=5194 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.16 ==&lt;br /&gt;
* Wojmamni ama busani&lt;br /&gt;
* 23 April 2010&lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5259-joomla-1516-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=5184 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.15 ==&lt;br /&gt;
* Wojmamni ama mamni&lt;br /&gt;
* 4 November 2009 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5249-joomla-1515-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=4947 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.14 ==&lt;br /&gt;
* Wojmamni ama naiki&lt;br /&gt;
* 30 July 2009 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5244-joomla-1514-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=4734 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.13 ==&lt;br /&gt;
* Wojmamni ama baji&lt;br /&gt;
* 22 July 2009 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5243-joomla-1513-security-release-now-available.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=4712 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.12 ==&lt;br /&gt;
* Wohmamni Ama Woi&lt;br /&gt;
* 1 July 2009 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5242-joomla-1512-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=4665 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.11 ==&lt;br /&gt;
* Vea&lt;br /&gt;
* 3 June 2009 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5235-joomla-1511-security-release-now-available.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=4556 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.10 ==&lt;br /&gt;
* Wohmamni&lt;br /&gt;
* 28 March 2009 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5231-joomla-1510-security-release-now-available.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=4460 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.9 ==&lt;br /&gt;
* Vatani&lt;br /&gt;
* 10 January 2009 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5226-joomla-159-security-release-now-available.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=4288 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.8 ==&lt;br /&gt;
* Wohnaiki&lt;br /&gt;
* 10 November 2008 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5219-joomla-158-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=4136 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.7 ==&lt;br /&gt;
* Wovusani&lt;br /&gt;
* 9 September 2008 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5212-joomla-157-security-release-now-available.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=3947 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.6 ==&lt;br /&gt;
* Vusani&lt;br /&gt;
* 12 August 2008 &lt;br /&gt;
* [http://www.joomla.org/announcements/release-news/5199-joomla-156-released.html Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=3883 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.5 ==&lt;br /&gt;
* Mamni&lt;br /&gt;
* 28 July 2008 &lt;br /&gt;
* [http://www.joomla.org/content/view/5216/1/ Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;amp;frs_package_id=3846 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.4 ==&lt;br /&gt;
* Naiki&lt;br /&gt;
* 08 July 2008 &lt;br /&gt;
* [http://www.joomla.org/content/view/5180/74/ Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=3786 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.3 ==&lt;br /&gt;
* Vahi&lt;br /&gt;
* 24 April 2008 &lt;br /&gt;
* [http://www.joomla.org/content/view/4852/74/ Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=3587 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.2 ==&lt;br /&gt;
* Woi&lt;br /&gt;
* 23 March 2008 &lt;br /&gt;
* [http://www.joomla.org/content/view/4720/74/ Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=3466 Packages and MD5s] &lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.1 ==&lt;br /&gt;
* Seenu&lt;br /&gt;
* 08 February 2008 &lt;br /&gt;
* [http://www.joomla.org/content/view/4560/74/ Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseBrowse&amp;amp;frs_package_id=3322 Packages and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5 ==&lt;br /&gt;
* Khepri&lt;br /&gt;
* 22 January 2008 &lt;br /&gt;
* [http://www.joomla.org/content/view/4488/74/ Release Notes]&lt;br /&gt;
* [http://joomlacode.org/gf/project/joomla/frs/?action=FrsReleaseView&amp;amp;release_id=5078 Package and MD5s]&lt;br /&gt;
&lt;br /&gt;
== Joomla! 1.5.x Change Log ==&lt;br /&gt;
For any Joomla! 1.5 release, use this [http://joomlacode.org/gf/project/joomla/scmsvn/?action=browse&amp;amp;path=/development/releases/1.5/administrator/&amp;amp;view=log Change Log]&lt;br /&gt;
&lt;br /&gt;
== To locate the MD5 Hash ==&lt;br /&gt;
# Click the link for &#039;&#039;&#039;Packages and MD5s&#039;&#039;&#039; above for the version desired.&lt;br /&gt;
# Click the word &#039;&#039;&#039;Files&#039;&#039;&#039; in the blue bar to expand the list of patch packages available.&lt;br /&gt;
# Locate the row that matches your current installation version.&lt;br /&gt;
# On that row, select the patch package (zip, tar.gz and tar.bz2) that is most convenient for you.&lt;br /&gt;
# Verify the download using the MD5 hash listed in the right column on the same line as the package you selected.&lt;br /&gt;
&lt;br /&gt;
[[Category:Joomla! 1.5]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Coding_style_and_standards&amp;diff=28844</id>
		<title>Coding style and standards</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Coding_style_and_standards&amp;diff=28844"/>
		<updated>2010-06-22T20:06:27Z</updated>

		<summary type="html">&lt;p&gt;Ian: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
{{RightTOC}}&lt;br /&gt;
remark: The following information has been copied from the old WIKI archive has not yet been reviewed.&lt;br /&gt;
See: http://dev.joomla.org/component/option,com_jd-wiki/Itemid,/id,standards:coding/&lt;br /&gt;
&lt;br /&gt;
Good coding standards are important in any development project, but particularly when multiple developers are working on the same project. Having coding standards helps ensure that the code is of high quality, has fewer bugs, and is easily maintained.&lt;br /&gt;
&lt;br /&gt;
First rule, if in doubt, ask.&lt;br /&gt;
&lt;br /&gt;
== File Format ==&lt;br /&gt;
All files contributed to Joomla must:&lt;br /&gt;
&lt;br /&gt;
* Be stored as ASCII text&lt;br /&gt;
* Use UTF-8 character encoding&lt;br /&gt;
* Be Unix formatted&lt;br /&gt;
** Lines must end only with a line feed (LF). Line feeds are represented as ordinal 10, octal 012 and hex 0A. Do not use carriage returns (CR) like Macintosh computers do or the carriage return/line feed combination (CRLF) like Windows computers do.&lt;br /&gt;
&lt;br /&gt;
New files will normally be added to the code base using Subversion (SVN). All SVN files should have the SVN property set &amp;quot;eol-style=LF&amp;quot;. Also, most Joomla! files will have &amp;quot;$Id&amp;quot; tags in the &amp;quot;@version&amp;quot; line of the Doc block. These require the SVN property &amp;quot;keywords=Id&amp;quot;. See [[Subversion File Properties]] for more information about how to set SVN properties.&lt;br /&gt;
&lt;br /&gt;
== Coding Standards ==&lt;br /&gt;
&lt;br /&gt;
=== Spelling ===&lt;br /&gt;
&lt;br /&gt;
Spelling of class, function, variable and constant names should generally be in accordance with British English rules (en_GB).  However, some exceptions are permitted, for example where common programming names are used that align with the PHP API such as &amp;lt;code&amp;gt;$color&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== E_STRICT-compatible code ===&lt;br /&gt;
&lt;br /&gt;
As of version 1.6, all new code that is suggested for inclusion into Joomla must be E_STRICT-compatible. This means that it must not produce any warnings or errors when PHP&#039;s error reporting level is set to E_ALL | E_STRICT.&lt;br /&gt;
&lt;br /&gt;
=== Indenting and Line Length ===&lt;br /&gt;
&lt;br /&gt;
Use tabs to indent, not spaces. Make sure that the tab-stops are set to only 4 spaces in length.&lt;br /&gt;
&lt;br /&gt;
There is no set limit for line length.  Use your judgment based on the nature of the line and readability.&lt;br /&gt;
&lt;br /&gt;
=== Control Structures ===&lt;br /&gt;
&lt;br /&gt;
These include if, for, while, switch, etc. Here is an example of an if statement, as it is the most complicated of the control structures:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if ((condition1) || (condition2)) {&lt;br /&gt;
    action1();&lt;br /&gt;
} else if ((condition3) &amp;amp;&amp;amp; (condition4)) {&lt;br /&gt;
    action2();&lt;br /&gt;
} else&lt;br /&gt;
{&lt;br /&gt;
   // Use one true brace in control structures&lt;br /&gt;
   // when the block is longer than one line&lt;br /&gt;
    defaultAction();&lt;br /&gt;
    anotherAction();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// optional formatting if it improves readability&lt;br /&gt;
if ((condition1) || (condition2)) {&lt;br /&gt;
    action1();&lt;br /&gt;
}&lt;br /&gt;
else if ((condition3) &amp;amp;&amp;amp; (condition4)) {&lt;br /&gt;
    action2();&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
    defaultAction();&lt;br /&gt;
    anotherAction();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls.&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;layouts&#039;&#039;&#039;, the alternative named notation should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if ((condition1) OR (condition2)) :&lt;br /&gt;
    action1();&lt;br /&gt;
elseif ((condition3) AND (condition4)) :&lt;br /&gt;
    action2();&lt;br /&gt;
else :&lt;br /&gt;
    defaultAction();&lt;br /&gt;
    anotherAction();&lt;br /&gt;
endif;&lt;br /&gt;
&lt;br /&gt;
foreach ($array as $element) :&lt;br /&gt;
    echo $element;&lt;br /&gt;
endforeach;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logical operators in condition statements should use uppercase words (&amp;lt;code&amp;gt;AND&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OR&amp;lt;/code&amp;gt;, etc) rather than programmatic notation (&amp;lt;code&amp;gt;&amp;amp;&amp;amp;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;||&amp;lt;/code&amp;gt;, etc).&lt;br /&gt;
&lt;br /&gt;
With the exception of &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt; statements, curly braces must always be included even though they are technically optional. Having them increases readability and decreases the likelihood of logic errors being introduced when new lines are added.&lt;br /&gt;
&lt;br /&gt;
For switch statements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
switch (condition)&lt;br /&gt;
{&lt;br /&gt;
    case 1:&lt;br /&gt;
        doAction1();&lt;br /&gt;
        break;&lt;br /&gt;
&lt;br /&gt;
    case 2:&lt;br /&gt;
        doAction2();&lt;br /&gt;
        break;&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
        doDefaultAction();&lt;br /&gt;
        break;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use indenting and line-breaks rather than curly braces in the &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt; statements to increase readability.  There should be no space between the condition and the colon in the &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt; statement.&lt;br /&gt;
&lt;br /&gt;
=== Function Calls ===&lt;br /&gt;
&lt;br /&gt;
Functions should be called with no spaces between the function name and the opening parenthesis, and no space between this and the first parameter; a space after the comma between each parameter (if they are present), and no space between the last parameter and the closing parenthesis, and the semicolon. Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$var = foo($bar, $baz, $quux);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As displayed above, there should be space before and one space after the equals sign used to assign the return value of a function to a variable. In the case of a block of related assignments, tabs (not spaces) may be inserted to promote readability:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$short          = foo($bar);&lt;br /&gt;
$long_variable  = foo($baz);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Function Definitions ===&lt;br /&gt;
&lt;br /&gt;
Class and function declarations follow the &amp;quot;one true brace&amp;quot; convention:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
function fooFunction($arg1, $arg2 = &#039;&#039;)&lt;br /&gt;
{&lt;br /&gt;
    if (condition) {&lt;br /&gt;
        statement;&lt;br /&gt;
    }&lt;br /&gt;
    return $val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class fooClass&lt;br /&gt;
{&lt;br /&gt;
    function fooMethod($arg1)&lt;br /&gt;
    {&lt;br /&gt;
        if ($arg) {&lt;br /&gt;
            $result = true;&lt;br /&gt;
        } else {&lt;br /&gt;
            $result = false;&lt;br /&gt;
        }&lt;br /&gt;
        return $result;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguments with default values go at the end of the argument list. Always attempt to return a meaningful value from a function if one is appropriate. Here is a slightly longer example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
function connect(&amp;amp;$dsn, $persistent = false)&lt;br /&gt;
{&lt;br /&gt;
    if (is_array($dsn)) {&lt;br /&gt;
        $dsninfo = &amp;amp;$dsn;&lt;br /&gt;
    } else {&lt;br /&gt;
        $dsninfo = DB::parseDSN($dsn);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (!$dsninfo OR !$dsninfo[&#039;phptype&#039;]) {&lt;br /&gt;
        return $this-&amp;gt;raiseError();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Inline documentation for classes should follow the PHPDoc convention, similar to Javadoc. More information about PHPDoc can be found here: http://www.phpdoc.org/&lt;br /&gt;
&lt;br /&gt;
See also [[Adding phpDocumentor comments]]&lt;br /&gt;
&lt;br /&gt;
Non-documentation comments are strongly encouraged. A general rule of thumb is that if you look at a section of code and think &amp;quot;Wow, I don&#039;t want to try and describe that&amp;quot;, you need to comment it before you forget how it works.&lt;br /&gt;
&lt;br /&gt;
C style comments (&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt;) and standard C++ comments (&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt;) are both satisfactory. Use of Perl/shell style comments (&amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;) is not permitted.&lt;br /&gt;
&lt;br /&gt;
Please note - commented code is not to be committed to trunk or release repositories.&lt;br /&gt;
&lt;br /&gt;
=== Including Code ===&lt;br /&gt;
&lt;br /&gt;
Anywhere you are unconditionally including a class file, use &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt;. Anywhere you are conditionally including a class file (for example, factory methods), use &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;. Either of these will ensure that class files are included only once. They share the same file list, so you don&#039;t need to worry about mixing them -- a file included with &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; will not be included again by &amp;lt;/code&amp;gt;include_once&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;Note: [[php:include_once|include_once]] and [[php:require_once|require_once]] are PHP &#039;&#039;language statements&#039;&#039;, not functions. You don&#039;t need parentheses around the filename to be included.&lt;br /&gt;
&lt;br /&gt;
=== PHP Code Tags ===&lt;br /&gt;
&lt;br /&gt;
Always use &amp;lt;tt&amp;gt;&amp;amp;lt;?php ?&amp;gt;&amp;lt;/tt&amp;gt; to delimit PHP code, not the &amp;lt;tt&amp;gt;&amp;amp;lt;? ?&amp;gt;&amp;lt;/tt&amp;gt; shorthand. This is the most portable way to include PHP code on differing operating systems and setups.&lt;br /&gt;
&lt;br /&gt;
For files that contain only PHP code, the closing tag (&amp;lt;tt&amp;gt;?&amp;gt;&amp;lt;/tt&amp;gt;) is never permitted. It is not required by PHP. Not including it prevents trailing white space from being accidentally injected into the output (see PHP manual on [http://au.php.net/basic-syntax.instruction-separation instruction separation]).&lt;br /&gt;
&lt;br /&gt;
=== SQL Queries ===&lt;br /&gt;
&lt;br /&gt;
SQL keywords are to be written in uppercase, while all other identifiers (which the exception of quoted text obviously) is to be in lowercase. Carriage returns should not be used as [[JDatabase]]::getQuery provides for formatted output.  However, indenting with spaces to improve readability is desireable.&lt;br /&gt;
&lt;br /&gt;
Queries should be wrapped in single quotes (as these text blocks are parsed faster by php).&lt;br /&gt;
&lt;br /&gt;
All quoted strings must use the &#039;&#039;Quote&#039;&#039; method to facilitate future compatibility with other database engines.&lt;br /&gt;
&lt;br /&gt;
All table names should use the &#039;&#039;&#039;&amp;lt;tt&amp;gt;#_&amp;lt;/tt&amp;gt;&#039;&#039;&#039; prefix rather than &amp;lt;tt&amp;gt;jos_&amp;lt;/tt&amp;gt; to access Joomla! contents and allow for the [[screen.config.15#Database_Settings|user defined database prefix]] to be applied.&lt;br /&gt;
&lt;br /&gt;
All expected integer or floating-point variable must be [http://php.net/manual/language.types.type-juggling.php cast] with &amp;lt;tt&amp;gt;(int)&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;(float)&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;(double)&amp;lt;/tt&amp;gt; as appropriate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$state = 1;&lt;br /&gt;
$name  = &#039;bill&#039;;&lt;br /&gt;
$db    = &amp;amp;JFactory::getDBO();&lt;br /&gt;
$query = &#039;SELECT COUNT( c.id ) AS num_articles, u.id, u.username&#039;.&lt;br /&gt;
    &#039; FROM #__content AS c&#039;.&lt;br /&gt;
    &#039; LEFT JOIN #__users AS u ON u.id = c.created_by&#039;.&lt;br /&gt;
    &#039; WHERE c.state = &#039;.(int) $state&lt;br /&gt;
    &#039;  AND u.id IS NOT NULL&#039;.&lt;br /&gt;
    &#039;  AND u.username &amp;lt;&amp;gt; &#039;.$db-&amp;gt;Quote( $name ).&lt;br /&gt;
    &#039; GROUP BY u.id&#039;.&lt;br /&gt;
    &#039;  HAVING COUNT( c.id ) &amp;gt; 0&#039;;&lt;br /&gt;
$db-&amp;gt;setQuery();&lt;br /&gt;
// Output formated query if joomla debug is active:&lt;br /&gt;
if (JDEBUG) {&lt;br /&gt;
    echo $db-&amp;gt;getQuery();&lt;br /&gt;
}&lt;br /&gt;
$stats = $db-&amp;gt;loadObjectList();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Doc Blocks ===&lt;br /&gt;
&lt;br /&gt;
All source code files in the core Joomla distribution must contain the following comment block as the header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @version	$Id$&lt;br /&gt;
 * @package	Joomla&lt;br /&gt;
 * @copyright	Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.&lt;br /&gt;
 * @license	GNU/GPL, see LICENSE.php&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@package&amp;lt;/code&amp;gt; in the header is not required for class-only files.&lt;br /&gt;
&lt;br /&gt;
Classes, functions, constants, class properties and class methods should all be supplied with appropriate DocBlocks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Short description for class&lt;br /&gt;
 *&lt;br /&gt;
 * Long description for class (if any)...&lt;br /&gt;
 *&lt;br /&gt;
 * @package    PackageName&lt;br /&gt;
 * @subpackage SubPackageName&lt;br /&gt;
 * @link       http://pear.php.net/package/PackageName&lt;br /&gt;
 * @see        NetOther, Net_Sample::Net_Sample()&lt;br /&gt;
 * @since      Class available since Release 1.2.0&lt;br /&gt;
 * @deprecated Class deprecated in Release 2.0.0&lt;br /&gt;
 */&lt;br /&gt;
class JFooBar&lt;br /&gt;
{&lt;br /&gt;
    /**&lt;br /&gt;
     * @var int $id Primary key&lt;br /&gt;
     */&lt;br /&gt;
    public $id = null;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following package names are to be used in the core stack:&lt;br /&gt;
&lt;br /&gt;
* Joomla.Administrator - all files that belong only to the administrator or backend application&lt;br /&gt;
* Joomla.Installation - all files that belong to the installation application&lt;br /&gt;
* Joomla.Plugin - all plugin files&lt;br /&gt;
* Joomla.Site - all files that pertain only to the site or frontend application&lt;br /&gt;
* Joomla.XML-RPC - all files that belong to the XML-RPC server application&lt;br /&gt;
&lt;br /&gt;
The sub-package name will vary according to the extension type:&lt;br /&gt;
&lt;br /&gt;
* Components - the component folder, eg &amp;lt;code&amp;gt;com_content&amp;lt;/code&amp;gt;&lt;br /&gt;
* Modules - the module folder, eg &amp;lt;code&amp;gt;mod_latest_news&amp;lt;/code&amp;gt;&lt;br /&gt;
* Plugins - the folder.element, eg &amp;lt;code&amp;gt;content.pagebreak&amp;lt;/code&amp;gt;&lt;br /&gt;
* Templates - the template folder, eg &amp;lt;code&amp;gt;rhuk_milkyway&amp;lt;/code&amp;gt;&lt;br /&gt;
* Framework - nothing for top level files (such as &amp;lt;code&amp;gt;factory.php&amp;lt;/code&amp;gt;), the first level folder or the first.second level folders as appropriate, eg &amp;lt;code&amp;gt;utilities&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;joomla/utilities/date.php&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;html.html&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;joomla/html/html/email.php&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that code contributed to the Joomla stack that will become the copyright of the project is not allowed to include &amp;lt;code&amp;gt;@author&amp;lt;/code&amp;gt; tags.  You should update the contribution log in &amp;lt;tt&amp;gt;CREDITS.php&amp;lt;/tt&amp;gt;.  Joomla&#039;s philosophy is that the code is written &amp;quot;all together&amp;quot; and there is no notion of any one person &#039;owning&#039; any section of code.&lt;br /&gt;
&lt;br /&gt;
Files included from third party sources must leave DocBlocks intact. Layout files use the same DocBlocks as other PHP files. &lt;br /&gt;
&lt;br /&gt;
Note that the &amp;quot;@version $Id&amp;quot; line uses the SVN &amp;quot;keywords=Id&amp;quot; property. See [[Subversion File Properties]] for information about setting this property.&lt;br /&gt;
&lt;br /&gt;
== Naming Conventions ==&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
Classes should be given descriptive names. Avoid using abbreviations where possible. Class names should always begin with an uppercase letter and be written in CamelCase even if using traditionally uppercase acronyms (such as XML, HTML).  One exception is for Joomla framework classes which must begin with an uppercase &#039;J&#039; with the next letter also being uppercase.  For example:&lt;br /&gt;
&lt;br /&gt;
* JHtmlHelper&lt;br /&gt;
* JXmlParser&lt;br /&gt;
* JModel&lt;br /&gt;
&lt;br /&gt;
Third-party developers are advised to namespace their functions with a unique prefix.&lt;br /&gt;
&lt;br /&gt;
=== Functions and Methods ===&lt;br /&gt;
&lt;br /&gt;
Functions and methods should be named using the &amp;quot;studly caps&amp;quot; style (also referred to as &amp;quot;bumpy case&amp;quot; or &amp;quot;camel caps&amp;quot;). The initial letter of the name is lowercase, and each letter that starts a new &amp;quot;word&amp;quot; is capitalized. Function in the Joomla framework must begin with a lowercase &#039;j&#039;.  Some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
connect();&lt;br /&gt;
getData();&lt;br /&gt;
buildSomeWidget();&lt;br /&gt;
jImport();&lt;br /&gt;
jDoSomething();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private class members (meaning class members that are intended to be used only from within the same class in which they are declared; are preceded by a single underscore. Properties are to be written in underscore format (that is, logical words separated by underscores) and should be all lowercase.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JFooBar&lt;br /&gt;
{&lt;br /&gt;
    // Joomla 1.5 and earlier format&lt;br /&gt;
    var $_status = null;&lt;br /&gt;
&lt;br /&gt;
    function _sort()&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Joomla 1.6 format&lt;br /&gt;
    private $_status = null;&lt;br /&gt;
&lt;br /&gt;
    protected $field_name = null;&lt;br /&gt;
&lt;br /&gt;
    protected function _sort()&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
Constants should always be all-uppercase, with underscores to separate words. Prefix constant names with the uppercase name of the class/package they are used in. For example, the constants used by the [[JError]] class all begin with &amp;quot;JERROR_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Global Variables ===&lt;br /&gt;
&lt;br /&gt;
If your package needs to define global variables, their name should start with a single underscore followed by the uppercase class/package name and another underscore. For example, the JError class uses a global variable called $_JERROR_LEVELS.&lt;br /&gt;
&lt;br /&gt;
With PHP5 and later you may use static class properties or constants instead of globals.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class JWhatever&lt;br /&gt;
{&lt;br /&gt;
    public static $instance = null;&lt;br /&gt;
    const SUCCESS = 1;&lt;br /&gt;
    const FAILURE = 0;&lt;br /&gt;
    // Methods...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Regular and Class Variables ===&lt;br /&gt;
&lt;br /&gt;
Regular variables, follow the same conventions as function.&lt;br /&gt;
&lt;br /&gt;
Class variables should be set to null or some other appropriate default value. Lining up the default values with tabs should only be used if particularly warranted for readability.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
When using references, there should be a space before the reference operator and no space between it and the function or variable name.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$ref1  = &amp;amp;$this-&amp;gt;_sql;&lt;br /&gt;
$db    = &amp;amp;JFactory::getDBO();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language Keys ===&lt;br /&gt;
&lt;br /&gt;
NOTE: This part has to be rewritten for 1.6 (JM)&lt;br /&gt;
&lt;br /&gt;
Except for the most common of words, such as &amp;quot;Yes&amp;quot;, &amp;quot;No&amp;quot;, &amp;quot;Show&amp;quot;, &amp;quot;Hide&amp;quot; all language keys should be namespaced to reflect the type of string they represent.  Always consider that if two extensions use the same key, the one loaded last will be the one that displays.  Namespacing should generally relate to the extension displaying the text. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
echo JText::_(&#039;Weblink Link&#039;);&lt;br /&gt;
echo JText::_(&#039;Weblink Title&#039;);&lt;br /&gt;
echo JText::_(&#039;Weblink Description&#039;);&lt;br /&gt;
&lt;br /&gt;
echo JText::_(&#039;Exception An error occurred while saving&#039;);&lt;br /&gt;
?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TODO: Link to page with &amp;quot;common&amp;quot; strings that can be used for typical actions in components, such a &amp;quot;Save&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Where the same English word is used in two different locations, two different language keys should be used to allow for cases where the translation results in different words or phrases.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// A table column title&lt;br /&gt;
&amp;lt;th&amp;gt;&amp;lt;?php echo JText::_(&#039;Weblink Column Title&#039;);?&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;&amp;lt;?php echo JText::_(&#039;Weblink Column Link&#039;);?&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// In the form&lt;br /&gt;
&amp;lt;?php echo JText::_(&#039;Weblink Title&#039;);?&amp;gt;&amp;lt;input name=&amp;quot;title&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;?php echo JText::_(&#039;Weblink Link&#039;);?&amp;gt;&amp;lt;input name=&amp;quot;link&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toolbar and Linkbar text should be prefixed Toolbar and Linkbar respectively.&lt;br /&gt;
&lt;br /&gt;
The language keys should be written as naturally as possible with spaces, not underscores separating words.  Long phrases can be condensed to reduce keys to a sensible length.  For example, tooltips for an edit field can be written like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo JText::_(&#039;Weblink Title&#039;);?&amp;gt;&amp;lt;input name=&amp;quot;title&amp;quot; title=&amp;quot;&amp;lt;?php echo JText::_(&#039;Weblink Title Desc&#039;);?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The convention used should be governed by common sense, but must be consistent.  In general consider how the language file will look with all keys sorted alphabetically.  Prefixes should be used to group text within a common context (such as column headings).  Suffixes should be used to group elements that logically go together (such as a field name and its description).&lt;br /&gt;
&lt;br /&gt;
Phrases must never be assembled by string concatenation. Each phrase must be represented by a single language key, using sprintf as appropriate to replace dynamic words in the phrase.  Where replacements are made, the word used should be as descriptive as possible and all-uppercase.  This assists the translators to determine the context of the replacement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
// Not permitted&lt;br /&gt;
echo JText::_(&#039;Deleted &#039;).$n.JText::_(&#039; items&#039;);&lt;br /&gt;
&lt;br /&gt;
// Permitted&lt;br /&gt;
echo JText::sprintf(&#039;Message Deleted NUMBER items&#039;, $n);&lt;br /&gt;
?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reference in the language file would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;MESSAGE DELETED NUMBER ITEMS=Deleted %d Item(s)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If more than one dynamic string is used in a phrase, the printf markers should employ order placement as other languages might change the position of the strings. This is done via %[number]$[printf_type] as follows:&lt;br /&gt;
&lt;br /&gt;
Left to right language:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;PAGE X OF Y=Page %1$d of %2$d&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Right to left language:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;PAGE X OF Y=%2$d of %1$d egaP&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Controllers ===&lt;br /&gt;
&lt;br /&gt;
For single controller components, the naming convention is &#039;&#039;[Name]Controller&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Content Controller&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class ContentController extends JController&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The file name will generally be &#039;&#039;controller.php&#039;&#039; and is located in the component folder.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
com_content&lt;br /&gt;
 / controller.php&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a multi-controller components, such as the Banners in the Administrator, the convention is &#039;&#039;[Component]Controller[Name]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Banner Client Controller&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class BannerControllerClient extends JController&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The files will be located in a &amp;lt;tt&amp;gt;/controllers/&amp;lt;/tt&amp;gt; folder under the component folder.  The file names will reflect the name of the controller.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
com_banner&lt;br /&gt;
  /controllers/&lt;br /&gt;
    / banner.php&lt;br /&gt;
    / client.php&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Models===&lt;br /&gt;
&lt;br /&gt;
The naming convention is &#039;&#039;[Component]Model[Name]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Banner Client Model&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class BannerModelClient extends JModel&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The files will be located in a &amp;lt;tt&amp;gt;/models/&amp;lt;/tt&amp;gt; folder under the component folder.  The file names will reflect the name of the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
com_banner&lt;br /&gt;
  /models/&lt;br /&gt;
    / banner.php&lt;br /&gt;
    / client.php&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Views ===&lt;br /&gt;
The naming convention is &#039;&#039;[Component]View[Name]&#039;&#039;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Contact Category View&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class ContactViewCategory extends JView&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The files will be located in a &amp;lt;tt&amp;gt;/view/&amp;lt;/tt&amp;gt; folder under the component folder. The subfolder names will reflect the name of a View.&lt;br /&gt;
&lt;br /&gt;
 com_contact&lt;br /&gt;
  /views/&lt;br /&gt;
    /&#039;&#039;view name 1&#039;&#039;/&lt;br /&gt;
      / view.html.php&lt;br /&gt;
    /&#039;&#039;view name 2&#039;&#039;/&lt;br /&gt;
      / view.html.php&lt;br /&gt;
&lt;br /&gt;
Multi-view components such as com_content may provide an optional &amp;quot;master&amp;quot; view class the specialised views extend from. It is located in the component folder and typically called &#039;&#039;view.php&#039;&#039;. The naming convention is &#039;&#039;[Component]View&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 com_content&lt;br /&gt;
  /views/&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#999&amp;quot;&amp;gt;/archive/&amp;lt;/span&amp;gt;&lt;br /&gt;
       / view.html.php&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#999&amp;quot;&amp;gt;/article/&amp;lt;/span&amp;gt;&lt;br /&gt;
  / view.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
view.php&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Content View&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class ContentView extends JView&lt;br /&gt;
{&lt;br /&gt;
    // Helper Methods&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
views/archive/view.html.php&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Content Archive View&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class ContactViewArchive extends ContentView&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Plugins ===&lt;br /&gt;
&lt;br /&gt;
The naming convention is &#039;&#039;plg[Folder][Element]&#039;&#039; as pointed out in [[How to create a content plugin|the relative HowTo page]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class plgContentPagebreak extends JPlugin&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Layouts ===&lt;br /&gt;
Components may support different Layouts to render the data supplied by a [[#Views|View]] and its [[#Models|Models]]. A Layout file usually contains markup and some PHP code for &#039;&#039;display logic only&#039;&#039;: no functions, no classes.&lt;br /&gt;
&lt;br /&gt;
A Layout consists of at least one .php file and an equally named [[Creating a basic layout.xml file|.xml manifest file]] located in the &amp;lt;tt&amp;gt;/tmpl/&amp;lt;/tt&amp;gt; folder of a View, both reflect the internal name of the Layout. The standard Layout is called &#039;&#039;default&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#999&amp;quot;&amp;gt;com_content&lt;br /&gt;
   /views/&lt;br /&gt;
     /article/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:#000&amp;quot;&amp;gt;&lt;br /&gt;
       /tmpl/&lt;br /&gt;
         / default.php&lt;br /&gt;
         / default.xml&lt;br /&gt;
         / form.php&lt;br /&gt;
         / form.xml&lt;br /&gt;
         / pagebreak.php&lt;br /&gt;
         / pagebreak.xml &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Layout may use supplemental .php files to provide more granule control in order to render individual parts or repetitive items of the data.&lt;br /&gt;
&lt;br /&gt;
Users may customize the Layout output via [[#Template Layout Overrides|Template Layout Overrides]].&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
=== Template Layout Overrides ===&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Coding_style_and_standards&amp;diff=28843</id>
		<title>Coding style and standards</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Coding_style_and_standards&amp;diff=28843"/>
		<updated>2010-06-22T19:29:30Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Controllers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
{{RightTOC}}&lt;br /&gt;
remark: The following information has been copied from the old WIKI archive has not yet been reviewed.&lt;br /&gt;
See: http://dev.joomla.org/component/option,com_jd-wiki/Itemid,/id,standards:coding/&lt;br /&gt;
&lt;br /&gt;
Good coding standards are important in any development project, but particularly when multiple developers are working on the same project. Having coding standards helps ensure that the code is of high quality, has fewer bugs, and is easily maintained.&lt;br /&gt;
&lt;br /&gt;
First rule, if in doubt, ask.&lt;br /&gt;
&lt;br /&gt;
== File Format ==&lt;br /&gt;
All files contributed to Joomla must:&lt;br /&gt;
&lt;br /&gt;
* Be stored as ASCII text&lt;br /&gt;
* Use UTF-8 character encoding&lt;br /&gt;
* Be Unix formatted&lt;br /&gt;
** Lines must end only with a line feed (LF). Line feeds are represented as ordinal 10, octal 012 and hex 0A. Do not use carriage returns (CR) like Macintosh computers do or the carriage return/line feed combination (CRLF) like Windows computers do.&lt;br /&gt;
&lt;br /&gt;
New files will normally be added to the code base using Subversion (SVN). All SVN files should have the SVN property set &amp;quot;eol-style=LF&amp;quot;. Also, most Joomla! files will have &amp;quot;$Id&amp;quot; tags in the &amp;quot;@version&amp;quot; line of the Doc block. These require the SVN property &amp;quot;keywords=Id&amp;quot;. See [[Subversion File Properties]] for more information about how to set SVN properties.&lt;br /&gt;
&lt;br /&gt;
== Coding Standards ==&lt;br /&gt;
&lt;br /&gt;
=== Spelling ===&lt;br /&gt;
&lt;br /&gt;
Spelling of class, function, variable and constant names should generally be in accordance with British English rules (en_GB).  However, some exceptions are permitted, for example where common programming names are used that align with the PHP API such as &amp;lt;code&amp;gt;$color&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== E_STRICT-compatible code ===&lt;br /&gt;
&lt;br /&gt;
As of version 1.6, all new code that is suggested for inclusion into Joomla must be E_STRICT-compatible. This means that it must not produce any warnings or errors when PHP&#039;s error reporting level is set to E_ALL | E_STRICT.&lt;br /&gt;
&lt;br /&gt;
=== Indenting and Line Length ===&lt;br /&gt;
&lt;br /&gt;
Use tabs to indent, not spaces. Make sure that the tab-stops are set to only 4 spaces in length.&lt;br /&gt;
&lt;br /&gt;
There is no set limit for line length.  Use your judgment based on the nature of the line and readability.&lt;br /&gt;
&lt;br /&gt;
=== Control Structures ===&lt;br /&gt;
&lt;br /&gt;
These include if, for, while, switch, etc. Here is an example of an if statement, as it is the most complicated of the control structures:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if ((condition1) || (condition2)) {&lt;br /&gt;
    action1();&lt;br /&gt;
} else if ((condition3) &amp;amp;&amp;amp; (condition4)) {&lt;br /&gt;
    action2();&lt;br /&gt;
} else&lt;br /&gt;
{&lt;br /&gt;
   // Use one true brace in control structures&lt;br /&gt;
   // when the block is longer than one line&lt;br /&gt;
    defaultAction();&lt;br /&gt;
    anotherAction();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// optional formatting if it improves readability&lt;br /&gt;
if ((condition1) || (condition2)) {&lt;br /&gt;
    action1();&lt;br /&gt;
}&lt;br /&gt;
else if ((condition3) &amp;amp;&amp;amp; (condition4)) {&lt;br /&gt;
    action2();&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
    defaultAction();&lt;br /&gt;
    anotherAction();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls.&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;layouts&#039;&#039;&#039;, the alternative named notation should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
if ((condition1) OR (condition2)) :&lt;br /&gt;
    action1();&lt;br /&gt;
elseif ((condition3) AND (condition4)) :&lt;br /&gt;
    action2();&lt;br /&gt;
else :&lt;br /&gt;
    defaultAction();&lt;br /&gt;
    anotherAction();&lt;br /&gt;
endif;&lt;br /&gt;
&lt;br /&gt;
foreach ($array as $element) :&lt;br /&gt;
    echo $element;&lt;br /&gt;
endforeach;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logical operators in condition statements should use uppercase words (&amp;lt;code&amp;gt;AND&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OR&amp;lt;/code&amp;gt;, etc) rather than programmatic notation (&amp;lt;code&amp;gt;&amp;amp;&amp;amp;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;||&amp;lt;/code&amp;gt;, etc).&lt;br /&gt;
&lt;br /&gt;
With the exception of &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt; statements, curly braces must always be included even though they are technically optional. Having them increases readability and decreases the likelihood of logic errors being introduced when new lines are added.&lt;br /&gt;
&lt;br /&gt;
For switch statements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
switch (condition)&lt;br /&gt;
{&lt;br /&gt;
    case 1:&lt;br /&gt;
        doAction1();&lt;br /&gt;
        break;&lt;br /&gt;
&lt;br /&gt;
    case 2:&lt;br /&gt;
        doAction2();&lt;br /&gt;
        break;&lt;br /&gt;
&lt;br /&gt;
    default:&lt;br /&gt;
        doDefaultAction();&lt;br /&gt;
        break;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use indenting and line-breaks rather than curly braces in the &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt; statements to increase readability.  There should be no space between the condition and the colon in the &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt; statement.&lt;br /&gt;
&lt;br /&gt;
=== Function Calls ===&lt;br /&gt;
&lt;br /&gt;
Functions should be called with no spaces between the function name and the opening parenthesis, and no space between this and the first parameter; a space after the comma between each parameter (if they are present), and no space between the last parameter and the closing parenthesis, and the semicolon. Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$var = foo($bar, $baz, $quux);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As displayed above, there should be space before and one space after the equals sign used to assign the return value of a function to a variable. In the case of a block of related assignments, tabs (not spaces) may be inserted to promote readability:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$short          = foo($bar);&lt;br /&gt;
$long_variable  = foo($baz);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Function Definitions ===&lt;br /&gt;
&lt;br /&gt;
Class and function declarations follow the &amp;quot;one true brace&amp;quot; convention:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
function fooFunction($arg1, $arg2 = &#039;&#039;)&lt;br /&gt;
{&lt;br /&gt;
    if (condition) {&lt;br /&gt;
        statement;&lt;br /&gt;
    }&lt;br /&gt;
    return $val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class fooClass&lt;br /&gt;
{&lt;br /&gt;
    function fooMethod($arg1)&lt;br /&gt;
    {&lt;br /&gt;
        if ($arg) {&lt;br /&gt;
            $result = true;&lt;br /&gt;
        } else {&lt;br /&gt;
            $result = false;&lt;br /&gt;
        }&lt;br /&gt;
        return $result;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguments with default values go at the end of the argument list. Always attempt to return a meaningful value from a function if one is appropriate. Here is a slightly longer example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
function connect(&amp;amp;$dsn, $persistent = false)&lt;br /&gt;
{&lt;br /&gt;
    if (is_array($dsn)) {&lt;br /&gt;
        $dsninfo = &amp;amp;$dsn;&lt;br /&gt;
    } else {&lt;br /&gt;
        $dsninfo = DB::parseDSN($dsn);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (!$dsninfo OR !$dsninfo[&#039;phptype&#039;]) {&lt;br /&gt;
        return $this-&amp;gt;raiseError();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Inline documentation for classes should follow the PHPDoc convention, similar to Javadoc. More information about PHPDoc can be found here: http://www.phpdoc.org/&lt;br /&gt;
&lt;br /&gt;
See also [[Adding phpDocumentor comments]]&lt;br /&gt;
&lt;br /&gt;
Non-documentation comments are strongly encouraged. A general rule of thumb is that if you look at a section of code and think &amp;quot;Wow, I don&#039;t want to try and describe that&amp;quot;, you need to comment it before you forget how it works.&lt;br /&gt;
&lt;br /&gt;
C style comments (&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt;) and standard C++ comments (&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt;) are both satisfactory. Use of Perl/shell style comments (&amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;) is not permitted.&lt;br /&gt;
&lt;br /&gt;
Please note - commented code is not to be committed to trunk or release repositories.&lt;br /&gt;
&lt;br /&gt;
=== Including Code ===&lt;br /&gt;
&lt;br /&gt;
Anywhere you are unconditionally including a class file, use &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt;. Anywhere you are conditionally including a class file (for example, factory methods), use &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;. Either of these will ensure that class files are included only once. They share the same file list, so you don&#039;t need to worry about mixing them -- a file included with &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; will not be included again by &amp;lt;/code&amp;gt;include_once&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;Note: [[php:include_once|include_once]] and [[php:require_once|require_once]] are PHP &#039;&#039;language statements&#039;&#039;, not functions. You don&#039;t need parentheses around the filename to be included.&lt;br /&gt;
&lt;br /&gt;
=== PHP Code Tags ===&lt;br /&gt;
&lt;br /&gt;
Always use &amp;lt;tt&amp;gt;&amp;amp;lt;?php ?&amp;gt;&amp;lt;/tt&amp;gt; to delimit PHP code, not the &amp;lt;tt&amp;gt;&amp;amp;lt;? ?&amp;gt;&amp;lt;/tt&amp;gt; shorthand. This is the most portable way to include PHP code on differing operating systems and setups.&lt;br /&gt;
&lt;br /&gt;
For files that contain only PHP code, the closing tag (&amp;lt;tt&amp;gt;?&amp;gt;&amp;lt;/tt&amp;gt;) is never permitted. It is not required by PHP. Not including it prevents trailing white space from being accidentally injected into the output (see PHP manual on [http://au.php.net/basic-syntax.instruction-separation instruction separation]).&lt;br /&gt;
&lt;br /&gt;
=== SQL Queries ===&lt;br /&gt;
&lt;br /&gt;
SQL keywords are to be written in uppercase, while all other identifiers (which the exception of quoted text obviously) is to be in lowercase. Carriage returns should not be used as [[JDatabase]]::getQuery provides for formatted output.  However, indenting with spaces to improve readability is desireable.&lt;br /&gt;
&lt;br /&gt;
Queries should be wrapped in single quotes (as these text blocks are parsed faster by php).&lt;br /&gt;
&lt;br /&gt;
All quoted strings must use the &#039;&#039;Quote&#039;&#039; method to facilitate future compatibility with other database engines.&lt;br /&gt;
&lt;br /&gt;
All table names should use the &#039;&#039;&#039;&amp;lt;tt&amp;gt;#_&amp;lt;/tt&amp;gt;&#039;&#039;&#039; prefix rather than &amp;lt;tt&amp;gt;jos_&amp;lt;/tt&amp;gt; to access Joomla! contents and allow for the [[screen.config.15#Database_Settings|user defined database prefix]] to be applied.&lt;br /&gt;
&lt;br /&gt;
All expected integer or floating-point variable must be [http://php.net/manual/language.types.type-juggling.php cast] with &amp;lt;tt&amp;gt;(int)&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;(float)&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;(double)&amp;lt;/tt&amp;gt; as appropriate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$state = 1;&lt;br /&gt;
$name  = &#039;bill&#039;;&lt;br /&gt;
$db    = &amp;amp;JFactory::getDBO();&lt;br /&gt;
$query = &#039;SELECT COUNT( c.id ) AS num_articles, u.id, u.username&#039;.&lt;br /&gt;
    &#039; FROM #__content AS c&#039;.&lt;br /&gt;
    &#039; LEFT JOIN #__users AS u ON u.id = c.created_by&#039;.&lt;br /&gt;
    &#039; WHERE c.state = &#039;.(int) $state&lt;br /&gt;
    &#039;  AND u.id IS NOT NULL&#039;.&lt;br /&gt;
    &#039;  AND u.username &amp;lt;&amp;gt; &#039;.$db-&amp;gt;Quote( $name ).&lt;br /&gt;
    &#039; GROUP BY u.id&#039;.&lt;br /&gt;
    &#039;  HAVING COUNT( c.id ) &amp;gt; 0&#039;;&lt;br /&gt;
$db-&amp;gt;setQuery();&lt;br /&gt;
// Output formated query if joomla debug is active:&lt;br /&gt;
if (JDEBUG) {&lt;br /&gt;
    echo $db-&amp;gt;getQuery();&lt;br /&gt;
}&lt;br /&gt;
$stats = $db-&amp;gt;loadObjectList();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Doc Blocks ===&lt;br /&gt;
&lt;br /&gt;
All source code files in the core Joomla distribution must contain the following comment block as the header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @version	$Id$&lt;br /&gt;
 * @package	Joomla&lt;br /&gt;
 * @copyright	Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.&lt;br /&gt;
 * @license	GNU/GPL, see LICENSE.php&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@package&amp;lt;/code&amp;gt; in the header is not required for class-only files.&lt;br /&gt;
&lt;br /&gt;
Classes, functions, constants, class properties and class methods should all be supplied with appropriate DocBlocks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Short description for class&lt;br /&gt;
 *&lt;br /&gt;
 * Long description for class (if any)...&lt;br /&gt;
 *&lt;br /&gt;
 * @package    PackageName&lt;br /&gt;
 * @subpackage SubPackageName&lt;br /&gt;
 * @link       http://pear.php.net/package/PackageName&lt;br /&gt;
 * @see        NetOther, Net_Sample::Net_Sample()&lt;br /&gt;
 * @since      Class available since Release 1.2.0&lt;br /&gt;
 * @deprecated Class deprecated in Release 2.0.0&lt;br /&gt;
 */&lt;br /&gt;
class JFooBar&lt;br /&gt;
{&lt;br /&gt;
    /**&lt;br /&gt;
     * @var int $id Primary key&lt;br /&gt;
     */&lt;br /&gt;
    public $id = null;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following package names are to be used in the core stack:&lt;br /&gt;
&lt;br /&gt;
* Joomla.Administrator - all files that belong only to the administrator or backend application&lt;br /&gt;
* Joomla.Installation - all files that belong to the installation application&lt;br /&gt;
* Joomla.Plugin - all plugin files&lt;br /&gt;
* Joomla.Site - all files that pertain only to the site or frontend application&lt;br /&gt;
* Joomla.XML-RPC - all files that belong to the XML-RPC server application&lt;br /&gt;
&lt;br /&gt;
The sub-package name will vary according to the extension type:&lt;br /&gt;
&lt;br /&gt;
* Components - the component folder, eg &amp;lt;code&amp;gt;com_content&amp;lt;/code&amp;gt;&lt;br /&gt;
* Modules - the module folder, eg &amp;lt;code&amp;gt;mod_latest_news&amp;lt;/code&amp;gt;&lt;br /&gt;
* Plugins - the folder.element, eg &amp;lt;code&amp;gt;content.pagebreak&amp;lt;/code&amp;gt;&lt;br /&gt;
* Templates - the template folder, eg &amp;lt;code&amp;gt;rhuk_milkyway&amp;lt;/code&amp;gt;&lt;br /&gt;
* Framework - nothing for top level files (such as &amp;lt;code&amp;gt;factory.php&amp;lt;/code&amp;gt;), the first level folder or the first.second level folders as appropriate, eg &amp;lt;code&amp;gt;utilities&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;joomla/utilities/date.php&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;html.html&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;joomla/html/html/email.php&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that code contributed to the Joomla stack that will become the copyright of the project is not allowed to include &amp;lt;code&amp;gt;@author&amp;lt;/code&amp;gt; tags.  You should update the contribution log in &amp;lt;tt&amp;gt;CREDITS.php&amp;lt;/tt&amp;gt;.  Joomla&#039;s philosophy is that the code is written &amp;quot;all together&amp;quot; and there is no notion of any one person &#039;owning&#039; any section of code.&lt;br /&gt;
&lt;br /&gt;
Files included from third party sources must leave DocBlocks intact. Layout files use the same DocBlocks as other PHP files. &lt;br /&gt;
&lt;br /&gt;
Note that the &amp;quot;@version $Id&amp;quot; line uses the SVN &amp;quot;keywords=Id&amp;quot; property. See [[Subversion File Properties]] for information about setting this property.&lt;br /&gt;
&lt;br /&gt;
== Naming Conventions ==&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
Classes should be given descriptive names. Avoid using abbreviations where possible. Class names should always begin with an uppercase letter and be written in CamelCase even if using traditionally uppercase acronyms (such as XML, HTML).  One exception is for Joomla framework classes which must begin with an uppercase &#039;J&#039; with the next letter also being uppercase.  For example:&lt;br /&gt;
&lt;br /&gt;
* JHtmlHelper&lt;br /&gt;
* JXmlParser&lt;br /&gt;
* JModel&lt;br /&gt;
&lt;br /&gt;
Third-party developers are advised to namespace their functions with a unique prefix.&lt;br /&gt;
&lt;br /&gt;
=== Functions and Methods ===&lt;br /&gt;
&lt;br /&gt;
Functions and methods should be named using the &amp;quot;studly caps&amp;quot; style (also referred to as &amp;quot;bumpy case&amp;quot; or &amp;quot;camel caps&amp;quot;). The initial letter of the name is lowercase, and each letter that starts a new &amp;quot;word&amp;quot; is capitalized. Function in the Joomla framework must begin with a lowercase &#039;j&#039;.  Some examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
connect();&lt;br /&gt;
getData();&lt;br /&gt;
buildSomeWidget();&lt;br /&gt;
jImport();&lt;br /&gt;
jDoSomething();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private class members (meaning class members that are intended to be used only from within the same class in which they are declared; are preceded by a single underscore. Properties are to be written in underscore format (that is, logical words separated by underscores) and should be all lowercase.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JFooBar&lt;br /&gt;
{&lt;br /&gt;
    // Joomla 1.5 and earlier format&lt;br /&gt;
    var $_status = null;&lt;br /&gt;
&lt;br /&gt;
    function _sort()&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Joomla 1.6 format&lt;br /&gt;
    private $_status = null;&lt;br /&gt;
&lt;br /&gt;
    protected $field_name = null;&lt;br /&gt;
&lt;br /&gt;
    protected function _sort()&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
Constants should always be all-uppercase, with underscores to separate words. Prefix constant names with the uppercase name of the class/package they are used in. For example, the constants used by the [[JError]] class all begin with &amp;quot;JERROR_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Global Variables ===&lt;br /&gt;
&lt;br /&gt;
If your package needs to define global variables, their name should start with a single underscore followed by the uppercase class/package name and another underscore. For example, the JError class uses a global variable called $_JERROR_LEVELS.&lt;br /&gt;
&lt;br /&gt;
With PHP5 and later you may use static class properties or constants instead of globals.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class JWhatever&lt;br /&gt;
{&lt;br /&gt;
    public static $instance = null;&lt;br /&gt;
    const SUCCESS = 1;&lt;br /&gt;
    const FAILURE = 0;&lt;br /&gt;
    // Methods...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Regular and Class Variables ===&lt;br /&gt;
&lt;br /&gt;
Regular variables, follow the same conventions as function.&lt;br /&gt;
&lt;br /&gt;
Class variables should be set to null or some other appropriate default value. Lining up the default values with tabs should only be used if particularly warranted for readability.&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
&lt;br /&gt;
When using references, there should be a space before the reference operator and no space between it and the function or variable name.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$ref1  = &amp;amp;$this-&amp;gt;_sql;&lt;br /&gt;
$db    = &amp;amp;JFactory::getDBO();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language Keys ===&lt;br /&gt;
&lt;br /&gt;
NOTE: This part has to be rewritten for 1.6 (JM)&lt;br /&gt;
&lt;br /&gt;
Except for the most common of words, such as &amp;quot;Yes&amp;quot;, &amp;quot;No&amp;quot;, &amp;quot;Show&amp;quot;, &amp;quot;Hide&amp;quot; all language keys should be namespaced to reflect the type of string they represent.  Always consider that if two extensions use the same key, the one loaded last will be the one that displays.  Namespacing should generally relate to the extension displaying the text. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
echo JText::_(&#039;Weblink Link&#039;);&lt;br /&gt;
echo JText::_(&#039;Weblink Title&#039;);&lt;br /&gt;
echo JText::_(&#039;Weblink Description&#039;);&lt;br /&gt;
&lt;br /&gt;
echo JText::_(&#039;Exception An error occurred while saving&#039;);&lt;br /&gt;
?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TODO: Link to page with &amp;quot;common&amp;quot; strings that can be used for typical actions in components, such a &amp;quot;Save&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Where the same English word is used in two different locations, two different language keys should be used to allow for cases where the translation results in different words or phrases.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// A table column title&lt;br /&gt;
&amp;lt;th&amp;gt;&amp;lt;?php echo JText::_(&#039;Weblink Column Title&#039;);?&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;&amp;lt;?php echo JText::_(&#039;Weblink Column Link&#039;);?&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// In the form&lt;br /&gt;
&amp;lt;?php echo JText::_(&#039;Weblink Title&#039;);?&amp;gt;&amp;lt;input name=&amp;quot;title&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;?php echo JText::_(&#039;Weblink Link&#039;);?&amp;gt;&amp;lt;input name=&amp;quot;link&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toolbar and Linkbar text should be prefixed Toolbar and Linkbar respectively.&lt;br /&gt;
&lt;br /&gt;
The language keys should be written as naturally as possible with spaces, not underscores separating words.  Long phrases can be condensed to reduce keys to a sensible length.  For example, tooltips for an edit field can be written like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo JText::_(&#039;Weblink Title&#039;);?&amp;gt;&amp;lt;input name=&amp;quot;title&amp;quot; title=&amp;quot;&amp;lt;?php echo JText::_(&#039;Weblink Title Desc&#039;);?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The convention used should be governed by common sense, but must be consistent.  In general consider how the language file will look with all keys sorted alphabetically.  Prefixes should be used to group text within a common context (such as column headings).  Suffixes should be used to group elements that logically go together (such as a field name and its description).&lt;br /&gt;
&lt;br /&gt;
Phrases must never be assembled by string concatenation. Each phrase must be represented by a single language key, using sprintf as appropriate to replace dynamic words in the phrase.  Where replacements are made, the word used should be as descriptive as possible and all-uppercase.  This assists the translators to determine the context of the replacement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
// Not permitted&lt;br /&gt;
echo JText::_(&#039;Deleted &#039;).$n.JText::_(&#039; items&#039;);&lt;br /&gt;
&lt;br /&gt;
// Permitted&lt;br /&gt;
echo JText::sprintf(&#039;Message Deleted NUMBER items&#039;, $n);&lt;br /&gt;
?&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reference in the language file would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;MESSAGE DELETED NUMBER ITEMS=Deleted %d Item(s)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If more than one dynamic string is used in a phrase, the printf markers should employ order placement as other languages might change the position of the strings. This is done via %[number]$[printf_type] as follows:&lt;br /&gt;
&lt;br /&gt;
Left to right language:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;PAGE X OF Y=Page %1$d of %2$d&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Right to left language:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;PAGE X OF Y=%2$d of %1$d egaP&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Controllers ===&lt;br /&gt;
&lt;br /&gt;
For single controller components, the naming convention is &#039;&#039;[Name]Controller&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Content Controller&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class ContentController extends JController&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The file name will generally be &#039;&#039;controller.php&#039;&#039; and is located in the component folder.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
com_content&lt;br /&gt;
 / controller.php&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a multi-controller components, such as the Banners in the Administrator, the convention is &#039;&#039;[Component]Controller[Name]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Banner Client Controller&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class BannerControllerClient extends JController&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The files will be located in a &amp;lt;tt&amp;gt;/controllers/&amp;lt;/tt&amp;gt; folder under the component folder.  The file names will reflect the name of the controller.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
com_banner&lt;br /&gt;
  /controllers/&lt;br /&gt;
    / banner.php&lt;br /&gt;
    / client.php&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Models===&lt;br /&gt;
&lt;br /&gt;
The naming convention is &#039;&#039;[Component]Model[Name]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Banner Client Model&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class BannerModelClient extends JModel&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The files will be located in a &amp;lt;tt&amp;gt;/models/&amp;lt;/tt&amp;gt; folder under the component folder.  The file names will reflect the name of the model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
com_banner&lt;br /&gt;
  /models/&lt;br /&gt;
    / banner.php&lt;br /&gt;
    / client.php&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Views ===&lt;br /&gt;
The naming convention is &#039;&#039;[Component]View[Name]&#039;&#039;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Contact Category View&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class ContactViewCategory extends JView&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The files will be located in a &amp;lt;tt&amp;gt;/view/&amp;lt;/tt&amp;gt; folder under the component folder. The subfolder names will reflect the name of a View.&lt;br /&gt;
&lt;br /&gt;
 com_contact&lt;br /&gt;
  /views/&lt;br /&gt;
    /&#039;&#039;view name 1&#039;&#039;/&lt;br /&gt;
      / view.html.php&lt;br /&gt;
    /&#039;&#039;view name 2&#039;&#039;/&lt;br /&gt;
      / view.html.php&lt;br /&gt;
&lt;br /&gt;
Multi-view components such as com_content may provide an optional &amp;quot;master&amp;quot; view class the specialised views extend from. It is located in the component folder and typically called &#039;&#039;view.php&#039;&#039;. The naming convention is &#039;&#039;[Component]View&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 com_content&lt;br /&gt;
  /views/&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#999&amp;quot;&amp;gt;/archive/&amp;lt;/span&amp;gt;&lt;br /&gt;
       / view.html.php&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:#999&amp;quot;&amp;gt;/article/&amp;lt;/span&amp;gt;&lt;br /&gt;
  / view.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
view.php&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Content View&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class ContentView extends JView&lt;br /&gt;
{&lt;br /&gt;
    // Helper Methods&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
views/archive/view.html.php&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Content Archive View&lt;br /&gt;
 * @package Joomla&lt;br /&gt;
 */&lt;br /&gt;
class ContactViewArchive extends ContentView&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Plugins ===&lt;br /&gt;
&lt;br /&gt;
The naming convention is &#039;&#039;plg[Folder][Element]&#039;&#039; as pointed out in [[How to create a content plugin|the relative HowTo page]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class plgContentPagebreak extends JPlugin&lt;br /&gt;
{&lt;br /&gt;
    // Methods&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Layouts ===&lt;br /&gt;
Components may support different Layouts to render the data supplied by a [[#Views|View]] and its [[#Models|Models]]. A Layout file usually contains markup and some PHP code for &#039;&#039;display logic only&#039;&#039;: no functions, no classes.&lt;br /&gt;
&lt;br /&gt;
A Layout consists of at least one .php file and an equally named [[Creating a basic layout.xml file|.xml manifest file]] located in the &amp;lt;tt&amp;gt;/tmpl/&amp;lt;/tt&amp;gt; folder of a View, both reflect the internal name of the Layout. The standard Layout is called &#039;&#039;default&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:#999&amp;quot;&amp;gt;com_content&lt;br /&gt;
   /views/&lt;br /&gt;
     /article/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:#000&amp;quot;&amp;gt;&lt;br /&gt;
       /tmpl/&lt;br /&gt;
         / default.php&lt;br /&gt;
         / default.xml&lt;br /&gt;
         / form.php&lt;br /&gt;
         / form.xml&lt;br /&gt;
         / pagebreak.php&lt;br /&gt;
         / pagebreak.xml &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Layout may use supplemental .php files to provide more granule control in order to render individual parts or repetitive items of the data.&lt;br /&gt;
&lt;br /&gt;
Users may customize the Layout output via [[#Template Layout Overrides|Template Layout Overrides]].&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
=== Template Layout Overrides ===&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_2&amp;diff=26770</id>
		<title>Unit Test Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_2&amp;diff=26770"/>
		<updated>2010-04-20T03:12:42Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Looking at the Unit Test Class */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Looking at the Unit Test Class ==&lt;br /&gt;
&lt;br /&gt;
In our first unit test, we create a single test.  This test was a part of a presumed preexisting test class.  Although an individual test can be contained in a single method, these methods have to be a part of a test class.&lt;br /&gt;
&lt;br /&gt;
Unit Test classes generally inherit from the class &#039;PHPUnit_Framework_TestCase&#039;.&lt;br /&gt;
&lt;br /&gt;
You can see a basic test class below:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @version		$Id$&lt;br /&gt;
 * @copyright	Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.&lt;br /&gt;
 * @license		GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
require_once JPATH_BASE.&#039;/libraries/joomla/utilities/arrayhelper.php&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Test class for JArrayHelper.&lt;br /&gt;
 */&lt;br /&gt;
class JArrayHelperTest extends PHPUnit_Framework_TestCase {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Sets up the fixture, for example, opens a network connection.&lt;br /&gt;
	 * This method is called before a test is executed.&lt;br /&gt;
	 *&lt;br /&gt;
	 * @access protected&lt;br /&gt;
	 */&lt;br /&gt;
	protected function setUp() {&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Tears down the fixture, for example, closes a network connection.&lt;br /&gt;
	 * This method is called after a test is executed.&lt;br /&gt;
	 *&lt;br /&gt;
	 * @access protected&lt;br /&gt;
	 */&lt;br /&gt;
	protected function tearDown() {&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Simple Test for getColumn method.&lt;br /&gt;
	 */&lt;br /&gt;
	public function testGetColumn()&lt;br /&gt;
	{&lt;br /&gt;
		$test_array = array(&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
			),&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
			),&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
			)&lt;br /&gt;
		);&lt;br /&gt;
&lt;br /&gt;
		$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
		$this-&amp;gt;assertThat(&lt;br /&gt;
			$result_array,&lt;br /&gt;
			$this-&amp;gt;equalTo(&lt;br /&gt;
				array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
			),&lt;br /&gt;
			&#039;We did not get the proper column data back&#039;&lt;br /&gt;
		);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Okay, so some notes:&lt;br /&gt;
&lt;br /&gt;
* As noted, the class extends from PHPUnit_Framework_TestCase&lt;br /&gt;
* Outside of our class, we do a require for the class that we want to test&lt;br /&gt;
* Our class name starts with the name of the class we want to test and has &#039;Test&#039; appended to the end. i.e. we are testing JArrayHelper, so our test class is JArrayHelperTest.&lt;br /&gt;
* We have two methods that are not part of our tests: setUp() and tearDown(). As noted in the comments for these methods, setUp() is called before each test and tearDown() is called after each test. To clarify, if there are 10 tests in a class, they are each called ten times.  There are two other methods available that you can supply: setUpBeforeClass() and tearDownAfterClass(). As the names imply, these are each called before and after all the tests from the class are performed, thus getting executed once each.&lt;br /&gt;
* Test methods start with the word test and generally end with the name of the method that is under test.  We are testing the getColumn() method, therefore, our method is called testGetColumn(). As methods get more complicated, more than one method is required for testing. In this situation, method names that describe the general purpose of the method should be used.&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_2&amp;diff=26762</id>
		<title>Unit Test Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_2&amp;diff=26762"/>
		<updated>2010-04-19T04:08:35Z</updated>

		<summary type="html">&lt;p&gt;Ian: New page: == Looking at the Unit Test Class ==  In our first unit test, we create a single test.  This test was a part of a presumed preexisting test class.  Although an individual test can be conta...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Looking at the Unit Test Class ==&lt;br /&gt;
&lt;br /&gt;
In our first unit test, we create a single test.  This test was a part of a presumed preexisting test class.  Although an individual test can be contained in a single method, these methods have to be a part of a test class.&lt;br /&gt;
&lt;br /&gt;
Unit Test classes generally inherit from the class &#039;PHPUnit_Framework_TestCase&#039;.&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Running_Unit_Tests&amp;diff=26759</id>
		<title>Running Unit Tests</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Running_Unit_Tests&amp;diff=26759"/>
		<updated>2010-04-19T02:56:36Z</updated>

		<summary type="html">&lt;p&gt;Ian: New page:  == Running the Entire Test Suite ==  The entire test suite can be run by simply entering the test directory and typing phpunit:  &amp;lt;pre&amp;gt; cd /path/to/joomla/tests/unit phpunit &amp;lt;/pre&amp;gt;   == Sp...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Running the Entire Test Suite ==&lt;br /&gt;
&lt;br /&gt;
The entire test suite can be run by simply entering the test directory and typing phpunit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Specifying a Directory of Tests to Run ==&lt;br /&gt;
&lt;br /&gt;
You can run a subset of tests by specifying the directory path of the tests that you want to run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;phpunit suite/libraries/joomla/utilities&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will run all of the tests in the specified directory and any subdirectory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Using the --filter Parameter to Run Certain Tests ==&lt;br /&gt;
&lt;br /&gt;
The --filter parameter allows you to run a specific subset of the entire test suite.  The --filter parameter takes a regular expression that can be used to filter out tests.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;phpunit --filter JForm&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will scan through the suite directory and run tests that contain JForm in the class name or in the method name.&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26758</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26758"/>
		<updated>2010-04-19T02:44:24Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Running Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many situations where you may not want to run the whole test suite.  See the [[Running Unit Tests]] page for details on how to be selective with the tests that you run.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function testGetColumnTutorial()&lt;br /&gt;
{&lt;br /&gt;
	$test_array = array(&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
	$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;assertThat(&lt;br /&gt;
		$result_array,&lt;br /&gt;
		$this-&amp;gt;equalTo(&lt;br /&gt;
			array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
		),&lt;br /&gt;
		&#039;We did not get the proper column data back&#039;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26757</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26757"/>
		<updated>2010-04-19T02:43:44Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Running Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many situations where you may not want to run the whole test suite.  See the [Running Unit Tests] page for details on how to be selective with the tests that you run.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function testGetColumnTutorial()&lt;br /&gt;
{&lt;br /&gt;
	$test_array = array(&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
	$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;assertThat(&lt;br /&gt;
		$result_array,&lt;br /&gt;
		$this-&amp;gt;equalTo(&lt;br /&gt;
			array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
		),&lt;br /&gt;
		&#039;We did not get the proper column data back&#039;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26756</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26756"/>
		<updated>2010-04-19T02:40:15Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* 3. Tests assertions about the results (outputs) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function testGetColumnTutorial()&lt;br /&gt;
{&lt;br /&gt;
	$test_array = array(&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
	$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;assertThat(&lt;br /&gt;
		$result_array,&lt;br /&gt;
		$this-&amp;gt;equalTo(&lt;br /&gt;
			array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
		),&lt;br /&gt;
		&#039;We did not get the proper column data back&#039;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26755</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26755"/>
		<updated>2010-04-19T02:39:02Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* 3. Tests assertions about the results (outputs) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function testGetColumnTutorial()&lt;br /&gt;
{&lt;br /&gt;
	$test_array = array(&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
	$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
	$this-&amp;gt;assertThat(&lt;br /&gt;
		$result_array,&lt;br /&gt;
		$this-&amp;gt;equalTo(&lt;br /&gt;
			array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
		),&lt;br /&gt;
		&#039;We did not get the proper column data back&#039;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26754</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26754"/>
		<updated>2010-04-19T02:38:27Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* 3. Tests assertions about the results (outputs) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
	public function testGetColumnTutorial()&lt;br /&gt;
	{&lt;br /&gt;
		$test_array = array(&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
			),&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
			),&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
			)&lt;br /&gt;
		);&lt;br /&gt;
		$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
		$this-&amp;gt;assertThat(&lt;br /&gt;
			$result_array,&lt;br /&gt;
			$this-&amp;gt;equalTo(&lt;br /&gt;
				array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
			),&lt;br /&gt;
			&#039;We did not get the proper column data back&#039;&lt;br /&gt;
		);&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26753</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26753"/>
		<updated>2010-04-19T02:33:56Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* 1. Setup Preconditions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26752</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=26752"/>
		<updated>2010-04-19T02:33:04Z</updated>

		<summary type="html">&lt;p&gt;Ian: New page:  = Unit Testing and Joomla! =  As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Portal:Administrators&amp;diff=22186</id>
		<title>Portal:Administrators</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Portal:Administrators&amp;diff=22186"/>
		<updated>2010-03-10T17:43:10Z</updated>

		<summary type="html">&lt;p&gt;Ian: Reverted edits by Louisakusnandar (Talk) to last version by E-builds&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{RightTOC}}&lt;br /&gt;
{{Administrator profile}}&lt;br /&gt;
&lt;br /&gt;
==Joomla! Administrator&#039;s Manual==&lt;br /&gt;
Note from the Doc Team: At the present time we are assembling an outline &amp;quot;content plan&amp;quot; for this document.  What you see is not complete and is subject to change as we re-organise stuff and develop our thinking of what should be included and where it should be placed.  The intention is that the list of topics you see below should be goal-orientated and not a &amp;quot;feature list&amp;quot; for the Administrator back-end.  The items should address real and common activities that an Administrator will need to perform from time to time.  Please feel free to help us by adding items you think should be included or amending items already present if you think they can be improved.&lt;br /&gt;
&lt;br /&gt;
===Managing the Website===&lt;br /&gt;
* [[taking the website temporarily offline]]&lt;br /&gt;
* [[changing the appearance of your site]]&lt;br /&gt;
* [[giving the Front Page a different style from other pages]]&lt;br /&gt;
* [[changing the style according to article section or category]]&lt;br /&gt;
* [[logging in or out of the Administrator back-end]]&lt;br /&gt;
* [[making your site Search Engine Friendly]]&lt;br /&gt;
* [[entering search engine meta-data]]&lt;br /&gt;
* [[moving the site among directories/sub-directories]]&lt;br /&gt;
&lt;br /&gt;
===Managing Users===&lt;br /&gt;
* [[setting user registration policy]]&lt;br /&gt;
** [[changing user registration settings]]&lt;br /&gt;
** [[disabling user registration]]&lt;br /&gt;
** [[allowing only manual user registration]]&lt;br /&gt;
** [[allowing user registration]]&lt;br /&gt;
** [[restricting user access to resources]]&lt;br /&gt;
* [[customising the Login Form module]]&lt;br /&gt;
** [[changing the Login Form module settings]]&lt;br /&gt;
** [[enabling the Login Form module]]&lt;br /&gt;
** [[assigning the Login Form module to selected web pages]]&lt;br /&gt;
** [[customising the information shown in the Login Form module]]&lt;br /&gt;
* [[adding a new user]]&lt;br /&gt;
* [[changing user groups]]&lt;br /&gt;
* [[resetting a user password]]&lt;br /&gt;
* [[listing a user on a contacts page]]&lt;br /&gt;
* [[dealing with a problem user]]&lt;br /&gt;
* [[sending an email to a user]]&lt;br /&gt;
* [[sending an email to a group of users]]&lt;br /&gt;
* [[sending a private message to a user]]&lt;br /&gt;
* [[reading a private message from a user]]&lt;br /&gt;
&lt;br /&gt;
===Access Control===&lt;br /&gt;
* [[ACL Tutorial for Joomla 1.6]] {{JVer|1.6}}&lt;br /&gt;
&lt;br /&gt;
===Managing Content===&lt;br /&gt;
* [[understanding sections, categories and articles]]&lt;br /&gt;
* [[creating a section and category hierarchy]]&lt;br /&gt;
* [[scheduling an Article to be available only between certain dates]]&lt;br /&gt;
* [[restricting access to an Article]]&lt;br /&gt;
* [[restricting access to &amp;quot;read more&amp;quot;]]&lt;br /&gt;
* [[restricting access to a Section]]&lt;br /&gt;
* [[restricting access to a Category]]&lt;br /&gt;
* [[removing email, print or PDF icons from all Articles]]&lt;br /&gt;
* [[removing author name, creation date or update date from all Articles]]&lt;br /&gt;
* [[moving an Article to the archive]]&lt;br /&gt;
* [[deleting an Article]]&lt;br /&gt;
&lt;br /&gt;
===Managing Articles===&lt;br /&gt;
* [[adding a new article]]&lt;br /&gt;
* [[adding an image to an article]]&lt;br /&gt;
* [[adding a menu item which points to an Article]]&lt;br /&gt;
* [[managing the front page]]&lt;br /&gt;
&lt;br /&gt;
===Editing an Article===&lt;br /&gt;
* [[inserting a heading into an Article]]&lt;br /&gt;
* [[inserting a list into an Article]]&lt;br /&gt;
* [[inserting a table into an Article]]&lt;br /&gt;
* [[modifying a table in an Article]]&lt;br /&gt;
* [[inserting a link to another Article or content page into an Article]]&lt;br /&gt;
* [[inserting a link to another website into an Article]]&lt;br /&gt;
* [[removing a link from an Article]]&lt;br /&gt;
* [[splitting an Article into an introduction with a link to read more]]&lt;br /&gt;
* [[removing email, print or PDF icons from an Article]]&lt;br /&gt;
* [[removing author name, creation date or update date from an Article]]&lt;br /&gt;
* [[previewing an Article]]&lt;br /&gt;
* [[splitting a long Article into multiple linked pages]]&lt;br /&gt;
&lt;br /&gt;
===Managing Menus===&lt;br /&gt;
* [[adding a new menu]]&lt;br /&gt;
* [[adding a new menu item]]&lt;br /&gt;
* [[changing the order of items in a menu]]&lt;br /&gt;
* [[moving a menu to a different position]]&lt;br /&gt;
* [[restricting access to a Menu]]&lt;br /&gt;
* [[restricting access to a Menu Item]]&lt;br /&gt;
* [[Tutorial: Creating a submenu | creating a submenu]]&lt;br /&gt;
&lt;br /&gt;
===Managing Contacts===&lt;br /&gt;
* [[restricting access to a Contact]]&lt;br /&gt;
* [[restricting access to a Contact Category]]&lt;br /&gt;
&lt;br /&gt;
===Managing Newsfeeds===&lt;br /&gt;
* [[restricting access to a Newsfeed Category]]&lt;br /&gt;
&lt;br /&gt;
===Managing Polls===&lt;br /&gt;
* [[adding a new Poll]]&lt;br /&gt;
&lt;br /&gt;
===Managing Web Links===&lt;br /&gt;
* [[restricting access to a Web Links Category]]&lt;br /&gt;
&lt;br /&gt;
===Managing Extensions===&lt;br /&gt;
* [[finding an extension]]&lt;br /&gt;
* [[installing an extension]]&lt;br /&gt;
* [[uninstalling an extension]]&lt;br /&gt;
* reinstalling deleted core extensions for [[Reinstalling deleted Joomla 1.5 core extensions|Joomla 1.5]] and [[Reinstalling deleted Joomla 1.0 core extensions|Joomla 1.0]]&lt;br /&gt;
* [[restricting access to a Module]]&lt;br /&gt;
* [[restricting access to a Plugin]]&lt;br /&gt;
&lt;br /&gt;
===Tips, tricks and performance===&lt;br /&gt;
* Speed up your site with caching: [[Cache]]&lt;br /&gt;
&lt;br /&gt;
==Joomla Security Guide==&lt;br /&gt;
Administrators should also be aware of security issues.&lt;br /&gt;
{{Security Guide}}&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Start_here&amp;diff=22185</id>
		<title>Start here</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Start_here&amp;diff=22185"/>
		<updated>2010-03-10T17:42:21Z</updated>

		<summary type="html">&lt;p&gt;Ian: Reverted edits by Louisakusnandar (Talk) to last version by Dextercowley&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To make it easy to find the information you need, read the profiles below and choose the one that most accurately describes your current role.  This will take you to an area where the documentation is organised according to the goals that you are most likely to require help with.  There is a lot of overlap in the documentation for each of these roles; they are not mutually exclusive; so just choose one that seems to be nearest to your own role even if the fit is not exact.  To make these user profiles more concrete and so help writers to target the material more accurately, we are looking at creating [[personas]] for each of the profiles.&lt;br /&gt;
;[[Beginners]]&lt;br /&gt;
:{{Beginner profile}}&lt;br /&gt;
;[[Evaluators]]&lt;br /&gt;
:{{Evaluators}}&lt;br /&gt;
;[[Content creators]]&lt;br /&gt;
:{{Content creator profile}}&lt;br /&gt;
;[[Editors]]&lt;br /&gt;
:{{Editor profile}}&lt;br /&gt;
;[[Publishers]]&lt;br /&gt;
:{{Publisher profile}}&lt;br /&gt;
;[[Administrators]]&lt;br /&gt;
:{{Administrator profile}}&lt;br /&gt;
;[[Web designers]]&lt;br /&gt;
:{{Web designer profile}}&lt;br /&gt;
;[[Web developers]]&lt;br /&gt;
:{{Web developer profile}}&lt;br /&gt;
;[[Developers]]&lt;br /&gt;
:{{Developer profile}}&lt;br /&gt;
;[[Testers]]&lt;br /&gt;
:{{Tester profile}}&lt;br /&gt;
;[[Translators]]&lt;br /&gt;
:{{Translator profile}}&lt;br /&gt;
;[[Trainers]]&lt;br /&gt;
:{{Trainer profile}}&lt;br /&gt;
;[[Documentors]]&lt;br /&gt;
:{{Documentor profile}}&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=21698</id>
		<title>System Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=21698"/>
		<updated>2010-02-11T14:47:25Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Joomla Core Selenium testcases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== News and Updates ==&lt;br /&gt;
2009 07 27 Document created.&lt;br /&gt;
&lt;br /&gt;
== Functional Testing ==&lt;br /&gt;
Functional (or system) testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of functional testing, visit the [http://en.wikipedia.org/wiki/Functional_Testing Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Open Source ===&lt;br /&gt;
Web applications have been notoriously difficult to do functional testing with. It has traditionally required a great deal of time and effort. This can be a special challenge for open source projects because testing is often not very popular and designing tests that can be executed in a systematic way even less so. For a complicated application like Joomla!, this means that although we might do testing, we very seldom are able to perform extensive testing on each release that covers even a fraction of the elements in the CMS.&lt;br /&gt;
&lt;br /&gt;
Relatively recently, a project called Selenium has arrived on the scene.  This project makes performing automated functional testing of web applications possible. This means that it is possible to devise a test and have it performed in an automated way without the requirement of somebody sitting in front of a browser and being a click monkey.&lt;br /&gt;
&lt;br /&gt;
The benefits of functional testing are:&lt;br /&gt;
* Functional tests help highlight cases where changes in one element of the system might cause breakage in other, unexpected areas.&lt;br /&gt;
* Functional tests help clearly specify how the application should behave.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing versus Unit Testing ===&lt;br /&gt;
In order to fully test an application, both functional and unit testing are essential. Each approach has their benefits and weaknesses. Unit testing is very good for isolating small chunks of code and ensuring that they are behaving as expected. Functional testing, on the other hand, is geared towards looking at the system as a whole and ensuring that the units are behaving together in a way that achieves the desired effect.&lt;br /&gt;
&lt;br /&gt;
The advantages of functional testing is that functional tests are easier to understand and conceptualize by people who are unfamiliar with the underlying code. With Selenium, tests can be designed by people who are not overly familiar with PHP - they only need to understand the application and what results should be expected.&lt;br /&gt;
&lt;br /&gt;
The downside of functional testing is that it will only tell you that something broke. It isn&#039;t as obvious with functional testing exactly what went wrong or where the problem is.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
If the purpose of unit tests is to isolate a module of code, then the purpose of functional tests is to evaluate the entire system. This is much easier for those unfamiliar with what happens under the hood of Joomla! because one is not required to understand what happens during a Joomla! page request. A functional test might evaluate, for example, if unpublishing an article works properly. Therefore, to design the test, it is only necessary to figure out how to change an article from Published to Unpublished, and how to verify that the article was actually unpublished.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Joomla! ===&lt;br /&gt;
I have recently been building a functional testing architecture that will make it possible to write tests once, and to execute those tests on a variety of platforms and clients. I currently have infrastructure in place that makes it possible to run one command and execute functional tests in one browser on one host system. I have designed the host system in such a way that it will run on 6 different PHP versions (stock Ubuntu PHP 5 and self-compiled PHP 4.3, 4.4, 5.0, 5.1 and 5.2) and 2 different web servers (Apache and Lighttpd).  These are all currently serving from the same database.&lt;br /&gt;
&lt;br /&gt;
The future steps will be to make it possible to run on multiple host systems (the requirement for this is to generalize the code that resets the database state after the tests are run) and to make it possible to use different clients (i.e. different systems with different web browsers). These steps should be fairly trivial, but I have not yet had time to focus on them.&lt;br /&gt;
&lt;br /&gt;
This will eventually make it possible to run the designed tests on every major browser and on multiple server platforms (various PHP versions, various configurations, various operating systems and various web servers).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Writing Functional Tests ====&lt;br /&gt;
Selenium IDE makes it fairly easy to write functional tests. It is a Firefox extension that operates as an Integrated Development Environment for creating functional tests. In essence, it records your clicks as you navigate in your browser and encodes them into a series of commands that can control the browser.&lt;br /&gt;
&lt;br /&gt;
===== Getting Selenium IDE =====&lt;br /&gt;
At the time of writing, the latest version of Selenium IDE is 1.0.2.  You can get it at http://seleniumhq.org/download/. Click on the download link and install like you would any Firefox plugin.&lt;br /&gt;
&lt;br /&gt;
===== Preparing your Environment =====&lt;br /&gt;
To get started, create a vanilla install of Joomla! with the standard sample data.&lt;br /&gt;
&lt;br /&gt;
===== Creating a Basic Test =====&lt;br /&gt;
To start, open Firefox and browse to the home page of your Joomla! install.  I setup my install on my localhost, and so the URL is http://127.0.0.1/selsampledata.&lt;br /&gt;
&lt;br /&gt;
Then, click on Tools -&amp;gt; Selenium IDE. You will notice that on the right of the window that appears near the top, that there is a red circle that is highlighted. This is the start/stop recording button. When you start Selenium IDE, recording starts right away.&lt;br /&gt;
&lt;br /&gt;
For our first test, all we will do is load up the home page and check to make sure that all the items in the Main Menu are present.&lt;br /&gt;
&lt;br /&gt;
The commands that we use to check that items are present are called assertions. Basically, you perform your actions and make assertions about the results.&lt;br /&gt;
&lt;br /&gt;
In our case, we are going to use the command assertText. This command will read the text of a specified element and ensure it matches a particular value.&lt;br /&gt;
&lt;br /&gt;
So, first ensure that the Base URL displayed in the Selenium IDE window is the home page of your Joomla! install.&lt;br /&gt;
&lt;br /&gt;
Then, switch to the window that has your Joomla install open.&lt;br /&gt;
&lt;br /&gt;
In that window, right click on each menu item and select &#039;Assert Text&#039;.&lt;br /&gt;
&lt;br /&gt;
Then, switch to your Selenium IDE window and click the Red Button to stop recording.&lt;br /&gt;
&lt;br /&gt;
You should see two tabs in your Selenium IDE window - one labeled Table, and one labeled Source. You don&#039;t really need to look at the Source window.&lt;br /&gt;
&lt;br /&gt;
So, now our first test is done.&lt;br /&gt;
&lt;br /&gt;
To run your test, you use the icons on the bar between the Base URL address bar and the Table and Source tabs. The two important buttons are the buttons with the Green Triangle with Three Solid rectangles and the one with the Green Triangle and One Solid Rectangle. The first one will execute the entire test suite and the second one will run the currently selected test case. Since we currently have only one test case, both of these currently do the same thing.&lt;br /&gt;
&lt;br /&gt;
To run your test, press one of these buttons.&lt;br /&gt;
&lt;br /&gt;
As you watch the Selenium IDE, you will see a yellow bar move down your list of steps. Once a step is completed, a successfully executed action (i.e. a button was successfully located and clicked) should show up in light green and a successful assertion should show up in darker green. Failed actions show up in light red and failed assertions show up in darker red.&lt;br /&gt;
&lt;br /&gt;
Click on the Window Expander on the left to unhide the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
If your test completed successfully, you should see Runs: 1, Failures: 0 at the bottom of the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
==== Running Functional Tests ====&lt;br /&gt;
&lt;br /&gt;
=== Joomla Core Selenium testcases ===&lt;br /&gt;
The testing repository for the Selenium test suite for version 1.5 can be found here:&lt;br /&gt;
&lt;br /&gt;
* [http://joomlacode.org/svn/joomla/development/releases/1.5/tests/system/ http://joomlacode.org/svn/joomla/development/releases/1.5/tests/system/]&lt;br /&gt;
&lt;br /&gt;
As of February 2010, the unit and functional tests for version1.6 have been incorporated into the SVN trunk under a folder called &amp;quot;tests&amp;quot;. More information about running the version 1.6 tests is available in the article [[Running Automated Tests for Version 1.6]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: If a login mask comes up, use &amp;lt;/br&amp;gt;&lt;br /&gt;
:User: anonymous &amp;lt;/br&amp;gt;&lt;br /&gt;
:Password: &amp;lt;empty&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
For writing a more advanced Selenium testcase see [http://docs.joomla.org/Intermediate_Selenium_Example here].&lt;br /&gt;
&lt;br /&gt;
[http://seleniumhq.org/docs/ Selenium documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Testing]]&lt;br /&gt;
[[Category:Bug Squad]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Functional_Testing&amp;diff=21697</id>
		<title>Functional Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Functional_Testing&amp;diff=21697"/>
		<updated>2010-02-11T14:44:51Z</updated>

		<summary type="html">&lt;p&gt;Ian: Functional Testing moved to System Testing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[System Testing]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=21696</id>
		<title>System Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=21696"/>
		<updated>2010-02-11T14:44:51Z</updated>

		<summary type="html">&lt;p&gt;Ian: Functional Testing moved to System Testing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== News and Updates ==&lt;br /&gt;
2009 07 27 Document created.&lt;br /&gt;
&lt;br /&gt;
== Functional Testing ==&lt;br /&gt;
Functional (or system) testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of functional testing, visit the [http://en.wikipedia.org/wiki/Functional_Testing Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Open Source ===&lt;br /&gt;
Web applications have been notoriously difficult to do functional testing with. It has traditionally required a great deal of time and effort. This can be a special challenge for open source projects because testing is often not very popular and designing tests that can be executed in a systematic way even less so. For a complicated application like Joomla!, this means that although we might do testing, we very seldom are able to perform extensive testing on each release that covers even a fraction of the elements in the CMS.&lt;br /&gt;
&lt;br /&gt;
Relatively recently, a project called Selenium has arrived on the scene.  This project makes performing automated functional testing of web applications possible. This means that it is possible to devise a test and have it performed in an automated way without the requirement of somebody sitting in front of a browser and being a click monkey.&lt;br /&gt;
&lt;br /&gt;
The benefits of functional testing are:&lt;br /&gt;
* Functional tests help highlight cases where changes in one element of the system might cause breakage in other, unexpected areas.&lt;br /&gt;
* Functional tests help clearly specify how the application should behave.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing versus Unit Testing ===&lt;br /&gt;
In order to fully test an application, both functional and unit testing are essential. Each approach has their benefits and weaknesses. Unit testing is very good for isolating small chunks of code and ensuring that they are behaving as expected. Functional testing, on the other hand, is geared towards looking at the system as a whole and ensuring that the units are behaving together in a way that achieves the desired effect.&lt;br /&gt;
&lt;br /&gt;
The advantages of functional testing is that functional tests are easier to understand and conceptualize by people who are unfamiliar with the underlying code. With Selenium, tests can be designed by people who are not overly familiar with PHP - they only need to understand the application and what results should be expected.&lt;br /&gt;
&lt;br /&gt;
The downside of functional testing is that it will only tell you that something broke. It isn&#039;t as obvious with functional testing exactly what went wrong or where the problem is.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
If the purpose of unit tests is to isolate a module of code, then the purpose of functional tests is to evaluate the entire system. This is much easier for those unfamiliar with what happens under the hood of Joomla! because one is not required to understand what happens during a Joomla! page request. A functional test might evaluate, for example, if unpublishing an article works properly. Therefore, to design the test, it is only necessary to figure out how to change an article from Published to Unpublished, and how to verify that the article was actually unpublished.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Joomla! ===&lt;br /&gt;
I have recently been building a functional testing architecture that will make it possible to write tests once, and to execute those tests on a variety of platforms and clients. I currently have infrastructure in place that makes it possible to run one command and execute functional tests in one browser on one host system. I have designed the host system in such a way that it will run on 6 different PHP versions (stock Ubuntu PHP 5 and self-compiled PHP 4.3, 4.4, 5.0, 5.1 and 5.2) and 2 different web servers (Apache and Lighttpd).  These are all currently serving from the same database.&lt;br /&gt;
&lt;br /&gt;
The future steps will be to make it possible to run on multiple host systems (the requirement for this is to generalize the code that resets the database state after the tests are run) and to make it possible to use different clients (i.e. different systems with different web browsers). These steps should be fairly trivial, but I have not yet had time to focus on them.&lt;br /&gt;
&lt;br /&gt;
This will eventually make it possible to run the designed tests on every major browser and on multiple server platforms (various PHP versions, various configurations, various operating systems and various web servers).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Writing Functional Tests ====&lt;br /&gt;
Selenium IDE makes it fairly easy to write functional tests. It is a Firefox extension that operates as an Integrated Development Environment for creating functional tests. In essence, it records your clicks as you navigate in your browser and encodes them into a series of commands that can control the browser.&lt;br /&gt;
&lt;br /&gt;
===== Getting Selenium IDE =====&lt;br /&gt;
At the time of writing, the latest version of Selenium IDE is 1.0.2.  You can get it at http://seleniumhq.org/download/. Click on the download link and install like you would any Firefox plugin.&lt;br /&gt;
&lt;br /&gt;
===== Preparing your Environment =====&lt;br /&gt;
To get started, create a vanilla install of Joomla! with the standard sample data.&lt;br /&gt;
&lt;br /&gt;
===== Creating a Basic Test =====&lt;br /&gt;
To start, open Firefox and browse to the home page of your Joomla! install.  I setup my install on my localhost, and so the URL is http://127.0.0.1/selsampledata.&lt;br /&gt;
&lt;br /&gt;
Then, click on Tools -&amp;gt; Selenium IDE. You will notice that on the right of the window that appears near the top, that there is a red circle that is highlighted. This is the start/stop recording button. When you start Selenium IDE, recording starts right away.&lt;br /&gt;
&lt;br /&gt;
For our first test, all we will do is load up the home page and check to make sure that all the items in the Main Menu are present.&lt;br /&gt;
&lt;br /&gt;
The commands that we use to check that items are present are called assertions. Basically, you perform your actions and make assertions about the results.&lt;br /&gt;
&lt;br /&gt;
In our case, we are going to use the command assertText. This command will read the text of a specified element and ensure it matches a particular value.&lt;br /&gt;
&lt;br /&gt;
So, first ensure that the Base URL displayed in the Selenium IDE window is the home page of your Joomla! install.&lt;br /&gt;
&lt;br /&gt;
Then, switch to the window that has your Joomla install open.&lt;br /&gt;
&lt;br /&gt;
In that window, right click on each menu item and select &#039;Assert Text&#039;.&lt;br /&gt;
&lt;br /&gt;
Then, switch to your Selenium IDE window and click the Red Button to stop recording.&lt;br /&gt;
&lt;br /&gt;
You should see two tabs in your Selenium IDE window - one labeled Table, and one labeled Source. You don&#039;t really need to look at the Source window.&lt;br /&gt;
&lt;br /&gt;
So, now our first test is done.&lt;br /&gt;
&lt;br /&gt;
To run your test, you use the icons on the bar between the Base URL address bar and the Table and Source tabs. The two important buttons are the buttons with the Green Triangle with Three Solid rectangles and the one with the Green Triangle and One Solid Rectangle. The first one will execute the entire test suite and the second one will run the currently selected test case. Since we currently have only one test case, both of these currently do the same thing.&lt;br /&gt;
&lt;br /&gt;
To run your test, press one of these buttons.&lt;br /&gt;
&lt;br /&gt;
As you watch the Selenium IDE, you will see a yellow bar move down your list of steps. Once a step is completed, a successfully executed action (i.e. a button was successfully located and clicked) should show up in light green and a successful assertion should show up in darker green. Failed actions show up in light red and failed assertions show up in darker red.&lt;br /&gt;
&lt;br /&gt;
Click on the Window Expander on the left to unhide the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
If your test completed successfully, you should see Runs: 1, Failures: 0 at the bottom of the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
==== Running Functional Tests ====&lt;br /&gt;
&lt;br /&gt;
=== Joomla Core Selenium testcases ===&lt;br /&gt;
The testing repository for the Selenium test suite for version 1.5 can be found here:&lt;br /&gt;
&lt;br /&gt;
* [http://joomlacode.org/svn/joomla/testing/trunk/1.5/functionaltest/selenium/ http://joomlacode.org/svn/joomla/testing/trunk/1.5/functionaltest/selenium/]&lt;br /&gt;
&lt;br /&gt;
As of February 2010, the unit and functional tests for version 1.6 have been incorporated into the SVN trunk under a folder called &amp;quot;tests&amp;quot;. More information about running the version 1.6 tests is available in the article [[Running Automated Tests for Version 1.6]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: If a login mask comes up, use &amp;lt;/br&amp;gt;&lt;br /&gt;
:User: anonymous &amp;lt;/br&amp;gt;&lt;br /&gt;
:Password: &amp;lt;empty&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
For writing a more advanced Selenium testcase see [http://docs.joomla.org/Intermediate_Selenium_Example here].&lt;br /&gt;
&lt;br /&gt;
[http://seleniumhq.org/docs/ Selenium documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Testing]]&lt;br /&gt;
[[Category:Bug Squad]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Writing_Functional_Tests_for_Version_1.6&amp;diff=21695</id>
		<title>Writing Functional Tests for Version 1.6</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Writing_Functional_Tests_for_Version_1.6&amp;diff=21695"/>
		<updated>2010-02-11T14:43:38Z</updated>

		<summary type="html">&lt;p&gt;Ian: Writing Functional Tests for Version 1.6 moved to Writing System Tests for Version 1.6: Adjusting to use new nomenclature.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Writing System Tests for Version 1.6]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Writing_System_Tests_for_Joomla!_-_Part_1&amp;diff=21694</id>
		<title>Writing System Tests for Joomla! - Part 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Writing_System_Tests_for_Joomla!_-_Part_1&amp;diff=21694"/>
		<updated>2010-02-11T14:43:01Z</updated>

		<summary type="html">&lt;p&gt;Ian: Writing Functional Tests for Version 1.6 moved to Writing System Tests for Version 1.6: Adjusting to use new nomenclature.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{stub}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
As documented at [[Running_Automated_Tests_for_Version_1.6]], Joomla! version 1.6 now includes a library of system tests. This document details the steps necessary to create system tests using Selenium IDE. You will also need to run Firefox and install the Selenium IDE add-on to Firefox. Instructions for this can be found in the [[Functional Testing]] article. &lt;br /&gt;
&lt;br /&gt;
NOTE: This article assumes that you have read the aforementioned article and have PHPUnit and Selenium set up and working properly.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Writing a system test essentially entails converting a Selenium IDE test to a format that we can easily integrate into the Joomla! test suite. &lt;br /&gt;
See [[Functional_Testing]] for a good primer on system tests as well as [[Intermediate_Selenium_Example]] for a great example of creating an Intermediate Selenium test.&lt;br /&gt;
&lt;br /&gt;
== Creating a basic system test ==&lt;br /&gt;
A few items to note:&lt;br /&gt;
* It&#039;s recommended to update your local copy of 1.6 to the latest build before writing any tests.&lt;br /&gt;
* The test are written in PHP and we are using Selenium RC to execute them later. You will need to select the PHP Selenium RC Format in Slenium IDE. Go to Options -&amp;gt; Format -&amp;gt; PHP Selenium RC&lt;br /&gt;
* More information about writing test can be found at [http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html]&lt;br /&gt;
&lt;br /&gt;
In this test, we are going to execute the test described at [[Intermediate_Selenium_Example]] and integrate it into the system tests suite in 1.6.&lt;br /&gt;
&lt;br /&gt;
1. Open 1.6 in FireFox and navigate to the home page.&lt;br /&gt;
&lt;br /&gt;
2. Open Selenium IDE by going to the Tools menu and select Selenium IDE. Selenium will start recording automatically and the record button will appear highlighted.&lt;br /&gt;
&lt;br /&gt;
3. Verify that the Base URL displayed in Selenium is that of your test site.&lt;br /&gt;
&lt;br /&gt;
4. Perform the test by following the instructions described above (note: there are some slight variations between the test described above and the one we performed. This is due to variation of 1.6 during the development process).&lt;br /&gt;
&lt;br /&gt;
5. When you have completed your test, click the the red record button (see image below) to stop recording. &lt;br /&gt;
&lt;br /&gt;
[[Image:Selenium-screen.png]]&lt;br /&gt;
&lt;br /&gt;
6. Once recording has stopped, create a new PHP file in Eclipse (or your favorite code editor) and copy / paste the code from Selenium IDE to there. The contents of the example test is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
require_once &#039;PHPUnit/Extensions/SeleniumTestCase.php&#039;;&lt;br /&gt;
&lt;br /&gt;
class Example extends PHPUnit_Extensions_SeleniumTestCase&lt;br /&gt;
{&lt;br /&gt;
  function setUp()&lt;br /&gt;
  {&lt;br /&gt;
    $this-&amp;gt;setBrowser(&amp;quot;*chrome&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;setBrowserUrl(&amp;quot;http://change-this-to-the-site-you-are-testing/&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  function testMyTestCase()&lt;br /&gt;
  {&lt;br /&gt;
    $this-&amp;gt;open(&amp;quot;/workspace/joomla-1-6-source/administrator/index.php?option=com_login&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;mod-login-username&amp;quot;, &amp;quot;admin&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Log in&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=User Manager&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;//li[@id=&#039;toolbar-new&#039;]/a/span&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;jform_name&amp;quot;, &amp;quot;My Test User&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;jform_username&amp;quot;, &amp;quot;TestUser&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;jform_password&amp;quot;, &amp;quot;password&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;jform_password2&amp;quot;, &amp;quot;password&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;jform_email&amp;quot;, &amp;quot;test@example.com&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;1group_2&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Save &amp;amp; Close&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    try {&lt;br /&gt;
        $this-&amp;gt;assertTrue($this-&amp;gt;isTextPresent(&amp;quot;Item successfully saved.&amp;quot;));&lt;br /&gt;
    } catch (PHPUnit_Framework_AssertionFailedError $e) {&lt;br /&gt;
        array_push($this-&amp;gt;verificationErrors, $e-&amp;gt;toString());&lt;br /&gt;
    }&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;search&amp;quot;, &amp;quot;TestUser&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;//button[@type=&#039;submit&#039;]&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    try {&lt;br /&gt;
        $this-&amp;gt;assertTrue($this-&amp;gt;isTextPresent(&amp;quot;TestUser&amp;quot;));&lt;br /&gt;
    } catch (PHPUnit_Framework_AssertionFailedError $e) {&lt;br /&gt;
        array_push($this-&amp;gt;verificationErrors, $e-&amp;gt;toString());&lt;br /&gt;
    }&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Log out&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Go to site home page.&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;modlgn_username&amp;quot;, &amp;quot;TestUser&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;modlgn_passwd&amp;quot;, &amp;quot;password&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;Submit&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    try {&lt;br /&gt;
        $this-&amp;gt;assertTrue($this-&amp;gt;isTextPresent(&amp;quot;My Test User&amp;quot;));&lt;br /&gt;
    } catch (PHPUnit_Framework_AssertionFailedError $e) {&lt;br /&gt;
        array_push($this-&amp;gt;verificationErrors, $e-&amp;gt;toString());&lt;br /&gt;
    }&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Logout&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;//button[@type=&#039;submit&#039;]&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Site Administrator&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;type(&amp;quot;mod-login-username&amp;quot;, &amp;quot;admin&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Log in&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;//img[@alt=&#039;User Manager&#039;]&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;cb0&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Delete&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
    try {&lt;br /&gt;
        $this-&amp;gt;assertTrue($this-&amp;gt;isTextPresent(&amp;quot;1 item(s) successfully deleted.&amp;quot;));&lt;br /&gt;
    } catch (PHPUnit_Framework_AssertionFailedError $e) {&lt;br /&gt;
        array_push($this-&amp;gt;verificationErrors, $e-&amp;gt;toString());&lt;br /&gt;
    }&lt;br /&gt;
    $this-&amp;gt;click(&amp;quot;link=Log out&amp;quot;);&lt;br /&gt;
    $this-&amp;gt;waitForPageToLoad(&amp;quot;30000&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted in [[Intermediate_Selenium_Example]] Selenium does not record passwords that are entered. Additionally, we can utilize [[Selenium_Test_Case_Methods]] to prevent coding path or login information in the test:&lt;br /&gt;
&lt;br /&gt;
1. The first step in integrating this test into &amp;lt;code&amp;gt;tests/suite&amp;lt;/code&amp;gt; is to call &amp;lt;code&amp;gt;SeleniumJoomlaTestCase.php&amp;lt;/code&amp;gt; so that we can utilize the Selenium Test Case Methods. To do this, we will replace the first portion of our code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;?php&lt;br /&gt;
require_once &#039;PHPUnit/Extensions/SeleniumTestCase.php&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;?php&lt;br /&gt;
require_once &#039;SeleniumJoomlaTestCase.php&#039;;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We can now start utilizing the Selenium Test Case Methods.&lt;br /&gt;
&lt;br /&gt;
2. We will now extend a class into our SeleniumJoomlaTestCase to implement the client/server protocol to talk to Selenium RC as well as specialized assertion methods for web testing. &lt;br /&gt;
&lt;br /&gt;
This is done by replacing:&lt;br /&gt;
&amp;lt;pre&amp;gt;class Example extends PHPUnit_Extensions_SeleniumTestCase&lt;br /&gt;
{&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;class MyTestCase extends SeleniumJoomlaTestCase&lt;br /&gt;
{&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Bug Squad]] [[Category:Development]] [[Category:Testing]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_can%27t_you_upload_files_using_the_flash_uploader%3F&amp;diff=20824</id>
		<title>Why can&#039;t you upload files using the flash uploader?</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_can%27t_you_upload_files_using_the_flash_uploader%3F&amp;diff=20824"/>
		<updated>2009-12-17T14:31:42Z</updated>

		<summary type="html">&lt;p&gt;Ian: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes the flash uploader does not work.&lt;br /&gt;
&lt;br /&gt;
There are known issues with the Flash Uploader and Flash 10.  At this time it is recommended to deactivate the Flash Uploader in the Main Configuration Settings and use the traditional and safe form uploader.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Joomla! 1.5]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15962</id>
		<title>Unit Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15962"/>
		<updated>2009-10-17T15:25:23Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* News and Updates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{cookiejar}}&lt;br /&gt;
== News and Updates ==&lt;br /&gt;
2009 10 06: Tests now depend on the SVN version of PHPUnit 3.4.1.&lt;br /&gt;
&lt;br /&gt;
2008 06 24: Update to reflect move of PHPUnit code from branch to trunk (former trunk now in /branches/old_simpletest).&lt;br /&gt;
&lt;br /&gt;
2008 06 22: Add information on limiting tests by version.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: Added --class-exclude, --sequence-exclude, and --test-exclude options.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: PHPUnit has been updated to version 3.2.21 with SVN rev 10436. Please update.&lt;br /&gt;
&lt;br /&gt;
== Unit Testing ==&lt;br /&gt;
Unit testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of unit testing, visit the [http://en.wikipedia.org/wiki/Unit_test Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Open Source ===&lt;br /&gt;
Open source projects, with multiple developers working in parallel around the world, can greatly benefit from unit testing. The main benefits are:&lt;br /&gt;
* Unit tests help highlight cases where seemingly minor changes cause unexpected breakage.&lt;br /&gt;
* Unit tests help clearly specify how a class should behave.&lt;br /&gt;
* Unit tests can expose design flaws very early in development.&lt;br /&gt;
* Unit tests make great examples. They are a great place for developers to learn how to use the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Testing Hierarchy: Unit, Subsystem, Integrated ===&lt;br /&gt;
Software testing systems usually run through a spectrum from &amp;quot;pure&amp;quot; unit tests through to fully integrated systems tests. We&#039;ve described low level unit tests above. Integrated testing typically involves some sort of script that simulates user actions and then verifies that the result matches what&#039;s expected. This sort of &amp;quot;end to end&amp;quot; test verifies that all parts of the system are working correctly.&lt;br /&gt;
&lt;br /&gt;
It&#039;s unfortunate that there is no clear nomenclature to describe all the intermediate stages of testing. The next stage beyond testing a single unit of code is subsystem testing. A subsystem test verifies that two or more units of code are interacting correctly to produce the desired result. In the simplest case, a subsystem test can be created simply by replacing mock objects with real objects and running unit tests on the top level module. In practise, this tends to not work as well as expected, because the original unit test data wasn&#039;t designed for a subsystem test, or because the nature of the test cases needs to be changed in order to fully test the subsystem. After all there is little point in simply repeating the unit test cases; the objective of a subsystem test should be to test boundary conditions and special cases that would be difficult to duplicate in unit tests.&lt;br /&gt;
&lt;br /&gt;
Once a subsystem has been tested, it can be integrated into a larger system, which is still a subset of the whole product. Tests can be written for larger and larger subsystems, but at each stage the complexity of the tests increases. At some point, the effort required to hand craft tests exceeds the benefits of running them. This is where integrated testing comes in.&lt;br /&gt;
&lt;br /&gt;
Integrated testing involves recording a user&#039;s interaction with the system into a script that can be replayed. The testing framework then compares the system&#039;s response with the expected response and passes or fails the test. The PHPUnit testing framework that we use has the ability to work with Selenium, a browser based test automation tool.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
The purpose of unit tests is to isolate a module of code. A test that tests only one thing provides better information than a test that involves several object interactions. But how do we isolate an object from its dependencies? By writing stub classes. [http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html xUnit Patterns] defines a the hierarchy of dummy classes, ranging from simple to complex:&lt;br /&gt;
* Dummy - Defines attributes and methods of a dummy class (not particularly useful in PHP).&lt;br /&gt;
* Fake - Provides canned responses to method calls and fixed attribute values. Good for speed.&lt;br /&gt;
* Stub - Allows the test to define responses to method calls (return values, exceptions) to simulate the dependent object.&lt;br /&gt;
* Spy - A Fake or Stub that records method calls and parameters for later analysis.&lt;br /&gt;
* Mock - A Fake or Stub with a set of expectations -- method calls and parameters -- that are automatically verified for correctness.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Joomla! ===&lt;br /&gt;
Unit testing capabilities in Joomla are still at an early stage. The intention is to define more standards for developing tests, and then to expand the scope of available tests.&lt;br /&gt;
&lt;br /&gt;
For an overview of unit testing status in Joomla visit the [[Unit_Testing_Status]] page.&lt;br /&gt;
&lt;br /&gt;
The SVN repository contains code under the /testing path. /testing/trunk used to contain code based on the SimpleTest framework. In early December 2007, the development team elected to move to the [http://www.phpunit.de PHPUnit] framework.&lt;br /&gt;
&lt;br /&gt;
The PHPUnit tests are available from &#039;&#039;&#039;/testing/trunk&#039;&#039;&#039;. Some new tests have been added, any remaining tests from the SimpleTest days are completely broken. See /testing/branches/old-simpletest if you need to run something from that suite.&lt;br /&gt;
&lt;br /&gt;
The unit tests are located in two places:&lt;br /&gt;
* /testing/trunk/1.5/unittest - these are tests for Joomla! 1.5 (/development/releases/1.5)&lt;br /&gt;
* /testing/trunk/1.6/unittest - there are tests for Joomla! 1.6 (/development/trunk)&lt;br /&gt;
&lt;br /&gt;
At this point, PHPUnit based tests only run in a command line environment.&lt;br /&gt;
&lt;br /&gt;
==== The Unit Test Team ====&lt;br /&gt;
If you can commit to the Joomla code base, then you should consider yourself part of the unit test team!&lt;br /&gt;
&lt;br /&gt;
Writing tests concurrently with code (or even before) is a good way to not only save development time, but a great tool for defending against regressions. Writing tests early in the development cycle also helps identify and resolve design issues sooner, which reduces refactoring.&lt;br /&gt;
&lt;br /&gt;
If you want to get started on unit testing, get in touch with Alan Langford (instance) or Ray Tsai (mihu). Either of us will be happy to help out.&lt;br /&gt;
&lt;br /&gt;
==== Current Work ====&lt;br /&gt;
* There is no longer any need to patch the main code to enable unit tests.&lt;br /&gt;
* Basic techniques for mock objects are defined.&lt;br /&gt;
* Strategies for dealing with local configuration is not yet complete, but there is a plan.&lt;br /&gt;
* Files of the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php use PHPUnit.&lt;br /&gt;
* The JDate tests present a good example of a data-driven test, but they won&#039;t run on the current 1.5 code base (there are some proposed API changes as a result of unit test development).&lt;br /&gt;
* Previously functional tests, such as JFTP, haven&#039;t been moved to the PHPUnit environment yet.&lt;br /&gt;
* The custom test runner is no longer needed. The current tests will run with the latest SVN version of PHPUnit 3.4. This code will eventually become PHPUnit 3.4.1.  Thanks to Sebastian Bergmann for his excellent work on an excellent project!&lt;br /&gt;
&lt;br /&gt;
==== Writing Unit Tests ====&lt;br /&gt;
At risk of stating the obvious, in the &amp;quot;purest&amp;quot; case the purpose of a unit test is to &#039;&#039;isolate a unit of code from its environment and to test the operation of that code&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This isolation is usually achieved by writing dummy classes that emulate the code unit&#039;s environment. These dummy objects can be passive, by simply simulating the environment, or they can be more active, keeping track of how they are being used by the test unit and reporting any variations from the expected behaviour. See [[Unit_Testing_Mock_Objects|Mock Objects in Joomla]] for a detailed example.&lt;br /&gt;
&lt;br /&gt;
An interesting aspect of writing tests is that they become &#039;&#039;de facto&#039;&#039; detailed technical specifications of the interfaces between units of code. The fact that these specifications can be verified in an automated way makes them a superb resource when refactoring code.&lt;br /&gt;
&lt;br /&gt;
The test code has a few templates designed to kick-start a test. They are:&lt;br /&gt;
&lt;br /&gt;
/unittest/sample-datatest-php.txt&lt;br /&gt;
/unittest/sample-simpletest.php.txt&lt;br /&gt;
&lt;br /&gt;
Here are some example tests: [[Unit_Testing_--_a_Simple_Example|Simple Example]], [[Unit_Testing_--_Data_Driven_Example|Data Driven Example]], [[Unit_Testing_--_Plugin_Example|Plugin Example]], [[Unit_Testing_--_UI_Example|UI Example]].&lt;br /&gt;
&lt;br /&gt;
==== Running Unit Tests ====&lt;br /&gt;
Test files follow the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php. For tests that are not class based, the first element refers to the object being tested. An example of this is the e-mail cloaking plugin test, which is called emailcloak-0000-mode1-Test.php.&lt;br /&gt;
&lt;br /&gt;
Joomla unit tests use the standard PHPUnit test runner.  See http://www.phpunit.de for documentation.&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
Before you start make sure you have installed PHPUnit and of course PHP (5!) properly...&lt;br /&gt;
&lt;br /&gt;
To get the unit tests to run on your Joomla! installation, perform the following steps:&lt;br /&gt;
* Create an instance of your Joomla! installation&lt;br /&gt;
* In the root checkout (or export) the latest version of the unit test code from SVN &#039;&#039;&amp;quot;/testing/trunk/1.5/unittest&amp;quot;&#039;&#039; or &#039;&#039;&amp;quot;/testing/trunk/1.6/unittest&amp;quot;&#039;&#039; to your installation base. This will create a &#039;&#039;&amp;quot;/unittest&amp;quot;&#039;&#039; sub-folder under your joomla installation.&lt;br /&gt;
* Change to the unittest directory.&lt;br /&gt;
* Run the unit test from the command prompt using the following command:&lt;br /&gt;
 phpunit tests&lt;br /&gt;
&lt;br /&gt;
The unit test will the run, and the results are rendered.&lt;br /&gt;
&lt;br /&gt;
See http://www.phpunit.de/manual/current/en/textui.html for help using the --filter switch to run only certain tests.  There are also many other command line switches you can use to get results in various formats.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
The provided configurations should work out of the box. We have seen problems with it (currently the cause is unknown). If you get an error like below, the solution is pretty easy.&lt;br /&gt;
&lt;br /&gt;
 file=/var/www/unittest/runtests.php&lt;br /&gt;
 posn=17&lt;br /&gt;
 base=runtests.php&lt;br /&gt;
 /var/www&lt;br /&gt;
  JPATH_BASE does not point to a valid Joomla! installation:&lt;br /&gt;
 JPATH_BASE = /var/www&lt;br /&gt;
  Please modify your copy of &amp;quot;TestConfiguration.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Modify the &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file and change the definition of the JPATH_BASE so it points to the path of you Joomla! installation, in the example below the Joomla! installation is installed at &amp;quot;&#039;&#039;/var/www/update&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 define(&#039;JPATH_BASE&#039;, &#039;/var/www/update&#039;);&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&#039;&#039;&#039;Why can&#039;t I use &amp;quot;phpunit &#039;&#039;testname.php&#039;&#039;&amp;quot; to run my tests?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The test facility has to do some work to be able to load the &amp;quot;Joomla!&amp;quot; framework and to be able to inject mock classes. It&#039;s difficult to do this from the PHPUnit test runner, so we built our own. Also, the Joomla test runner has specific options designed to make it easy to select specific tests. Over time we will add more functionality to the test runner so it has many of the capabilities of the phpunit command.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[http://www.phpunit.de/manual/current/en/ PHPUnit Manual]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15847</id>
		<title>Unit Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15847"/>
		<updated>2009-10-06T14:24:00Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* News and Updates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{cookiejar}}&lt;br /&gt;
== News and Updates ==&lt;br /&gt;
2009 10 06: Tests now depend on the SVN version of PHPUnit 3.4. Hopefully they release soon.&lt;br /&gt;
&lt;br /&gt;
2008 06 24: Update to reflect move of PHPUnit code from branch to trunk (former trunk now in /branches/old_simpletest).&lt;br /&gt;
&lt;br /&gt;
2008 06 22: Add information on limiting tests by version.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: Added --class-exclude, --sequence-exclude, and --test-exclude options.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: PHPUnit has been updated to version 3.2.21 with SVN rev 10436. Please update.&lt;br /&gt;
&lt;br /&gt;
== Unit Testing ==&lt;br /&gt;
Unit testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of unit testing, visit the [http://en.wikipedia.org/wiki/Unit_test Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Open Source ===&lt;br /&gt;
Open source projects, with multiple developers working in parallel around the world, can greatly benefit from unit testing. The main benefits are:&lt;br /&gt;
* Unit tests help highlight cases where seemingly minor changes cause unexpected breakage.&lt;br /&gt;
* Unit tests help clearly specify how a class should behave.&lt;br /&gt;
* Unit tests can expose design flaws very early in development.&lt;br /&gt;
* Unit tests make great examples. They are a great place for developers to learn how to use the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Testing Hierarchy: Unit, Subsystem, Integrated ===&lt;br /&gt;
Software testing systems usually run through a spectrum from &amp;quot;pure&amp;quot; unit tests through to fully integrated systems tests. We&#039;ve described low level unit tests above. Integrated testing typically involves some sort of script that simulates user actions and then verifies that the result matches what&#039;s expected. This sort of &amp;quot;end to end&amp;quot; test verifies that all parts of the system are working correctly.&lt;br /&gt;
&lt;br /&gt;
It&#039;s unfortunate that there is no clear nomenclature to describe all the intermediate stages of testing. The next stage beyond testing a single unit of code is subsystem testing. A subsystem test verifies that two or more units of code are interacting correctly to produce the desired result. In the simplest case, a subsystem test can be created simply by replacing mock objects with real objects and running unit tests on the top level module. In practise, this tends to not work as well as expected, because the original unit test data wasn&#039;t designed for a subsystem test, or because the nature of the test cases needs to be changed in order to fully test the subsystem. After all there is little point in simply repeating the unit test cases; the objective of a subsystem test should be to test boundary conditions and special cases that would be difficult to duplicate in unit tests.&lt;br /&gt;
&lt;br /&gt;
Once a subsystem has been tested, it can be integrated into a larger system, which is still a subset of the whole product. Tests can be written for larger and larger subsystems, but at each stage the complexity of the tests increases. At some point, the effort required to hand craft tests exceeds the benefits of running them. This is where integrated testing comes in.&lt;br /&gt;
&lt;br /&gt;
Integrated testing involves recording a user&#039;s interaction with the system into a script that can be replayed. The testing framework then compares the system&#039;s response with the expected response and passes or fails the test. The PHPUnit testing framework that we use has the ability to work with Selenium, a browser based test automation tool.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
The purpose of unit tests is to isolate a module of code. A test that tests only one thing provides better information than a test that involves several object interactions. But how do we isolate an object from its dependencies? By writing stub classes. [http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html xUnit Patterns] defines a the hierarchy of dummy classes, ranging from simple to complex:&lt;br /&gt;
* Dummy - Defines attributes and methods of a dummy class (not particularly useful in PHP).&lt;br /&gt;
* Fake - Provides canned responses to method calls and fixed attribute values. Good for speed.&lt;br /&gt;
* Stub - Allows the test to define responses to method calls (return values, exceptions) to simulate the dependent object.&lt;br /&gt;
* Spy - A Fake or Stub that records method calls and parameters for later analysis.&lt;br /&gt;
* Mock - A Fake or Stub with a set of expectations -- method calls and parameters -- that are automatically verified for correctness.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Joomla! ===&lt;br /&gt;
Unit testing capabilities in Joomla are still at an early stage. The intention is to define more standards for developing tests, and then to expand the scope of available tests.&lt;br /&gt;
&lt;br /&gt;
For an overview of unit testing status in Joomla visit the [[Unit_Testing_Status]] page.&lt;br /&gt;
&lt;br /&gt;
The SVN repository contains code under the /testing path. /testing/trunk used to contain code based on the SimpleTest framework. In early December 2007, the development team elected to move to the [http://www.phpunit.de PHPUnit] framework.&lt;br /&gt;
&lt;br /&gt;
The PHPUnit tests are available from &#039;&#039;&#039;/testing/trunk&#039;&#039;&#039;. Some new tests have been added, any remaining tests from the SimpleTest days are completely broken. See /testing/branches/old-simpletest if you need to run something from that suite.&lt;br /&gt;
&lt;br /&gt;
The unit tests are located in two places:&lt;br /&gt;
* /testing/trunk/1.5/unittest - these are tests for Joomla! 1.5 (/development/releases/1.5)&lt;br /&gt;
* /testing/trunk/1.6/unittest - there are tests for Joomla! 1.6 (/development/trunk)&lt;br /&gt;
&lt;br /&gt;
At this point, PHPUnit based tests only run in a command line environment.&lt;br /&gt;
&lt;br /&gt;
==== The Unit Test Team ====&lt;br /&gt;
If you can commit to the Joomla code base, then you should consider yourself part of the unit test team!&lt;br /&gt;
&lt;br /&gt;
Writing tests concurrently with code (or even before) is a good way to not only save development time, but a great tool for defending against regressions. Writing tests early in the development cycle also helps identify and resolve design issues sooner, which reduces refactoring.&lt;br /&gt;
&lt;br /&gt;
If you want to get started on unit testing, get in touch with Alan Langford (instance) or Ray Tsai (mihu). Either of us will be happy to help out.&lt;br /&gt;
&lt;br /&gt;
==== Current Work ====&lt;br /&gt;
* There is no longer any need to patch the main code to enable unit tests.&lt;br /&gt;
* Basic techniques for mock objects are defined.&lt;br /&gt;
* Strategies for dealing with local configuration is not yet complete, but there is a plan.&lt;br /&gt;
* Files of the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php use PHPUnit.&lt;br /&gt;
* The JDate tests present a good example of a data-driven test, but they won&#039;t run on the current 1.5 code base (there are some proposed API changes as a result of unit test development).&lt;br /&gt;
* Previously functional tests, such as JFTP, haven&#039;t been moved to the PHPUnit environment yet.&lt;br /&gt;
* The custom test runner is no longer needed. The current tests will run with the latest SVN version of PHPUnit 3.4. This code will eventually become PHPUnit 3.4.1.  Thanks to Sebastian Bergmann for his excellent work on an excellent project!&lt;br /&gt;
&lt;br /&gt;
==== Writing Unit Tests ====&lt;br /&gt;
At risk of stating the obvious, in the &amp;quot;purest&amp;quot; case the purpose of a unit test is to &#039;&#039;isolate a unit of code from its environment and to test the operation of that code&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This isolation is usually achieved by writing dummy classes that emulate the code unit&#039;s environment. These dummy objects can be passive, by simply simulating the environment, or they can be more active, keeping track of how they are being used by the test unit and reporting any variations from the expected behaviour. See [[Unit_Testing_Mock_Objects|Mock Objects in Joomla]] for a detailed example.&lt;br /&gt;
&lt;br /&gt;
An interesting aspect of writing tests is that they become &#039;&#039;de facto&#039;&#039; detailed technical specifications of the interfaces between units of code. The fact that these specifications can be verified in an automated way makes them a superb resource when refactoring code.&lt;br /&gt;
&lt;br /&gt;
The test code has a few templates designed to kick-start a test. They are:&lt;br /&gt;
&lt;br /&gt;
/unittest/sample-datatest-php.txt&lt;br /&gt;
/unittest/sample-simpletest.php.txt&lt;br /&gt;
&lt;br /&gt;
Here are some example tests: [[Unit_Testing_--_a_Simple_Example|Simple Example]], [[Unit_Testing_--_Data_Driven_Example|Data Driven Example]], [[Unit_Testing_--_Plugin_Example|Plugin Example]], [[Unit_Testing_--_UI_Example|UI Example]].&lt;br /&gt;
&lt;br /&gt;
==== Running Unit Tests ====&lt;br /&gt;
Test files follow the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php. For tests that are not class based, the first element refers to the object being tested. An example of this is the e-mail cloaking plugin test, which is called emailcloak-0000-mode1-Test.php.&lt;br /&gt;
&lt;br /&gt;
Joomla unit tests use the standard PHPUnit test runner.  See http://www.phpunit.de for documentation.&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
Before you start make sure you have installed PHPUnit and of course PHP (5!) properly...&lt;br /&gt;
&lt;br /&gt;
To get the unit tests to run on your Joomla! installation, perform the following steps:&lt;br /&gt;
* Create an instance of your Joomla! installation&lt;br /&gt;
* In the root checkout (or export) the latest version of the unit test code from SVN &#039;&#039;&amp;quot;/testing/trunk/1.5/unittest&amp;quot;&#039;&#039; or &#039;&#039;&amp;quot;/testing/trunk/1.6/unittest&amp;quot;&#039;&#039; to your installation base. This will create a &#039;&#039;&amp;quot;/unittest&amp;quot;&#039;&#039; sub-folder under your joomla installation.&lt;br /&gt;
* Change to the unittest directory.&lt;br /&gt;
* Run the unit test from the command prompt using the following command:&lt;br /&gt;
 phpunit tests&lt;br /&gt;
&lt;br /&gt;
The unit test will the run, and the results are rendered.&lt;br /&gt;
&lt;br /&gt;
See http://www.phpunit.de/manual/current/en/textui.html for help using the --filter switch to run only certain tests.  There are also many other command line switches you can use to get results in various formats.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
The provided configurations should work out of the box. We have seen problems with it (currently the cause is unknown). If you get an error like below, the solution is pretty easy.&lt;br /&gt;
&lt;br /&gt;
 file=/var/www/unittest/runtests.php&lt;br /&gt;
 posn=17&lt;br /&gt;
 base=runtests.php&lt;br /&gt;
 /var/www&lt;br /&gt;
  JPATH_BASE does not point to a valid Joomla! installation:&lt;br /&gt;
 JPATH_BASE = /var/www&lt;br /&gt;
  Please modify your copy of &amp;quot;TestConfiguration.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Modify the &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file and change the definition of the JPATH_BASE so it points to the path of you Joomla! installation, in the example below the Joomla! installation is installed at &amp;quot;&#039;&#039;/var/www/update&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 define(&#039;JPATH_BASE&#039;, &#039;/var/www/update&#039;);&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&#039;&#039;&#039;Why can&#039;t I use &amp;quot;phpunit &#039;&#039;testname.php&#039;&#039;&amp;quot; to run my tests?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The test facility has to do some work to be able to load the &amp;quot;Joomla!&amp;quot; framework and to be able to inject mock classes. It&#039;s difficult to do this from the PHPUnit test runner, so we built our own. Also, the Joomla test runner has specific options designed to make it easy to select specific tests. Over time we will add more functionality to the test runner so it has many of the capabilities of the phpunit command.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[http://www.phpunit.de/manual/current/en/ PHPUnit Manual]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15846</id>
		<title>Unit Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15846"/>
		<updated>2009-10-06T14:22:25Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* How to Get it Running */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{cookiejar}}&lt;br /&gt;
== News and Updates ==&lt;br /&gt;
2008 06 24: Update to reflect move of PHPUnit code from branch to trunk (former trunk now in /branches/old_simpletest).&lt;br /&gt;
&lt;br /&gt;
2008 06 22: Add information on limiting tests by version.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: Added --class-exclude, --sequence-exclude, and --test-exclude options.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: PHPUnit has been updated to version 3.2.21 with SVN rev 10436. Please update.&lt;br /&gt;
&lt;br /&gt;
== Unit Testing ==&lt;br /&gt;
Unit testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of unit testing, visit the [http://en.wikipedia.org/wiki/Unit_test Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Open Source ===&lt;br /&gt;
Open source projects, with multiple developers working in parallel around the world, can greatly benefit from unit testing. The main benefits are:&lt;br /&gt;
* Unit tests help highlight cases where seemingly minor changes cause unexpected breakage.&lt;br /&gt;
* Unit tests help clearly specify how a class should behave.&lt;br /&gt;
* Unit tests can expose design flaws very early in development.&lt;br /&gt;
* Unit tests make great examples. They are a great place for developers to learn how to use the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Testing Hierarchy: Unit, Subsystem, Integrated ===&lt;br /&gt;
Software testing systems usually run through a spectrum from &amp;quot;pure&amp;quot; unit tests through to fully integrated systems tests. We&#039;ve described low level unit tests above. Integrated testing typically involves some sort of script that simulates user actions and then verifies that the result matches what&#039;s expected. This sort of &amp;quot;end to end&amp;quot; test verifies that all parts of the system are working correctly.&lt;br /&gt;
&lt;br /&gt;
It&#039;s unfortunate that there is no clear nomenclature to describe all the intermediate stages of testing. The next stage beyond testing a single unit of code is subsystem testing. A subsystem test verifies that two or more units of code are interacting correctly to produce the desired result. In the simplest case, a subsystem test can be created simply by replacing mock objects with real objects and running unit tests on the top level module. In practise, this tends to not work as well as expected, because the original unit test data wasn&#039;t designed for a subsystem test, or because the nature of the test cases needs to be changed in order to fully test the subsystem. After all there is little point in simply repeating the unit test cases; the objective of a subsystem test should be to test boundary conditions and special cases that would be difficult to duplicate in unit tests.&lt;br /&gt;
&lt;br /&gt;
Once a subsystem has been tested, it can be integrated into a larger system, which is still a subset of the whole product. Tests can be written for larger and larger subsystems, but at each stage the complexity of the tests increases. At some point, the effort required to hand craft tests exceeds the benefits of running them. This is where integrated testing comes in.&lt;br /&gt;
&lt;br /&gt;
Integrated testing involves recording a user&#039;s interaction with the system into a script that can be replayed. The testing framework then compares the system&#039;s response with the expected response and passes or fails the test. The PHPUnit testing framework that we use has the ability to work with Selenium, a browser based test automation tool.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
The purpose of unit tests is to isolate a module of code. A test that tests only one thing provides better information than a test that involves several object interactions. But how do we isolate an object from its dependencies? By writing stub classes. [http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html xUnit Patterns] defines a the hierarchy of dummy classes, ranging from simple to complex:&lt;br /&gt;
* Dummy - Defines attributes and methods of a dummy class (not particularly useful in PHP).&lt;br /&gt;
* Fake - Provides canned responses to method calls and fixed attribute values. Good for speed.&lt;br /&gt;
* Stub - Allows the test to define responses to method calls (return values, exceptions) to simulate the dependent object.&lt;br /&gt;
* Spy - A Fake or Stub that records method calls and parameters for later analysis.&lt;br /&gt;
* Mock - A Fake or Stub with a set of expectations -- method calls and parameters -- that are automatically verified for correctness.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Joomla! ===&lt;br /&gt;
Unit testing capabilities in Joomla are still at an early stage. The intention is to define more standards for developing tests, and then to expand the scope of available tests.&lt;br /&gt;
&lt;br /&gt;
For an overview of unit testing status in Joomla visit the [[Unit_Testing_Status]] page.&lt;br /&gt;
&lt;br /&gt;
The SVN repository contains code under the /testing path. /testing/trunk used to contain code based on the SimpleTest framework. In early December 2007, the development team elected to move to the [http://www.phpunit.de PHPUnit] framework.&lt;br /&gt;
&lt;br /&gt;
The PHPUnit tests are available from &#039;&#039;&#039;/testing/trunk&#039;&#039;&#039;. Some new tests have been added, any remaining tests from the SimpleTest days are completely broken. See /testing/branches/old-simpletest if you need to run something from that suite.&lt;br /&gt;
&lt;br /&gt;
The unit tests are located in two places:&lt;br /&gt;
* /testing/trunk/1.5/unittest - these are tests for Joomla! 1.5 (/development/releases/1.5)&lt;br /&gt;
* /testing/trunk/1.6/unittest - there are tests for Joomla! 1.6 (/development/trunk)&lt;br /&gt;
&lt;br /&gt;
At this point, PHPUnit based tests only run in a command line environment.&lt;br /&gt;
&lt;br /&gt;
==== The Unit Test Team ====&lt;br /&gt;
If you can commit to the Joomla code base, then you should consider yourself part of the unit test team!&lt;br /&gt;
&lt;br /&gt;
Writing tests concurrently with code (or even before) is a good way to not only save development time, but a great tool for defending against regressions. Writing tests early in the development cycle also helps identify and resolve design issues sooner, which reduces refactoring.&lt;br /&gt;
&lt;br /&gt;
If you want to get started on unit testing, get in touch with Alan Langford (instance) or Ray Tsai (mihu). Either of us will be happy to help out.&lt;br /&gt;
&lt;br /&gt;
==== Current Work ====&lt;br /&gt;
* There is no longer any need to patch the main code to enable unit tests.&lt;br /&gt;
* Basic techniques for mock objects are defined.&lt;br /&gt;
* Strategies for dealing with local configuration is not yet complete, but there is a plan.&lt;br /&gt;
* Files of the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php use PHPUnit.&lt;br /&gt;
* The JDate tests present a good example of a data-driven test, but they won&#039;t run on the current 1.5 code base (there are some proposed API changes as a result of unit test development).&lt;br /&gt;
* Previously functional tests, such as JFTP, haven&#039;t been moved to the PHPUnit environment yet.&lt;br /&gt;
* The custom test runner is no longer needed. The current tests will run with the latest SVN version of PHPUnit 3.4. This code will eventually become PHPUnit 3.4.1.  Thanks to Sebastian Bergmann for his excellent work on an excellent project!&lt;br /&gt;
&lt;br /&gt;
==== Writing Unit Tests ====&lt;br /&gt;
At risk of stating the obvious, in the &amp;quot;purest&amp;quot; case the purpose of a unit test is to &#039;&#039;isolate a unit of code from its environment and to test the operation of that code&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This isolation is usually achieved by writing dummy classes that emulate the code unit&#039;s environment. These dummy objects can be passive, by simply simulating the environment, or they can be more active, keeping track of how they are being used by the test unit and reporting any variations from the expected behaviour. See [[Unit_Testing_Mock_Objects|Mock Objects in Joomla]] for a detailed example.&lt;br /&gt;
&lt;br /&gt;
An interesting aspect of writing tests is that they become &#039;&#039;de facto&#039;&#039; detailed technical specifications of the interfaces between units of code. The fact that these specifications can be verified in an automated way makes them a superb resource when refactoring code.&lt;br /&gt;
&lt;br /&gt;
The test code has a few templates designed to kick-start a test. They are:&lt;br /&gt;
&lt;br /&gt;
/unittest/sample-datatest-php.txt&lt;br /&gt;
/unittest/sample-simpletest.php.txt&lt;br /&gt;
&lt;br /&gt;
Here are some example tests: [[Unit_Testing_--_a_Simple_Example|Simple Example]], [[Unit_Testing_--_Data_Driven_Example|Data Driven Example]], [[Unit_Testing_--_Plugin_Example|Plugin Example]], [[Unit_Testing_--_UI_Example|UI Example]].&lt;br /&gt;
&lt;br /&gt;
==== Running Unit Tests ====&lt;br /&gt;
Test files follow the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php. For tests that are not class based, the first element refers to the object being tested. An example of this is the e-mail cloaking plugin test, which is called emailcloak-0000-mode1-Test.php.&lt;br /&gt;
&lt;br /&gt;
Joomla unit tests use the standard PHPUnit test runner.  See http://www.phpunit.de for documentation.&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
Before you start make sure you have installed PHPUnit and of course PHP (5!) properly...&lt;br /&gt;
&lt;br /&gt;
To get the unit tests to run on your Joomla! installation, perform the following steps:&lt;br /&gt;
* Create an instance of your Joomla! installation&lt;br /&gt;
* In the root checkout (or export) the latest version of the unit test code from SVN &#039;&#039;&amp;quot;/testing/trunk/1.5/unittest&amp;quot;&#039;&#039; or &#039;&#039;&amp;quot;/testing/trunk/1.6/unittest&amp;quot;&#039;&#039; to your installation base. This will create a &#039;&#039;&amp;quot;/unittest&amp;quot;&#039;&#039; sub-folder under your joomla installation.&lt;br /&gt;
* Change to the unittest directory.&lt;br /&gt;
* Run the unit test from the command prompt using the following command:&lt;br /&gt;
 phpunit tests&lt;br /&gt;
&lt;br /&gt;
The unit test will the run, and the results are rendered.&lt;br /&gt;
&lt;br /&gt;
See http://www.phpunit.de/manual/current/en/textui.html for help using the --filter switch to run only certain tests.  There are also many other command line switches you can use to get results in various formats.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
The provided configurations should work out of the box. We have seen problems with it (currently the cause is unknown). If you get an error like below, the solution is pretty easy.&lt;br /&gt;
&lt;br /&gt;
 file=/var/www/unittest/runtests.php&lt;br /&gt;
 posn=17&lt;br /&gt;
 base=runtests.php&lt;br /&gt;
 /var/www&lt;br /&gt;
  JPATH_BASE does not point to a valid Joomla! installation:&lt;br /&gt;
 JPATH_BASE = /var/www&lt;br /&gt;
  Please modify your copy of &amp;quot;TestConfiguration.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Modify the &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file and change the definition of the JPATH_BASE so it points to the path of you Joomla! installation, in the example below the Joomla! installation is installed at &amp;quot;&#039;&#039;/var/www/update&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 define(&#039;JPATH_BASE&#039;, &#039;/var/www/update&#039;);&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&#039;&#039;&#039;Why can&#039;t I use &amp;quot;phpunit &#039;&#039;testname.php&#039;&#039;&amp;quot; to run my tests?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The test facility has to do some work to be able to load the &amp;quot;Joomla!&amp;quot; framework and to be able to inject mock classes. It&#039;s difficult to do this from the PHPUnit test runner, so we built our own. Also, the Joomla test runner has specific options designed to make it easy to select specific tests. Over time we will add more functionality to the test runner so it has many of the capabilities of the phpunit command.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[http://www.phpunit.de/manual/current/en/ PHPUnit Manual]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15845</id>
		<title>Unit Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15845"/>
		<updated>2009-10-06T14:18:22Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Running Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{cookiejar}}&lt;br /&gt;
== News and Updates ==&lt;br /&gt;
2008 06 24: Update to reflect move of PHPUnit code from branch to trunk (former trunk now in /branches/old_simpletest).&lt;br /&gt;
&lt;br /&gt;
2008 06 22: Add information on limiting tests by version.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: Added --class-exclude, --sequence-exclude, and --test-exclude options.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: PHPUnit has been updated to version 3.2.21 with SVN rev 10436. Please update.&lt;br /&gt;
&lt;br /&gt;
== Unit Testing ==&lt;br /&gt;
Unit testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of unit testing, visit the [http://en.wikipedia.org/wiki/Unit_test Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Open Source ===&lt;br /&gt;
Open source projects, with multiple developers working in parallel around the world, can greatly benefit from unit testing. The main benefits are:&lt;br /&gt;
* Unit tests help highlight cases where seemingly minor changes cause unexpected breakage.&lt;br /&gt;
* Unit tests help clearly specify how a class should behave.&lt;br /&gt;
* Unit tests can expose design flaws very early in development.&lt;br /&gt;
* Unit tests make great examples. They are a great place for developers to learn how to use the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Testing Hierarchy: Unit, Subsystem, Integrated ===&lt;br /&gt;
Software testing systems usually run through a spectrum from &amp;quot;pure&amp;quot; unit tests through to fully integrated systems tests. We&#039;ve described low level unit tests above. Integrated testing typically involves some sort of script that simulates user actions and then verifies that the result matches what&#039;s expected. This sort of &amp;quot;end to end&amp;quot; test verifies that all parts of the system are working correctly.&lt;br /&gt;
&lt;br /&gt;
It&#039;s unfortunate that there is no clear nomenclature to describe all the intermediate stages of testing. The next stage beyond testing a single unit of code is subsystem testing. A subsystem test verifies that two or more units of code are interacting correctly to produce the desired result. In the simplest case, a subsystem test can be created simply by replacing mock objects with real objects and running unit tests on the top level module. In practise, this tends to not work as well as expected, because the original unit test data wasn&#039;t designed for a subsystem test, or because the nature of the test cases needs to be changed in order to fully test the subsystem. After all there is little point in simply repeating the unit test cases; the objective of a subsystem test should be to test boundary conditions and special cases that would be difficult to duplicate in unit tests.&lt;br /&gt;
&lt;br /&gt;
Once a subsystem has been tested, it can be integrated into a larger system, which is still a subset of the whole product. Tests can be written for larger and larger subsystems, but at each stage the complexity of the tests increases. At some point, the effort required to hand craft tests exceeds the benefits of running them. This is where integrated testing comes in.&lt;br /&gt;
&lt;br /&gt;
Integrated testing involves recording a user&#039;s interaction with the system into a script that can be replayed. The testing framework then compares the system&#039;s response with the expected response and passes or fails the test. The PHPUnit testing framework that we use has the ability to work with Selenium, a browser based test automation tool.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
The purpose of unit tests is to isolate a module of code. A test that tests only one thing provides better information than a test that involves several object interactions. But how do we isolate an object from its dependencies? By writing stub classes. [http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html xUnit Patterns] defines a the hierarchy of dummy classes, ranging from simple to complex:&lt;br /&gt;
* Dummy - Defines attributes and methods of a dummy class (not particularly useful in PHP).&lt;br /&gt;
* Fake - Provides canned responses to method calls and fixed attribute values. Good for speed.&lt;br /&gt;
* Stub - Allows the test to define responses to method calls (return values, exceptions) to simulate the dependent object.&lt;br /&gt;
* Spy - A Fake or Stub that records method calls and parameters for later analysis.&lt;br /&gt;
* Mock - A Fake or Stub with a set of expectations -- method calls and parameters -- that are automatically verified for correctness.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Joomla! ===&lt;br /&gt;
Unit testing capabilities in Joomla are still at an early stage. The intention is to define more standards for developing tests, and then to expand the scope of available tests.&lt;br /&gt;
&lt;br /&gt;
For an overview of unit testing status in Joomla visit the [[Unit_Testing_Status]] page.&lt;br /&gt;
&lt;br /&gt;
The SVN repository contains code under the /testing path. /testing/trunk used to contain code based on the SimpleTest framework. In early December 2007, the development team elected to move to the [http://www.phpunit.de PHPUnit] framework.&lt;br /&gt;
&lt;br /&gt;
The PHPUnit tests are available from &#039;&#039;&#039;/testing/trunk&#039;&#039;&#039;. Some new tests have been added, any remaining tests from the SimpleTest days are completely broken. See /testing/branches/old-simpletest if you need to run something from that suite.&lt;br /&gt;
&lt;br /&gt;
The unit tests are located in two places:&lt;br /&gt;
* /testing/trunk/1.5/unittest - these are tests for Joomla! 1.5 (/development/releases/1.5)&lt;br /&gt;
* /testing/trunk/1.6/unittest - there are tests for Joomla! 1.6 (/development/trunk)&lt;br /&gt;
&lt;br /&gt;
At this point, PHPUnit based tests only run in a command line environment.&lt;br /&gt;
&lt;br /&gt;
==== The Unit Test Team ====&lt;br /&gt;
If you can commit to the Joomla code base, then you should consider yourself part of the unit test team!&lt;br /&gt;
&lt;br /&gt;
Writing tests concurrently with code (or even before) is a good way to not only save development time, but a great tool for defending against regressions. Writing tests early in the development cycle also helps identify and resolve design issues sooner, which reduces refactoring.&lt;br /&gt;
&lt;br /&gt;
If you want to get started on unit testing, get in touch with Alan Langford (instance) or Ray Tsai (mihu). Either of us will be happy to help out.&lt;br /&gt;
&lt;br /&gt;
==== Current Work ====&lt;br /&gt;
* There is no longer any need to patch the main code to enable unit tests.&lt;br /&gt;
* Basic techniques for mock objects are defined.&lt;br /&gt;
* Strategies for dealing with local configuration is not yet complete, but there is a plan.&lt;br /&gt;
* Files of the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php use PHPUnit.&lt;br /&gt;
* The JDate tests present a good example of a data-driven test, but they won&#039;t run on the current 1.5 code base (there are some proposed API changes as a result of unit test development).&lt;br /&gt;
* Previously functional tests, such as JFTP, haven&#039;t been moved to the PHPUnit environment yet.&lt;br /&gt;
* The custom test runner is no longer needed. The current tests will run with the latest SVN version of PHPUnit 3.4. This code will eventually become PHPUnit 3.4.1.  Thanks to Sebastian Bergmann for his excellent work on an excellent project!&lt;br /&gt;
&lt;br /&gt;
==== Writing Unit Tests ====&lt;br /&gt;
At risk of stating the obvious, in the &amp;quot;purest&amp;quot; case the purpose of a unit test is to &#039;&#039;isolate a unit of code from its environment and to test the operation of that code&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This isolation is usually achieved by writing dummy classes that emulate the code unit&#039;s environment. These dummy objects can be passive, by simply simulating the environment, or they can be more active, keeping track of how they are being used by the test unit and reporting any variations from the expected behaviour. See [[Unit_Testing_Mock_Objects|Mock Objects in Joomla]] for a detailed example.&lt;br /&gt;
&lt;br /&gt;
An interesting aspect of writing tests is that they become &#039;&#039;de facto&#039;&#039; detailed technical specifications of the interfaces between units of code. The fact that these specifications can be verified in an automated way makes them a superb resource when refactoring code.&lt;br /&gt;
&lt;br /&gt;
The test code has a few templates designed to kick-start a test. They are:&lt;br /&gt;
&lt;br /&gt;
/unittest/sample-datatest-php.txt&lt;br /&gt;
/unittest/sample-simpletest.php.txt&lt;br /&gt;
&lt;br /&gt;
Here are some example tests: [[Unit_Testing_--_a_Simple_Example|Simple Example]], [[Unit_Testing_--_Data_Driven_Example|Data Driven Example]], [[Unit_Testing_--_Plugin_Example|Plugin Example]], [[Unit_Testing_--_UI_Example|UI Example]].&lt;br /&gt;
&lt;br /&gt;
==== Running Unit Tests ====&lt;br /&gt;
Test files follow the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php. For tests that are not class based, the first element refers to the object being tested. An example of this is the e-mail cloaking plugin test, which is called emailcloak-0000-mode1-Test.php.&lt;br /&gt;
&lt;br /&gt;
Joomla unit tests use the standard PHPUnit test runner.  See http://www.phpunit.de for documentation.&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
Before you start make sure you have installed PHPUnit and of course PHP (5!) properly...&lt;br /&gt;
&lt;br /&gt;
To get the unit tests to run on your Joomla! installation, perform the following steps:&lt;br /&gt;
* Create an instance of your Joomla! installation&lt;br /&gt;
* In the root checkout (or export) the latest version of the unit test code from SVN &#039;&#039;&amp;quot;/testing/trunk&amp;quot;&#039;&#039; to your installation base. This will create a &#039;&#039;&amp;quot;/unittest&amp;quot;&#039;&#039; sub-folder under your joomla installation.&lt;br /&gt;
* Create a &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file. You can copy a the file from &#039;&#039;&amp;quot;TestConfiguration-dist.php&amp;quot;&#039;&#039; that is part of the package you just have checked out.&lt;br /&gt;
* If you want to run a subset of the commands, change to the directory that contains those tests.&lt;br /&gt;
* Run the unit test from the command using the following command:&lt;br /&gt;
&lt;br /&gt;
 php runtests.php&lt;br /&gt;
&lt;br /&gt;
The unit test will the run, and the results are rendered.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
The provided configurations should work out of the box. We have seen problems with it (currently the cause is unknown). If you get an error like below, the solution is pretty easy.&lt;br /&gt;
&lt;br /&gt;
 file=/var/www/unittest/runtests.php&lt;br /&gt;
 posn=17&lt;br /&gt;
 base=runtests.php&lt;br /&gt;
 /var/www&lt;br /&gt;
  JPATH_BASE does not point to a valid Joomla! installation:&lt;br /&gt;
 JPATH_BASE = /var/www&lt;br /&gt;
  Please modify your copy of &amp;quot;TestConfiguration.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Modify the &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file and change the definition of the JPATH_BASE so it points to the path of you Joomla! installation, in the example below the Joomla! installation is installed at &amp;quot;&#039;&#039;/var/www/update&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 define(&#039;JPATH_BASE&#039;, &#039;/var/www/update&#039;);&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&#039;&#039;&#039;Why can&#039;t I use &amp;quot;phpunit &#039;&#039;testname.php&#039;&#039;&amp;quot; to run my tests?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The test facility has to do some work to be able to load the &amp;quot;Joomla!&amp;quot; framework and to be able to inject mock classes. It&#039;s difficult to do this from the PHPUnit test runner, so we built our own. Also, the Joomla test runner has specific options designed to make it easy to select specific tests. Over time we will add more functionality to the test runner so it has many of the capabilities of the phpunit command.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[http://www.phpunit.de/manual/current/en/ PHPUnit Manual]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15844</id>
		<title>Unit Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=15844"/>
		<updated>2009-10-06T14:17:59Z</updated>

		<summary type="html">&lt;p&gt;Ian: /* Running Unit Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{cookiejar}}&lt;br /&gt;
== News and Updates ==&lt;br /&gt;
2008 06 24: Update to reflect move of PHPUnit code from branch to trunk (former trunk now in /branches/old_simpletest).&lt;br /&gt;
&lt;br /&gt;
2008 06 22: Add information on limiting tests by version.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: Added --class-exclude, --sequence-exclude, and --test-exclude options.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: PHPUnit has been updated to version 3.2.21 with SVN rev 10436. Please update.&lt;br /&gt;
&lt;br /&gt;
== Unit Testing ==&lt;br /&gt;
Unit testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of unit testing, visit the [http://en.wikipedia.org/wiki/Unit_test Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Open Source ===&lt;br /&gt;
Open source projects, with multiple developers working in parallel around the world, can greatly benefit from unit testing. The main benefits are:&lt;br /&gt;
* Unit tests help highlight cases where seemingly minor changes cause unexpected breakage.&lt;br /&gt;
* Unit tests help clearly specify how a class should behave.&lt;br /&gt;
* Unit tests can expose design flaws very early in development.&lt;br /&gt;
* Unit tests make great examples. They are a great place for developers to learn how to use the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Testing Hierarchy: Unit, Subsystem, Integrated ===&lt;br /&gt;
Software testing systems usually run through a spectrum from &amp;quot;pure&amp;quot; unit tests through to fully integrated systems tests. We&#039;ve described low level unit tests above. Integrated testing typically involves some sort of script that simulates user actions and then verifies that the result matches what&#039;s expected. This sort of &amp;quot;end to end&amp;quot; test verifies that all parts of the system are working correctly.&lt;br /&gt;
&lt;br /&gt;
It&#039;s unfortunate that there is no clear nomenclature to describe all the intermediate stages of testing. The next stage beyond testing a single unit of code is subsystem testing. A subsystem test verifies that two or more units of code are interacting correctly to produce the desired result. In the simplest case, a subsystem test can be created simply by replacing mock objects with real objects and running unit tests on the top level module. In practise, this tends to not work as well as expected, because the original unit test data wasn&#039;t designed for a subsystem test, or because the nature of the test cases needs to be changed in order to fully test the subsystem. After all there is little point in simply repeating the unit test cases; the objective of a subsystem test should be to test boundary conditions and special cases that would be difficult to duplicate in unit tests.&lt;br /&gt;
&lt;br /&gt;
Once a subsystem has been tested, it can be integrated into a larger system, which is still a subset of the whole product. Tests can be written for larger and larger subsystems, but at each stage the complexity of the tests increases. At some point, the effort required to hand craft tests exceeds the benefits of running them. This is where integrated testing comes in.&lt;br /&gt;
&lt;br /&gt;
Integrated testing involves recording a user&#039;s interaction with the system into a script that can be replayed. The testing framework then compares the system&#039;s response with the expected response and passes or fails the test. The PHPUnit testing framework that we use has the ability to work with Selenium, a browser based test automation tool.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
The purpose of unit tests is to isolate a module of code. A test that tests only one thing provides better information than a test that involves several object interactions. But how do we isolate an object from its dependencies? By writing stub classes. [http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html xUnit Patterns] defines a the hierarchy of dummy classes, ranging from simple to complex:&lt;br /&gt;
* Dummy - Defines attributes and methods of a dummy class (not particularly useful in PHP).&lt;br /&gt;
* Fake - Provides canned responses to method calls and fixed attribute values. Good for speed.&lt;br /&gt;
* Stub - Allows the test to define responses to method calls (return values, exceptions) to simulate the dependent object.&lt;br /&gt;
* Spy - A Fake or Stub that records method calls and parameters for later analysis.&lt;br /&gt;
* Mock - A Fake or Stub with a set of expectations -- method calls and parameters -- that are automatically verified for correctness.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Joomla! ===&lt;br /&gt;
Unit testing capabilities in Joomla are still at an early stage. The intention is to define more standards for developing tests, and then to expand the scope of available tests.&lt;br /&gt;
&lt;br /&gt;
For an overview of unit testing status in Joomla visit the [[Unit_Testing_Status]] page.&lt;br /&gt;
&lt;br /&gt;
The SVN repository contains code under the /testing path. /testing/trunk used to contain code based on the SimpleTest framework. In early December 2007, the development team elected to move to the [http://www.phpunit.de PHPUnit] framework.&lt;br /&gt;
&lt;br /&gt;
The PHPUnit tests are available from &#039;&#039;&#039;/testing/trunk&#039;&#039;&#039;. Some new tests have been added, any remaining tests from the SimpleTest days are completely broken. See /testing/branches/old-simpletest if you need to run something from that suite.&lt;br /&gt;
&lt;br /&gt;
The unit tests are located in two places:&lt;br /&gt;
* /testing/trunk/1.5/unittest - these are tests for Joomla! 1.5 (/development/releases/1.5)&lt;br /&gt;
* /testing/trunk/1.6/unittest - there are tests for Joomla! 1.6 (/development/trunk)&lt;br /&gt;
&lt;br /&gt;
At this point, PHPUnit based tests only run in a command line environment.&lt;br /&gt;
&lt;br /&gt;
==== The Unit Test Team ====&lt;br /&gt;
If you can commit to the Joomla code base, then you should consider yourself part of the unit test team!&lt;br /&gt;
&lt;br /&gt;
Writing tests concurrently with code (or even before) is a good way to not only save development time, but a great tool for defending against regressions. Writing tests early in the development cycle also helps identify and resolve design issues sooner, which reduces refactoring.&lt;br /&gt;
&lt;br /&gt;
If you want to get started on unit testing, get in touch with Alan Langford (instance) or Ray Tsai (mihu). Either of us will be happy to help out.&lt;br /&gt;
&lt;br /&gt;
==== Current Work ====&lt;br /&gt;
* There is no longer any need to patch the main code to enable unit tests.&lt;br /&gt;
* Basic techniques for mock objects are defined.&lt;br /&gt;
* Strategies for dealing with local configuration is not yet complete, but there is a plan.&lt;br /&gt;
* Files of the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php use PHPUnit.&lt;br /&gt;
* The JDate tests present a good example of a data-driven test, but they won&#039;t run on the current 1.5 code base (there are some proposed API changes as a result of unit test development).&lt;br /&gt;
* Previously functional tests, such as JFTP, haven&#039;t been moved to the PHPUnit environment yet.&lt;br /&gt;
* The custom test runner is no longer needed. The current tests will run with the latest SVN version of PHPUnit 3.4. This code will eventually become PHPUnit 3.4.1.  Thanks to Sebastian Bergmann for his excellent work on an excellent project!&lt;br /&gt;
&lt;br /&gt;
==== Writing Unit Tests ====&lt;br /&gt;
At risk of stating the obvious, in the &amp;quot;purest&amp;quot; case the purpose of a unit test is to &#039;&#039;isolate a unit of code from its environment and to test the operation of that code&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This isolation is usually achieved by writing dummy classes that emulate the code unit&#039;s environment. These dummy objects can be passive, by simply simulating the environment, or they can be more active, keeping track of how they are being used by the test unit and reporting any variations from the expected behaviour. See [[Unit_Testing_Mock_Objects|Mock Objects in Joomla]] for a detailed example.&lt;br /&gt;
&lt;br /&gt;
An interesting aspect of writing tests is that they become &#039;&#039;de facto&#039;&#039; detailed technical specifications of the interfaces between units of code. The fact that these specifications can be verified in an automated way makes them a superb resource when refactoring code.&lt;br /&gt;
&lt;br /&gt;
The test code has a few templates designed to kick-start a test. They are:&lt;br /&gt;
&lt;br /&gt;
/unittest/sample-datatest-php.txt&lt;br /&gt;
/unittest/sample-simpletest.php.txt&lt;br /&gt;
&lt;br /&gt;
Here are some example tests: [[Unit_Testing_--_a_Simple_Example|Simple Example]], [[Unit_Testing_--_Data_Driven_Example|Data Driven Example]], [[Unit_Testing_--_Plugin_Example|Plugin Example]], [[Unit_Testing_--_UI_Example|UI Example]].&lt;br /&gt;
&lt;br /&gt;
==== Running Unit Tests ====&lt;br /&gt;
Test files follow the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php. For tests that are not class based, the first element refers to the object being tested. An example of this is the e-mail cloaking plugin test, which is called emailcloak-0000-mode1-Test.php.&lt;br /&gt;
&lt;br /&gt;
Joomla unit tests use the standard PHPUnit test runner.  See www.phpunit.de for documentation.&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
Before you start make sure you have installed PHPUnit and of course PHP (5!) properly...&lt;br /&gt;
&lt;br /&gt;
To get the unit tests to run on your Joomla! installation, perform the following steps:&lt;br /&gt;
* Create an instance of your Joomla! installation&lt;br /&gt;
* In the root checkout (or export) the latest version of the unit test code from SVN &#039;&#039;&amp;quot;/testing/trunk&amp;quot;&#039;&#039; to your installation base. This will create a &#039;&#039;&amp;quot;/unittest&amp;quot;&#039;&#039; sub-folder under your joomla installation.&lt;br /&gt;
* Create a &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file. You can copy a the file from &#039;&#039;&amp;quot;TestConfiguration-dist.php&amp;quot;&#039;&#039; that is part of the package you just have checked out.&lt;br /&gt;
* If you want to run a subset of the commands, change to the directory that contains those tests.&lt;br /&gt;
* Run the unit test from the command using the following command:&lt;br /&gt;
&lt;br /&gt;
 php runtests.php&lt;br /&gt;
&lt;br /&gt;
The unit test will the run, and the results are rendered.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
The provided configurations should work out of the box. We have seen problems with it (currently the cause is unknown). If you get an error like below, the solution is pretty easy.&lt;br /&gt;
&lt;br /&gt;
 file=/var/www/unittest/runtests.php&lt;br /&gt;
 posn=17&lt;br /&gt;
 base=runtests.php&lt;br /&gt;
 /var/www&lt;br /&gt;
  JPATH_BASE does not point to a valid Joomla! installation:&lt;br /&gt;
 JPATH_BASE = /var/www&lt;br /&gt;
  Please modify your copy of &amp;quot;TestConfiguration.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Modify the &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file and change the definition of the JPATH_BASE so it points to the path of you Joomla! installation, in the example below the Joomla! installation is installed at &amp;quot;&#039;&#039;/var/www/update&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 define(&#039;JPATH_BASE&#039;, &#039;/var/www/update&#039;);&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&#039;&#039;&#039;Why can&#039;t I use &amp;quot;phpunit &#039;&#039;testname.php&#039;&#039;&amp;quot; to run my tests?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The test facility has to do some work to be able to load the &amp;quot;Joomla!&amp;quot; framework and to be able to inject mock classes. It&#039;s difficult to do this from the PHPUnit test runner, so we built our own. Also, the Joomla test runner has specific options designed to make it easy to select specific tests. Over time we will add more functionality to the test runner so it has many of the capabilities of the phpunit command.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[http://www.phpunit.de/manual/current/en/ PHPUnit Manual]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Ian</name></author>
	</entry>
</feed>