it-swarm.com.de

Die serverseitige Formularüberprüfung gibt immer true zurück

Ich versuche, die Eingabe meines Formulars auf der Serverseite zu validieren, aber der Validator gibt mir immer die Wahrheit. Was mache ich falsch?

.../templates/customer_registration.xml

<?xml version="1.0" encoding="UTF-8"?>
<form name="customer_registration_form" title="COM_CANTEEN_CUSTOMER_REGISTRATION_TITLE" description="COM_CANTEEN_CUSTOMER_REGISTRATION_DESCRIPTION" buttonLabel="COM_CANTEEN_CUSTOMER_REGISTRATION_BUTTON_LABEL">
    <fields name="customer_registration">
        <fieldset name="customer_registration">
            <field name="name" type="text" class="required validate-username" size="80" minLength="4" maxLength="255"
                label="COM_CANTEEN_CUSTOMER_REGISTRATION_NAME_LABEL" description="COM_CANTEEN_CUSTOMER_REGISTRATION_NAME_DESCRIPTION" message="COM_CANTEEN_CUSTOMER_REGISTRATION_NAME_MESSAGE" />
            <field name="age" type="integer" class="required" default="6" first="1" last="150" step="1"
                label="COM_CANTEEN_CUSTOMER_REGISTRATION_AGE_LABEL" description="COM_CANTEEN_CUSTOMER_REGISTRATION_AGE_DESCRIPTION" message="COM_CANTEEN_CUSTOMER_REGISTRATION_AGE_MESSAGE" />
            <field name="permanent_orderer" type="checkbox" default="1"
                label="COM_CANTEEN_CUSTOMER_REGISTRATION_PERMANENT_ORDERER_LABEL" description="COM_CANTEEN_CUSTOMER_REGISTRATION_PERMANENT_ORDERER_DESCRIPTION" message="COM_CANTEEN_CUSTOMER_REGISTRATION_PERMANENT_ORDERER_MESSAGE" />
        </fieldset>
    </fields>
</form>

.../templates/basic_form_layout.php

<?php
extract($displayData);
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_canteen&controller=main&action=form_test'); ?>"
      method="post" name="<?php echo $form->getAttribute('name'); ?>" class="<?php echo $form->getAttribute('class'); ?>">
    <legend><?php echo JText::_($form->getAttribute('title')); ?></legend>
    <?php
        echo JText::_($form->getAttribute('description'));
        foreach (array_keys($form->getFieldsets()) as $fieldset)
            echo $form->renderFieldset($fieldset);
    ?>
    <div>
        <?php echo JHtml::_('form.token'); ?>
        <button type="submit"><?php echo JText::_($form->getAttribute('buttonLabel')); ?></button>
    </div>
</form>

.../MainController.php

/**
* @action 
* @allow("public")
*/
public function formTest(iRequest $request, iResponse $response){

    $templateDir = JPATH_COMPONENT . '/Canteen/presentation/templates';
    $form = JForm::getInstance('customer_registration', $templateDir . '/customer_registration.xml');

    $formData = $request->getPostData()->getArray();
    $filtered = $form->filter($formData);

    foreach ($filtered as $fieldset => $fields)
        foreach ($fields as $field => $value)
            $form->setValue($field, $fieldset, $value);

    $result = $form->validate($filtered);

    $content = new HtmlFragment();
    $content->addTemplate($response->getTemplate('basic_form_layout.php'), array('form' => $form));
    $content->addText(var_export($result, true));
    $response->setContent($content);

}

Ich habe die Variable $filtered Überprüft. Es enthält die gefilterten Daten ohne das CSRF-Token, etwa: {'customer_registration': {name: "", age: "6", permanent_orderer: "1"}}. Unabhängig davon, welche Daten ich der $form->validate($data) gebe, wird immer true zurückgegeben. Ich möchte JForm verwenden, um Fehlermeldungen zu überprüfen und anzuzeigen. Irgendeine Idee, warum das nicht funktioniert?

1
inf3rno

Ich überprüfte der Code des JForm .

Demnach funktioniert class="required validate-username" Nicht und ich sollte stattdessen required="true" Für die erforderlichen Felder verwenden.

Alles andere wird durch Regeln bestätigt. Ich muss der XML-Datei validate="ruleType" Hinzufügen. Das minLength, maxLength usw. funktioniert anscheinend nur auf Clientseite, und die serverseitige Validierung folgt nicht den HTML5-Spezifikationen.

Ich denke, ich muss die gleichen Regeltypen auch auf der Clientseite lib definieren, wenn ich auf der Clientseite validieren möchte. Ich habe mit HTML5 nachgesehen, es hat funktioniert, aber ich habe keine Fehlermeldungen erhalten. Ich dachte, es ist kaputt, aber ich vermute, es stellt keine ordnungsgemäße Verbindung zur HTML5-Validierung her. Ist eigentlich egal, ich möchte nicht zweimal arbeiten, daher werde ich keine clientseitige Validierung haben.

Ich kann die Fehlermeldungen mit $form->getErrors() lesen. Ich dachte, sie werden zu den Feldern hinzugefügt, sodass beim automatischen Rendern die Fehlermeldungen angezeigt werden, aber anscheinend muss ich diese Meldungen in der Joomla-App einreihen. Es ist okay, hätte aber besser sein können.

hinweis:

Ich habe den dazugehörigen Teil in docs gefunden, wahrscheinlich habe ich zu oberflächlich gelesen. Ich habe nicht geschlafen. : S

Am Ende habe ich den folgenden Code erhalten:

.../templates/customer_registration.xml

<?xml version="1.0" encoding="UTF-8"?>
<form name="customer_registration_form" title="COM_CANTEEN_CUSTOMER_REGISTRATION_TITLE" description="COM_CANTEEN_CUSTOMER_REGISTRATION_DESCRIPTION" buttonLabel="COM_CANTEEN_CUSTOMER_REGISTRATION_BUTTON_LABEL">
    <fields name="customer_registration">
        <fieldset name="customer_registration">
            <field name="name" type="text" required="true" size="80"
                validate="text" minLength="4" maxLength="80" pattern="\p{L}+(?:\p{Zs}\p{L}+)+" 
                label="COM_CANTEEN_CUSTOMER_REGISTRATION_NAME_LABEL" description="COM_CANTEEN_CUSTOMER_REGISTRATION_NAME_DESCRIPTION" message="COM_CANTEEN_CUSTOMER_REGISTRATION_NAME_MESSAGE" />
            <field name="age" type="integer" required="true" default="6" first="1" last="150" step="1"
                validate="integer" min="1" max="150"
                label="COM_CANTEEN_CUSTOMER_REGISTRATION_AGE_LABEL" description="COM_CANTEEN_CUSTOMER_REGISTRATION_AGE_DESCRIPTION" message="COM_CANTEEN_CUSTOMER_REGISTRATION_AGE_MESSAGE" />
            <field name="permanent_orderer" type="checkbox" default="1"
                label="COM_CANTEEN_CUSTOMER_REGISTRATION_PERMANENT_ORDERER_LABEL" description="COM_CANTEEN_CUSTOMER_REGISTRATION_PERMANENT_ORDERER_DESCRIPTION" message="COM_CANTEEN_CUSTOMER_REGISTRATION_PERMANENT_ORDERER_MESSAGE" />
        </fieldset>
    </fields>
</form>

.../templates/rules/text.php

<?php

use \SimpleXMLElement;
use \JForm;
use \JRegistry;
use \JFormRule;

class JFormRuleText extends JFormRule {

    public function test(SimpleXMLElement $element, $value, $group = null, JRegistry $input = null, JForm $form = null)
    {
        if (!isset($value))
            $value = '';
        if (!is_string($value))
            return false;

        $length = mb_strlen($value, mb_detect_encoding($value));

        if (isset($element['minLength'])) {
            $minLength = (int) $element['minLength'];
            if ($minLength > $length)
                return false;
        }

        if (isset($element['maxLength'])) {
            $maxLength = (int) $element['maxLength'];
            if ($maxLength < $length)
                return false;
        }

        if (isset($element['pattern'])) {
            $pattern = '/'.$element['pattern'].'/usD';
            if (!preg_match($pattern, $value))
                return false;
        }

        return true;
    }
}

.../templates/rules/integer.php

<?php

use \SimpleXMLElement;
use \JForm;
use \JRegistry;
use \JFormRule;

class JFormRuleInteger extends JFormRule {

    public function test(SimpleXMLElement $element, $value, $group = null, JRegistry $input = null, JForm $form = null)
    {
        $intValue = (int) $value;
        if ((string) $intValue !== $value || (float) $intValue !== (float) $value)
            return false;

        if (isset($element['min'])) {
            $min = (int) $element['min'];
            if ($min > $intValue)
                return false;
        }
        if (isset($element['max'])) {
            $max = (int) $element['max'];
            if ($max < $intValue)
                return false;
        }
        return true;
    }
}

.../MainController.php

/**
* @action 
* @allow("public")
*/
public function formTest(iRequest $request, iResponse $response){
    $form = $response->getForm('customer_registration.xml', $request->getAddress(), $request->getQuery());
    if ($request->isPost()){
        $form->fill($request->getPostData());
        $isValid = true;
        if (!$request->hasValidToken()) {
            $response->reportError(new Exception('Invalid token.'));
            $isValid = false;
        }
        if (!$form->validate()) {
            foreach ($form->getErrors() as $error)
                $response->reportError($error);
            $isValid = false;
        }
        if ($isValid) {
            $response->reportSuccess('Customer created.');
            $form->reset();
        }
    }

    $content = new HtmlFragment();
    $content->addForm($form, $response->getTemplate('basic_form_layout.php'));
    $response->setContent($content);
}

Ofc. Dies ist nur ein Dummy-Proof-of-Concept-Code, der demonstriert, dass die Validierung funktioniert.

Es ist auch möglich, die Standardfehlermeldungen zu überschreiben, wenn jemand Folgendes möchte:

// required: JText::sprintf('JLIB_FORM_VALIDATE_FIELD_REQUIRED', $name|label);
// rule: $message | JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $label)

Und indem Sie eine Exception -Instanz anstelle von false zurückgeben, ist es möglich, verschiedene Fehlermeldungen von derselben Regel zu senden. Daher ist es nicht zwingend erforderlich, die in der XML angegebene Nachricht zu verwenden. Für mich hat es gereicht.

0
inf3rno