Building Joomla! extensions with Phing

This script is intended to be used if you are in a situation where you develop your extensions inside a joomla tree but store them in a repository or folder outside the tree. The script provides functionality to copy the extension by name out of the joomla tree.

Configuration

Rename build.properties.dist to build.properties and set the src.dir variable to the Joomla! path. For example

src.dir=/var/www/joomla

This is where the script will look for the components you are trying to build.

Naming conventions

The script uses the extension prefix to determine the extension type, so you have to use the following prefixes to the extension=VALUE

  • component : “com_”
  • module : “mod_”
  • template : “tpl_”
  • plugin: “plg_GROUP_”

Administrator modules and templates must use the following prefixes

  • module: “mod_admin_”
  • template: “tpl_admin_”

Language files

When using this script, the language files for an extension needs to be stored within the folder of the extension itself and not in the global language folder.

Usage examples

Building an extension from the joomla source tree

phing -Dextension=com_content build

Creating a package

Once you have built an extension you can create an installable package from the build using the following command.

phing -Dextension=com_content

This will create a package file “com_content_DATE.zip

If you also wish to add a version number you can use the following procedure

phing -Dextension=com_content -Dversion=2.5

Download latest version
or…
Take a peek at the source

Loading the Joomla! Platform in an external script

If you are looking to execute an external PHP script, and still have access to the functionality of the platform and your site, you can do something like this in order to load the platform.

<?php define('_JEXEC', 1);
define('DS', DIRECTORY_SEPARATOR);
 
if (file_exists(dirname(__FILE__) . '/defines.php')) {
    include_once dirname(__FILE__) . '/defines.php';
}
 
if (!defined('_JDEFINES')) {
    define('JPATH_BASE', dirname(__FILE__));
    require_once JPATH_BASE.'/includes/defines.php';
}
 
require_once JPATH_BASE.'/includes/framework.php';
 
/* Your code here */

If we take a closer look at the code, the first if construct will check if there exists a defines.php file in the directory of your external PHP script, and use if in case it does. If that file is not found, it will look in the includes subdirectory for defines.php. After the defines are included, the platform is loaded. There is really not much more to it, now you will be able to use the Joomla! platform like you would inside Jooml!. For example by instantiating JDatabase through $database = JFactory::getDBO(); or accessing the request through JRequest.

Removing the components administrator menu

So, your shiny new frontend component is all written and works flawlessly without any kind of bugs whatsoever and now you would like to remove the component menu item in the administrator Components menu. Why you say ? Of course because your shiny new component is a frontend-only component and you do not want to implement a dummy backend interface just because it is cool.

So here is how you do it, if you need to know how to create an installer script for your component, please refer to the official Joomla! MVC Component tutorial.

class Com_HelloworldInstallerScript {
    function postflight($type, $parent){
        if ($type == 'install' || $type == 'update') {
            $db = JFactory::getDBO();
            $query = $db->getQuery(true);
            $query->delete('#__menu');
            $id = JComponentHelper::getComponent('com_helloworld')->id;
            $query->where('component_id = '.$id);
            $query->where('client_id = 1');
            $db->setQuery($query);
            $db->query();
        }   
    }   
}

Note that during uninstall of a component which has had its menu entry removing in this manner, there will be a warning/error in versions 1.7.0 and older. The component will still uninstall like it should so do not worry if you see this error.