Caldera Forms (WordPress)?

1 Antwort

Kennt sich zufällig jemand mit dem Plugin Caldera Forms aus?

Ich habe noch nie praktisch damit gearbeitet, es mir aber eben einmal genauer angeschaut.

(...) vor dem Absenden eine Datenvalidierung durchführen, (...)

Genau. Entweder über die bereits integrierten Funktionen (die an sich eh nur die HTML5-Attribute pattern und required abstrahieren - als Checkbox oder via Mask Inputs) oder mittels eigenen Validatoren. Ich gehe davon aus, dass du dich nun auf letztere Möglichkeit beziehst, aber im Voraus würde ich dir empfehlen, doch noch einmal zu schauen, ob die Standardfunktionen nicht auch für deine Anforderungen ausreichen.

Daran klärt sich dann auch deine Frage:

(...) dass ich einen Preprocessor brauche, oder?

Prozessoren können zu drei unterschiedlichen Zeitpunkten aufgerufen werden:

  • als Präprozess, wenn das Formular noch nicht wirklich ausgewertet wurde
  • als Prozess nachdem das Formular bereits validiert wurde
  • als Postprozess, wenn die Auswertung der Daten erfolgte - kurz vor dem letzten Schritt der Formularbearbeitung (also bspw., bevor eine E-Mail verschickt wird)

Da dies alles in PHP passiert, werden diese Überprüfungen serverseitig vorgenommen. Das Formular wird in jedem Fall einmal neu geladen werden, sobald der Nutzer auf den Senden-Button gedrückt hat und der Datentransport nicht durch HTML5-Attribute (required, pattern, ...) / JavaScript blockiert wird.

Angenommen, du möchtest prüfen, ob der Wert einer Textbox in einer vordefinierten Liste vorliegt (z.B. Farben: rot, grün, gelb). In dem Fall kannst du entweder mit Mask Inputs arbeiten und via regulären Ausdruck ein Muster vorschreiben: /rot|grün|gelb/ oder du setzt deinen neuen, selbst geschriebenen Prozessor als Präprozess.

Wenn du stattdessen absichern möchtest, dass sich der Nutzer bei den Angaben von einer Postleitzahl und einer Stadt nicht vertan hat, könntest du deinen Prozessor als Präprozess oder Prozess laufen lassen. Ich muss sagen, dass ich mir an dieser Stelle nicht zu hundertprozent sicher bin, ob ein Prozess dafür wirklich eine richtige Wahl wäre. Doch wie es die Dokumentation schon selbst sagt, dieser Prozess wird eher weniger verwendet.

Nun noch zum dritten Fall: Vielleicht sollen die ausgewerteten Formulardaten via E-Mail verschickt werden und nun möchtest du da noch Werte einfügen, die du aus den bereits ausgewerteten Daten schon berechnen kannst. Der Nutzer muss vielleicht sein Geburtsdatum angeben und du könntest daraufhin nun das Alter berechnen lassen. Für solche Sachen wäre ein Postprozess zuständig.

Aber ich verstehe die Syntax bzw. die Logik bei Caldera Forms nicht wirklich.

Es ist modular aufgebaut. Wenn du einen neuen Prozessor schreiben möchtest, legst du für diesen ein Plugin an (der Prozessor ist das Plugin) und registriert ihn. Später zur Laufzeit wird Caldera über alle registrierten Prozessoren automatisch laufen.

Ein ganz simples Beispiel, um eine Vorstellung davon zu bekommen:

// code anywhere in caldera core library --------------

$processors = array();

function registerProcessor($processor) {
  $processors[] = $processor;
}

// gets called when form was submitted by user
function evaluateForm($formdata) {
  for ($i = 0; $i < count($processors); ++$i) {
    if ($processors[$i] instanceof IProcessor) {
      $processors[$i]->run($formdata);
    }
  }
}
                
interface IProcessor {
  public function run($formdata);
}

// your code --------------------

class MyProcessor implements IProcessor {
  public function run($formdata) {
    // do some fancy stuff ...
  }
}

registerProcessor(new MyProcessor());                           

Wenn du einmal dem Tutorial von Caldera folgst, wirst du zuallererst also ein neues Plugin anlegen und dieses registrieren.

Über addfilter gibst du als zweites Argument den Namen deiner Funktion an, die für die Registrierung zuständig ist.

add_filter("caldera_forms_get_form_processors", "some_form_processor");

Egal wie du deine Funktion auch nennst (ich habe mich doch einmal der snake_schreibweise angepasst...), die Funktion bekommt auf jeden Fall einen Parameter überreicht, welcher ein assoziatives Array aller Prozessoren beinhaltet. Der Name des Parameters ist an sich egal, doch sinnig wäre schon so etwas wie $processors, $allProcessors, o.ä..

