Custom-Plugin Erstellung

Individuelle Funktionalität durch individuelle Visforms Custom-Plugins

Visforms verfügt über ein umfangreiches eigenes Event-System. Es ermöglicht Visforms mit individuellem Code gezielt zu erweitern.

Mehr dazu in: Event-System für den Workflow.

Individueller Submit Handler - Beispiel für die Entwicklung eines Visforms Custom-Plugins

Beispielsweise können Sie allein durch die Verwendung eines Visforms Custom-Plugins dem Formular einen eigenen Submit-Handler Update-sicher übergeben. Zwischen zwei Visforms-Nutzern sind die Anforderungen, was denn ein eigener Submit-Handler genau leisten soll, sehr unterschiedlich. Daher müssen Sie das, was Ihr Submit-Handler machen soll, selbst programmieren: Sie müssen ein individuelles Visforms Custom-Plugin schreiben. Dies erfordert etwas Erfahrung in der Programmierung mit PHP und JavaScript oder zumindest die Bereitschaft sich in beides etwas einzuarbeiten.

Um Ihnen den Einstieg zu erleichtern haben wir eine Plugin-Vorlage erstellt. Im folgenden Beitrag versuchen wir, Schritt für Schritt zu erklären, wie Sie unsere Plugin-Vorlage für Ihre Bedürfnisse anpassen müssen. Wir geben außerdem konkrete Code-Beispiele für die Implementierung einiger häufig nachgefragter Submit-Handler-Aktionen.

Anleitung zur Erstellung eines Plugins

Laden Sie die Plugin-Vorlage für Joomla 4 herunter und entpacken Sie die ZIP-Datei: Download Plugin Master. Dieses ZIP-Archiv enthält drei Dateien:

  • eine index.html,
  • eine plgmaster.xml und
  • eine plgmaster.php.

Die index.html hat allein die Funktion, das Verzeichnis in dem das Plugin später installiert wird, vor fremder Einsicht zu schützen. Mit der Existenz dieser Datei kann man nicht länger von außen sehen, welche Dateien das Verzeichnis enthält.
Diese Datei müssen Sie nicht verändern.

Die plgmaster.xml ist die Vorlage für die sogenannte Manifest-Datei mit den sogenannten Manifest-Daten. Sie wird bei der Installation des Plugins unbedingt benötigt.

Sie enthält wichtige Informationen für die Installation des Plugins wie

  • den Namen,
  • den Plugin-Typ,
  • die zu installierenden Dateien,
  • die Plugin-Version.

Sie enthält auch sogenannte Metainformationen über das Plugin wie

  • das Datum, wann es entwickelt wurde und
  • von wem es entwickelt wurde.

Die plgmaster.php enthält den eigentlichen Code, der durch das Plugin ausgeführt wird.

Das Plugin mit einem Namen versehen

Als Erstes sollten Sie Ihr Plugin mit einem eigenen Namen versehen. Dieser sollte aus einem Wort in Kleinschreibung bestehen, etwa “meinvisformssubmithandler”. In der Vorlage ist der Name “plgmaster”. Um das Plugin mit einem eigenen Namen zu versehen, damit Joomla es unter diesem Namen installiert und verwenden kann, müssen Sie die Zeichenkette “plgmaster” an zahlreichen Stellen mit Ihrem eigenen Plugin-Namen ersetzen.

Benennen Sie zuerst die Dateien plgmaster.xml und plgmaster.php um, indem Sie die Zeichenkette “plgmaster” mit Ihrem eigenen Plugin-Namen ersetzen. Anschließend ersetzen Sie die Zeichenkette “plgmaster” an folgenden Stellen innerhalb dieser beiden Dateien. Öffnen Sie hierzu jeweils die umbenannte Datei mit einem Editor-Programm Ihrer Wahl.

In der umbenannten plgmaster.xml Datei müssen Sie die Zeichenkette “plgmaster” an 3 Stellen ersetzen:

  • in <name>plgmaster</name> und
  • in <filename plugin="plgmaster">plgmaster.php</filename>.

In der umbenannten plgmaster.php Datei müssen Sie die Zeichenkette “Plgmaster” an 1 Stelle ersetzen:

  • im Namen der PHP Klasse class plgVisformsPlgmaster extends JPlugin.

Für eine bessere Lesbarkeit sollten Sie hier Ihren Plugin-Namen mit einem Großbuchstaben am Anfang verwenden. Der Code funktioniert aber auch, wenn der Klassenname nur Kleinbuchstaben enthält.

Metainformationen anpassen

