Neue Aktion: Eingaben überprüfen/validieren

Wie verwendet man Module oder Aktion und passt diese an.

Neue Aktion: Eingaben überprüfen/validieren

Beitragvon ciss » 16. Jul 2008, 09:38

Hi,

ich habe mich mal des Problems angenommen, unterschiedlichste Eingaben in Modulen auf ihre Gültigkeit zu prüfen. Herausgekommen ist eine Aktion, die ... halt genau das tut.
Da es sicherlich noch einiges zu verbessern und zu erweitern gibt, stelle ich sie erst einmal hier zur Diskussion.

EDIT2:
Die Aktion gibt es hier: http://www.redaxo.de/176-Aktiondetails.html?action_id=17

Ausserdem eine weitere Aktion, die auf die gleiche Weise eingebunden wird und mit der man mögliche Modulkombinationen einschränken kann: http://www.redaxo.de/176-Aktiondetails.html?action_id=18

Ein Beispielmodul: http://www.redaxo.de/165-Moduldetails.h ... ule_id=393

Kritik, Anregungen und Verbesserungen sind nach wie vor willkommen. (Insbesondere 'number' ist momentan nur eingeschränkt verwendbar.)

Gruss
Fabian
Zuletzt geändert von ciss am 29. Jul 2008, 21:22, insgesamt 3-mal geändert.
Benutzeravatar
ciss
 
Beiträge: 359
Registriert: 8. Feb 2008, 04:24
Wohnort: Berlin

Beitragvon Jan.Kristinus » 16. Jul 2008, 10:12

HI,

ich habe es zwar nicht getestet, aber besser wäre es wenn Du Dich in myRedaxo einloggst und Deine Aktion anderen zur Verfügung stellst. Dann liegt es auch an der richtigen Stelle.

lg

jn
Yakamara Media GmbH & Co. KG | Kaiserstrasse 69 | 60329 Frankfurt
Tel.: 069-900.20.60.30
http://www.yakamara.de/
Benutzeravatar
Jan.Kristinus
Admin
 
Beiträge: 1928
Registriert: 24. Aug 2004, 21:11
Wohnort: Frankfurt

Beitragvon ciss » 17. Jul 2008, 02:26

Ich habe die Aktion überarbeitet. Die einzelnen Auswertungsblöcke funktionieren nun nach dem Schema

Code: Alles auswählen
$return[2]['VALID'] = (Bedingung 2);
$return[1]['VALID'] = (Bedingung 1);
$return[0]['VALID'] = $return[2]['VALID'] && $return[1]['VALID'];

$return[2]['MSG'] = 'Fehlermeldung 2';
$return[1]['MSG'] = 'Fehlermeldung 1';
$return[0]['MSG'] = '';


Gruss
Fabian
Benutzeravatar
ciss
 
Beiträge: 359
Registriert: 8. Feb 2008, 04:24
Wohnort: Berlin

Beitragvon Markus.Staab » 17. Jul 2008, 08:13

Hi Fabian,

sehr nett von dir.

Viele verwenden überhaupt keine Validierung was aus Usability-Sicht sehr zu wünschen übrig lässt.

Viele Grüße,
Markus
Benutzeravatar
Markus.Staab
Entwickler
 
Beiträge: 9781
Registriert: 29. Jan 2005, 14:50
Wohnort: Aschaffenburg/Germany

Beitragvon Markus.Staab » 17. Jul 2008, 08:46

Hi nochmal,

das ganze hat nur den Nachteil, dass man wieder eine neue Notation "lernen" muss. Wäre super, wenn da evtl 1:1 die Notation aus den XFORM übernommen werden könnte, damits einheitlich bleibt.

z.b.

validate|notEmpty|firstname|Bitte geben Sie Ihren Vornamen ein.
validate|email|email|Bitte geben Sie die E-Mail ein.
validate|notEmpty|login|Bitte geben Sie Ihr Login ein.
validate|notEmpty|password|Bitte geben Sie ein Passwort ein.
validate|compare|password|password_2|Bitte geben Sie zweimal das gleiche Passwort ein

du müsstest dann halt wie du es bereits machst, auf die rexvalues zugreifen anstatt auf labels für die einzelnen Felder.

Gruß,
Markus
Benutzeravatar
Markus.Staab
Entwickler
 
Beiträge: 9781
Registriert: 29. Jan 2005, 14:50
Wohnort: Aschaffenburg/Germany

Beitragvon ciss » 18. Jul 2008, 00:23

Hi Markus,

ich habe die Syntax nun zu einer PHP-ähnlichen abgeändert, die darauf aufbauende Validierungsaktion ist so gut wie fertig. Hier ein Beispiel für das Ansprechen von zwei Aktionen mit der neuen Syntax:

Code: Alles auswählen
<input type="hidden" name="VALUE[20]" value="
validate() {
1: 'Name' = text(0, 0, REQUIRED);
2: 'Genre' = text(0, 40);
3: 'Beschreibung' = text(0, 0, REQUIRED);
4: 'Datum' = date('TT.MM.JJJJ');
5: 'Zeit' = time('HH:MM', REQUIRED);
6: 'Eintritt' = number(2, 2, ',', REQUIRED);
7: 'Website' = url('http');
}

force_category(DISALLOW) {
3, 5
}
" />



Leerzeichen und Umbrüche sind weitestgehend frei. Um die Schreibweise für eigene Aktionen zu verwenden, müssen an den Anfang der Aktion folgende Zeilen eingefügt werden:

Code: Alles auswählen
define('GET_ACTIONS', '/\s*(?<name>[a-zA-Z_]+)\s*\((?<options>[^\)]*)\)\s*\{(?<body>[^\}]+)\}/');
define('GET_OPTIONS', '/[^\',\s]+|\'[^\']*\'/');
preg_match_all(GET_ACTIONS, $REX_ACTION['VALUE'][20], $actions, PREG_SET_ORDER);
foreach($actions as $action) {
   preg_match_all(GET_OPTIONS, $action['options'], $action['options']);
   foreach($action['options'][0] as $index=>$option){$action['options'][0][$index]=trim($action['options'][0][$index],'\'');} // Notlösung
   array_unshift($action['options'][0], $action['body']);
   if(function_exists($action['name'])) call_user_func_array($action['name'], $action['options'][0]);
}



Dadurch wird geprüft ob die jeweilige Funktion vorhanden ist und wenn ja, der Bereich in den geschweiften Klammern als erstes Argument übergeben, desweiteren alle in den runden Klammern angegebenen Argumente. Strings mit Leerzeichen müssen dabei in einfachen Anführungszeichen geschrieben werden.

Das Suchmuster für GET_OPTIONS benötigt noch etwas Feinschliff, hier könnte ich durchaus Hilfe gebrauchen. Z.B. werden momentan Anführungszeichen mit in die Treffer übernommen, daher die kommentierte "Notlösung" mittels trim().

Soweit erstmal, freue mich über weiteres Feedback.

Gruss
Fabian
Benutzeravatar
ciss
 
Beiträge: 359
Registriert: 8. Feb 2008, 04:24
Wohnort: Berlin

Beitragvon zehbaeh » 18. Jul 2008, 04:03

Warum nicht statt einer PHP ähnlichen Syntax direkt PHP verwenden?
Das halte ich im allgemeinen Kontext des Modul-Quelltext für am sinnigsten.
Jemand der darin "rumspielt" kennt sich hoffentlich mit PHP aus.)

Beispiel Eingabe:
Code: Alles auswählen
<input type="hidden" name="VALIDATE" value="<?php echo base64_encode(serialize(array(

'Name'  => array(1,
    'minlength' => array(1, 'Eingabe muss mindestens %d Zeichen lang sein'),
    'maxlength' => array(80, 'Eingabe ist zu lang. Maximal %d Zeichen sind erlaubt'),
),
'Datum' => array(2,
    'type' => 'DATE',
    'match' => 'TT.MM.JJJJ'
)
)))?>" />

Beispiel Ausgabe:
Code: Alles auswählen
<?php
$messages  = array();
$msgPrefix = 'Feld "%s" : ';

foreach((array)@unserialize(base64_decode(rex_post('VALIDATE'))) as $field => $validate)
{
    $value = $REX_ACTION['VALUE'][$validate[0]];
   
    switch(strtoupper(@$validate['type']))
    {
        case 'TEXT':
        default:
            if(isset($validate['minlength']) && strlen($value) < $validate['minlength'][0])
            {
                $messages[] = sprintf($msgPrefix . $validate['minlength'][1],
                    $field,
                    $validate['minlength'][0]
                );
            }
            if(isset($validate['maxlength']) && strlen($value) > $validate['maxlength'][0])
            {
                $messages[] = sprintf($msgPrefix . $validate['maxlength'][1],
                    $field,
                    $validate['maxlength'][0]
                );
            }
            break;
    }
}
if(count($messages))
{
    $REX_ACTION['MSG']  = implode('<br />'.PHP_EOL, $messages);
    $REX_ACTION['SAVE'] = FALSE;
}
?>

PS: Das echo base64_en/decode...blabla lässt sich bei Bedarf (Überforderung des Modul-Programmieres.) durch geeignete Globalisierungsmassnahmen vereinfachen.
zehbaeh
 
Beiträge: 563
Registriert: 17. Okt 2006, 10:52
Wohnort: Solingen

Beitragvon ciss » 18. Jul 2008, 12:25

Weil die Anwendung übersichtlich und auch für PHP-Laien noch nachvollziehbar bleiben soll und ich neben der Validierung eben auch noch andere Aktionen nutzen will, z.B. eine Aktion, die für das Modul bestimmte Kategorien vorschreibt oder verbietet.
Das kann dann z.B. so aussehen wie bei force_category() im obigen Beispiel.

Gruss
Fabian
Benutzeravatar
ciss
 
Beiträge: 359
Registriert: 8. Feb 2008, 04:24
Wohnort: Berlin

Beitragvon zehbaeh » 18. Jul 2008, 13:37

Für mich wäre deine Syntax aber weder übersichtlicher noch nachvollziehbarer und auf keinen Fall flexibler.
PHP - Laien, sprich Personen die sich nicht mit den "Basics" (und das sind Arrays) auskennen, sollten IMHO keine Module erstellen oder bearbeiten können. Der Stabilität einer Präsenz und/oder den eigenen Nerven bzw. dem Budget des Endkunden ist das auf jeden Fall SEHR zuträglich.
zehbaeh
 
Beiträge: 563
Registriert: 17. Okt 2006, 10:52
Wohnort: Solingen

Beitragvon ciss » 29. Jul 2008, 21:24

Hi,

mag sein, dass das mit den PHP-Laien etwas hoch gegriffen war. Eigentliches Ziel war/ist ein Gerüst, das sich leicht einbinden und flexibel einsetzen läßt und dabei mit geringem Aufwand erweiterbar bleibt.
Für mich erfüllt es bereits seinen Zweck, noch schöner wäre natürlich, wenn auch andere etwas damit anfangen können.
Ich habe die Art der Einbindung "REX20" getauft und hoffe, dass sich niemand daran stört.
Zwei Aktionen sind fertiggestellt und das Beispielmodul aktualisiert, ich habe die Links im ersten Beitrag entsprechend geändert und den Titel etwas aussagekräftiger gestaltet und hoffe meinen Vorschlägen damit etwas mehr Substanz verliehen zu haben.

Dokumentationen scheinen nicht zu meinen Stärken zu gehören, insofern bei Unklarheiten einfach fragen. :wink:

Die Modulkombinations-Aktion hat leider den Nachteil, dass eine Meldung erst dann ausgegeben wird wenn möglicherweise schon Eingaben getätigt wurden. Weil das mitunter zu Frust führen könnte werde ich versuchen, diese Funktionalität in ein Modulset-Addon auszulagern, ähnlich Drupals Content Types. Werde aber dazu bei Gelegenheit einen neuen Thread aufmachen (Addons sind bisher absolutes Neuland für mich).

Gruss
Fabian
Benutzeravatar
ciss
 
Beiträge: 359
Registriert: 8. Feb 2008, 04:24
Wohnort: Berlin


Zurück zu Module/Aktionen [R4]

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast