Schlagwort-Archiv: PHP

Extbase: Model-Zugriff in Validatoren

Für den Fall, dass die Standard-Validatoren von Extbase oder benutzerdefinierte Validatoren für einzelne Eigenschaften eines Models nicht genügen, gibt es noch die Option eines benutzerdefinierten Validators mit vollem Zugriff auf die neue Instanz eines Models.

Dafür kann man sich eine gänzlich undokumentierte Feinheit des Extbase-Frameworks zunutze machen: standardmäßig wird in einem Standardpfad versucht, einen passenden Validator passend zu einem Model zu finden. Wieder ein Beispiel für „Konvention über Konfiguration“, worauf in Extbase und FLOW3 Wert gelegt wird.

Der besagte Validator wird standardmäßig unter Classes/Domain/Validator/ModelNameValidator.php gesucht. Wie bei allen Extbase-Validatoren üblich ist zur Erfüllung der Schnittstelle Tx_Extbase_Validation_Validator_ValidatorInterface (OOP-Konvention wäre hier eigentlich IValidator) eine Ableitung von Tx_Extbase_Validation_Validator_AbstractValidator empfehlenswert. Dessen isValid-Methode erhält als einziges Argument die betreffende Instanz des Models, womit dann beliebige Überprüfungen vorgenommen werden können. Da hier ein uneingeschränkter Zugriff auf alle Eigenschaften des Models gegeben ist, können so auch komplexe Validierungen mit Abhängigkeiten zwischen Eigenschaften und dergleichen vorgenommen werden.

Der Validator sollte zu guter Letzt wie immer true oder false zurückgeben um über das Ergebnis der Validierung zu informieren und im Fehlerfall zuvor noch eine aussagekräftige Fehlermeldung vermerken. Dies kann entweder über die addError-Methode oder direkt per Manipulation der errors-Eigenschaft geschehen:

// 1) addError()
$this->addError('Descriptive error message', 0000000000); // Hier sollte 0000000000 eine eindeutige Nummer sein
 
// 2) errors
$this->errors[] = new Tx_Extbase_Validation_Error('Descriptive error message', 0000000000); // Siehe oben

Letztere Variante bietet die Möglichkeit, manuell Instanzen von Tx_Extbase_Validation_PropertyError einzufügen. Dadurch können bestehende, auf Model-Eigenschaften optimierte, Partials für die Ausgabe von Validierungsfehlern ohne Anpassung verwendet werden. Dazu hängt man die eigentlichen Fehlermeldungen an eine Fake-Eigenschaft:

// Container für gruppierte Fehlermeldungen über eine Fake-Eigenschaft anlegen
if (!isset($this->errors['fakeProperty']) {
 
  $this->errors['fakeProperty'] = new Tx_Extbase_Validation_PropertyError('fakeProperty');
}
 
// Eigentliche Fehlermeldungen an den Container anhängen
$this->errors['fakeProperty']->addErrors(array(
  new Tx_Extbase_Validation_Error('Descriptive error message', 0000000000); // See above
));

Da dieser Validator allgemein für das Model gilt, wird er immer dann zur Rate gezogen, wenn eine neue Instanz des Models im Zuge einer Aktion angelegt werden soll. Wahlweise kann man dies allerdings auch manuell für die gewünschten Aktionen eines Controllers über die  @validate …Validator.php DocComment-Notation erfolgen. Allerdings sollte man dann darauf achten, dass der Validator nicht der oben beschriebenen Pfad-Konvention folgt. Andernfalls wird der Validator wie gehabt immer aufgerufen, @dontvalidate einmal ausgenommen. Auf diese Weise können der Zielaktion auch beliebige weitere Validatoren hinzugefügt werden, welche jeweils den gleichen Zugriff auf das Model haben.

E-Mail-Schutz vor Spambots

Einer Bitte folgend veröffentliche ich hier den – zugegeben nicht sonderlich komplexen – Code in meinem Impressum, welcher die E-Mail-Adresse vor Spambots verbirgt, bis der erforderliche Button betätigt wurde:

<?php
 
$str_value = 'E-Mail (Anzeigen)';
 
if (isset($_POST['showmail']) and $_POST['showmail'] == $str_value) {
 
    echo '      <p><a href="mailto:info@example.org">E-Mail-Adresse</a><p>' . "\n";
 
} else {
 
    echo '      <form action="" method="post" accept-charset="utf-8">' . "\n" .
         '        <p><input type="submit" name="showmail" value="' . $str_value . '" />' . "\n" .
         '      </form>' . "\n";
}
 
?>

Früher oder später wird auch der Code meines Gästebuches folgen. Ich hoffe früher.

No more Spam!

Die nicht ständig aber oft genug um lästig zu werden auftretenden Spameinträge in meinem Gästebuch werden von heute an der Vergangenheit angehören. Ich habe nun endlich mein Gästebuch-Script von Grund auf neu geschrieben.

Bisher stand ich Spam recht hilflos gegenüber, da ich nicht mehr tun konnte, als das uralte Script, welches ich mir irgendwann einmal irgendwoher besorgt hatte, zu flicken und hier und da Schutzmaßnahmen einzubauen. Mein bisheriger Spamschutz bestand darin, entweder den Funktionsaufruf, der die Daten ins Gästebuch-XML-Dokument schreibt, auszukommentieren oder dem Server die Schreibrechte zu entziehen. Unsauber ist gar kein Ausdruck.

Auch wenn die augenscheinlich schlankere Eingabemaske nur geringfügige Unterschiede aufweist, hat sich unter der Oberfläche schlichtweg alles verändert. Ich verwende nun PHPs DOM-Funktionen an Stelle des alten ereignisbasierten XML-Parsers, da ich mit Ersterem dank meines Umgangs mit dem gleichnamigen JavaScript-Pendant weitaus besser arbeiten kann. Zudem habe ich nun erste erfolgreiche Gehversuche mit XPath unternommen, was das Agieren im Dokumentenbaum enorm erleichtert. Bei der Formularvalidierung schlug ich einen etwas unorthodoxen Weg ein, da ich hier erstmalig Gebrauch von den Bitoperatoren mache. Dadurch wird nun auf praktisch jeden Fehler individuell reagiert. Neu ist hierbei auch die Vorschaufunktion welche neben der Korrekturmöglichkeit auch auf die eventuell aufgetretenen Fehler hinweist.

Doch nun zum eigentlich Relevanten: dem Spamschutz. Sämtliche Beiträge müssen nun von mir kontrolliert und freigeschaltet werden. Außerdem habe ich die widersinnige Verlinkung der eingegebenen E-Mail-Adresse entfernt; die Adresse wird nun, sofern eingegeben, nur noch alleinig zur Kontaktaufnahme meinerseits gespeichert. Somit trägt das neue Gästebuch nicht nur zu meinem Spamschutz bei.

Und als kleines Bonbon gibt es, auch wenn es rein gar nichts mit dem Thema zu tun hat, hier noch zu sehen, was während des Verfassens dieses Beitrags passiert ist: