Actions

J2.5

Difference between revisions of "Adapting a Joomla 1.5 extension to Joomla 2.5"

From Joomla! Documentation

m (Changing name="adminForm" to id="adminForm": changed "tag" to the more correct term "attribute")
(Small But Annoying Problems You May Find After Adapting: Use code tag)
 
(23 intermediate revisions by 10 users not shown)
Line 1: Line 1:
{{incomplete}}
+
{{version/tutor|2.5}}{{page|needs technical review|Please check and see if this article is complete. If so, please remove the from the beginning of the article.}}
  
This article is written to help developers upgrade their extensions from Joomla 1.5 to Joomla 1.6. If you have any further tips, feel free to add them onto this wiki article.
+
This article is written to help developers upgrade their extensions from Joomla 1.5 to Joomla 2.5 and later. If you have any further tips, feel free to add them to this article.
  
== System setup ==
+
== System Setup ==
This document assumes that you are running the program eclipse for your development. This will allow you to automate most of the Joomla conversion process. For more instructions on how to setup eclipse, see [[Setting up your workstation for Joomla! development]].
+
This document assumes that you are running the program Eclipse for your development. This will allow you to automate most of the Joomla conversion process. For instructions on how to setup Eclipse, see [[Setting up your workstation for Joomla! development]].
  
== Background reading ==
+
== Background Reading ==
[[What's new in Joomla 1.6#Developers]] describes most changes of Joomla 1.6 and how this affect developers. Please note that the API documentation on the joomla wiki is incomplete/inaccurate. Therefore the best way to look at the Joomla 1.6 API is to look directly at the joomla source code.
+
[[What's new in Joomla 1.6#Developers]] describes most changes to Joomla 1.6 and how this affect developers. Please note that the API documentation on the joomla wiki is incomplete and can be inaccurate. The best way to look at the Joomla 1.6 API is to look directly at the Joomla source code.
  
== Updating your Joomla 1.5 language files to work on Joomla 1.6 ==   
+
== Updating Your Joomla 1.5 Language Files to Work on Joomla 2.5+ ==   
Using the native php ini parser for language files has many benefits including much faster performace. Converting your exisiting Joomla 1.5 into the new format is very easy if you use a coding platform like eclipse. Search your file for *.ini in your project of choice. Then use the following search/replace values to automatically, replace exisiting quotes, add quotes to string values and update your comments.
+
Using the native PHP ini parser for language files has many benefits including much faster performace. Converting your existing Joomla 1.5 into the new format is very easy if you use a coding platform like Eclipse. Search your file for *.ini in your project of choice. Then use the following search/replace values to automatically replace existing quotes, add quotes to string values and update your comments.
  
 
'''''Double quotes are NOT allowed inside the string value''', except when using "_QQ_" to represent them. In case of js use, better use html entities or single quotes.''
 
'''''Double quotes are NOT allowed inside the string value''', except when using "_QQ_" to represent them. In case of js use, better use html entities or single quotes.''
Line 24: Line 24:
 
Enabling Debug System in Global configuration will display the parsing errors per file and lines.
 
Enabling Debug System in Global configuration will display the parsing errors per file and lines.
  
If you do not remove the illegal strings, then your language file will load until one of them is reached. The now "illegal" strings in the language file like NO, are handled by adding a 'J' in-front of them. Just make sure you change these language strings in your XML files as well. You can include in your language file:
+
If you do not remove the illegal strings, your language file will load until one of them is reached. The now "illegal" strings in the language file like NO, are handled by adding a 'J' in-front of them. Make sure you change these language strings in your XML files as well. You can include in your language file:
 
<source lang="ini">
 
<source lang="ini">
 
;forbidden words
 
;forbidden words
Line 36: Line 36:
 
JNONE="None"
 
JNONE="None"
 
</source>
 
</source>
 +
{{notice|You can use double quotes inside the string value if you surround your string with single quotes. Actually, it gives better  performance and is easier for html attributes. Be careful that single quotes are not allowed then! (But you can use '_Q_').}}
  
== Legacy mode removed ==
+
== Legacy Mode Removed ==
More information needed....
+
''More information needed....''
  
== Changes in the XML installer manifest file ==
+
=== Global Variables (<code>$option</code> and <code>$mainframe</code>) are Gone ===
Joomla 1.6 now uses a more streamlined format for the XML file containing installation instructions in ZIP extension package files. All [[Extension types (technical definitions)|extension types]] now use very similar formats, allowing each type to access the full power of the Joomla! installer. See [[Manifest files]] for details.
+
The statement <code>global $option</code> that often appears in Joomla 1.5 extension code is no longer supported.
  
== Load language in plugins ==
+
To update the code, you may
On the day of release, the way Language files are loaded for Joomla! 1.6 Plugins was changed. As a result, all Plugins must add the following code:
+
* Replace <code>global $option</code> with
  
 
<source lang="php">
 
<source lang="php">
public function __construct(& $subject, $config)
+
  $option = JRequest::getCmd('option')
        {
+
</source>
  
                parent::__construct($subject, $config);
+
If your code is in a controller class derived from JControllerForm, you may prefer:
 +
* Delete any lines with <code>global $option</code>
 +
* Replace all occurrences of <code>$option</code> with <code>$this->option</code>
  
                $this->loadLanguage();
+
The same goes for the often-used <code>global $mainframe</code>. This also is not supported since 1.6.
  
        }
+
To update the code, you may
 +
* Replace <code>global $mainframe</code> with
 +
 
 +
<source lang="php">
 +
  $mainframe = JFactory::getApplication();
 
</source>
 
</source>
  
== change in BuildRoute logic ==
+
== Changes in the XML Installer Manifest File ==
In Joomla! 1.6, the router BuildRoute logic for each Component was changed to require a Menu Item in order to build the link.
+
Joomla 1.6 and later now uses a more streamlined format for the XML file containing installation instructions in the ZIP extension package files. All [[Extension types (technical definitions)|extension types]] now use similar formats, allowing each type to access the full power of the Joomla! installer. See [[Manifest files]] for details.
 +
 
 +
== Load Language in Plugins ==
 +
The way Language files are loaded for Joomla! 1.6 Plugins has changed. All Plugins must add the following code:
  
 
<source lang="php">
 
<source lang="php">
        // we need a menu item. Either the one specified in the query, or the current active one if none specified
+
  public function __construct(& $subject, $config)
        if (empty($query['Itemid'])) {
+
    {
                $menuItem = $menu->getActive();
+
            parent::__construct($subject, $config);
 +
            $this->loadLanguage();
 +
    }
 +
</source>
  
        }
+
== Change in the BuildRoute Logic ==
 +
In Joomla! 1.6+, the router BuildRoute logic for each Component has changed to require a Menu Item in order to build the link.
  
 +
<source lang="php">
 +
        // We need a menu item. Either the one specified in the query or the current active one if none specified
 +
        if (empty($query['Itemid'])) {
 +
            $menuItem = $menu->getActive();
 +
        }
 
         else {
 
         else {
 
+
            $menuItem = $menu->getItem($query['Itemid']);
                $menuItem = $menu->getItem($query['Itemid']);
+
  
 
         }
 
         }
 
</source>
 
</source>
  
There continue to be problems with the router. It is not uncommon to see a URL that bears the existing page URL as the "base" (if you will), followed by it's real URL. Look for these situations and report them on the tracker.
+
There continue to be problems with the router. It is not uncommon to see a URL that bears the existing page URL as the "base" (if you will), followed by its real URL. Look for these situations and report them on the tracker.
  
 
For those who have been around long enough, forcing the Menu Item on the URL was done in 1.0.12 and it turned out poorly.
 
For those who have been around long enough, forcing the Menu Item on the URL was done in 1.0.12 and it turned out poorly.
  
 
+
== Accessing Component Parameters in the Front-end ==
 
+
Accessing component parameters in the frontend for specific menu item, we will use com_content as example. In 1.5 this was done with
== Accessing component parameters in front-end ==
+
 
+
Accessing component parameters in frontend for specific menu item, we will use com_content as example : in 1.5 this was done with
+
 
<source lang="php">
 
<source lang="php">
 
     <?php
 
     <?php
Line 92: Line 107:
 
</source>
 
</source>
  
 
+
The above code in Joomla 1.6+ will output the DEFAULT com_content params. It is not affected by the menu item, so the new code for 1.6 would be
above code in joomla 1.6will output the DEFAULT com_content params , not affected with menu item so the new code for 1.6 would be
+
 
<source lang="php">
 
<source lang="php">
 
     <?php
 
     <?php
 
     $app = JFactory::getApplication('site');
 
     $app = JFactory::getApplication('site');
 
+
     mycom_params = $app->getParams('com_content');
     mycom_params = & $app->getParams('com_content');
+
 
+
 
     echo $mycom_params->get('num_leading_articles');
 
     echo $mycom_params->get('num_leading_articles');
 
 
     ?>
 
     ?>
 
</source>
 
</source>
  
== Plugin parameters ==
+
== Plugin Parameters ==
 
+
 
In 1.5, you had to use the Plugin Helper to retrieve the Plugin object and then JParameter to retrieve the Parameter Object. Following those steps, you could work with a single parameter.
 
In 1.5, you had to use the Plugin Helper to retrieve the Plugin object and then JParameter to retrieve the Parameter Object. Following those steps, you could work with a single parameter.
  
 
<source lang="php">
 
<source lang="php">
 
<?php
 
<?php
 
 
$plugin = & JPluginHelper::getPlugin('content', 'emailcloak');
 
$plugin = & JPluginHelper::getPlugin('content', 'emailcloak');
 
 
$pluginParams = new JParameter($plugin->params);
 
$pluginParams = new JParameter($plugin->params);
 
 
$mode = $pluginParams->def('mode', 1);
 
$mode = $pluginParams->def('mode', 1);
 
 
?>
 
?>
 
</source>
 
</source>
  
In 1.6,Joomla makes the parameter object automatically available to you.
+
In 1.6, Joomla makes the parameter object automatically available to you.
 
+
 
<source lang="php">
 
<source lang="php">
 
<?php
 
<?php
 
 
$mode = $this->params->def('mode', 1);
 
$mode = $this->params->def('mode', 1);
 
 
?>
 
?>
 
</source>
 
</source>
  
== Changing Javascript function overrides ==
+
== Changing the Javascript Function Overrides ==
Joomla now has some of its Javascript functions prefixed with "Joomla". This means the functions are always unique and won't clash with other javascript functions on your server/webpage. However, you now need a different method to override the default Joomla Javascript. The Joomla 1.5 method was:
+
Joomla now has some of its Javascript functions prefixed with ''Joomla''. This means the functions are always unique and won't clash with other Javascript functions on your server or webpage. However, you now need a different method to override the default Joomla Javascript. The Joomla 1.5 method was:
 
<source lang="javascript">
 
<source lang="javascript">
 
function submitbutton(pressbutton) {
 
function submitbutton(pressbutton) {
Line 142: Line 145:
 
         return;
 
         return;
 
     }
 
     }
 
 
     submitform(pressbutton);
 
     submitform(pressbutton);
 
     return;
 
     return;
 
}
 
}
 
</source>
 
</source>
For Joomla 1.6 you need to copy your exisiting function but modify your top line to:
+
For Joomla 1.6+ you need to copy your existing function but modify your top line to:
 
<source lang="javascript">
 
<source lang="javascript">
 
Joomla.submitbutton = function(pressbutton) {
 
Joomla.submitbutton = function(pressbutton) {
Line 157: Line 159:
 
         return;
 
         return;
 
     }
 
     }
 
 
     submitform(pressbutton);
 
     submitform(pressbutton);
 
     return;
 
     return;
Line 163: Line 164:
 
</source>
 
</source>
  
== Changing removed functions ==
+
== Changing Removed Functions ==
 
Some functions were removed for various reasons. You can find a list of them on [[What's new in Joomla_1.6#Removed_features]].
 
Some functions were removed for various reasons. You can find a list of them on [[What's new in Joomla_1.6#Removed_features]].
  
 
Note that the ADODB compatibility methods included function like $db->Execute($query) which now need a separate $db->setQuery($query);$db->Query();
 
Note that the ADODB compatibility methods included function like $db->Execute($query) which now need a separate $db->setQuery($query);$db->Query();
  
 
+
== Renamed Events ==
== Renamed events ==
+
 
+
 
A large number of the Joomla 1.5 events have been renamed. Here is the list of renamed events.
 
A large number of the Joomla 1.5 events have been renamed. Here is the list of renamed events.
*onContentAfterSave
+
*[[Plugin/Events/Content#onContentAfterSave|onContentAfterSave]]
*onContentAfterTitle
+
*[[Plugin/Events/Content#onContentAfterTitle|onContentAfterTitle]]
*onContentAfterDisplay
+
*[[Plugin/Events/Content#onContentAfterDisplay|onContentAfterDisplay]]
*onContentBeforeDisplay
+
*[[Plugin/Events/Content#onContentBeforeDisplay|onContentBeforeDisplay]]
*onContentBeforeSave
+
*[[Plugin/Events/Content#onContentBeforeSave|onContentBeforeSave]]
*onContentSearch
+
*[[Plugin/Events/Content#onContentSearch|onContentSearch]]
*onContentSearchAreas
+
*[[Plugin/Events/Content#onContentSearchAreas|onContentSearchAreas]]
*onUserAuthenticate
+
*[[Plugin/Events/User#onUserAuthenticate|onUserAuthenticate]]
*onUserAfterDelete
+
*[[Plugin/Events/User#onUserAfterDelete|onUserAfterDelete]]
*onUserAfterSave
+
*[[Plugin/Events/User#onUserAfterSave|onUserAfterSave]]
*onUserBeforeDelete
+
*[[Plugin/Events/User#onUserBeforeDelete|onUserBeforeDelete]]
*onUserBeforeSave
+
*[[Plugin/Events/User#onUserBeforeSave|onUserBeforeSave]]
*onUserLogin
+
*[[Plugin/Events/User#onUserLogin|onUserLogin]]
*onUserLogout
+
*[[Plugin/Events/User#onUserLogout|onUserLogout]]
*All content events (except for search and search areas) now pass a 'context' as the first argument to alert the plugin as to what type of content is being passed. The plugin event may or may not heed this context.
+
*All content events (except for search and search areas) now pass a 'context' as the first argument to alert the plugin as to what type of content is being passed. The plugin event may or may not heed this context.
  
 
This means that if you use Joomla events you have two options:<br/>
 
This means that if you use Joomla events you have two options:<br/>
1) rename the event and your extension can only be used on Joomla 1.6<br/>
+
# rename the event and your extension can only be used on Joomla 2.5<br/>
2) create your own "legacy layer" and add the new event function name to your plugin. Here is an example of the user plugin:<br/>
+
# create your own "legacy layer" and add the new event function name to your plugin.
  
 +
Here is an example of the user plugin:
 
<source lang="php">
 
<source lang="php">
     //joomla 1.6 compatibility code  
+
     //joomla 2.5 compatibility code  
 
  public function onUserLogin($user, $options){
 
  public function onUserLogin($user, $options){
 
      $result = $this->onLoginUser($user, $options);
 
      $result = $this->onLoginUser($user, $options);
Line 217: Line 217:
  
 
== Changing name="adminForm" to id="adminForm" ==
 
== Changing name="adminForm" to id="adminForm" ==
To create your own admin forms in joomla you now need to use id="adminForm". This is because the use of the "name" attribute is not valid HTML strict and has compatibility issues when used in XHTML served as XML. Although there is a built-in compatibility check to look for the old name="adminForm" attribute, it is best to add the new id attribute. Depending on the features you want to use you may need to include both, name="adminForm" and id="adminForm" because not all core functionality has been updated to use id's. An example of the new form code is:
+
To create your own admin forms, you now need to use id="adminForm". This is because the use of the "name" attribute is not valid HTML strict and has compatibility issues when used in XHTML served as XML. Although there is a built-in compatibility check to look for the old name="adminForm" attribute, it is best to add the new id attribute. Depending on the features you want to use you may need to include both, name="adminForm" and id="adminForm" because not all core functionality has been updated to use id's. An example of the new form code is:
 
<source lang="html4strict"><form method="post" action="index.php" name="adminForm" id="adminForm"></form></source>
 
<source lang="html4strict"><form method="post" action="index.php" name="adminForm" id="adminForm"></form></source>
  
== Removing references to index2.php and index3.php ==
+
== Removing References to index2.php and index3.php ==
Joomla 1.0 had different index files to serve admin content in different manners. Joomla 1.6 has now got better way to handle this and you need to search your codebase for "index2.php" and "index3.php" to ensure you don't have any Joomla 1.0 style links. If you need to display your component without any of the other Joomla 1.6 admin content (menus, etc) then add the following to the url: "&tmpl=component"
+
Joomla 1.0 had different index files to serve admin content in different manners. Joomla 1.6+ has a better way to handle this. Search your codebase for "index2.php" and "index3.php" to ensure you don't have any Joomla 1.0 style links. If you need to display your component without any of the other Joomla 1.6+ admin content (menus, etc), add the following to the url: "&tmpl=component"
 
+
== Upgrading core table and field name usage ==
+
Many of the core Joomla tables have been simplified, combined or renamed. This was needed to get rid of some limitation dating back to Joomla 1.0. This means however that if you have code that directly manipulates Joomla tables, that you need to add a function that detects Joomla 1.6 and had different SQL queries based on the joomla version. Plase note that both tables and field names have been renamed or removed. An example is the following function that can find if a plugin is published on both Joomla 1.5 and 1.6:
+
  
 +
== Upgrading Core Table and Field Name Usage ==
 +
Many of the core Joomla tables have been simplified, combined or renamed. This was needed to get rid of some limitation dating back to Joomla 1.0. If you have code that directly manipulates Joomla tables, add a function that detects Joomla 1.6+ and had different SQL queries based on the Joomla version. Please note that both tables and field names have been renamed or removed. An example is the following function that can determine if a plugin is published on both Joomla 1.5 and 1.6+:
 
<source lang="php">
 
<source lang="php">
 
function getPluginStatus($element, $folder) {
 
function getPluginStatus($element, $folder) {
 
     //get joomla specs
 
     //get joomla specs
     $db = & JFactory::getDBO();
+
     $db = JFactory::getDbo();
 
     $version = new JVersion;
 
     $version = new JVersion;
 
     $joomla = $version->getShortVersion();
 
     $joomla = $version->getShortVersion();
 
     if(substr($joomla,0,3) == '1.6'){
 
     if(substr($joomla,0,3) == '1.6'){
 
         //Joomla 1.6 code
 
         //Joomla 1.6 code
         $query = 'SELECT enabled FROM #__extensions WHERE element=' . $db->Quote($element) . ' AND folder=' . $db->Quote($folder);
+
         $query = $db->getQuery(true);
 +
        $query->select($db->quoteName('*'))
 +
              ->from($db->quoteName('#__extensions'))
 +
              ->where($db->quoteName('element') . '=' . $db->Quote($element))
 +
              ->where($db->quoteName('folder') . '=' . $db->Quote($folder))
 
     } else {
 
     } else {
 
         //Joomla 1.0/1.5 code
 
         //Joomla 1.0/1.5 code
Line 245: Line 248:
 
</source>
 
</source>
  
== New mootools version ==
+
== New Mootools Version ==
Most important is that the Ajax class has been depreciated and replaced by the Request class. That means that if you use ajax calls you need to have a version switcher (below a sample code)
+
The Ajax class is deprecated and replaced by the Request class. If you use Ajax calls, you need to have a version switcher. See this sample code.
 
+
 
+
 
<source lang="php">
 
<source lang="php">
 
$version = new JVersion;
 
$version = new JVersion;
Line 276: Line 277:
 
</source>
 
</source>
  
Also another common usuage of mootools in Joomla is the popup box. The Joomla 1.5 javascript code to close this box is:
+
Also another common usage of mootools in Joomla is the popup box. The Joomla 1.5 Javascript code to close this box is:
 
<source lang="javascript">document.getElementById('sbox-window').close();</source>
 
<source lang="javascript">document.getElementById('sbox-window').close();</source>
in Joomla 1.6 you need to use:
+
In Joomla 1.6+ you need to use:
 
<source lang="javascript">window.parent.SqueezeBox.close();</source>
 
<source lang="javascript">window.parent.SqueezeBox.close();</source>
  
== Converting your JParameters to JForms ==
+
== Converting Your JParameters to JForms ==
Joomla 1.6 now uses the JForms class to handle parameters and it has also changed the way parameters are defined in your XML files. To make menu/component/module/plugin parameters work, first you need to update the XML file. Here is an automated way to handle the bulk of the conversion. (added "" to the examples below so you can see spaces in the search query as well). Use eclipse to search and replace parameters in *.xml files
+
Joomla 1.6+ now uses the JForms class to handle parameters and it has also changed the way parameters are defined in your XML files. To make menu/component/module/plugin parameters work, first you need to update the XML file. Here is an automated way to handle the bulk of the conversion. (added "" to the examples below so you can see spaces in the search query as well). Use Eclipse to search and replace parameters in *.xml files
  
 
replace "<params>" with "<config><fields name="params"><fieldset name="basic" label="basic">"<br>
 
replace "<params>" with "<config><fields name="params"><fieldset name="basic" label="basic">"<br>
Line 303: Line 304:
 
</source>
 
</source>
  
Now if you want to use your joomla extension on both Joomla 1.5 and 1.6 you will need to go to your "team synchronising" view in eclipse. Double click on your changed xml file, which will open the compare editor. Then simply copy-paste back your old Joomla 1.5 params into your new Joomla 1.6 xml file and save.
+
Now if you want to use your Joomla extension on both Joomla 1.5 and 1.6+, you will need to go to your "team synchronising" view in Eclipse. Double click on your changed XML file, which will open the compare editor. Then simply copy-paste back your old Joomla 1.5 params into your new Joomla 1.6+ XML file and save.
  
If you have custom parameter types, you will need to do some additional work. In Joomla 1.5 you would use the following code:
+
If you have custom parameter types, you will need to do some additional work. In Joomla 1.5, you would use the following code:
  
 
<source lang="php"><params addpath="/administrator/components/com_yourname/elements"></source>
 
<source lang="php"><params addpath="/administrator/components/com_yourname/elements"></source>
In joomla 1.6 JParameter classes won't work and you will need to convert your jparameter fields into JForm fields. Create a new directory and copy your "old elements" into them. Then you need to load these new fields with the individual parameter
+
In Joomla 1.6+ JParameter classes won't work and you will need to convert your jParameter fields into JForm fields. Create a new directory and copy your "old elements" into them. Then you need to load these new fields with the individual parameter.
  
 
<source lang="php"><field name="sample" type="sampleField" size="5" default="" label="sampleField"
 
<source lang="php"><field name="sample" type="sampleField" size="5" default="" label="sampleField"
 
       description="sampleField" addfieldpath="/administrator/components/com_yourname/fields"/></source>
 
       description="sampleField" addfieldpath="/administrator/components/com_yourname/fields"/></source>
  
Use eclipse to search and replace files in your newly created fields directory.
+
Use Eclipse to search and replace files in your newly-created fields directory.
 
replace "JElement" with "JFormField"<br>
 
replace "JElement" with "JFormField"<br>
 
replace "var $_name =" with "public $type ="<br>
 
replace "var $_name =" with "public $type ="<br>
 
replace "function fetchElement($name, $value, &$node, $control_name)" with "protected function getInput()"<br>
 
replace "function fetchElement($name, $value, &$node, $control_name)" with "protected function getInput()"<br>
  
Then you still need to replace the references to $control_name and others in your new JForm field, but at least the bulk of the work has been done automatically
+
You still need to replace the references to $control_name and others in your new JForm field, but at least the bulk of the work has been done automatically.
  
 
Using label tag is needed if you name your fieldset anything other than basic and advanced.
 
Using label tag is needed if you name your fieldset anything other than basic and advanced.
Basic and advanced are in com_modules language file and will be translated, but if you use "other" which was in 1.5 or your own name (the number of fieldsets and therefore panes is no longer fixed) then the pane will output COM_MODULES_your fieledset name_FIELDSET_LABEL If you use label="your fieldset name" then it will show the correct label in your pane.
+
Basic and advanced are in the com_modules language file and will be translated, but if you use "other" which was in 1.5 or your own name (the number of fieldsets and therefore panes is no longer fixed) then the pane will output COM_MODULES_your fieledset name_FIELDSET_LABEL. If you use label="your fieldset name" then it will show the correct label in your pane.
  
== renamed core component names and login form parameters ==
+
== Renamed Core Component Names and Login Form Parameters ==
A login module for Joomla 1.5 will not work without modifications on Joomla 1.6. Here is a part of the logout module that will work on both Joomla 1.5 and Joomla 1.6. You can compare the two to see the difference in input names.
+
A login module for Joomla 1.5 will not work without modifications on Joomla 1.6+. Here is part of the logout module that will work on both Joomla 1.5 and Joomla 1.6+. You can compare the two to see the difference in input names.
  
 
<source lang="php">
 
<source lang="php">
Line 340: Line 341:
 
</source>
 
</source>
  
here is the code for the login module
+
Here is the code for the login module:
 
+
  
 
<source lang="php">
 
<source lang="php">
Line 359: Line 359:
 
</source>
 
</source>
  
These changes might also apply to front-end forms of other Joomla core components (more information needed)
+
These changes might also apply to front-end forms of other Joomla core components. (''more information needed'')
  
 
+
== ACL Changes ==
== ACL changes ==
+
 
Joomla 1.6 now has an advanced ACL system. It is unknown how this affects people that have previously used the ACL API in their extension.
 
Joomla 1.6 now has an advanced ACL system. It is unknown how this affects people that have previously used the ACL API in their extension.
  
Line 368: Line 367:
 
<source lang="xml">
 
<source lang="xml">
 
<?xml version="1.0" encoding="utf-8"?>
 
<?xml version="1.0" encoding="utf-8"?>
<access component="com_example">
+
  <access component="com_example">
<section name="component">
+
      <section name="component">
<!-- Joomla! core privileges -->
+
        <!-- Joomla! core privileges -->
<action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
+
        <action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
<action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
+
        <action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
<!-- Custom privileges -->
+
        <!-- Custom privileges -->
<action name="example.something" title="COM_EXAMPLE_ACL_SOMETHING_TITLE" description="COM_EXAMPLE_ACL_SOMETHING_DESC" />
+
        <action name="example.something" title="COM_EXAMPLE_ACL_SOMETHING_TITLE" description="COM_EXAMPLE_ACL_SOMETHING_DESC" />
</section>
+
      </section>
</access>
+
  </access>
 
</source>
 
</source>
  
 
Important things to notice:
 
Important things to notice:
* The root tag is called access and you must specify the component="com_yourComponentName" attribute
+
* The root tag is called access and you must specify the component="com_yourComponentName" attribute.
* The section tag is mandatory
+
* The section tag is mandatory.
* No ACL privilege will display on the list unless you '''explicitly''' add it. This means that you do have to add the core privileges that concern your component
+
* No ACL privilege will display on the list unless you '''explicitly''' add it. This means that you do have to add the core privileges that concern your component.
* You can create custom privileges! You don't have to register them anywhere except your access.xml file. The name format is liberal, but no two components should use the same key for a different purpose (all components' privileges share the same namespace). As a rule of thumb use the convention componentName.privilegeName. You must NEVER use core.* names as they are reserved by Joomla!.
+
* You can create custom privileges! You don't have to register them anywhere except your access.xml file. The name format is liberal, but no two components should use the same key for a different purpose (all components' privileges share the same namespace). As a rule of thumb, use the convention componentName.privilegeName. You must NEVER use core.* names - they are reserved by Joomla.
  
 
In order to apply ACLs, you have to override your controller's constructor:
 
In order to apply ACLs, you have to override your controller's constructor:
 
 
<source lang="php">
 
<source lang="php">
public function __construct($config = array())
+
  public function __construct($config = array())
{
+
  {
parent::__construct($config);
+
      parent::__construct($config);
// This conditional lets the ACL check run only on Joomla! 1.6+
+
      // This conditional lets the ACL check run only on Joomla! 1.6+
if( version_compare( JVERSION, '1.6.0', 'ge' ) ) {
+
      if( version_compare( JVERSION, '1.6.0', 'ge' ) ) {
$user = JFactory::getUser();
+
        $user = JFactory::getUser();
if (!$user->authorise('example.something', 'com_example')) {
+
        if (!$user->authorise('example.something', 'com_example')) {
return JError::raiseWarning(403, JText::_('JERROR_ALERTNOAUTHOR'));
+
            return JError::raiseWarning(403, JText::_('JERROR_ALERTNOAUTHOR'));
}
+
        }
}
+
      }
// Place anything else you need in the constructor below this line
+
      // Place anything else you need in the constructor below this line
}
+
    }
 
</source>  
 
</source>  
  
 
The heavy lifting is done by the authorise() method of the JUser class. The first parameter is the privilege name, the second one is the "section", i.e. your component's name. As you can see, this allows for great flexibility. You can check any privilege, for any component, for any user, from anywhere in your code.
 
The heavy lifting is done by the authorise() method of the JUser class. The first parameter is the privilege name, the second one is the "section", i.e. your component's name. As you can see, this allows for great flexibility. You can check any privilege, for any component, for any user, from anywhere in your code.
  
== Plugin files now in different locations ==
+
== Plugin Files Now in Different Locations ==
Joomla 1.6 now creates a different hierarchy structure for plugins. Files are no longer placed where they used to be, so if your other parts of your application (comp, mods, etc.) expects them to be in a certain position, it won't work. The change has been that now plugins are in an additional subdirectory. If you only load your plugins via the 1.5 API you should be fine.
+
Joomla 1.6+ now creates a different hierarchy structure for plugins. Files are no longer placed where they used to be, so if your other parts of your application (comp, mods, etc.) expects them to be in a certain position, it won't work. Now plugins are in an additional subdirectory. If you only load your plugins via the 1.5 API you should be fine.
 
* Joomla 1.5 example location  
 
* Joomla 1.5 example location  
 
<source lang="php">JPATH_SITE . DS . 'plugins' . DS . 'authentication' . DS . 'example.php';</source>
 
<source lang="php">JPATH_SITE . DS . 'plugins' . DS . 'authentication' . DS . 'example.php';</source>
 
* Joomla 1.6 example location
 
* Joomla 1.6 example location
<source lang="php">JPATH_SITE . DS . 'plugins' . DS . 'authentication' . DS . 'example'. DS . 'example.php';</source>
+
<source lang="php">JPATH_SITE . '/plugins/authentication/example/example.php';</source>
  
== Changes to view parameters ==
+
== Changes to View Parameters ==
J!1.6 has a strict new way of specifying parameters for views. J!1.5 allowed a bit of freedom where the parameters could be defined at the view.html.php level but now ithas to be at the tmpl level. AE believes the view paramters were removed.
+
Joomla 1.6+ has a strict new way of specifying parameters for views. Joomla 1.5 allowed a bit of freedom where the parameters could be defined at the view.html.php level but now it has to be at the tmpl level. AE believes the view parameters were removed.
  
 +
== Installation Process - Preflight and Postflight ==
 +
These are new events that can screw up an existing installation process. They should be totally optional access points to the installation process. But if your 1.5 install process is tricky for some reason, these can be used to do clean up activities.
  
== Installation process - preflight, postflight, etc ==
+
== Admin Template Changes ==
These are new events that can screw up an existing installlation process.  -1 on me for not documenting the process while stepping through xdebug.
+
Admin functions that depended on certain functions (naming conventions etc) no longer workKhepri has been removed. Other admin functions/libraries may have changed.  
They should be totally optional access points to the installation processBut if your 1.5 install process is tricky for some reason, then these can be used to do clean up activities.
+
  
 
+
==sys.ini Language Translation File==
== Admin template changes ==
+
Admin functions that depended on certain functions, naming conventions etc no longer work.  Khepri has been removed.  Other admin functions/libraries may have changed.
+
 
+
==sys.ini language translation file==
+
 
This file has 3 purposes:
 
This file has 3 purposes:
  
 
1. It is used for installation process translations, when a folder language is included in the pack.
 
1. It is used for installation process translations, when a folder language is included in the pack.
  
pack/language/en-gb/en-gb.extension.ini
+
pack/language/en-GB/en-GB.''extension'''''.ini'''
  
pack/language/en-gb/en-gb.extension.sys.ini
+
pack/language/en-GB/en-GB.''extension'''''.sys.ini'''
  
 
In this case, the <description>COM_MYCOMPONENT_XML_DESCRIPTION</description> used in the sys.ini will display on installing/updating the extension.
 
In this case, the <description>COM_MYCOMPONENT_XML_DESCRIPTION</description> used in the sys.ini will display on installing/updating the extension.
Line 436: Line 431:
 
When editing the extension in administration, it will be the .ini version of COM_MYCOMPONENT_XML_DESCRIPTION which will display.
 
When editing the extension in administration, it will be the .ini version of COM_MYCOMPONENT_XML_DESCRIPTION which will display.
  
 +
2. It is used to replace the former ''extension'''''.menu.ini'''
  
2. It is used to replace the former .menu.ini
+
3. It is used to display the translated name of the extension in many managers.
  
 +
== Removed Include Folders ==
 +
Most of the 3rd party libraries (Archive, domit, js, PEAR, etc) in the include folder have been removed in Joomla 1.6+.
  
3. It is used to display the translated extension name in many managers.
+
== Use Paths Defined in defines.php ==
 +
(Note they are different for the site and the administration)
  
== removed include folders ==
+
== Small But Annoying Problems You May Find After Adapting ==
Most of the 3rd party libraries (Archive, domit, js, PEAR, etc) in the include folder have been removed in J!1.6.  
+
If you have a component including tables with sortable columns - JHTML::_('grid.sort'... Maybe it will not work - you try to sort be a column other than the default one, by pressing the column title, and nothing happens. Solution: at the default.php file that displays the table, in the html line that opens the form, add the attribute id="adminForm". In Joomla 1.5, the important attribute for the form was name="adminForm". Some developers didn't add the id attribute. It should look like this:
 
+
<source lang="php">
 
+
<form action="<?php echo $this->request_url; ?>" method="post" name="adminForm" id="adminForm">
== Use paths defined in defines.php. ==
+
</source>
(Note they are different for the site and the administration)
+
  
 
[[Category:Joomla! 1.6]]
 
[[Category:Joomla! 1.6]]
 
[[Category:Tutorials]]
 
[[Category:Tutorials]]
[[Category:Development]]
+
[[Category:Migration]]
 
[[Category:Module Development]]
 
[[Category:Module Development]]
 
[[Category:Component Development]]
 
[[Category:Component Development]]
 
[[Category:Plugin Development]]
 
[[Category:Plugin Development]]
 
 
== global $option is gone ==
 
 
The statement 'global $option' that often appears in Joomla 1.5 extension code is no longer supported.
 
 
To update the code, you may
 
* Replace 'global $option' with
 
 
<source lang="php">
 
  $option = JRequest::getCmd('option')
 
</source>
 
 
If your code is in a controller class derived from JControllerForm, you may prefer:
 
* Delete any lines with 'global $option'
 
* Replace all occurrences of '$option' with '$this->option'
 
 
See:
 

Latest revision as of 23:03, 16 November 2013

Copyedit.png
This Page Needs Your Help

This page is tagged because it NEEDS TECHNICAL REVIEW. You can help the Joomla! Documentation Wiki by contributing to it.
More pages that need help similar to this one are here. NOTE-If you feel the need is satistified, please remove this notice.

Reason: Please check and see if this article is complete. If so, please remove the from the beginning of the article.


This article is written to help developers upgrade their extensions from Joomla 1.5 to Joomla 2.5 and later. If you have any further tips, feel free to add them to this article.

Contents

System Setup

This document assumes that you are running the program Eclipse for your development. This will allow you to automate most of the Joomla conversion process. For instructions on how to setup Eclipse, see Setting up your workstation for Joomla! development.

Background Reading

What's new in Joomla 1.6#Developers describes most changes to Joomla 1.6 and how this affect developers. Please note that the API documentation on the joomla wiki is incomplete and can be inaccurate. The best way to look at the Joomla 1.6 API is to look directly at the Joomla source code.

Updating Your Joomla 1.5 Language Files to Work on Joomla 2.5+

Using the native PHP ini parser for language files has many benefits including much faster performace. Converting your existing Joomla 1.5 into the new format is very easy if you use a coding platform like Eclipse. Search your file for *.ini in your project of choice. Then use the following search/replace values to automatically replace existing quotes, add quotes to string values and update your comments.

Double quotes are NOT allowed inside the string value, except when using "_QQ_" to represent them. In case of js use, better use html entities or single quotes.

  1. Single quotes are allowed.
  2. Put a closing double quote at end of line if not empty or a comment. Find ^((?!#).+)\R replace with $1"\R
  3. Put an opening double quote at start of translated string if not empty or comment. Find ^((?!#).+?\=)(.+)\R replace with $1"$2\R
  4. Now replace the hash comments with the new semi colon. Find ^# and replace with ;
  5. Remove any illegal strings that can prevent files loading. Find ^(null|yes|no|true|false|on|off|none)=(.+)\R and replace with nothing.

IMPORTANT: never use the escape \" for double quotes. It may work on PHP 5.3 but will break in PHP 5.2.4+

Enabling Debug System in Global configuration will display the parsing errors per file and lines.

If you do not remove the illegal strings, your language file will load until one of them is reached. The now "illegal" strings in the language file like NO, are handled by adding a 'J' in-front of them. Make sure you change these language strings in your XML files as well. You can include in your language file:

;forbidden words
JNULL="Null"
JYES="Yes"
JNO="No"
JTRUE="True"
JFALSE="False"
JON="On"
JOFF="Off"
JNONE="None"
Info non-talk.png
General Information

You can use double quotes inside the string value if you surround your string with single quotes. Actually, it gives better performance and is easier for html attributes. Be careful that single quotes are not allowed then! (But you can use '_Q_').

Legacy Mode Removed

More information needed....

Global Variables ($option and $mainframe) are Gone

The statement global $option that often appears in Joomla 1.5 extension code is no longer supported.

To update the code, you may

  • Replace global $option with
   $option = JRequest::getCmd('option')

If your code is in a controller class derived from JControllerForm, you may prefer:

  • Delete any lines with global $option
  • Replace all occurrences of $option with $this->option

The same goes for the often-used global $mainframe. This also is not supported since 1.6.

To update the code, you may

  • Replace global $mainframe with
   $mainframe = JFactory::getApplication();

Changes in the XML Installer Manifest File

Joomla 1.6 and later now uses a more streamlined format for the XML file containing installation instructions in the ZIP extension package files. All extension types now use similar formats, allowing each type to access the full power of the Joomla! installer. See Manifest files for details.

Load Language in Plugins

The way Language files are loaded for Joomla! 1.6 Plugins has changed. All Plugins must add the following code:

 public function __construct(& $subject, $config)
    {
            parent::__construct($subject, $config);
            $this->loadLanguage();
    }

Change in the BuildRoute Logic

In Joomla! 1.6+, the router BuildRoute logic for each Component has changed to require a Menu Item in order to build the link.

        // We need a menu item. Either the one specified in the query or the current active one if none specified
        if (empty($query['Itemid'])) {
             $menuItem = $menu->getActive();
        }
        else {
             $menuItem = $menu->getItem($query['Itemid']);
 
        }

There continue to be problems with the router. It is not uncommon to see a URL that bears the existing page URL as the "base" (if you will), followed by its real URL. Look for these situations and report them on the tracker.

For those who have been around long enough, forcing the Menu Item on the URL was done in 1.0.12 and it turned out poorly.

Accessing Component Parameters in the Front-end

Accessing component parameters in the frontend for specific menu item, we will use com_content as example. In 1.5 this was done with

    <?php
    $mycom_params =  JComponentHelper::getParams('com_content');
 
    echo $mycom_params->get('num_leading_articles');
 
    ?>

The above code in Joomla 1.6+ will output the DEFAULT com_content params. It is not affected by the menu item, so the new code for 1.6 would be

    <?php
    $app = JFactory::getApplication('site');
    mycom_params = $app->getParams('com_content');
    echo $mycom_params->get('num_leading_articles');
    ?>

Plugin Parameters

In 1.5, you had to use the Plugin Helper to retrieve the Plugin object and then JParameter to retrieve the Parameter Object. Following those steps, you could work with a single parameter.

<?php
$plugin = & JPluginHelper::getPlugin('content', 'emailcloak');
$pluginParams = new JParameter($plugin->params);
$mode = $pluginParams->def('mode', 1);
?>

In 1.6, Joomla makes the parameter object automatically available to you.

<?php
$mode = $this->params->def('mode', 1);
?>

Changing the Javascript Function Overrides

Joomla now has some of its Javascript functions prefixed with Joomla. This means the functions are always unique and won't clash with other Javascript functions on your server or webpage. However, you now need a different method to override the default Joomla Javascript. The Joomla 1.5 method was:

function submitbutton(pressbutton) {
var form = document.adminForm;
    if (pressbutton == 'applyconfig') {
        //do something unique
        form.action.value = 'apply'
        submitform('saveconfig');
        return;
    }
    submitform(pressbutton);
    return;
}

For Joomla 1.6+ you need to copy your existing function but modify your top line to:

Joomla.submitbutton = function(pressbutton) {
var form = document.adminForm;
    if (pressbutton == 'applyconfig') {
        //do something unique
        form.action.value = 'apply'
        submitform('saveconfig');
        return;
    }
    submitform(pressbutton);
    return;
}

Changing Removed Functions

Some functions were removed for various reasons. You can find a list of them on What's new in Joomla_1.6#Removed_features.

Note that the ADODB compatibility methods included function like $db->Execute($query) which now need a separate $db->setQuery($query);$db->Query();

Renamed Events

A large number of the Joomla 1.5 events have been renamed. Here is the list of renamed events.

This means that if you use Joomla events you have two options:

  1. rename the event and your extension can only be used on Joomla 2.5
  2. create your own "legacy layer" and add the new event function name to your plugin.

Here is an example of the user plugin:

    //joomla 2.5 compatibility code 
        public function onUserLogin($user, $options){
            $result = $this->onLoginUser($user, $options);
            return $result;
        }
        public function onUserLogout($user)     {
            $result = $this->onLogoutUser($user);
            return $result;
        }
        public function onUserAfterDelete($user, $succes, $msg) {
            $result = $this->onAfterDeleteUser($user, $succes, $msg);
            return $result;
        }
        public function onUserBeforeSave($user, $isnew, $new){
            $result = $this->onBeforeStoreUser($user, $isnew, $new);
            return $result;     
        }
        public function onUserAfterSave($user, $isnew, $success, $msg){
            $result = $this->onAfterStoreUser($user, $isnew, $success, $msg);
            return $result;                     
        }

Changing name="adminForm" to id="adminForm"

To create your own admin forms, you now need to use id="adminForm". This is because the use of the "name" attribute is not valid HTML strict and has compatibility issues when used in XHTML served as XML. Although there is a built-in compatibility check to look for the old name="adminForm" attribute, it is best to add the new id attribute. Depending on the features you want to use you may need to include both, name="adminForm" and id="adminForm" because not all core functionality has been updated to use id's. An example of the new form code is:

<form method="post" action="index.php" name="adminForm" id="adminForm"></form>

Removing References to index2.php and index3.php

Joomla 1.0 had different index files to serve admin content in different manners. Joomla 1.6+ has a better way to handle this. Search your codebase for "index2.php" and "index3.php" to ensure you don't have any Joomla 1.0 style links. If you need to display your component without any of the other Joomla 1.6+ admin content (menus, etc), add the following to the url: "&tmpl=component"

Upgrading Core Table and Field Name Usage

Many of the core Joomla tables have been simplified, combined or renamed. This was needed to get rid of some limitation dating back to Joomla 1.0. If you have code that directly manipulates Joomla tables, add a function that detects Joomla 1.6+ and had different SQL queries based on the Joomla version. Please note that both tables and field names have been renamed or removed. An example is the following function that can determine if a plugin is published on both Joomla 1.5 and 1.6+:

 
function getPluginStatus($element, $folder) {
    //get joomla specs
    $db = JFactory::getDbo();           
    $version = new JVersion;
    $joomla = $version->getShortVersion();
    if(substr($joomla,0,3) == '1.6'){
        //Joomla 1.6 code
        $query = $db->getQuery(true);
        $query->select($db->quoteName('*'))
              ->from($db->quoteName('#__extensions'))
              ->where($db->quoteName('element') . '=' . $db->Quote($element))
              ->where($db->quoteName('folder') . '=' . $db->Quote($folder))
    } else {
        //Joomla 1.0/1.5 code
        $query = 'SELECT published FROM #__plugins WHERE element=' . $db->Quote($element) . ' AND folder=' .   $db->Quote($folder); 
    }
    $db->setQuery($query);
    $result = $db->loadResult();
    return $result;
}

New Mootools Version

The Ajax class is deprecated and replaced by the Request class. If you use Ajax calls, you need to have a version switcher. See this sample code.

$version = new JVersion;
$joomla = $version->getShortVersion();
 
..... (your code) ....
 
    /* our ajax istance for starting the sync */
    <?php  if(substr($joomla,0,3) == '1.6'){
 echo 'var ajax = new Request.HTML({
           url: url,';
    } else {
 echo 'var ajax = new Ajax(url, {';
    }?>
 
.... your code .....
 
    <?php  if(substr($joomla,0,3) == '1.6'){
     echo 'var ajaxsync = new Request.HTML({
        url: url, ';
    } else {
echo 'var ajaxsync = new Ajax(url, {';
    }?>
 
.... your code .....

Also another common usage of mootools in Joomla is the popup box. The Joomla 1.5 Javascript code to close this box is:

document.getElementById('sbox-window').close();

In Joomla 1.6+ you need to use:

window.parent.SqueezeBox.close();

Converting Your JParameters to JForms

Joomla 1.6+ now uses the JForms class to handle parameters and it has also changed the way parameters are defined in your XML files. To make menu/component/module/plugin parameters work, first you need to update the XML file. Here is an automated way to handle the bulk of the conversion. (added "" to the examples below so you can see spaces in the search query as well). Use Eclipse to search and replace parameters in *.xml files

replace "<params>" with "<config><fields name="params"><fieldset name="basic" label="basic">"
replace "<params*?>" with "<config><fields name="params"><fieldset name="basic">"
replace "</params>" with "</fieldset></fields></config>"
replace "<param " with "<field "
replace "</param>" with </field>"
replace "<install " with "<extension "
replace "</install>" with "</extension>"

Change the "extension" node to add the following attributes:

  • Keep the existing "type" attribute
  • version="1.6.0"
  • client="site"
  • method="upgrade"

Example for a module:

<extension type="module" version="1.6.0" client="site" method="upgrade">

Now if you want to use your Joomla extension on both Joomla 1.5 and 1.6+, you will need to go to your "team synchronising" view in Eclipse. Double click on your changed XML file, which will open the compare editor. Then simply copy-paste back your old Joomla 1.5 params into your new Joomla 1.6+ XML file and save.

If you have custom parameter types, you will need to do some additional work. In Joomla 1.5, you would use the following code:

<params addpath="/administrator/components/com_yourname/elements">

In Joomla 1.6+ JParameter classes won't work and you will need to convert your jParameter fields into JForm fields. Create a new directory and copy your "old elements" into them. Then you need to load these new fields with the individual parameter.

<field name="sample" type="sampleField" size="5" default="" label="sampleField"
       description="sampleField" addfieldpath="/administrator/components/com_yourname/fields"/>

Use Eclipse to search and replace files in your newly-created fields directory. replace "JElement" with "JFormField"
replace "var $_name =" with "public $type ="
replace "function fetchElement($name, $value, &$node, $control_name)" with "protected function getInput()"

You still need to replace the references to $control_name and others in your new JForm field, but at least the bulk of the work has been done automatically.

Using label tag is needed if you name your fieldset anything other than basic and advanced. Basic and advanced are in the com_modules language file and will be translated, but if you use "other" which was in 1.5 or your own name (the number of fieldsets and therefore panes is no longer fixed) then the pane will output COM_MODULES_your fieledset name_FIELDSET_LABEL. If you use label="your fieldset name" then it will show the correct label in your pane.

Renamed Core Component Names and Login Form Parameters

A login module for Joomla 1.5 will not work without modifications on Joomla 1.6+. Here is part of the logout module that will work on both Joomla 1.5 and Joomla 1.6+. You can compare the two to see the difference in input names.

        $version = new JVersion;
        $joomla = $version->getShortVersion();
        if(substr($joomla,0,3) == '1.5'){
            //joomla 1.5 format          
            $output .= '<input type="hidden" name="task" value="logout" />';
            $output .= '<input type="hidden" name="option" value="com_user" />';
        } else {    
            //joomla 1.6/1.7/2.5 format
            $output .= '<input type="hidden" name="task" value="user.logout" />';
            $output .= '<input type="hidden" name="option" value="com_users" />';            
        }

Here is the code for the login module:

        $version = new JVersion;
        $joomla = $version->getShortVersion();
        if(substr($joomla,0,3) == '1.5'){        
            //joomla 1.5 format     
            $output .= '<input type="hidden" name="task" value="login" />';
            $output .= '<input type="hidden" name="option" value="com_user" />';
            $output .= '<input id="modlgn_passwd" type="password" name="passwd" class="inputbox" size="18" alt="password" /> ';
        } else {
            //joomla 1.6/1.7/2.5 format
            $output .= '<input type="hidden" name="task" value="user.login" />';
            $output .= '<input type="hidden" name="option" value="com_users" />';     
            $output .= '<input id="modlgn_passwd" type="password" name="password" class="inputbox" size="18" alt="password" /> ';                       
        }

These changes might also apply to front-end forms of other Joomla core components. (more information needed)

ACL Changes

Joomla 1.6 now has an advanced ACL system. It is unknown how this affects people that have previously used the ACL API in their extension.

In order to allow your component's Options page to display the ACL settings editor, you need to create a file named access.xml in your component's administrator directory, e.g. administrator/components/com_example/access.xml. The syntax of the file is fairly easy to understand:

<?xml version="1.0" encoding="utf-8"?>
   <access component="com_example">
      <section name="component">
         <!-- Joomla! core privileges -->
         <action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
         <action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
         <!-- Custom privileges -->
         <action name="example.something" title="COM_EXAMPLE_ACL_SOMETHING_TITLE" description="COM_EXAMPLE_ACL_SOMETHING_DESC" />
      </section>
   </access>

Important things to notice:

  • The root tag is called access and you must specify the component="com_yourComponentName" attribute.
  • The section tag is mandatory.
  • No ACL privilege will display on the list unless you explicitly add it. This means that you do have to add the core privileges that concern your component.
  • You can create custom privileges! You don't have to register them anywhere except your access.xml file. The name format is liberal, but no two components should use the same key for a different purpose (all components' privileges share the same namespace). As a rule of thumb, use the convention componentName.privilegeName. You must NEVER use core.* names - they are reserved by Joomla.

In order to apply ACLs, you have to override your controller's constructor:

   public function __construct($config = array())
   {
      parent::__construct($config);
      // This conditional lets the ACL check run only on Joomla! 1.6+
      if( version_compare( JVERSION, '1.6.0', 'ge' ) ) {
         $user = JFactory::getUser();
         if (!$user->authorise('example.something', 'com_example')) {
            return JError::raiseWarning(403, JText::_('JERROR_ALERTNOAUTHOR'));
         }
      }
      // Place anything else you need in the constructor below this line
    }

The heavy lifting is done by the authorise() method of the JUser class. The first parameter is the privilege name, the second one is the "section", i.e. your component's name. As you can see, this allows for great flexibility. You can check any privilege, for any component, for any user, from anywhere in your code.

Plugin Files Now in Different Locations

Joomla 1.6+ now creates a different hierarchy structure for plugins. Files are no longer placed where they used to be, so if your other parts of your application (comp, mods, etc.) expects them to be in a certain position, it won't work. Now plugins are in an additional subdirectory. If you only load your plugins via the 1.5 API you should be fine.

  • Joomla 1.5 example location
JPATH_SITE . DS . 'plugins' . DS . 'authentication' . DS . 'example.php';
  • Joomla 1.6 example location
JPATH_SITE . '/plugins/authentication/example/example.php';

Changes to View Parameters

Joomla 1.6+ has a strict new way of specifying parameters for views. Joomla 1.5 allowed a bit of freedom where the parameters could be defined at the view.html.php level but now it has to be at the tmpl level. AE believes the view parameters were removed.

Installation Process - Preflight and Postflight

These are new events that can screw up an existing installation process. They should be totally optional access points to the installation process. But if your 1.5 install process is tricky for some reason, these can be used to do clean up activities.

Admin Template Changes

Admin functions that depended on certain functions (naming conventions etc) no longer work. Khepri has been removed. Other admin functions/libraries may have changed.

sys.ini Language Translation File

This file has 3 purposes:

1. It is used for installation process translations, when a folder language is included in the pack.

pack/language/en-GB/en-GB.extension.ini

pack/language/en-GB/en-GB.extension.sys.ini

In this case, the <description>COM_MYCOMPONENT_XML_DESCRIPTION</description> used in the sys.ini will display on installing/updating the extension.

When editing the extension in administration, it will be the .ini version of COM_MYCOMPONENT_XML_DESCRIPTION which will display.

2. It is used to replace the former extension.menu.ini

3. It is used to display the translated name of the extension in many managers.

Removed Include Folders

Most of the 3rd party libraries (Archive, domit, js, PEAR, etc) in the include folder have been removed in Joomla 1.6+.

Use Paths Defined in defines.php

(Note they are different for the site and the administration)

Small But Annoying Problems You May Find After Adapting

If you have a component including tables with sortable columns - JHTML::_('grid.sort'... Maybe it will not work - you try to sort be a column other than the default one, by pressing the column title, and nothing happens. Solution: at the default.php file that displays the table, in the html line that opens the form, add the attribute id="adminForm". In Joomla 1.5, the important attribute for the form was name="adminForm". Some developers didn't add the id attribute. It should look like this:

<form action="<?php echo $this->request_url; ?>" method="post" name="adminForm" id="adminForm">