function some_form_processor($processors) {
  $processors["some_validator"] = array(/* processor config, look at doku ... */);
  return $processors;
}

Am Ende der Funktion muss das Array wieder zurückgegeben werden, andernfalls kann das originale $processors-Array nicht geändert werden (PHP übergibt Arrays als Kopie an eine Funktion).

In dem Array, welches die Processor-Konfiguration beinhaltet, gibst du unter anderem einen Eintrag für den Präprozess an (pre_process). Dieser verweist auf den Namen deiner Funktion (bei mir künftig: validate_some_form_fields), die du später für die Validierung benutzt.

Wenn du nun aber die anderen Prozessortypen nutzen wollen würdest, müsstest du andere Keys einsetzen. Ich finde die Dokumentation an dieser Stelle etwas undeutlich, vielleicht haben sie sich auch verschrieben oder ich verstehe es einfach falsch:

We could add arguments to our processor configuration array for “processor” to run a function at the processor stage, or “process” to run a function at the process stage.

(Quelle)

Ein Array, welches zum Beispiel alle Prozesstypen nutzt (falls das funktionieren sollte), müsste demzufolge wohl so aussehen:

$processor = array(
  /* name, description, template, ... */,
  "pre_processor" => "validate_some_form_fields",
  "process" => "validate_some_form_fields_during_process",
  "processor" => "validate_some_form_fields_before_sending_mail"
);

Sollte so etwas nicht instant klappen, würde ich mir doch nochmals Beispiele heraussuchen oder stattdessen sinnigere Keys ausprobieren (pre_processor, processor, post_processor).

So. Dann fehlt erst einmal nur noch die Implementation der Validierungsfunktion. Diese verhält sich genauso wie die Registrierungsfunktion oben, sie bekommt auf jeden Fall Parameter überreicht, diesmal zwei an der Zahl, beide vom Typ Array. Wieder brauchst du dich nicht darum zu kümmern, woher diese Parameter kommen. Caldera wird die Funktion zu gegebenem Anlass selbst aufrufen und die notwendigen Argumente an die Parameter übergeben.

function validate_some_form_fields($config, $form) {
  // some fancy validation ...
} 

Zur Vorbereitung der Formulardaten (bzw. um einfach an die Feldwerte zu kommen), bietet Caldera eine Klasse (Caldera_Forms_Processor_Get_Data) an.

$data = new Caldera_Forms_Processor_Get_Data($config, $form, $fields);

Die Variable $fields würde in dem Fall ein multidimensionales Array beinhalten, in dem die Formularfelder angegeben werden, die betrachtet werden sollen. Im Tutorial hat man der grafischen Oberfläche von Caldera (im CMS) ein neues Feld hinzugefügt und betrachtet fortan dieses. Lies dazu den Abschnitt (Creating The processor UI).

An die Werte der betrachteten Felder kommst du über die Variable $data nun sehr einfach.

$value = $data->get_value("fieldname");

-------------------

Oder wie kann ich eine Fehlermeldung in einem Feld ausgeben, wenn ein falscher Wert in einem anderen Feld eingegeben wurde?

Wenn die Funktion keinen Rückgabewert liefert, ist erst einmal alles in Ordnung. Wenn du allerdings im Fehlerfall einen Fehler zurückgeben möchtest, muss ein assoziatives Array geliefert werden.

function validate_some_form_fields($config, $form) {
  // some fancy validation ...

  if ($valid) {
    return;
  }

  return array(/* ... */);
} 

Dieses Array beinhaltet einmal wieder Einträge, die genau beschreiben, welcher Fehler vom Formular ausgegeben werden soll und für welches Feld. Schau dir dazu im Tutorial den letzten Code-Abschnitt an. Er zeigt genau diesen Fall auf.

-------------------

Oder wie kann ich von dort aus auf meine Datenbank zugreifen um mit diesen Daten eine Überprüfung durchzuführen?

Probiere es erst einmal auf den üblichen Weg mit dem wpdb-Objekt.

organix2012  21.02.2022, 16:21

hm, ich habe nun das Plugin erstellt, aber da tut sich so gar nichts. Es scheint, als dass schon mal add_filter (caldera_forms_get_form_processors...) gar nicht die custom-Funktion aufruft.´?!?! Ich sitze da jetzt schon seit Stunden dran ... ;-(((

0
regex9  21.02.2022, 18:24
@organix2012

Ich denke, es macht keinen Sinn mehr, für die eigene Seite noch Caldera einzubauen, denn dessen Support läuft im März dieses Jahres aus (lies hier). Eine Nachfolgeroption wäre wohl Ninja Forms.

0