Anschließend sollten Sie folgende Metainformationen in der umbenannten Datei plgmaster.xml anpassen. Das machen Sie, indem Sie den Wert im jeweiligen XML-Knoten entsprechend Ihren Voraussetzungen ändern.

Ein sogenannter XML-Knoten besteht immer aus

  • einem öffnenden Element (z.B. <author>),
  • einem schließenden Element (z.B. </author>) und
  • einem Text dazwischen.

Passen Sie die Texte in folgenden XML-Knoten an. Einige Informationen sind nicht zwingend notwendig und können auch ganz entfallen, indem Sie den kompletten XML-Knoten einfach löschen.

  • <author>: Autor
  • <creationDate>: Erstelldatum
  • <copyright>: Copyright Information (kann auch entfallen)
  • <license>: Lizenztyp (kann auch entfallen)
  • <authorEmail>: E-Mail des Autors (kann auch entfallen)
  • <authorUrl>: URL des Autors (kann auch entfallen)
  • <description>: Text der in der Administration als Beschreibung des Plugins angezeigt wird

Alle anderen XML-Knoten lassen Sie unverändert.

Den Plugin-Code schreiben

Nachdem nun alle Rahmenbedingungen für die korrekte Installation des Plugins gesetzt sind, können Sie den eigentlichen Code für Ihren Submit-Handler schreiben. Öffnen Sie die umbenannte Datei plgmaster.php und schauen Sie sich kurz den Democode an.

Funktion onVisformsFormPrepare()

Code in der public function onVisformsFormPrepare($context, $form, $menu_params) Funktion wird ausgeführt, bevor das Formular zur Anzeige gebracht wird. In dieser Funktion können Sie alle möglichen Manipulationen am Formular und den Feldern vornehmen. Hier können Sie der Seite auch individuelles JavaScript hinzufügen.

Mit individuellem JavaScript können Sie etwa dem Formular zusätzliche versteckte Steuerfelder hinzufügen. Die Werte eins versteckten Steuerfeldes können durch Ihren JavaScript-Code dynamisch gesetzt und mit dem Post übermittelt werden. Oder Sie können den Absenden-Vorgang blockieren.

Funktion onVisformsBeforeFormSave()

Code in der public function onVisformsBeforeFormSave($context, $form, $fields) Funktion wird ausgeführt, bevor die eigentliche Verarbeitung der mit dem Formular übertragenen Daten auf dem Server beginnt.

Zu der später beginnenden Verarbeitung gehören etwa

  • Daten speichern,
  • Mails schicken,
  • PDFs erzeugen und
  • Ergebnistext anzeigen.

Hier können Sie diesen Prozess manipulieren. Etwa indem Sie etwa die Formular-Parameter dynamisch ändern oder eigene serverseitige Sicherheitschecks durchführen.

Der Template-Code der Funktion onVisformsFormPrepare()

public function onVisformsFormPrepare($context, $form, $menu_params)	{
    // Skip plugin if context is wrong
    $allowedContexts = array('com_visforms.form', 'mod_visforms.form', 'plg_vfformview.form');
    if (!in_array($context, $allowedContexts)) {
        return true;
    }
    $app = JFactory::getApplication();
    // only perform action, if we are in front end
    if ($app->isClient('administrator')) {
        return true;
    }
    //if $form->parentFormId is not set, Visforms or Content Plugin Form View version is to old
    if (!isset($form->parentFormId)) {
        return true;
    }
    // get value of id attribute of the form which is going to be displayed for further use
    $parentFormId = $form->parentFormId;
    // START: add custom submit handler function to the form	
    $script = 'jQuery(document).ready(function () {
        // add custom submit action function to form
        window["' . $parentFormId . 'SubmitAction"] = function (form) {
            
            // PLACE YOUR CODE IN HERE
            
            // return false to prevent form from being submitted
            // return true if submithandler performs another action but form should be send
            return true;
        };
    });';
    $wa = Factory::getApplication()->getDocument()->getWebAssetManager();
    $wa->addInlineScript($script);
    // END: add custom submit handler function to the form	
}

Der Parameter $context

Der Parameter $context enthält Informationen darüber, von wo aus die Funktion onVisformsFormPrepare aufgerufen wurde.
Die unterschiedlichen Aufrufstellen um ein Visforms Formular zur Anzeige zu bringen, können sein:

