SQL Update Mechanismus für Joomla! Komponente nachträglich einbauen

Joomla! bietet Entwicklern von Erweiterung (Komponenten, Module...) bereits seit der Version 1.6 eine einfach Möglichkeit, während einer Updateinstallation SQL-Statements ablaufen zu lassen, um Änderungen an Datentabellen der Erweiterung vorzunehmen. Dies geschieht über einen "Update"-Knoten im xml-Manifest der Erweiterung sowie über SQL-Files, die die SQL-Anweisungen für die Änderungen enthalten. (Sie z.B. docs.joomla.org.) Hierbei bauen die Änderungen für eine spezifische Version jeweils auf den Änderungen früherer Versionen auf. D.h. auf den ersten Blick ist es schwierig den Update-Mechanismus nachträglich in Erweiterung einzubauen, für die bereits frühere Versionen existieren. Dieser Artikel beschreibt am Beispiel einer Komponente, wie man dieses Problem lösen kann.

1. Eine install-uninstall-update Script Datei in die Komponente einbinden

Fügen Sie der xml-Manifest-Datei Ihrer Erweiterung direkt im "extension"-Knoten einen "scriptfile"-Knoten hinzu. <scriptfile>script.php</scriptfile> und legen Sie eine script.php entsprechend der Beschreibung auf docs.joomla.org an, falls Ihre Komponente nicht bereits über eine solche Datei verfügt.

2. "#__schemas" Tabelle reparieren

Damit der SQL-Updater anläuft benötigen Sie an erster Stelle benötigen Sie einen Eintrag in der "#__schemas" Tabelle. Um diesen zu erzeugen verwenden wir die Funktionen __construct und preflight unserer script.php, die wir wie unten beschrieben anpassen. Hierbei muss "myComponent" entsprechend den Werten in der "#__extensions" Tabelle angepasst werden.

public function __construct(JAdapterInstance $adapter)
{
    $this->release = $adapter->get( "manifest" )->version;
}

public function preflight($route, JAdapterInstance $adapter)
{
    if ( $route == 'update' ) 
    {
        $this->oldRelease = $this->getParam('version');
        if (version_compare($this->oldRelease, $this->release, 'lt'))
        {
            //Repair table #__schema which was not used before
            //Just create a dataset with extension id and old version (before update).
            $db = JFactory::getDbo();
            $query = $db->getQuery(true);
            $query->select($db->quoteName('extension_id'))
                ->from('#__extensions')
                ->where($db->quoteName('type') . ' = ' . $db->quote('component') . ' AND ' . $db->quoteName('element') . ' = ' . $db->quote('com_myComponent') . ' AND ' . $db->quoteName('name') . ' = ' . $db->quote('myComponent'));
            $db->setQuery($query);
            if ($eid = $db->loadResult())
            {
                $query->clear();
                $query->insert($db->quoteName('#__schemas'));
                $query->columns(array($db->quoteName('extension_id'), $db->quoteName('version_id')));
                $query->values($eid . ', ' . $db->quote($this->oldRelease));
                $db->setQuery($query);
                $db->execute();
            }
        }
    }
}

3. Pfad zu den SQL-Dateien festlegen

Nun fügen Sie in der xml-Manifest-Datei den "update"-Knoten ein, der festlegt, wo die Dateien mit den SQL-Statements liegen. Da der Joomla! Installer beim Abarbeiten der Update-Funktionen zuerst alle Dateien aus dem Installationspaket an ihren Zielort kopiert, können auf diesem Weg alle benötigten SQL-Dateien, auch solche, die eigentlich bereits durch frühere Version hätten installiert werden sollen, eingefügt werden.

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

Wenn Sie neben mySql auch andere Datenbanken unterstützen müssen Sie evtl. mehrere "schemapath"-Knoten anlegen und deren "type" entsprechend anpassen.

Fügen sie den Code direkt in den "extension"-Knoten der xml-Manifest-Datei ein.

4. SQL-Dateien anlegen

Der Mechanismus zum Abarbeiten von SQL-Updates ist namensbasiert. Für jede Version der Komponente muss eine Datei angelegt werden, deren Name aus der Versionnummer und der Dateiendung .sql besteht. Hierbei ist es elementar wichtig, dass wirklich für jede Version der Komponente ein Datei angelegt wird. Also z.B. 1.0.0.sql, 1.0.1.sql, 1.2.0.sql .... auch wenn für die jeweilige Version keinen Änderung an der Datenbank vorgenommen wurde und die sql Datei deshalb einfach leer ist. Legen Sie alle .sql Dateien in das Verzeichnis admin/sql/updates/mysql (also den Pfad, den wir im "update"-Knoten unter 3. angegeben haben.) Verwenden Sie mehrere "schemapath"-Knoten, dann müssen Sie für jeden die entsprechenden Dateien anlegen und im richtigen Verzeichnis speichern.

Fertig

Zur Beitragsliste