Implementing One-Click Update

Joomla 2.5 includes a number of powerful update features designed to make extension version updates as easy and bulletproof as possible. For example, Joomla will automatically notify the web administrator when an update is needed and select the correct update file. Also, we can add special processing that executes during the update to make any required database changes or perform other required processing.

 

To take advantage of these features, we need to make some modifications to our extension and set up an update server. In this tutorial, we will go through this process in two steps. The first step will be to create a new version of the component that supports one-click update. This will be version 1.6.1. The second step will be to use the one-click update to update to version 1.6.2. In that update, we will illustrate making SQL database changes and running the update script.

 

We will simulate the updates from version 1.6.0 to 1.6.2. The existing component created in Chapter 10 is version 1.6.0. (This version number is entirely arbitrary and is just an example. It is unrelated to Joomla version numbers.)

 

The first set of changes we will make will be to enable automatic updates. This will be done in version 1.6.1. Note that the update from 1.6.0 to 1.6.1 will have to be done manually, because 1.6.0 is not set up to support automatic updates.

 

Once we have version 1.6.1 installed, we will be able to use the automatic update. For version 1.6.2, we will learn how to make changes to the SQL database during an update. We will also delete a file we no longer need.

Version 1.6.1 – Preparing for One-Click Updates

In this version we need to make two changes:

  1. Change the extension's installation XML file.

  2. Add an update SQL file to set the extension's version number in the #__schemas table.

We will also create a new file for 1.6.1 that we will delete during the update to 1.6.2. This will illustrate how we can do run PHP code during the update process.

You can start by installing the Joomprosubs component using the zip archive from the code downloads section (http://joomlaprogrammingbook.com/images/code/chapter-10/com_joomprosubs_dev.zip).

Modify Joomprosubs.xml File

We need to make three changes to the installation XML file. First, we need to change the version number from 1.6.0 to 1.6.1 in the version element. Next, we need to add an update element. The update element defines the location for the SQL update files. As we will see in the 1.6.2 update, we can use these files to make changes to the database during an update. Here we just need to define the location of the SQL update files. We will locate them in a folder called sql/updates/mysql under the administrator/com_joomprosubs folder. The update element is a child element of extension element. We have added it just after the uninstall element in the joomprosubs.xml file, as follows:

 

<update> <!-- Runs on update; New in 2.5 -->

   <schemas>

      <schemapath type="mysql">sql/updates/mysql</schemapath>

   </schemas>

</update>

 

Note that this is only for the MySQL database. If we wanted to support SQL Server, we would add a second schemapath element pointing to the folder for SQL Server update scripts.

 

Finally we need to add the updateservers element. This element defines the URL for the update server. This is the location of the XML file that will be read to determine (a) if an update is available for this extension and (b) what archive file to use for the udpate. Again, this is a child element of extension. We have chosen to put this element after the administation element. Here is the code:

 

<!-- The updateservers element is required to enable the automatic update. -->

<!-- It is used to add the rows to #__update_sites and #__update_sites_extensions tables -->

<updateservers>

   <server type="extension" priority="1" name="JoomproSubs"

   >http://joomlaprogrammingbook.com/updateserver/joomprosubs-update.xml</server>

</updateservers>

 

It is important that there be no new lines or spaces in the text (the URL) for the server element. Here we are pointing to an XML file on joomlaprogrammingbook.com.

Add the SQL Update File

This second step is simple but important if we want to be able to make SQL changes automatically during the update process. We will create a "dummy" SQL file called admin/sql/mysql/1.6.1.sql. It can be empty or it can contain the following comment line:

 

# Empty SQL file to set the version number in #__schemas table (to enable future updates)

 

During the installation or update, Joomla will use the name of this file for the version number to put in the #__schemas table. This will allow us to execute SQL files during future updates.

Add the Dummy File to Delete

Finally, let's create a new file called admin/helpers/delete-me.php. This file will be deleted during the update to version 1.6.2.

At this point, we have version 1.6.1 of the component ready to go. We can zip it into an installable archive file called com_joomprosubs_1.6.1.zip. If you like, you can download this file here: http://joomlaprogrammingbook.com/images/code/bonus/com_joomprosubs_1.6.1.zip.

Prepare for Verison 1.6.2 Update

At this point, we have version 1.6.1 installed. This version is now equipped to check for one-click updates and to successfully install these when detected. Now we move forward in time to when the next version, 1.6.2, is ready to release. First we will make the changes we need to version 1.6.2. Then we will use our update server site to allow users to update to it automatically.

 

For this exercise, we will not make any real changes to the component code for 1.6.2. What we will do is:

  • Change the version to 1.6.2 in the XML installation file.

  • Add a scriptfile element to the XML installation file to call our installation and update script

  • Make a SQL database change

  • Add the script.php file to delete the delete-me.php file we added in version 1.6.1.

Change the Installation XML File

In the XML file, we just change the version number from 1.6.1 to 1.6.2. Next we need to add a new element called scriptfile, as a child of the extension element. We will add it after the description element, as follows:

 

<!-- Runs on install/uninstall/update; New in 2.5 -->

<scriptfile>script.php</scriptfile>

 

This tells the installer to find this file and run its various methods during installation and updates.

Create the SQL Update File

Then we create a new file called 1.6.2.sql and put it in the admin/sql/updates/mysql folder. This file will add a new column to one of the tables, as follows:

 

ALTER TABLE `#__joompro_subscriptions` ADD COLUMN `new_column` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'New column added during update' AFTER `publish_down`;

 

This illustrates how to run a SQL command during the update.

Create the script.php File

Finally, we need to add a file called /admin/script.php. This is the PHP file that will be executed during the update. Here is the code:

 

<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');

/**
 * Script file of HelloWorld component
 */
class com_joomprosubsInstallerScript
{

   /**
    * method to update the component
    *
    * @return void
    */
   function update($parent)
   {
      // $parent is the class calling this method
      $this->deleteUnexistingFiles();
      echo '<p>' . JText::sprintf('COM_JOOMPROSUBS_UPDATE_TEXT', $parent->get('manifest')->version) . '</p>';
   }

   /**
    * Adapted from the core file administrator/components/com_admin/script.php
    */
   public function deleteUnexistingFiles()
   {
      $files = array(
            '/administrator/components/com_joomprosubs/helpers/delete-me.php',
      );

      // Delete the files in the array
      foreach ($files as $file) {
         if (JFile::exists(JPATH_ROOT . $file) && !JFile::delete(JPATH_ROOT . $file)) {
            echo JText::sprintf('FILES_JOOMLA_ERROR_FILE_FOLDER', $file).'<br />';
         }
      }
   }
}

 

There are a couple of important things to point out about this code. First, the name of the class must be the extension name + "InstallerScript". In our example, this is "com_joomprosubsInstallerScript". This class can have methods called preflight(), install(), update(), uninstall(), and postflight(). See the wiki article http://docs.joomla.org/Developing_a_Model-View-Controller_%28MVC%29_Component_for_Joomla!2.5_-_Part_15 for more information.

 

In our example, we are only adding an update method that calls the deleteUnexistingFiles() method. This deletes our example "delete-me.php" file. Then we print out a language string that shows the version we updated to. We read the version number from the manifest field. This way, we don't have to hard-code the version and change it for each new release. To accomplish this, we add one line to the file admin/language/en-GB/en-GB.com_joomprosubs.sys.ini , where we insert the version number as a string variable, as follows:

 

COM_JOOMPROSUBS_UPDATE_TEXT="JoomproSubs now updated to version %s."

 

At this point, we can package up the new version of the component into a zip archive called com_joomprosubs_1.6.2.zip. Now, we could just update from that archive using Extension Manager: Install. However, we want to be able to detect updates and do one-click installs.

 

To do that, we need to do two more tasks:

  • Create the update XML file

  • Upload the XML update file and the version 1.6.2 archive file to the update site

Create the Update XML File

Now we add the XML file that will control the one-click update process. We have called this file joomprosubs-update.xml. We can name it any name we like as long as it matches the name in the updateservers element above.

 

Here is the code from joomprosubs-update.xml:

 

<?xml version="1.0" ?>
<updates>
   <update>
      <name>JoomproSubs</name>
      <description>Joomla Programming Book Component</description>
      <element>com_joomprosubs</element>
      <type>component</type>
      <!-- For a plugin, we would add a <folder> element with the plugin type (authentication, content, etc.). -->
      <!-- For example, <folder>system</folder>-->
      <!-- For a plugin, we would add a <client> element with a value of 0 (<client>0</client>). -->
      <version>1.6.2</version> <!-- This will be the component version after the update. -->
      <infourl title="Joomla Programming">http://joomlaprogrammingbook.com</infourl>
      <downloads> <!-- Careful: No spaces or new lines are allowed in the downloadurl. -->
         <downloadurl type="full" format="zip"

         >http://joomlaprogrammingbook.com/updateserver/com_joomprosubs_1.6.2.zip</downloadurl>         
      </downloads>
      <maintainer>Mark Dexter</maintainer>
      <maintainerurl>http://joomlaprogrammingbook.com</maintainerurl>

      <!-- This is the version of Joomla that this update works in. -->
      <targetplatform name="joomla" version="2.5" />
   </update>
</updates>

 

The elements in the update element are:

  • name: name of the extension
  • description: optional short description
  • element: the exact system / folder name of the extension
  • type: extension type (module, component, plugin, etc.)
  • folder: (required for plugins, not used for other types) the type of plugin (content, system, authentication, etc.)
  • client: (required for plugins with a value of 0)
  • version: the version that this update will update to (after the update is run). Notice that we are creating this file for version 1.6.2, the next update.
  • infourl: optional URL for more information about the extension
  • downloads: element to list the download locations
  • downloadurl: URL to download the update archive file. Again, this is for the 1.6.2 update.
  • type: (full or upgrade) normally full so you can use the normal archive file
  • format: (zip, tar, etc.) normally zip
  • maintainer: optional person who maintains
  • mantainerurl: optional URL for maintainer
  • targetplatform: defines the required platform, with the following required elements:
  • name: always "joomla"
  • version: the Joomla version that can run this update

See http://docs.joomla.org/Deploying_an_Update_Server#Troubleshooting for more information about this XML file. We have already added this file to this site. You can view it by entering its URL: http://joomlaprogrammingbook.com/updateserver/joomprosubs-update.xml.

Upload the Files to the Update Server

At this point, we need to upload the two files, com_joomprosubs_1.6.2.zip and joomprosubs-update.xml, to our update server. For this tutorial, this has already been done.

See It In Action

To test this out, install the component (in a version 2.5 site) using the URL http://joomlaprogrammingbook.com/images/code/bonus/com_joomprosubs_1.6.1.zip. After you install this, navigate to the Control Panel in the back end. You should see the automatic update notification icon telling you that "Updates are available!" Clicking on that will take you to Extension Manager: Update and show the Version 1.6.2 update.

 

Select the update and click on the Update icon in the toolbar. You should see the message "Updating component was successful." and "JoomproSubs now updated to version 1.6.2."

 

After the update, check that the file administrator/components/com_joomprosubs/helpers/delete-me.php has been deleted. Also check that the new column called "new_column" has been added to the table #__joompro_subscriptions.

What About Version 1.6.3?

When you need to release the next version, 1.6.3, here are the steps you would follow.

  1. Create the changes for version 1.6.3. Be sure to include the 1.6.3.sql file (even if there are no SQL changes). Also, be sure to change the version number in the joomprosubs.xml installation file.

  2. Create the new com_joomprosubs_1.6.3.zip archive file and upload it to the update server.

  3. Edit the file joomprosubs-update.xml to change the version element to "1.6.3" and the downloadurl element to the new archive (for example, "http://joomlaprogrammingbook.com/updateserver/com_joomprosubs_1.6.2.zip").

Once this is done, anyone with version 1.6.2 installed will see the update the next time it is checked. Note that the automatic update only checks once a day. To see it immediately, just go to Extension Manager: Update and click the Purge Cache icon in the toolbar.

Related Links

I hope this has shown you that creating an update site is not difficult. For more information about this, see the following articles in the Joomla documentation wiki: