web-dev-qa-db-fra.com

La validation du formulaire côté serveur renvoie toujours la valeur true

J'essaie de valider l'entrée de mon formulaire côté serveur, mais le validateur me vérifie toujours. Qu'est-ce que je fais mal?

.../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);

}

J'ai vérifié la variable $filtered; il contient les données filtrées sans le jeton CSRF, quelque chose comme: {'customer_registration': {name: "", age: "6", permanent_orderer: "1"}}. En fait, peu importe les données que je donne à la $form->validate($data), elle retourne toujours la valeur true. J'aimerais utiliser JForm pour valider et afficher les messages d'erreur. Une idée pourquoi cela ne fonctionne pas?

1
inf3rno

J'ai vérifié le code du JForm .

Selon cela, class="required validate-username" Ne fonctionne pas et je devrais utiliser required="true" À la place par les champs obligatoires.

Tout le reste est validé par des règles. J'ai besoin d'ajouter validate="ruleType" Au fichier XML. Les minLength, maxLength etc. ne fonctionnent apparemment que du côté client, et la validation côté serveur ne suit pas les spécifications HTML5.

Je suppose que je dois également définir les mêmes types de règles sur une bibliothèque côté client si je souhaite valider côté client. J'ai vérifié avec HTML5, cela a fonctionné, mais je n'ai reçu aucun message d'erreur. Je pensais qu'il était cassé, mais j'imagine qu'il ne se connecte pas correctement à la validation HTML5. Peu importe, je ne veux pas travailler deux fois, je n'aurai donc pas de validation côté client.

Je peux lire les messages d'erreur avec $form->getErrors(). Je pensais qu'ils étaient ajoutés aux champs, donc leur rendu automatique montrerait les messages d'erreur, mais apparemment, je dois mettre ces messages en file d'attente sur l'application joomla. C'est bon, mais ça aurait pu être mieux.

remarque:

J'ai trouvé la partie liée dans le docs , probablement que je lisais trop superficiellement. Je n'ai pas dormi. : S

J'ai fini avec le code suivant:

.../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. il ne s’agit toujours que d’un code factice pour démontrer que la validation fonctionne.

Il est également possible de remplacer les messages d'erreur par défaut si quelqu'un souhaite:

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

Et en renvoyant une instance Exception à la place de false, il est possible d'envoyer différents messages d'erreur à partir de la même règle. Il n'est donc pas obligatoire d'utiliser le message donné dans le XML. Pour moi c'était suffisant.

0
inf3rno