Skip to content

Instantly share code, notes, and snippets.

@fiedsch
Last active October 24, 2019 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fiedsch/1575f5ab27c6d2623fe6fe99896c5239 to your computer and use it in GitHub Desktop.
Save fiedsch/1575f5ab27c6d2623fe6fe99896c5239 to your computer and use it in GitHub Desktop.

IBAN validieren -- jetzt aber!

Im Contao-Forum gibt es einen Thread (https://community.contao.org/de/showthread.php?76233-globalcitizen-php-iban), in dem ein User Probleme dabei hat, eine IBAN in einem Formular zu validieren. Er ist dabei vorgegangen, wie in unseren Blog-Posts auf https://www.contao-bayern.de beschrieben.

Um zu überprüfen, woran es lag, habe ich alle beschriebenen Schritte durchgeführt und bei Null begonnen.

Wie sich herausstellen wird: die Anleitung war unvollständig und ein klassicher Fall von "works on my mashine" :-(

Die Schritte -- inklusive der erfolglosen -- habe ich im Folgenden dokumentiert. Um zu einer funktionierenden Lösung zu kommen also am besten erst ein Mal ganz durchlesen und dann die erfolglosen Schritte auslassen.

Installationsschritte

Frisches Contao aufgesetzt

mkdir testumgebung
cd testumgebung
composer create-project contao/managed-edition . 4.4

Die weiteren Schritte gemäß dem Blogpost https://www.contao-bayern.de/newsreader/iban-im-formular-validieren-revisited.html

Benötigtes Paket installiert

composer require globalcitizen/php-iban

ergibt

...
 - Installing globalcitizen/php-iban (v2.7.1): Downloading (100%)     
...

Autoloader in der composer.json

(vgl. alten Blogeintrag, auf den verwiesen wird)

in der composer.json am Ende (vor der letzten schließenden Klammer) hinzugefügt:

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

Beachte: , zur Trennung vom bereits existierenden vormals letzten Eintrag!) nicht vergessen. Also so:

    ...
  },
  "autoload": {
    ...

Danach (siehe ebenfalls den referenzierten Blogeintrag https://www.contao-bayern.de/newsreader/iban-im-formular-validieren.html):

composer dump-autoload

ausführen.

Dateien anlegen

Dateinamen, jeweils wie im Kommentar in ersten Codezeile der Beispiele angegeben. Nicht existierende Dateien und Verzeichnisse wurden angelegt:

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

Test:

vendor/bin/contao-console cache:clear

und noch nichts zu sehen. Also weiter:

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

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

und noch nichts zu sehen. Also debuging:

  • Worked on my mashine (aber in der damaligen Testumgebung gab es mutmaßlich bereits mehr)
  • Daher
    • composer.json erweitert
  "autoload": {
      "classmap": [
            "app/ContaoManagerPlugin.php",
            "src/AppBundle/Resources/contao"
      ],
      "psr-4": {
          "AppBundle\\": "src/AppBundle/"
      },
      "exclude-from-classmap": [
        "src/AppBundle/Resources/contao/assets",
        "src/AppBundle/Resources/contao/config",
        "src/AppBundle/Resources/contao/dca",
        "src/AppBundle/Resources/contao/languages",
        "src/AppBundle/Resources/contao/templates"
      ]
  }
  • Dateien angelegt:
<?php
  // app/ContaoManagerPlugin.php

  use AppBundle\AppBundle;
  use Contao\ManagerPlugin\Bundle\Config\BundleConfig;
  use Contao\ManagerPlugin\Bundle\BundlePluginInterface;
  use Contao\ManagerPlugin\Bundle\Parser\ParserInterface;
  use Contao\CoreBundle\ContaoCoreBundle;

  class ContaoManagerPlugin implements BundlePluginInterface
  {

      /**
       * {@inheritdoc}
       */
      public function getBundles(ParserInterface $parser)
      {
          return [
              BundleConfig::create(AppBundle::class)
                  ->setLoadAfter([ContaoCoreBundle::class]),
          ];
      }
  }

<?php
// src/AppBundle/AppBundle.php

  namespace AppBundle;

  use Symfony\Component\HttpKernel\Bundle\Bundle;

  class AppBundle extends Bundle
  {
  }

Ein abschließendes

composer install

und voila: wir haben die IBAN-Prüfung in der Auswahl bei "Eingabeprüfung".

Problem solved?

Nicht ganz, denn "kannste zwar so machen, ist halt ...".

Wie sollte man es machen? Das hängt wohl auch von der Contao-Version ab.

Die sehr gute neue Contao-Doku (https://docs.contao.org/dev) zeigt, wie es gemacht werden sollte: Dateien unter contao/ anlegen.

Für die 4.4er Versionen entspräche das: Anlegen unter app/Resources/contao.

Also noch Mal los auf Start:

  • "autoload"-Eintrag aus der composer.json entfernt
  • ContaoManagerPlugin.php und src/AppBundle/AppBundle.php gelöscht
  • src/AppBundle/Resourcesnach app/Resources verschoben. Der Ordner src/, der nun nur noch den leeren Ordner AppBundle enthält kann gelöscht werden.
  • composer dump-autoload und composer install ausgeführt.

Ergebnis: wir haben die IBAN-Prüfung immer noch in der Auswahl bei "Eingabeprüfung".

Wir sind aber natürlich noch nicht fertig, denn der Teil, der den nun unbekannten rgxp iban behandelt fehlt noch.

Hier machen wir weiter wie im ursprünglichenBlogpost beschrieben, beachten aber, daß alles nun unterhalb von app/Resources/contao angelegt wird.

<?php
// app/Resources/contao/config/config.php

$GLOBALS['TL_HOOKS']['addCustomRegexp'][] = ['AppBundle\Hooks\Iban', 'validateIban'];
<?php
// app/Resources/contao/classes/AppBundle/Hooks/Iban.php

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
    }
}
<?php
// app/Resources/contao/languages/de/default.php
$GLOBALS['TL_LANG']['ERR']['iban'] = 'Bitte geben Sie eine gültige IBAN an.';

Noch mal den Contao Cache löschen.

Ergebnis: die Klasse Iban wird nicht gefunden. Also wieder den "autoload"-Abschnitt zur composer.json hinzufügt (und natürlich composer dump-autoload).

"autoload": {
   "psr-4": {
      "AppBundle\\": "app/Resources/contao/classes/AppBundle/"
   }
}

Ergebnis: Bei Eingabe einer (absichtlich falschen) IBAN in einem Formular erscheint die gewünschte Fehlermeldung "Bitte geben Sie eine gültige IBAN an.". 🤩

@fritzmg
Copy link

fritzmg commented Oct 23, 2019

@fritzmg
Copy link

fritzmg commented Oct 23, 2019

Die Zeile

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

sollte nicht notwendig sein, da das bereits per Composer geladen wird: https://github.com/globalcitizen/php-iban/blob/master/composer.json#L6

@fritzmg
Copy link

fritzmg commented Oct 23, 2019

Unter app/Resources sollten keine PHP Klassen angelegt werden. Hooks sollte man in den EventListener Namespace geben. Siehe auch https://docs.contao.org/dev/guides/namespaces/

@fiedsch
Copy link
Author

fiedsch commented Oct 23, 2019

Danke.

Das beim Entwickeln vohandene, aber im Blogpost nicht beschrieben Bundle war das ursprüngliche Problem. Ich habe daher in diesem Gist auch versucht, zu beschreiben, wie es ohne Bundle geht (Code unter app/Resources/contao).

@fritzmg
Copy link

fritzmg commented Oct 23, 2019

Du brauchst eigentlich nur folgende Dateien:

  • contao/config/config.php [1]
  • contao/dca/tl_form_field.php [1]
  • contao/languages/en/tl_form_field.php [1]
  • src/EventListener/AddCustomRegexpListener.php

Plus folgendes autoloading in der composer.json: [2]

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

[1] Unter Contao 4.4 mit app/Resources/ voranstellen
[2] Ab Contao 4.5 bereits mit composer create-project vorhanden

@fiedsch
Copy link
Author

fiedsch commented Oct 23, 2019

Lese gerade die neue Doku und bin sehr begeistert! Ich versuche parallel alles in einem neuen Projekt (Contao 4.8) umzusetzen. Funktioniert bestens. Ich frage mich nur bei manchem: "geht das auch schon in Contao 4.4 so? Dort gibt es ja z.B. die Ordner contao/ und config/ noch nicht.

Edit: Du postest schneller, als ich lesen und antworten kann.

@fritzmg
Copy link

fritzmg commented Oct 23, 2019

Ja, das geht alles auch in Contao 4.4 so :). Nur der Pfad zu den Contao Config Dateien ist anders (app/Resourcces/contao/ statt contao/). Es würder aber auch unter Contao 4.8 mit dem alten Pfad funktionieren.

@fiedsch
Copy link
Author

fiedsch commented Oct 23, 2019

Danke. Wenn es die Zeit zulässt fasse ich das alles mal in einem neuen Blog-Post auf contao-bayern.de zusammen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment