Benutzerspezifische Evaluierung in mpform

Martin Hecht

ich geh mal davon aus, dass kein Bedarf an weiteren Anpassungen besteht. Daher hier mal ein Release das die Änderungen aus diesem Thread mit beinhaltet. Sollte doch noch was nachzubessern sein, dann kommt das eben ins nächste Release.

Martin Hecht

und? gibt's was Neues zu berichten? positive oder negative Erfahrungen?

bbs2

Hallo,

es funktioniert. Ich Dussel hatte
<?php
vergessen. Ich teste weiter.

Gruß
Heinz

bbs2

Hallo Martin,

die Lösung verspricht einen wesentlichen Fortschritt im Modul.

Evtl. mache ich noch einen Fehler in der Umsetzung
Anbei die beiden neuen php-files, wobei die private.php testweise für nur ein Feld eine
benutzerdefinierte Evaluierung vorsieht. Es kommt jedoch nicht soweit. Siehe
http://test.bbsiikl.de/pages/anmeldung/bs-anmeldung.php

Die define-Anweisung führt zu einer Ausgabe des Befehls im frontend.

Viele Grüße
Heinz

Martin Hecht

Hallo Heinz,

ich habe eine Vorabversion gebaut, die glaube ich auf deine Anforderungen passt:
Quote from: bbs2 on March 26, 2019, 01:56:05 PM
Dein Vorschlag

"Oder wie wäre es, wenn es eine private Funktion gäbe, die $field_id und $post_field übergeben bekommt und einen String für $err_txt[] zurückliefert. Ist der String leer, ist alles Ok, ansonsten wird die $field_id zu $fer[] hinzugefügt sowie der Rückgabewert in $err_txt[] eingefügt?"

würde eine benutzerdefinierte Evaluierung außerhalb der evalform.php ermöglichen und ist somit ein wesentlicher Fortschritt für Eingabeüberprüfungen weit über eine Pflichtfelddeklarierung hinaus.
in der angehängten Version gibt es eine private_function_for_field, die genau wie oben beschrieben zu verwenden ist. Wenn es schon eine private.php gibt, wird diese nicht überschrieben. Die Vorlage aus private.default.php musst du daher explizit rüber kopieren. In die dortige Funktion könntest du deinen Code mehr oder weniger einfügen. ich habe es insofern vereinfacht, dass du nicht fer[] und err_txt[] setzen musst, sondern einfach nur einen String zurückgeben musst, wenn es an der Eingabe was zu bemängeln gibt.

QuoteLeider lässt ein Pflichtfelddeklarierung immer noch die Eingabe von viele Unsinn zu.

Verstehe ich richtig, dass Dein Vorschlag jedoch nach der browsergestützten Prüfung erfolgt. Dies würde leider weiterhin bedeuten, dass zunächst alle Pflichteingaben gemacht werden müssen. Erst nach Bewältigung dieser Stufe würden die Eingaben gemäß der privat.php durchgeführt. Im Extremfall müsste der Absender also noch einmal alle Pflichteingaben korrigieren, da sie nicht den Vorgaben bzw. Wünschen des Empfängers entsprechen.[...]
um dieses Problem anzugehen, habe ich in constants.php eine neue Konstante MPFORM_REQUIRED_ATTRIBUTE einngeführt. Wenn du eine Datei namens constants.user.php anlegst, die folgendes enthält:

define('MPFORM_REQUIRED_ATTRIBUTE',  '');

dann wird das Verhalten auf das von Version 1.3.24 zurückgestellt. Es wird dann nämlich bei Pflichtfeldern anstelle eines "required"-Attributs ein Leersting (also nichts zusätzliches) eingefügt. Damit akzeptiert der Browser alle leer gelassenen Pflichtfelder und sendet wie gewohnt das halbausgefüllte Formular so dass es serverseitig durch die oben beschriebene private Funktion evaluiert werden kann.

viele Grüße,
Martin

bbs2

Hallo Martin,

Dein Vorschlag

"Oder wie wäre es, wenn es eine private Funktion gäbe, die $field_id und $post_field übergeben bekommt und einen String für $err_txt[] zurückliefert. Ist der String leer, ist alles Ok, ansonsten wird die $field_id zu $fer[] hinzugefügt sowie der Rückgabewert in $err_txt[] eingefügt? "

würde eine benutzerdefinierte Evaluierung außerhalb der evalform.php ermöglichen und ist somit ein wesentlicher Fortschritt
für Eingabeüberprüfungen weit über eine Pflichtfelddeklarierung hinaus. Leider lässt ein Pflichtfelddeklarierung immer noch
die Eingabe von viele Unsinn zu.

Verstehe ich richtig, dass Dein Vorschlag jedoch nach der browsergestützten Prüfung erfolgt. Dies würde leider weiterhin bedeuten, dass zunächst alle Pflichteingaben gemacht werden müssen. Erst nach Bewältigung dieser Stufe würden die Eingaben gemäß der privat.php durchgeführt. Im Extremfall müsste der Absender also noch einmal alle Pflichteingaben korrigieren, da sie nicht den Vorgaben bzw. Wünschen des Empfängers entsprechen.

Beispiel:

Funktionsweise in der Version .....28

1. Geburtstag ist Pflichteingabe
2. Absender lässt das Feld leer und sendet das Formular
3. Browser lehnt die Speicherung ab, da Pflichteingabe nicht erfüllt. Es erfolgt keine weitere Hilfe.
4. Absender gibt Geburtstag in der Zukunft ein (12.08.2020) oder auch ein anderes unzulässiges Datum.
5. Browser akzeptiert, da das Feld nicht leer ist.
6. Die benutzerdefinierte Evaluierung in der evalform.php bzw. der privat.php startet erst jetzt und lehnt jedoch das Geburtstsdatum ab, da nur Personen akzeptiert werden, die mindestens 18 Jahre und hochstens 50 Jahre alt sind.

Besser wäre und dies funktionierte so noch in der Version .....24

1. Geburtstag ist Pflichteingabe
2. Absender lässt das Feld leer oder gibt ein unzulässiges Datum ein und sendet das Formular ab
3. Die benutzerdefinierte Evaluierung in der evalform.php bzw. besser in der privat.php startet und lehnt jedoch das Geburtstsdatum ab, da nur Personen akzeptiert werden, die mindestens 18 Jahre und hochstens 50 Jahre alt sind. Gleichzeitig erfolgt  die Errormeldung, dass das Geburtsjahr größer 1968 und kleiner 2002 sein muss.

Ähnlich könnte dies mit PLZ geschehen, wenn nur Personen Daten übertragen dürfen, deren Wohnsitz im Bundesland
RLP liegt. u.s.w.

Bisher konnte ich dies in der evalform in einem Schritt lösen.

Eine Evaluierung in der beigefügten Form ist mir noch möglich, egal in der evalform.php oder in der privat.php
(siehe Anlage).

Viele Grüße
Heinz

Martin Hecht

Hallo Heinz,

ja, du hast recht, in der private.php ist die Evaluierung etwas schwieriger. Du müsstest so etwas wie die Feldschleife nachbilden. In $mpform_fields werden die Eingaben übergeben. Über die könntest du iterieren und jeweils die Prüfungen durchführen - und gegen Ende der Funktion die erneute Ausgabe des Formulars aufrufen, so in etwa in der Art:

        if($fer != array()) {
            // paint form again:
            include_once(WB_PATH .'/modules/mpform/paintform.php');
            paint_form($section_id, $fer, $err_txt, false);
           return FALSE;
       }
      return TRUE;


Oder wie wäre es, wenn es eine private Funktion gäbe, die $field_id und $post_field übergeben bekommt und einen String für $err_txt[] zurückliefert. Ist der String leer, ist alles Ok, ansonsten wird die $field_id zu $fer[] hinzugefügt sowie der Rückgabewert in $err_txt[] eingefügt?
Damit der Browser halb-ausgefüllte Formulare abschickt, dürfen die Felder nicht als required markiert sein. Sie werden dann zwar auch nicht schon intern von mpform darauf geprüft, ob sie ausgefüllt sind, aber die private Funktion kann ja viel detailliertere Prüfungen vornehmen.

