web-dev-qa-db-fra.com

Comment puis-je afficher les erreurs après validation avec une interface de formulaire personnalisé?

J'ai du mal à comprendre comment je devrais obtenir un gestionnaire d'erreur décent à l'interface frontale (côté serveur). Le code est écrit dans functions.php dans un thème spécifique (si cela compte). En bas, un type de message personnalisé nommé élève est créé lors de la soumission.

$pupil = new Pupil();
add_shortcode('wppb-register', array($pupil, 'frontEndRegistration'));

//Check if visitor is trying to save a new pupil
$pupil->checkFrontEndRegistration();

Dans la classe-élève, je montre (retourne) ce contenu:

//Show public register-form
public function frontEndRegistration($atts, $content="", $errors = null) {   
     $class_errors = array();

    if (is_array($errors) && !empty($errors)) {

        foreach($errors as $key=>$err) {
            if ($err === true) {
                $class_errors[$key] = ' error';
            }
        }           
    }
    $content .= '
    <form id="adduser" name="adduser" method="post" action="">' .
            '<table class="form-table"><tbody><tr><td colspan="2">'.$this->getRelatedCoursesPupil(null, array('args' => array('fetchContent' => 'returncontent')))
    .  '</td></tr>
    <tr>
        <th><label for="email">Förnamn*</label></th>
        <td><input name="first_name" id="first_name" value="" class="regular-text' . $class_errors['first_name'] . '" type="text"></td>
    </tr>
    <tr>
        <th><label for="email">Efternamn*</label></th>
        <td><input name="last_name" id="last_name" value="" class="regular-text' . $class_errors['last_name'] . '" type="text"></td>
    </tr>        
    <tr>
        <th><label for="age">Ålder*</label></th>
        <td><input name="age" id="age" value="" class="regular-text" type="text"></td>
    </tr>          <tr>
        <th><label for="email">E-post</label></th>
        <td><input name="email" id="email" value="" class="regular-text" type="text"></td>
    </tr>
    <tr>
        <th><label for="homephone">Telefon hem*</label></th>
        <td><input name="homephone" id="homephone" value="" class="regular-text" type="text"></td>
    </tr>

    <tr>
        <th><label for="cellphone">Mobiltelefon*</label></th>
        <td><input name="cellphone" id="cellphone" value="" class="regular-text" type="text"></td>
    </tr>
    <tr>
        <th><label for="adress">Adress</label></th>
        <td><input name="adress" id="adress" value="" class="regular-text" type="text"></td>
    </tr>
    <tr>
        <th><label for="postnr">Postnr</label></th>
        <td><input name="postnr" id="postnr" value="" class="regular-text" type="text"></td>
    </tr>
    <tr>
        <th><label for="ort">Ort</label></th>
        <td><input name="ort" id="ort" value="" class="regular-text" type="text"></td>
    </tr>
    <tr>
        <th><label for="description">Övrigt</label></th>
        <td><textarea name="description" id="description" class="description"></textarea></td>
    </tr>    
    <tr><td>
    <input type="hidden" name="action" value="newpupil-frontend" />
    ' . wp_nonce_field( 'newpupil-frontend', 'newpupil-frontend') . 

    '</td></tr></tbody>
    </table>
    <input type="submit" value="OK" name="addusersub" id="addusersub" />
    </form>
    ';

    return $content;
}

Ici, je fais la vérification avant de l’enregistrer dans la base de données.

//Save pupil
public function checkFrontEndRegistration() {

        if( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) &&  $_POST['action'] == "newpupil-frontend") {

            //Required fields
            $errors = array();
            if (!isset($_POST['first_name']) || strlen($_POST['first_name']) == 0) {
                $errors['first_name'] = true;
            }
            if (!isset($_POST['last_name']) || strlen($_POST['last_name']) == 0) {
                $errors['last_name'] = true;
            }
            if (!isset($_POST['age']) || strlen($_POST['age'] == 0)) {
                $errors['age'] = true;
            }         
            if (!isset($_POST['homephone']) || strlen($_POST['homephone']) == 0) {
                $errors['homephone'] = true;
            } 
            if (!isset($_POST['cellphone']) || strlen($_POST['cellphone']) == 0) {
                 $errors['cellphone'] = true;
            }           

            //Add new pupil-cpt into post-table when there are no errors
            if (empty($errors)) {
                //Remove hook temporarily
                remove_action( 'save_post' , 'postsubmitted');

                $pupil = array(
                    'post_title'    => 'unregistered',
                    'post_status'   => 'private',           // Choose: publish, preview, future, draft, etc.
                    'post_type' => 'pupil',
                    'post_author' => 5500                   
                );
                //save the new post and return its ID
                $post_id = wp_insert_post($pupil); 

                //Save everything relevant for this new pupil
                saveform_db($post_id, $_POST, true);        //True says that it's frontend-saving

                //Rehook temporarily removed hook
                add_action( 'save_post' , 'postsubmitted');
            }
            else {
                throw new Exception('Pupils must be entered');
                //$this->frontEndRegistration('', '', $errors);
            }

        }

    }

Cela fonctionne bien, mais je ne vois pas comment afficher les erreurs lorsque l'utilisateur n'a pas saisi les champs obligatoires.

Au lieu de throw new Exception(Pupils must be entered);, je souhaite afficher le même frontendRegistrationform() mais avec les erreurs définies lorsqu'il n'y a aucune valeur dans les champs obligatoires.

Je suppose que je pourrais utiliser des sessions, mais y at-il une meilleure façon?

C'est une jolie solution de base. Premièrement, je suppose que vous n'enregistrez pas les données/formulaire et revenez simplement à la même page .. Dans votre $formContent, vous feriez quelque chose comme ceci.

<?php
$formContent = '
    ....
    <tr>
        <th><label for="email">Förnamn*</label></th>
        <td><input name="first_name" id="first_name" value="" class="regular-text' . $class_errors['first_name'] . '" type="text">'
    . ( array_key_exists( 'first_name', $class_errors ) ? "<br/>You must enter your first name." : "" ) . '</td>
    </tr>";

Si vous souhaitez accéder aux erreurs sur le formulaire lui-même, je vous recommande personnellement de vérifier l'erreur via JavaScript. De cette façon, vous pouvez réellement empêcher la page de soumettre, plutôt que de soumettre, d'annuler et de rediriger. Avec jQuery, ce serait quelque chose comme:

$('form').submit(function(event){
    var $form = $(this);

    // if any empty fields with the required class are found
    if ($form.find('input.required:empty').length) {
        event.preventDefault(); // cancel form submission
        $form.find('input.required:empty').after('<p class="error">This field is required');
    }
});

Évidemment, vous pouvez personnaliser le message de chaque champ en lisant l'étiquette attachée à cette entrée ou en mettant des contrôles individuels sur chaque champ. Vous pouvez également utiliser une validation personnalisée ici, comme la validation du numéro de téléphone, la messagerie, etc.

C'est ma méthode préférée.

Pour le côté PHP, vous devriez pouvoir stocker vos classes d'erreur soit sur une variable de classe, soit sur une variable globale. Étant donné que la page post.php pointe sur elle-même, il n'y a pas de redirection entre la vérification de votre soumission de formulaire et le rendu de la page. Vous devriez pouvoir stocker les erreurs dans une variable de classe et l'utiliser dans les deux fonctions.

Très haut niveau:

class myFormStuff {
    protected $error_classes;

    // happens first, on init most likely
    function checkFrontEndRegistration(){
        $this->error_classes['first_name'] = "Dude, where's your name at?";
    }

    // Happens way later in the page reload, when rendering the form
    function frontEndRegistration() {

        if ( array_key_exists( 'first_name', $this->error_classes ) ) {
            echo '<p class="error">' . $this->error_classes['first_name'] . '</p>';
        }
    }
}
1
Eric Holmes