Mithilfe dieses Parameters kann unter anderem gesteuert werden, dass ein individueller Submit-Handler nur den Formularen hinzugefügt wird, die über ein Modul zur Anzeige gebracht werden.

  • $context === ‘com_visforms.form'
    Formular wird über Menüeintrag vom Typ Visforms » Formular angezeigt.
  • $context === ‘mod_visforms.form'
    Formular wird über ein Visforms Modul angezeigt.
  • $context === ‘plg_vfformview.form'
    Formular wird in einem Beitrag über das Content Plugin - Visforms Form View angezeigt.

Prinzipiell sollten Sie immer sicherstellen, dass Ihr Plugin-Code nur dann abläuft, wenn er auch tatsächlich gebraucht wird.
Über die Variable $allowedContexts können Sie steuern, in welchen Fällen der Plugin-Code ablaufen soll.

Der Parameter $form

Der Parameter $form enthält das komplette Formular.
Mit $form->id können Sie auf die ID des gerade angezeigten Formulars zugreifen.
Mit dem Wert aus $form->parentFormId kennen Sie das HTML id-Attribut des <form> Elements.
Das <form> Element ist die äußerste HTML-Hülle des eigentlichen Formulars.

Sie können z.B. die Bedingung if ($form->id !== 1) {return true;} verwenden.
Damit stellen Sie sicher, dass der Plugin-Code nur für das Formular mit der ID 1 ausgeführt wird.
Oder nutzen die Formular-ID nutzen, um für unterschiedliche Formulare unterschiedlichen Code ablaufen zu lassen.

if ($form->id === 1) {
    // your actions for form 1 ...
}
if ($form->id === 2) {
    // your actions for form 2 ...
}

Der Parameter $menu_params

Der Parameter enthält alle administrativen Einstellungen des Menüs, mit dem das Formular aufgerufen wurde. Er wird für ein Plugin, dass einen individuellen Submit-Handler implementiert nicht genutzt. Über diesen Parameter könnten Sie unter anderem beeinflussen, ob der Formulartitel angezeigt wird oder nicht.

Die JavaScript Submit-Handler Funktion

Wenn ein Benutzer versucht das Formular abzusenden, werden zuerst die Benutzereingaben browserseitig mit JavaScript validiert. Anschließend prüft der Visforms-Code, ob es eine zusätzliche Submit-Handler Funktion gibt. Die Prüfung sucht dabei nach einer Formular-spezifischen JavaScript-Funktion mit einem speziellen Namen.

Der gesuchte Funktionsname setzt sich aus der ID des HTML-form Elements $parentFormId und dem Wort SubmitAction zusammen. Ist eine solche JavaScript-Funktion vorhanden, wird diese nun ausgeführt. Sie kann genutzt werden, um spezielle Aktionen auszuführen.

Abhängig vom Rückgabewert der Funktion wird das Formular abgeschickt oder nicht.

  • Ist der Rückgabewert true, wird das Formular normal abgeschickt.
  • Ist der Rückgabewert false, wird das Abschicken unterbunden.

Bitte stellen Sie also immer sicher, dass Ihre Funktion den korrekten Rückgabewert hat.

Der Template-Code der Funktion onVisformsBeforeFormSave()

public function onVisformsBeforeFormSave($context, $form, $fields) {
    // Skip plugin if context is wrong
    $allowedContexts = array('com_visforms.form', 'mod_visforms.form', 'plg_vfformview.form');
    if (!in_array($context, $allowedContexts)) {
        return true;
    }
    $app = JFactory::getApplication();
    // only perform action, if we are in front end
    if ($app->isClient('administrator')) {
        return true;
    }
    // PLACE YOUR CODE IN HERE
    return true;
}

Zu den Parametern siehe weiter oben in der Beschreibung der Funktion onVisformsFormPrepare.
Der Parameter $form->parentFormId wird nur im Frontend benötigt. Er ist hier nicht vorhanden.

Beispiel-Code 1: Submit durch nicht angemeldete Benutzer verhindern

Es werden zwei alternative Möglichkeiten gezeigt.

Besondere Sicherheit erreichen Sie, wenn Sie beide Möglichkeiten gleichzeitig einsetzen:

  • Möglichkeit 1: Die Meldung erscheint in einem modalen JavaScript-Fenster, unmittelbar nach dem Klick auf den Button ‘Absenden’.
    Hier wird vor dem Abschicken des Formulars direkt im Browser das Abschicken verhindert.
    Grundsätzlich besteht hier die Gefahr, dass die Seite manipuliert wird und ein Abschicken dadurch erzwungen werden kann.
  • Möglichkeit 2: Die Meldung erscheint als Teil der Seite, nachdem das Formular abgeschickt und auf dem Server abgelehnt wurde.
    Hier wird erst nach dem Abschicken des Formulars auf dem Server geprüft.
    Grundsätzlich besteht hier keine Gefahr, dass die Seite manipuliert wird und ein Abschicken dadurch erzwungen werden kann.