Alternativ könntest du auch mit einer zusätzlichen Code2 Section clientseitig eine detailierte Prüfung der Eingaben umsetzen. Auf die Eingabefelder kannst du mit getElementById zugreifen und EventListener für den EventType input oder change hinterlegen die dann das Property value abfragen und ggf. - im einfachsten Fall mittels alert() - eine Meldung einblednen (aber es gibt im Netz viele Beispiele für deutlich elegantere Popups). 

viele Grüße,
Martin

bbs2

Richtig,

das kann aber auch nicht jeder, einschl. mir.
Ich finde diese Diskussion aber gut, fair, hilfreich und sinnvoll.
Zudem gibt es im Forum viele gute und professionelle Geister

Gruß

Heinz

dbs

Warum entweder oder?
Es muss auch möglich sein sofort korrekt zu validieren. Dann halt ohne deinen alten PHP-Code, dafür mit neuerem Javascript.
Ich finde aber die Browservalidierung trotzdem sinnvoll, weil nicht jeder Code suchen, finden und einbauen kann.
[url="https://onkel-franky.de"]https://onkel-franky.de[/url]

bbs2

Hallo,

weitere Test haben ergeben, dass in der Version 1.3.28 zuerst alle Pflichtfelder ausgefüllt werden müssen,
wenn auch mit Unsinn. z.B. in meinem Fall mit einem Geburtsdatum von gestern, obwohl ein Schüler unserer
Schule mindestens 14 Jahre alt ist. Die Evalform.php wird also nicht ausgeführt,
solange ein Pflichtfeld nicht mit irgendwas beschrieben ist. Selbst Geburtstage in der Zukunft und die PLZ=00000
werden akzeptiert und nie evaluiert, wenn dies nicht benutzerdefiniert geschieht.

