Contao-Camp 2024
Ergebnis 1 bis 15 von 15

Thema: Contao 4.4 und der validateFormField Hook

  1. #1
    Contao-Fan Avatar von dirksche
    Registriert seit
    05.08.2009.
    Ort
    Grosslittgen
    Beiträge
    641

    Standard Contao 4.4 und der validateFormField Hook

    Hallo liebe Community,

    ich möchte gerne in einem Gewinnspiel Formular eine E-Mail Prüfung einbauen.
    Die Mail Adressen werden über Contao Leads in einer Datenbank gespeichert. Wenn nun ein Teilnehmer schon eingetragen ist, soll eine Fehlermeldung erscheinen.
    Ich habe folgenden Hook zum Testen angelegt:

    Code:
    <?php
    
    namespace AppBundle;
    use Contao\Database;
    
    class MyHooks {
    
    
      public function myValidateFormField(Widget $objWidget, $intId){
        $sql = "SELECT value FROM tl_lead_data";
        $result = Database::getInstance()->prepare($sql)->execute('mustermann@test.de');
        
        if($objWidget->email == $result){ 
             echo "Dieser Nutzer ist schon angemeldet.";
        }
        return $objWidget;          
      }
    }
    Leider erscheint folgende Fehlermeldung im Log:
    Code:
    [2019-01-21 15:36:15] request.INFO: Matched route "contao_index". {"route":"contao_index","route_parameters":{"_token_check":true,"_controller":"Contao\\CoreBundle\\Controller\\FrontendController::indexAction","_scope":"frontend","_route":"contao_index"},"request_uri":"http://metamodels.zpn-live.de/","method":"POST"} []
    [2019-01-21 15:36:15] security.INFO: Attempting SimplePreAuthentication. {"key":"frontend","authenticator":"Contao\\CoreBundle\\Security\\ContaoAuthenticator"} []
    [2019-01-21 15:36:15] app.CRITICAL: An exception occurred. {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Type error: Argument 1 passed to AppBundle\\MyHooks::myValidateFormField() must be an instance of AppBundle\\Widget, instance of Contao\\FormTextField given, called in /var/www/vhosts/xxx/xxx/vendor/contao/core-bundle/src/Resources/contao/forms/Form.php on line 216 at /var/www/vhosts/xxx/xxx/src/AppBundle/MyHooks.php:9)"} []
    Hat jemand eine Idee?

    Grüße,
    Dirk

  2. #2
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.897
    Partner-ID
    10107

    Standard

    Dir fehlt ein use Contao\Widget;

  3. #3
    Contao-Fan Avatar von dirksche
    Registriert seit
    05.08.2009.
    Ort
    Grosslittgen
    Beiträge
    641

    Standard

    Arghh.. stimmt. die Fehlermeldung ist nun weg :-)

    Allerdings funzt die Prüfung noch nicht richtig. Das Formular wird trotzdem gesendet, auch wenn die Mail Adresse schon in der Datenbank vorhanden ist.



    Code:
        if($objWidget->email == 'max@mustermann.de'){ 
             echo "Dieser Nutzer ist schon angemeldet.";
        }
        return $objWidget;
    Ist denn $objWidget->email richtig, wenn der Feldname email ist?

    LG,
    Dirk

  4. #4
    Contao-Urgestein Avatar von fiedsch
    Registriert seit
    09.07.2009.
    Ort
    München
    Beiträge
    2.935

    Standard

    Anstelle des echo solltest Du wahrscheinlich $objWidget->addError('Dein Fehlertext'); verwenden. Sonst weiß das Widget und damit das Formulat nichts vom fehler.
    Contao-Community-Treff Bayern: http://www.contao-bayern.de

  5. #5
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.897
    Partner-ID
    10107

    Standard

    Zitat Zitat von dirksche Beitrag anzeigen
    Arghh.. stimmt. die Fehlermeldung ist nun weg :-)

    Allerdings funzt die Prüfung noch nicht richtig. Das Formular wird trotzdem gesendet, auch wenn die Mail Adresse schon in der Datenbank vorhanden ist.



    Code:
        if($objWidget->email == 'max@mustermann.de'){ 
             echo "Dieser Nutzer ist schon angemeldet.";
        }
        return $objWidget;
    Ist denn $objWidget->email richtig, wenn der Feldname email ist?

    LG,
    Dirk
    Nein, auf den Feldnamen überprüfst du mit $objWidget->name. Den Wert bekommst du mit $objWidget->value. Und wenn die Email Adresse vorhanden ist, musst du mit $objWidget->addError() eine Fehlermeldung hinzufügen, wie von fiedsch schon erwähnt.

  6. #6
    Contao-Fan Avatar von dirksche
    Registriert seit
    05.08.2009.
    Ort
    Grosslittgen
    Beiträge
    641

    Standard

    Super. Ich bin schon einen guten Schritt weiter. So funktioniert es:

    Code:
    <?php
    
    namespace AppBundle;
    use Contao\Database;
    use Contao\Widget;
    
    class MyHooks {
    
    
      public function myValidateFormField(Widget $objWidget, $intId){
        
        if($objWidget->name == 'email'){
          $result = 'max@mustermann.de';
            if($objWidget->value == $result){
                $objWidget->addError('Diese E-Mail ist schon eingetragen!');
            }
        }
        return $objWidget;          
      }
    }
    Allerdings funktioniert es leider nicht, wenn ich die E-Mail aus der Datenbank Abfrage. Dann wird das Formular trotzdem gespeichert.

    So sieht mein Code mit der Datenbank Abfrage aus:

    Code:
    <?php
    
    namespace AppBundle;
    use Contao\Database;
    use Contao\Widget;
    
    class MyHooks {
    
    
      public function myValidateFormField(Widget $objWidget, $intId){
        
        if($objWidget->name == 'email'){
          $sql = "SELECT * FROM tl_lead_data WHERE value=?"; 
          $result = Database::getInstance()->prepare($sql)->execute($objWidget->value);
            if($objWidget->value == $result){
                $objWidget->addError('Diese E-Mail ist schon eingetragen!');
            }
        }
        return $objWidget;          
      }
    }
    Wo könnte da der Fehler liegen?

  7. #7
    Contao-Urgestein Avatar von fiedsch
    Registriert seit
    09.07.2009.
    Ort
    München
    Beiträge
    2.935

    Standard

    Der Fehler liegt darin, daß Du das Ergebnis der Datenbankabfrage mit dem Wert des Widgets vergleichst. Es sollte wahrscheinlich reichen, zu überprüfen, ob n > 0 Zeilen gefunden wurde, Daß Die E-Mail-Adresse die gewünschte ist, hast Du ja bereits durch die Abfrage sicher gestellt (...->execute($objWidget->value)).
    Contao-Community-Treff Bayern: http://www.contao-bayern.de

  8. #8
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.897
    Partner-ID
    10107

    Standard

    ->execute liefert ein \Contao\Database\Result Objekt, keinen String. Für deine Zwecke reicht es, wenn du deine Abfrage auf
    PHP-Code:
    if ($result->numRows 0) { 
    änderst.

  9. #9
    Contao-Fan Avatar von dirksche
    Registriert seit
    05.08.2009.
    Ort
    Grosslittgen
    Beiträge
    641

    Standard

    Super. Wieder einen Schritt weiter :-)
    Als letztes würde ich das ganze gerne auch ein bestimmtes Formular beschränken.
    Dafür scheint ja $intId zuständig zu sein.

    Das ganze nochmal in die if Abfrage
    Code:
    if($intId['formID'] == 'gewinnspiel'){...}
    oder
    Code:
    if($intId == 2){..}
    zu packen, hat aber leider nicht den gewünschten Erfolg.

    Wie kann ich den Hook auf ein bestimmtes Formular beschränken?

  10. #10
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.897
    Partner-ID
    10107

    Standard

    Folgende Daten werden an den Hook übergeben: https://github.com/contao/contao/blo.../Form.php#L216

    Die "formId" des zweiten Parameters würd eich nicht unbedingt nehmen. Ich würde die ->formID aus dem Form Objekt des letzten Parameters holen. Das ist die Formular-ID, die du im Formular Generator für das Formular einträgst.

  11. #11
    Contao-Fan Avatar von dirksche
    Registriert seit
    05.08.2009.
    Ort
    Grosslittgen
    Beiträge
    641

    Standard

    Stehe jetzt gerade etwas auf dem Schlauch.
    Als Formular-ID habe ich "gewinnspiel" im Generator eingetragen.

    Schreibe ich nun
    Code:
    if($intId->formID == 'gewinnspiel'){...}
    oder
    Code:
    if($objWidget->formID == 'gewinnspiel'){...}

  12. #12
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.897
    Partner-ID
    10107

    Standard

    Nein, siehe mein Link. Deine Hook Funktion bekommst aktuell noch gar nicht das Form Objekt.

  13. #13
    Contao-Fan Avatar von dirksche
    Registriert seit
    05.08.2009.
    Ort
    Grosslittgen
    Beiträge
    641

    Standard

    Juhuu, ich habs. Es funzt. Mein Code sieht nun so aus:

    Code:
    <?php
    
    namespace AppBundle;
    use Contao\Database;
    use Contao\Widget;
    
    class MyHooks {
    
    
      public function myValidateFormField(Widget $objWidget, $intId, $arrForm){
       
        if ($arrForm['formID'] == 'gewinnspiel') {
          if($objWidget->name == 'email'){
            $sql = "SELECT * FROM tl_lead_data WHERE value=?"; 
            $result = Database::getInstance()->prepare($sql)->execute($objWidget->value);
              if($result->numRows > 0){
                  $objWidget->addError('Diese E-Mail ist schon eingetragen!');
              }
          }
        }
          return $objWidget;     
      }
    }
    Hast Du es auch so gemeint?

  14. #14
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.897
    Partner-ID
    10107

    Standard

    Nicht ganz, aber so reicht es auch

  15. #15
    Contao-Fan Avatar von MrLumbergh
    Registriert seit
    11.01.2012.
    Ort
    Hamburg
    Beiträge
    367

    Standard

    Falls es jemanden interessiert, wie man z.B. "Vorname", "Nachname", "Straße", "Zip" abfangen kann:

    Wenn jemand sich bei einem Gewinnspiel regsitriert und nur einmal mitmachen darf, kann man es mit folgendem SQL Statement prüfen (zusätzlich zur E-Mail Prüfung):

    PHP-Code:
    <?php

    namespace AppBundle;
    use 
    Contao\Database;
    use 
    Contao\Widget;

    class 
    MyHooks {


      public function 
    myValidateFormField(Widget $objWidget$intId$arrForm$form){
       
        if (
    $arrForm['formID'] == 'gewinnspiel-maerz-2022') {
          if(
    $objWidget->name == 'email'){
            
    $sql "SELECT tll.form_id, tlld.*" .
                                    
    " FROM tl_lead tll, tl_lead_data tlld" .
                                    
    " WHERE tll.id = tlld.pid" .
                                    
    " AND tll.form_id = ?" .
                                    
    " AND value = ?";
            
    $result Database::getInstance()->prepare($sql)->execute(array($arrForm['id'], $objWidget->value));
            if(
    $result->numRows 0){
                
    $objWidget->addError('Diese E-Mail ist schon eingetragen!');
            } else {
                        
                
    $sql "SELECT tll.form_id, tlld.*" .
                                        
    " FROM tl_lead tll, tl_lead_data tlld" .
                                        
    " WHERE tll.id = tlld.pid" .
                                        
    " AND tll.form_id = ?" .
                                        
    " AND ((`name` = 'firstname' AND `value` = ?)" .
                                            
    " OR (`name` = 'lastname' AND `value` = ?)" .
                                            
    " OR (`name` = 'street' AND `value` = ?)" .
                                            
    " OR (`name` = 'zip' AND `value` = ?))" .
                                        
    " GROUP BY tlld.pid" .
                                        
    " HAVING COUNT(tlld.pid) > 3;";
                
    $result Database::getInstance()->prepare($sql)->execute(array($arrForm['id'], $_SESSION['FORM_DATA']['firstname'], $_SESSION['FORM_DATA']['lastname'], $_SESSION['FORM_DATA']['street'], $_SESSION['FORM_DATA']['zip']));
                if(
    $result->numRows 0){
                    
    $objWidget->addError('Sie haben sich bereits registriert.');
                }
            }
          }
        }
        return 
    $objWidget;     
      }
    }

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •