IBAN im Formular validieren (revisited)

von Andreas Fieger

Achtung: bitte auch (diesen Artikel)[https://gist.github.com/fiedsch/1575f5ab27c6d2623fe6fe99896c5239] beachten, der das hier beschriebene noch Mal testet und zeigt, warum es so (einfach) nicht geht. Der Blogpost wird bei Gelegenheit noch angepasst.

Motivation

In diesem Blogintrag beschreibt Hella, wie man in einem Contao-Formular eine IBAN validieren kann. Der Ansatz hat einige kleine Schönheitsfehler:

  • Im Backend ist für einen Redakteur nicht ersichtlich, daß das Formularfeld validiert wird
  • Im Hook sind die ID des Formulars und der Name des Eingabefelds fest verdrahtet. Wird hier etwas verändert, so scheitert der Ansatz.

Beseitigung dieser Probleme

Der Lösungsansatz bleibt im wesentlichen gleich:

  • wir verwenden eine Bibliothek, mit deren Hilfe wir IBANs validieren können
  • wir verwenden einen Hook, um unseren Code zu triggern. Hier allerdings einen anderen!

Vorarbeiten

Wie im gehen wir davon aus, daß die PHP-Bibliothek globalcitizen/php-iban installiert wurde. Dies kann auf der Kommandozeile (composer require globalcitizen/php-iban) oder über über den Contao Manager gemacht werden (über den Contao Manager geht es leider nur teilweise, da der Manager nur nach bestimmten Paketen sucht. Danke an xchs im Forum!):

Umsetzung

Zuerst wollen wir erreichen, daß "IBAN" als Auswahlmöglchkeit unter den Auswahlmöglichkeiten im Dropdown "Eingabeprüfung" der Felddefinition auswählbar ist. Damit wäre der erste Kritikpunkt beseitigt.

Dazu legen wir die Datei src/AppBundle/Resources/contao/dca/tl_form_field.php an und definieren dort eine weitere Auswahlmöglichkeit bei den Optionen des Felds rgxp. (Sollten der Ordner src oder weitere Unterordner nicht existieren, so werden diese hier neu angelegt):

<?php
// src/AppBundle/Resources/contao/dca/tl_form_field.php
$GLOBALS['TL_DCA']['tl_form_field']['fields']['rgxp']['options'][] = 'iban';

Damit die neue Auswahlmöglichkeit auch "hübsch" gelabelt wird definieren wir für alle verwendeten Sprachen ein Label. Hier für Deutsch (de), andere Sprachen analog:

<?php
// src/AppBundle/Resources/contao/languages/de/tl_form_field.php

$GLOBALS['TL_LANG']['tl_form_field']['iban'] = [
    'IBAN',
    'IBAN-Verifizierung'
];

Wenn nun in einem Formular ein Textfeld bei der Eingabeprüfung "IBAN" gewählt wird und Contao die Formulardaten verarbeitet, so ist der rgxp unbekannt und der Hook addCustomRegexp wird getriggert. Dies ist der Ansatzpunkt um unseren Code ausführen zu lassen:

<?php
// src/AppBundle/Resources/contao/config/config.php

$GLOBALS['TL_HOOKS']['addCustomRegexp'][] = ['AppBundle\Hooks\Iban', 'validateIban'];

Zuletzt muss die im Hook verwendet Klasse noch angelegt werden:

// src/AppBundle/Hooks/Iban.php

<?php
declare(strict_types=1);

namespace AppBundle\Hooks;

// Voraussetzung: globalcitizen/php-iban ist über Composer installiert

require_once(TL_ROOT.'/vendor/globalcitizen/php-iban/php-iban.php');

use Contao\Widget;

class Iban
{
    /**
     * Custom Rgxp for 'iban'
     * https://docs.contao.org/books/api/extensions/hooks/addCustomRegexp.html
     *
     * @param string $rgxp
     * @param string $varValue
     * @param Widget $objWidget
     * @return bool
     */
    public static function validateIban(string $rgxp, string $varValue, Widget $objWidget)
    {
        if ('iban' === $rgxp) {
            $isValidIban = verify_iban(strtoupper($varValue));
            if (!$isValidIban) {
                $objWidget->addError($GLOBALS['TL_LANG']['ERR']['iban']);
            }
            
            return true; // Ergebnis: wir haben den custom rgxp behandelt
        }
        
        return false; // Ergebnis: wir haben den custom rgxp nicht behandelt
    }
}

Die ggf. auszugebende Fehlermeldung kann über Sprachvariablen definiert werden:

<?php
// src/AppBundle/Resources/contao/languages/de/default.php
$GLOBALS['TL_LANG']['ERR']['iban'] = 'Bitte geben Sie eine gültige IBAN an.';

Zurück