15
Creating a simple Joomla 3 module Introduction Joomla! 3.x is constructed using three different applications: installation (used for installing Joomla) administrator (used for managing content) public (used for displaying content) The installation application is used once. The administrator and public are used through the concept of components with modules. Each module has a single entry point located in the modules directory. This is called mod_modulename/modulename.php (the mod_ prefix is a historical trace) Requirements You need the latest version of Joomla! 3.x (with PHP, MySQL, Apache and Microsoft II) for this tutorial (as of writing currently 3.1.1)

Creating a Simple Joomla 3 Module

Embed Size (px)

DESCRIPTION

Creating a Simple Joomla 3 Module, Joomla 3, Step by Step Instruction

Citation preview

Page 1: Creating a Simple Joomla 3 Module

Creating a simple Joomla 3 module

Introduction

Joomla! 3.x is constructed using three different applications:

installation (used for installing Joomla) administrator (used for managing content) public (used for displaying content)

The installation application is used once. The administrator and public are used through the concept of components with modules. Each module has a single entry point located in the modules directory. This is called mod_modulename/modulename.php (the mod_ prefix is a historical trace)

Requirements

You need the latest version of Joomla! 3.x (with PHP, MySQL, Apache and Microsoft II) for this tutorial (as of writing currently 3.1.1)

Page 2: Creating a Simple Joomla 3 Module

Developing a Basic Module

A module is a lightweight and flexible extension. They are used for small bits of the page that are generally less complex and are able to be seen across different components.

You can see many examples of modules in the standard Joomla! install: - menus - Latest News - Login form - and many more.

This tutorial will explain how to go about creating a simple Hello World module. Through this tutorial you will learn the basic file structure of a module. This basic structure can then be expanded to produce more elaborate modules.

File Structure

There are four basic files that are used in the standard pattern of module development:

mod_helloworld.php - This file is the main entry point for the module. It will perform any necessary initialization routines, call helper routines to collect any necessary data, and include the template which will display the module output.

mod_helloworld.xml - This file contains information about the module. It defines the files that need to be installed by the Joomla! installer and specifies configuration parameters for the module.

helper.php - This file contains the helper class which is used to do the actual work in retrieving the information to be displayed in the module (usually from the database or some other source).

tmpl/default.php - This is the module template. This file will take the data collected by mod_helloworld.php and generate the HTML to be displayed on the page.

Creating mod_helloworld.php

The mod_helloworld.php file will perform three tasks:

include the helper.php file which contains the class to be used to collect the necessary data

invoke the appropriate helper class method to retrieve the data include the template to display the output.

The helper class is defined in our helper.php file. This file is included with a require_once statement:

require_once( dirname(__FILE__).'/helper.php' );

require_once is used because our helper functions are defined within a class, and we only want the class defined once.

Our helper class has not been defined yet, but when it is, it will contain one method: getHello(). For our basic example, it is not really necessary to do this - the “Hello, World” message that this method returns could simply be included in the template. We use a helper class here to demonstrate this basic technique.

Page 3: Creating a Simple Joomla 3 Module

Our module currently does not use any parameters, but we will pass them to the helper method anyway so that it can be used later if we decide to expand the functionality of our module.

The helper class method is invoked in the following way:

$hello = modHelloWorldHelper::getHello( $params );

Completed mod_helloworld.php file

The complete mod_helloworld.php file is as follows:

<?php/** * Hello World! Module Entry Point * * @package Joomla.Tutorials * @subpackage Modules * @link http://dev.joomla.org/component/option,com_jd-wiki/Itemid,31/id,tutorials:modules/ * @license GNU/GPL, see LICENSE.php * mod_helloworld is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. */ // no direct accessdefined( '_JEXEC' ) or die( 'Restricted access' );// Include the syndicate functions only oncerequire_once( dirname(__FILE__).'/helper.php' ); $hello = modHelloWorldHelper::getHello( $params );require( JModuleHelper::getLayoutPath( 'mod_helloworld' ) );?>

The one line that we haven’t explained so far is the first line. This line checks to make sure that this file is being included from the Joomla! application. This is necessary to prevent variable injection and other potential security concerns.

Creating helper.php

The helper.php file contains that helper class that is used to retrieve the data to be displayed in the module output. As stated earlier, our helper class will have one method: getHello(). This method will return the ‘Hello, World’ message.