Die Prüfungen auf zulässige Daten gemäß eigenen Validierungen erfolgen erst nach dem Absenden des vollständig
ausgefüllten Formulars. Bisher bekam der User bereits beim ersten Absenden auch eines nicht
vollständig ausgefüllten Formulars aussagekräftige Validierungen und Hilfen durch die Errortexte
(z.B. "Das Geburtsdatum muss zwischen 1960 und 2006 liegen".

Diese Validierung erscheint mir sinnvoller als eine simple Vorabprüfung durch den Browser, der fast jeden Unsinn in den
Pflichteingaben akzeptiert. Der erneute Aufbau des Formulars war hierbei nicht störend und ging sehr schnell.
Ihr könnt dies auf https://bbsiikl.de/pages/anmeldung/bs-anmeldung.php sehen (noch Version 1.3.24) und ein nicht ausgefülltes Formular absenden. Bitte keine fehlerfreie Anmeldung durchführen, da diese dann effektiv in der Schule ankommt.

Was ist sinnvoller??

Gruß
Heinz

bbs2

Sorry,

ich habe bei allen updates seit Jahren meine rund 600 Zeilen Evaluation in die evalform.php
immer an der gleichen Stelle eingebunden. Immer mit Erfolg. Ich weiß sehr wohl, dass dies nicht der
professionelle Weg ist.

Auch mit der Einbindung in die private.php der Version 1.3.28 hat es nicht geklappt bzw. ich mache dabei
fundamentale Fehler. Muss hierzu nicht die field_id an die private Funktion übergeben werden,
damit ein spezifischer Feldinhalt dort evaluiert wird?

Ich bin nun zurückgegangen auf die Version 1.3.24. Alles läuft wieder perfekt. Vielleicht finde ich
noch eine Lösung für 1.3.28.

Zunächst einmal vielen Dank.

Gruß
Heinz

Martin Hecht

Ich dachte die Evaluierungen wären in der private.php in private_function_before_email(). Die evalform.php wird beim Update überschrieben. ggf. musst du deine eigenen Anpassungen dort wieder einfügen, aber ich rate davon ab, die Dateien vom Modul zu ändern wo es nicht vorgesehen ist.

Damit der Browser die Daten überhaupt an den Server schickt müssen alle Pflichtfelder entweder ausgefüllt sein oder nicht als Pflichtfeld markiert sein.

DarkViper

Quote from: bbs2 on March 25, 2019, 01:30:36 PM
Achtung eine weitere Auffälligkeit:
Ich habe aus Versehen nach der Speicherung einer Änderung im Backend nicht den Abbrechen-Button benutzt, sondern
den zurück-Pfeil im Firefox. Ich erhielt dann folgende Meldung:

Sicherheitsverletzung!! Zugriff wurde verweigert! (IDKEY) /mnt/web203/c2/45/5705045/htdocs/homepage/modules/mpform/modify_field.php:47

Dieses Verhalten ist völlig korrekt.
FTANS und IDKEYs können jeweils nur ein einziges mal verwendet werden (à la TAN beim Onlinebanking).
Durch die Speicherung wurden beide Elemente benutzt und sind somit verfallen, da bei Browser-Back die Seite ja nicht neu aufgebaut wird (also auch serverseitig keine neue FTAN und IDKEYs erzeugt werden), sondern nur aus dem Browsercache gelesen wird.
[url=http://www.youtube.com/watch?v=tmzDAz6ZvFQ]Der blaue Planet[/url] - er ist nicht unser Eigentum - wir haben ihn nur von unseren Nachkommen geliehen[br]
[i]"You have to take the men as they are... but you can not leave them like that !" :-P [/i]
[i]Das tägliche Stoßgebet: [b]Oh Herr, wirf Hirn vom Himmel ![/b][/i]

bbs2

Vielen Dank Martin,

ich habe 2 Pflichtfelder testweise als freiwillig deklariert. Dennoch werden meine benutzerdefinierten Evaluierungen nicht
durchlaufen. Die beiden Felder mit ID = 8 (Geburtstag) und ID = 11 (Geschlecht) werden also auch so nicht benutzerdefiniert
evaluiert.
Siehe neue Version unter                 https://bbsiikl.de/pages/anmeldung/bs-anmeldung.php
Siehe Funktion unter 1.3.24 unter    http://test.bbsiikl.de/pages/anmeldung/bs-anmeldung.php

Insgesamt habe ich (schon immer seit der Nutzung von mpform)  solche Evaluierungen von Zeile 604 bis 1116 in der
evalform.php. Die benutzerdefinierten Evaluierungen sind für fehlerreduzierte Anmeldungen an unserer Schule wichtig
und haben sich in dem hervorragenden Modul mpform bisher sehr bewährt. Es gibt sicher eine Lösung.

Hier die Evaluierungen für die beiden o.g. Felder. Zudem in der Anlage die evalform.php.
Gibt es evtl. eine Lösung über die privat.php.

// Eingabe Geschlecht

if ($field_id == 11)  {
               $v = substr($_POST['field11'][0],0,3);
               if ($v == "Bit") {
                    $err_txt[$field_id] = "Bitte wählen Sie männlich oder weiblich aus ";//$LANG['frontend']['date_error'];
               $fer[]=$field_id;
                    }
               }

// Eingabe Geburtstag mit Geburtsjahren zwischen 1960 und 2006

if(($field_id == 8) or ($field_id == 307) or ($field_id == 229)){
                $v = $post_field;
                    $pos=strpos($v,".");
               $pos2=strpos(substr($v,($pos+1)),".");
                                        $date=substr($v,0,($pos));
               $result=preg_match("/^[0-9]+$/",$date,$trashed);
               $month=substr($v,($pos+1),($pos2));
               $result2=preg_match("/^[0-9]+$/",$month,$trashed);
               $year=substr($v,($pos+$pos2+2));                                   
                    $gebjahr=(int)$year;
                    global $gebjahr;               
               $result3=preg_match("/^[0-9]+$/",$year,$trashed);
               
               if((substr_count($v,"."))<>2){
                    $err_txt[$field_id] = $LANG['frontend']['date_error'];
               $fer[]=$field_id;
                    }
               elseif (!($result)){
                    $err_txt[$field_id] = $LANG['frontend']['date_error'];
               $fer[]=$field_id;
               }
               elseif (($date<=0)OR($date>31)){
                    $err_txt[$field_id] = $LANG['frontend']['date_error'];
               $fer[]=$field_id;
               }elseif (($month<=0)OR($month>12)){
                    $err_txt[$field_id] = $LANG['frontend']['date_error_monat'];
               $fer[]=$field_id;
               }
               elseif (!($result2)){
                    $err_txt[$field_id] = $LANG['frontend']['date_error_monat'];
               $fer[]=$field_id;
               }
               elseif (!($result3)){
                    $err_txt[$field_id] = $LANG['frontend']['date_error_jahr'];
               $fer[]=$field_id;
               }
               elseif (($year<1960)OR($year>2006)){
                    $err_txt[$field_id] = $gebjahr." nicht logisch. Die Jahresangabe muss zwischen 1960 und 2006 liegen.";  //$LANG['frontend']['date_error_jahr'];
               $fer[]=$field_id;
               }
               }

Achtung eine weitere Auffälligkeit:
Ich habe aus Versehen nach der Speicherung einer Änderung im Backend nicht den Abbrechen-Button benutzt, sondern
den zurück-Pfeil im Firefox. Ich erhielt dann folgende Meldung:

Sicherheitsverletzung!! Zugriff wurde verweigert! (IDKEY) /mnt/web203/c2/45/5705045/htdocs/homepage/modules/mpform/modify_field.php:47


Martin Hecht

Hallo Heinz,

Das liegt daran, dass die Pflichtfelder inzwischen als solche mit dem  required Attribut gekennzeichnet werden und der Browser selbst die Evaluierung vornimmt, sofern er es unterstützt. Bisher musste das Formular bei jeder fehlenden Eingabe erneut vom Server geladen werden. Das hat einige Nutzer gestört und so kam die Anfrage, ob man das nicht umstellen könnte.

Für deinen Anwendungsfall könntest Du einfach mal probehalber die Felder nicht als Pflichtfeld markieren, dann müsste meines Erachtens dein bisheriger Code wieder funktionieren.

Wenn das funktioniert, fehlt nur noch der Stern, der das Feld als Pflichtfeld markiert. Den könnte man über den {TEMPLATE} Plazhalter einfügen. In der Feldschleife. Wenn du diesen Platzhalter vor oder nach {REQUIRED} in die Feldschleife aufnimmst, bekommen die Felder im Backend ein zusätzliches Eingebefeld für diesen Platzhalter. Um den Stern der Pflichtefelder nachzuahmen  gibst du dort bei den Feldern, die die Markierung bekommen sollen <span class="mpform_required required">*</span> ein.

Viele Grüße,
Martin

bbs2

Hallo,

ich habe die Version 1.3.28 von mpform installiert.
Seit dieser Installation funktionieren die von mir in die file evalform.php eingefügten Evaluierungen nicht mehr.
Dies funktionierte seit ca. 10 Jahren. Zueltzt war die Version 1.3.24 installiert. Auf meiner Testseite mit
Version 1.3.24 gibt es hierbei keien Probleme.

Hier 2 Beispiele zu den Einfügungen, wobei die Standardvorgabe im Eingabefeld lautet: "Bitte auswählen"
Wird keine Auswahl getroffen, wird dies abgefangen und eine Fehlermeldung ausgegeben. Die Felder sind
Pflichteingabefelder.

       if($field_id == 3608) {
               $v = substr($_POST['field3608'][0],0,3);
               if ($v == "Bit") {
                    $err_txt[$field_id] = "Bitte wählen Sie die Religionszugehörigkeit aus";//$LANG['frontend']['date_error'];
               $fer[]=$field_id;
                    }
               }
               
               if ($field_id == 11)  {
               $v = substr($_POST['field11'][0],0,3);
               if ($v == "Bit") {
                    $err_txt[$field_id] = "Bitte wählen Sie männlich oder weiblich aus ";//$LANG['frontend']['date_error'];
               $fer[]=$field_id;
                    }
               }

Viele Grüße
Heinz