In this series of blogs, we will talk about common mistakes to avoid while building extensions for Joomla!.
In this particular blog, we will talk about these four common mistakes:
- Not using language constants and instead of hard coding language strings
- Not using JInput and instead directly accessing $_POST or $_GET
- Not using the Joomla Database layer and writing plain database queries instead
- Wrong usage of loadObjectList / loadAssocList() (Using loadObjectList() when just 1 row is needed)
Mistake 1: Not using language constants and instead of hard coding language strings
Joomla is a powerful CMS with multilingual support. Not just the core Joomla extensions, but even the 3rd party extensions can support this feature by adding language files for multiple languages they wish to support.
One of the very common mistakes a lot of developers make is not using language constants and hard coding language strings
Let’s say you want to show a message to end-user when a form submitted is saved. A mistake which developers usually make is hardcoding this language string as:
use Joomla\CMS\Factory; Factory::getApplication()->enqueueMessage(‘Form saved successfully’);
Which ideally should have been coded with the help of language constant as:
use Joomla\CMS\Factory; Factory::getApplication()->enqueueMessage(JText::_('COM_MYCOMPONENT_FORM_MSG_SAVE_SUCESS));
Using language constants give you two very obvious advantages:
- You can easily translate your extension’s user interface into multiple languages by adding multiple language files.
Eg: For British English language
Create file: en-GB.mycomponent.ini
Add language constant as: COM_MYCOMPONENT_FORM_MSG_SAVE_SUCESS=”For saved successfully”
Eg: For Italian language
Create file: it-IT.mycomponent.ini
Add language constant as: COM_MYCOMPONENT_FORM_MSG_SAVE_SUCESS=”Modulo salvato con successo”
2. Website maintainers can easily add overrides for these language constants using language override file, without touching your extension’s code
Mistake 2: Not using JInput and instead directly accessing $_POST
Another common mistake made is accessing form or request data directly using PHP superglobals such as $_POST or $_GET.
Joomla! has an API that lets you accessdata from any superglobals with ease such as
Getting Values from a Specific Super Global
use Joomla\CMS\Factory; $input = Factory::getApplication()->input; $postVar = $input->get->get('varname', 'default_value', 'filter'); $getVar = $input->post->get('varname', 'default_value', 'filter'); $serverVar = $input->server->get('varname', 'default_value', 'filter');
Two advantages of this:
- Ability to set default values
- Ability to apply filters to sanitize inputs eg: int, string, etc
There are also ways to get JSON data or the FILES posted using form.
Mistake 3: Not using the Joomla Database layer and writing plain database queries instead
Joomla! can use different kinds of SQL database systems eg: MySQL, SQL Server,PostgreSQL. As you know, there could be changes in the database query syntaxes in all of these.
So if you write queries in plain MySQL syntax, it might not work in different databases supported by Joomla!
To avoid that you can use Joomla’s database abstraction layer, Where you will write a query using Joolas query builder, and Joomla will take care of running it on different database systems.
use Joomla\CMS\Factory; // Get a db connection $db = Factory::getDbo(); // Create a new query object $query = $db->getQuery(true); // Select all records from table $query->select($db->quoteName(array('name', 'surname', 'userId'))); $query->from($db->quoteName('#__custom_table')); $query->where($db->quoteName('name') . ' LIKE ' . $db->quote('custom.%')); // Set query $db->setQuery($query); // Load the results as a list of stdClass objects $results = $db->loadObjectList();
Two advantages of this:
- Same database query works with different databases supported by Joomla
- Escaping is taken care of if $db->quote() is used
Mistake 4: Wrong usage of loadObjectList / loadAssocList() (Used loadObjectList() when just 1 row is needed)
At lot of times, the database query output expected is a single row. Even then developers make the mistake of using
$records = $db->loadObjectList() or $records = $db->loadAssocList() and try accessing it as $records.
Instead they should use
$record = $db->loadObject() ; or $record = $db->loadAssoc();
Also, if you are expecting only a single column value as database query output, you should use
$columnValue = $db->loadResult();