Development Best Practices
Here are a collection of the Joomla! Development practices you should observe when developing a component, plugin or module for Joomla.
General Development Guidelines
- Don't use the
DIRECTORY_SEPARATORconstant when including files. It is no longer needed, as pointed out by Christian on php.net
- Don't depend on
register_globals. This is a HIGH security risk, and the feature has been deprecated in PHP 5.3 and removed in 5.4.
- Don't access the
$_GET, $_POST, $_REQUEST, $_FILES and $_SERVERsuperglobals directly. Use
JInputfilters the input, helping you to easily write more secure software.
- Don't hardcode your SQL queries and do not include unescaped raw data into them. Always use
JDatabaseQuery. It's as simple as
- Don't use arbitrary entry points, i.e. .php files which must be accessible outside Joomla!, directly from the web. Typically used to accommodate for payment processors and image resizers, this practice is extremely insecure and strongly discouraged. Use a Joomla! component or a system plugin instead.
- Don't reinvent the wheel. If there's a Joomla! class to do that try using it before you roll your own. Chances are the core class is already good enough and much better tested.
- Do use sensible prefixes for your table names. If your component is called com_foobar it stands to reason that its tables follow the naming pattern:
// Good #__foobar_something // Bad #__fbr_something //Really Bad! #__something
- Do test your extensions with pre-release versions of Joomla! and/or the "staging" branch of the Git repository. Making sure that users of your extension can update Joomla! safely is your responsibility.
- Do provide documentation for your extensions. Even a short video with less than stellar English is better than nothing.
- Do use
JTextto translate the output of your extension instead of hardcoding text. The vast majority of Joomla! users are not native English speakers and they will thank you for your consideration.
- Do comment your code. Not just for the people who have to work with it, but also yourself six months from now.
- Do test your code under real usage conditions, with real world data sets. You might be surprised at what you find.
You can see in your root a general media folder to hold all assets.
What this means in real terms is that when in your XML install manifest, if you put files inside a <media> tag instead of a <files> tag then they will be sent to the JPATH_ROOT/media folder. If you give it <media destination="com_foo"> then it will put the files in JPATH_ROOT/media/com_foo
In some cases you have a component, we'll say com_foo, and then you have a few modules that go along with com_foo... for sake of the example we'll call them mod_foo_1, mod_foo_2 and mod_foo_3. There is no reason to package media elements for the three modules if they are all the same and they depend upon the component anyway. The best and most logical way to do things is to put them all in a central place that is namespaced appropriately.
By storing media in the media folder, this enables templates to override it with template overrides versus being required to modify the files shipped with your extension, causing those customizations to be lost during updates. By loading your media using the image, script, and stylesheet methods in the JHtml class instead of loading the media directly with JDocument or hard coded tags, this enables easy overrides of your extension's media so that its output can be customized to the site it is used on. See this blog post for more details.
Where should I place files generated by my Component?
It depends on the nature of these files. There are two decisive factors:
- The permanence of the file: temporary, cache or permanent. Temporary files are files which are supposed to be removed immediately after use, before the page load completes. Cache files will be stored on the server for a while, at most until their expiration date. Both temporary and cache files can be deleted without prior warning and your code must anticipate that. Permanent files, on the other hand, are not meant to be removed automatically.
- The disposition of the file: web accessible or web inaccessible. The web accessible files are those which MUST be able to be accessed over the web, e.g. when you type their URL in a web browser. The web inaccessible files are those which NEEDN'T be able to be accessed over the web.
This gives us the following possibilities:
- Temporary, web inaccessible. Use Joomla!'s temp-directory. You can get it by doing JFactory::getConfig()->get('tmp_path'). Hardcoding the path as JPATH_ROOT . '/tmp' is a bad practice and you must not do it.
- Temporary, web accessible. That's not acceptable! Temporary files are by definition inaccessible from the web. Maybe you really meant "cache" instead of "temporary"?
- Cache, web inaccessible. Use the defined Joomla! cache directory. Use the JPATH_CACHE constant to find its location. Please note that the cache directory may be different in the front-end and back-end of your site.
- Permanent, web inaccessible. Use a folder under your extension's main directory. If you really want the files to be completely inaccessible from the web remember to place a .htaccess file or, better yet, give your users the option to use a directory outside the site's root.
This applies to all files handled by your Component, including files your code generates and files the users of your component upload / generate.
Finally, if you want to manage log files you are advised to use the JLog class instead of rolling your own solution.
- Do use try/catch blocks for risky code. If you are unsure if some code is risky just surround it with a try/catch block anyway.
- Do not meddle with other developers' code. This includes moving script tags to the bottom of the page or forcibly removing script tags (e.g. removing any script tag whose source URL includes the strong "jq" – you know for whom the bell tolls).