Formulare, Startnummer, Notification Center

von Hella Schuster

Fortlaufende Nummer vergeben und versenden

Benutzte Contao-Version: 4.4.24

Die Anforderung

Bei der Registrierung über ein Formular soll eine fortlaufende Startnummer für eine Sportveranstaltung generiert und diese in der Bestätigungsmail direkt an den Teilnehmer versendet werden. Die Anmeldedaten werden in die eigens dafür angelegte Tabelle "anmeldungen" in unserer Datenbank gespeichert, die (verkürzt) mit dem unten stehenden CREATE-Statement erzeugt werden kann. Für den Versand wird das Notification Center verwendet.

Die Tabelle 'anmeldungen' erstellen

CREATE TABLE `anmeldungen` (
	`id` INT(5) NOT NULL AUTO_INCREMENT,
	`datum` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	`anmeldenummer` VARCHAR(10) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`kreditinstitut` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`bic` VARCHAR(30) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`iban` VARCHAR(30) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`kontoinhaber` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`anrede` VARCHAR(10) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`vorname` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`nachname` VARCHAR(80) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`email` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`teilnahmebedingungen` VARCHAR(10) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	PRIMARY KEY (`id`),
	UNIQUE INDEX `id` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;

Die Dateien

Um unser Problem anzugehen, legen wir zunächst folgende Verzeichnisse an, falls sie noch nicht existieren:

  • Unser-Contao-Verzeichnis/app/Resources/contao/config/
  • Unser-Contao-Verzeichnis/src/AppBundle/

Außerdem brauchen wir zwei Dateien. Im config-Verzeichnis brauchen wir eine Datei mit dem Namen config.php und im AppBundle-Verzeichnis brauchen wir eine Datei, die in diesem Beispiel MyHooks.php heißt.

config.php

Zunächst müssen wir herausfinden, welchen Hook wir genau brauchen. Es gibt verschiedene Hooks, die in die Formular-Verarbeitung oder -Speicherung eingreifen. Wir wurden fündig bei prepareFormData. Dieser Hook wird ausgelöst, nachdem ein Formular übergeben, aber noch nicht verarbeitet wurde. Das ist genau der Moment, den wir brauchen.

<?php

$GLOBALS['TL_HOOKS']['prepareFormData'][] = array('AppBundle\MyHooks', 'startnummerVergeben');

MyHooks.php

<?php

// Defition des Namespaces, in dem wir uns bewegen: src/AppBundle/ Verzeichnisse müssen angelegt sein (Konvention: Namespace und Verzeichnis haben gleichen Namen).
namespace AppBundle;

// Teile von Contao, die wir verwenden. Hier: Datenbank und Input-Parameter
use Contao\Database;
use Contao\Input;

// Klasse muss heißen wie php-Datei, hier MyHooks.php
class MyHooks {

    // Funktion: https://docs.contao.org/books/api/extensions/hooks/prepareFormData.html
    // Parameter auf die zugegriffen werden kann:
    public function startnummerVergeben(&$arrSubmitted, $arrLabels, $objForm)
    {   
        // Datenbankabfrage: Nimm aus der Tabelle "anmeldungen" den größten Wert in der Spalte anmeldenummer unter dem Alias maxanmeldenummer.
        $sql = "SELECT MAX(anmeldenummer) AS maxanmeldenummer FROM anmeldungen";

        // Ausführung der Datenbankabfrage
        $result = Database::getInstance()->prepare($sql)->execute();
        
        // Wenn die Tabelle leer ist, ist das Ergebnis NULL.
        if ($result->maxanmeldenummer == NULL) {
            // dann vergeben wir 1000 als erste Startnummer
            $arrSubmitted['anmeldenummer'] = 1000;
        }
        // Ansonsten nimm die höchste Nummer und erhöhe sie um 1
        else {
            $arrSubmitted['anmeldenummer'] = $result->maxanmeldenummer+1;
        }
        // Für die weitere Verarbeitung (Anzeige der Formulardaten mit Inserttags) auch die Post-Daten verändern:
        Input::setPost('anmeldenummer', $arrSubmitted['anmeldenummer']);
    }
}

composer.json

Schließlich ergänzen wir unsere composer.json-Datei im webroot noch um folgenden Eintrag, damit der Autoloader unsere neue Klasse finden kann. Das abschließende Komma ist nur nötig, wenn danach noch weitere Angaben folgen.

"autoload": {
    "psr-4": {
        "AppBundle\\": "src/AppBundle/"
    }
},

Autoloader, Cache und Tests

Damit die Einstellungen zum Classloader in der composer.json wirksam werden muss der Autoloader neu geschrieben werden. Im Contao-Manager gibt es dazu unter "Systemwartung" den Punkt "Composer Class Loader" (auf der Konsole: composer dump-autoload). Schließlich muss noch der Cache gelöscht werden, damit die Änderungen berücksichtigt werden.

Entweder

  • auf der Console mit vendor/bin/contao-console cache:clear
  • im Contao-Manager -> Systemwartung -> Prod.-Cache erneuern oder
  • durch Löschen des var/cache Verzeichnisses

Viel Spaß beim Ausprobieren!

Zurück