Möglichkeit 1: Funktion onVisformsFormPrepare() anpassen

Ersetzen Sie den Template-Code im umbenannten plgmaster.php
zwischen
// START: add custom submit handler function to the form
und
// END: add custom submit handler function to the form
mit dem untenstehendem Code.

Dieser Code prüft, ob der Benutzer, der das Formular ausfüllt, angemeldet ist. Ist der Benutzer nicht angemeldet, wird dem Formular eine JavaScript-Funktion hinzugefügt. Die Funktion aus unserem Beispiel gibt eine Nachricht aus und unterbindet das Absenden des Formulars.

// START: add custom submit handler function to the form	
$user = JFactory::getUser();
// user is not logged on. Add JavaScript that prevent form from being send
if (!$user->id) {
    $script = 'jQuery(document).ready(function () {
        // add custom submit action function to form
        window["' . $parentFormId . 'SubmitAction"] = function (form) {
            alert("Please log in first");
            return false;
        };
    });';
    $wa = Factory::getApplication()->getDocument()->getWebAssetManager();
    $wa->addInlineScript($script);
}
// END: add custom submit handler function to the form

Möglichkeit 2: Funktion onVisformsBeforeFormSave() anpassen

Ersetzen Sie // PLACE YOUR CODE IN HERE mit dem folgenden Code:

$user = JFactory::getUser();
if (!$user->id) {
    $message = 'Please log in first';
    $app = JFactory::getApplication();
    $input = $app->input;
    $return = $input->post->get('return', null, 'cmd');
    $url = (!empty($return)) ? base64_decode(strtr($return, '-_,', '+/=')) :  'index.php';
    $app->enqueueMessage($message, 'warning');
    $app->redirect(JRoute::_($url, false));
    $app->close();
}

Beispiel-Code 2: Ein verstecktes Feld hinzufügen und dessen Wert dynamisch setzen

Das Beispiel geht davon aus, dass es unter dem Formular 2 unterschiedliche Submit-Buttons gibt. Je nachdem welchen der beiden Buttons der Benutzer verwendet, wird ein unterschiedlicher Wert in dem dynamisch hinzugefügten versteckten Feld gesetzt. Dieser Wert kann dann später im PHP-Code ausgewertet werden.

In unserem Beispiel werden Mails verschickt, wenn der Benutzer auf den 2. Button geklickt hat.

Ersetzen Sie hierzu den Template-Code im umbenannten plgmaster.php
zwischen
// START: add custom submit handler function to the form
und
// END: add custom submit handler function to the form
mit dem untenstehendem Code.

Der Vorteil der Verwendung eines dynamisch erzeugen versteckten Feldes ist, dass es Visforms nicht bekannt ist. Daher wird es auch nicht in der Datenbank gespeichert oder mit Mails übertragen. Der 2. Submit-Button erhält die CSS-Klasse formready.

Funktion onVisformsFormPrepare() anpassen

$script = 'jQuery(document).ready(function () {
    let el = document.createElement("input");
    el.id = "'. $parentFormId .'myhiddenfield"
    el.type = "hidden"; 
    el.value = "0"; 
    el.name = "myhiddenfield";
    jQuery("#'. $parentFormId .'").append(el);
    window["'. $parentFormId .'SubmitAction"] = function (form) {
        if (jQuery(form.submitButton).hasClass("formready")) {
            jQuery("#'. $parentFormId .'myhiddenfield").val("1");
        };
        return true;
    };
});';
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->addInlineScript($script);

Funktion onVisformsBeforeFormSave() anpassen

Ersetzen Sie // PLACE YOUR CODE IN HERE mit dem folgenden Code:

$sendMail = $app->input->post->get('myhiddenfield', "0", 'STRING');
if (!empty($sendMail)) {
    // enable sending the result mail 
    $form->emailresult = 1;
    // enable sending the user mail 
    $form->emailreceipt = 1;
}

Fertigstellung und Installation

Abschließend müssen Sie Ihr neues Plugin packen, auf der Joomla Instanz installieren und testen.

  • Erzeugen Sie vom Verzeichnis mit den geänderten Dateien ein zip.
  • Installieren Sie die Erweiterung über den Joomla Erweiterungen Manager.
  • Veröffentlichen Sie die Erweiterungen im Joomla Erweiterungen Manager.
  • Testen Sie das Plugin.