Here is the code for the helper.php file:

<?php/** * Helper class for Hello World! module * * @package Joomla.Tutorials * @subpackage Modules * @link http://dev.joomla.org/component/option,com_jd-wiki/Itemid,31/id,tutorials:modules/ * @license GNU/GPL, see LICENSE.php * mod_helloworld is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses.

Page 4: Creating a Simple Joomla 3 Module

*/class modHelloWorldHelper{ /** * Retrieves the hello message * * @param array $params An object containing the module parameters * @access public */ public static function getHello( $params ) { return 'Hello, World!'; }}?>

There is no rule stating that we must name our helper class as we have, but it is helpful to do this so that it is easily identifiable and locateable. Note that it is required to be in this format if you plan to use the com_ajax plugin.

More advanced modules might include database requests or other functionality in the helper class method.

Creating tmpl/default.php

The default.php file is the template which displays the module output.

The code for the default.php file is as follows:

<?php // no direct accessdefined( '_JEXEC' ) or die( 'Restricted access' ); ?><?php echo $hello; ?>

An important point to note is that the template file has the same scope as the mod_helloworld.php file. What this means is that the variable $hello can be defined in the mod_helloworld.php file and then used in the template file without any extra declarations or function calls.

Creating mod_helloworld.xml

The mod_helloworld.xml is used to specify which files the installer needs to copy and is used by the Module Manager to determine which parameters are used to configure the module. Other information about the module is also specified in this file.

The code for mod_helloworld.xml is as follows:

<?xml version="1.0" encoding="utf-8"?><extension type="module" version="3.1.0" client="site" method="upgrade"> <name>Hello, World!</name> <author>John Doe</author> <version>1.0.0</version> <description>A simple Hello, World! module.</description> <files> <filename>mod_helloworld.xml</filename> <filename module="mod_helloworld">mod_helloworld.php</filename> <filename>index.html</filename> <filename>helper.php</filename> <filename>tmpl/default.php</filename> <filename>tmpl/index.html</filename> </files> <config> </config>

Page 5: Creating a Simple Joomla 3 Module

</extension>

Manifest files explains the technical details of the elements used in the XML file.

You will notice that there are two additional files that we have not yet mentioned: index.html and tmpl/index.html. These files are included so that these directories cannot be browsed. If a user attempts to point their browser to these folders, the index.html file will be displayed. These files can be left empty or can contain the simple line:

<html><body bgcolor="#FFFFFF"></body></html>

which will display an empty page.

Since our module does not use any form fields, the config section is empty.

Page 6: Creating a Simple Joomla 3 Module

Using the Database

Many modules in Joomla require using a database. It is assumed in this tutorial that you already understand the basics of using the JDatabase class. If you don't please read the documentation on accessing the database using JDatabase before continuing this tutorial

Creating a table on install

To create the xml table on install we are going to add the following lines into mod_helloworld.xml:

<install> <sql> <file driver="mysql" charset="utf8">sql/mysql/install.mysql.utf8.sql</file> <file driver="sqlazure" charset="utf8">sql/sqlazure/install.sqlazure.utf8.sql</file> </sql></install> <uninstall> <sql> <file driver="mysql" charset="utf8">sql/mysql/uninstall.mysql.utf8.sql</file> <file driver="sqlazure" charset="utf8">sql/sqlazure/uninstall.sqlazure.utf8.sql</file> </sql></uninstall> <update> <schemas> <schemapath type="mysql">sql/mysql/updates</schemapath> <schemapath type="sqlazure">sql/sqlazure/updates</schemapath> </schemas> </update>

There are 3 sections to this code:

The install tag adds the database table The uninstall tag removes the database table if the module is uninstalled. Note that not all

modules will want to use this feature (and it's not required). The update tag will update the databases if a database needs to be amended when

updating the module.

Note that we have both schemas for MySQL and Microsoft SQL - again you can choose to tailor your module for one or both of these systems.

In this example we will just show the example files for the MySQL database. Creating the Microsoft SQL Server will be left as an exercise for the reader.

In our install.mysql.utf8.sql file we will create the table and place some hellos into it

CREATE TABLE IF NOT EXISTS `#__helloworld` ( `id` int(10) NOT NULL AUTO_INCREMENT, `hello` text NOT NULL, `lang` varchar(25) NOT NULL,  PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; INSERT INTO `#__helloworld` (`hello`, `lang`) VALUES ('Hello World', 'en-GB');

Page 7: Creating a Simple Joomla 3 Module

INSERT INTO `#__helloworld` (`hello`, `lang`) VALUES ('Hola Mundo', 'es-ES');INSERT INTO `#__helloworld` (`hello`, `lang`) VALUES ('Bonjour tout le monde', 'fr-FR');

In the uninstall file we'll just remove the table.

DROP TABLE IF EXISTS `#__helloworld`

Finally we'll just leave a placeholder in the updates file. There is an SQL file for each component version. Each file name must match the version string in the manifest file for that version. Joomla uses this string to determine which SQL files(s) to execute, and in what order they will be executed.

Important Note: These files are also used to set the version number in the #__schemas table. This version number must be present in the current version of the component in order for the new SQL files to be run during the update. For example, if you have version 1.0 and are updating to version 1.1, the 1.1.sql file will not be executed if there was no 1.0.sql file in the 1.0 release. For this reason, it is good practice to have a SQL update file for each version, even if there is no SQL change in that version.

# Placeholder file for database changes for version 1.0.0

Making the request in the helper file

Now on installing our module we should find that there is a helloworld database set up in our database schema with our hello's in. We must now retrieve this from the database to display to the user. We will now amend the getHello function we placed in the helper file in the last part.

For now we'll ignore using form fields to choose a hello and just retrieve the English shout

//Obtain a database connection$db = JFactory::getDbo();//Retrieve the shout$query = $db->getQuery(true) ->select($db->quoteName('hello')) ->from($db->quoteName('#__helloworld')) ->where('lang = '. $db->Quote('en-GB'));//Prepare the query$db->setQuery($query);// Load the row.$result = $db->loadResult();//Return the Helloreturn $result;

Page 8: Creating a Simple Joomla 3 Module

Adding Form Fields

Form fields give a great deal of customisation in Joomla and for modules are the sole way of allowing the user to tweak the module to the needs of their site.

Adding Form Fields to the module

In this case we are going to extend our previous example using the database to provide a list of languages for the user to select from. To allow this to happen we will use the SQL form field type (full details for this on the SQL Form Field docs page).

First of all we are going to add a form field into our xml file. Remember those config tags that we added in earlier? Well now inside these tags we are going to add the following code:

<fields name="params"> <fieldset name="basic"> <field name="lang" type="sql" default="1" label="Select a language" query="SELECT id AS value, lang FROM #__helloworld" /> </fieldset></fields>

This selects the languages from the database table and allows the user to choose which one from a select element.

If you were to install the module as it is now you would see if you were to access the module in the backend of Joomla that a dropdown had appeared (although picking an option won't affect the module at the moment).

Note: The form field parameters are stored for each module in the #__modules table under the params field as json encoded string.

Now lets make the form field do something!

Lets go into the mod_helloworld.php and retrieve the parameter (note you cannot retrieve the parameter in the helper), and then pass it into the helper function.

/** * This retrieves the lang parameter we stored earlier. Note the second part * which states to use the default value of 1 if the parameter cannot be * retrieved for some reason**/$language = $params->get('lang', '1');$hello = modHelloWorldHelper::getHello( $language );

Now lets edit our database query in the helper file to reflect our parameter choice

//Obtain a database connection$db = JFactory::getDbo();//Retrieve the shout - note we are now retrieving the id not the lang field.$query = $db->getQuery(true) ->select($db->quoteName('hello')) ->from($db->quoteName('#__helloworld')) ->where('id = '. $db->Quote($params));//Prepare the query$db->setQuery($query);// Load the row.$result = $db->loadResult();//Return the Helloreturn $result;

Page 9: Creating a Simple Joomla 3 Module
Page 10: Creating a Simple Joomla 3 Module

Adding Auto Update

This section of the tutorial will help you create an update server so that your module can utilize the Joomla one-click-upgrade system.

Introduction & Pre-reading

The first thing to do is to read the Managing Component Upgrades with Joomla 2.5 - Part 1 tutorial to give an idea of how the upgrade process works in Joomla. Whilst written for 2.5 the process hasn't changed for Joomla 3.x. Also read Deploying an update server - this is what we'll be implementing in this tutorial.

Remember that sql update file we mentioned in the Using the database section? That will be used to update our database still. Whilst a new zipped version of our module will be used to update all the php files. To keep this simple for now we will update the files and sql database without any checks for Joomla version and the version of the module that is currently installed (it is recommended these are used in a production module).

Updating our module

The only way to update our existing module is to add in a update server into the xml file.

<updateservers> <server type="extension" name="Helloworld" priority="1">http://www.example.com/helloworld_update.xml</server></updateservers>

Joomla will now search http://www.example.com/helloworld_update.xml for updates with a frequency set in the extension manager options.

Creating an update

So now that Joomla is searching for updates to our extension - lets create one to test out our process.

Create a copy of the module as it is now. Then lets update the version number to 1.0.1, and also we'll add something into our Update SQL file - in this case an extra German Language file

<version>1.0.1</version>INSERT INTO `#__helloworld` (`hello`, `lang`) VALUES ('Hallo Welt', 'de-DE');

Note we can also edit any of our php files - all the existing php files will be overridden by the ones in the update file (Note: This is the reason why core hacks of any extension are discouraged - they will be lost on the extension update).

Now we must create the xml file at http://www.example.com/helloworld_update.xml to let Joomla know an update is available.

<updates> <update> <name>Helloworld</name> <description>This is mod_helloworld 1.0.1</description> <element>mod_helloworld</element> <type>module</type> <version>1.0.1</version> <downloads> <downloadurl type="full" format="zip">http://www.example.com/mod_helloworld_101.zip</downloadurl>

Page 11: Creating a Simple Joomla 3 Module

</downloads> <maintainer>Joomla</maintainer> <maintainerurl>http://www.example.com</maintainerurl> <targetplatform name="joomla" version="3.1"/> <client>0</client> <client_id>0</client_id> </update></updates>

where http://www.example.com/mod_helloworld_101.zip is the zip of our newly created update. If you now log into the backend of Joomla you should now see in the control panel that an automatic update is available (if not you may need to purge your cache in the update section of the extension manager). Simply click update and you'll find your module has been updated to version 1.0.1.

Commercial Modules

Note that in our files we have linked to the extensions updates xml file. And from that xml file we have a location for the zip of the module. This means that if someone were to track this backwards they could find the physical source of your modules zip file (and make it available/use it after a subscription has expired etc.). For this reason generally commercial modules do not contain automatic updates (although they often will inform you of updates in some alternative way).

Page 12: Creating a Simple Joomla 3 Module

Adding an install-uninstall-update script file

Introduction

Installing, updating and uninstalling a module may require additional operations that cannot be achieved by the basic operations described in the main xml file. Joomla offers a new approach to solve this problem. It consists in using a php script file containing a class using five methods:

preflight which is executed before install and update install update uninstall postflight which is executed after install and update

Creating the extension script file

Writing an extension script consists in declaring an class whose name is mod_ModuleNameInstallerScript with these 5 methods.

script.php

<?php// No direct access to this filedefined('_JEXEC') or die('Restricted access'); /** * Script file of HelloWorld module */class mod_helloWorldInstallerScript{ /** * Method to install the extension * $parent is the class calling this method * * @return void */ function install($parent) { echo '<p>The module has been installed</p>'; }  /** * Method to uninstall the extension * $parent is the class calling this method * * @return void */ function uninstall($parent) { echo '<p>The module has been uninstalled</p>'; }  /** * Method to update the extension * $parent is the class calling this method * * @return void */ function update($parent) { echo '<p>The module has been updated to version' . $parent->get('manifest')->version) . '</p>';

Page 13: Creating a Simple Joomla 3 Module

}  /** * Method to run before an install/update/uninstall method * $parent is the class calling this method * $type is the type of change (install, update or discover_install) * * @return void */ function preflight($type, $parent) { echo '<p>Anything here happens before the installation/update/uninstallation of the module</p>'; }  /** * Method to run after an install/update/uninstall method * $parent is the class calling this method * $type is the type of change (install, update or discover_install) * * @return void */ function postflight($type, $parent) { echo '<p>Anything here happens after the installation/update/uninstallation of the module</p>'; }}

In the update method we show the new version using $parent->get('manifest')->version. You can also redirect to a page of choice with $parent->getParent()->setRedirectURL('index.php?option=com_modules');.