web-dev-qa-db-fra.com

Validation côté serveur

J'essaie de faire une validation côté serveur des champs de publication (champs personnalisés et/ou non personnalisés). La validation fonctionne très bien, mais je n'arrive pas à arrêter l'enregistrement de la publication si la validation échoue.

J'ai essayé des hooks comme save_post, publish_post, wp_insert_post_data, etc. Tous ces hooks sont appelés, mais je ne peux pas empêcher la publication de sauvegarder sauf si j'utilise wp_die(). Pour être clair, je ne veux pas changer le statut de la publication; Je veux juste revenir à la page de publication (non enregistrée) et afficher un message lorsque la validation d'un champ échoue.

Je pense que c'est assez basique, mais quoi que je fasse, le post est sauvegardé.

METTRE À JOUR:

OK, le hook pre_post_update est une option. Cependant, en cas d'échec de la validation, je dois utiliser wp_redirect pour revenir à la page d'édition sans enregistrer. Je stocke les msgs d'invalidation et les affiche sur la page, mais de cette façon, toutes les données $_POST ont disparu ... ce qui, bien sûr, n'est pas acceptable. N'y a-t-il vraiment pas d'autre moyen de faire cela?

Voici mon code jusqu'à présent:

add_action('pre_post_update', 'validate_meta', 99, 2);
function validate_meta($post_id){

    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;

    if (!isset($_POST['post_type']) )  return $post_id;

    if ( !current_user_can( 'edit_posts', $post_id ) ) return $post_id;

    $errors = array();

    if(trim($_POST['post_title']) == ''){
        $errors[] = new WP_Error('cpt_validation_titke',  'Bitte einen Titel eintragen', 'error');
    }

    if (!empty($errors)) {
        add_user_meta(get_current_user_id(), 'admin_notices', $errors, true);
        $url = admin_url( 'post.php?post=' . $post_id ) . '&action=edit';
        //exit;
        wp_redirect( $url );
        exit;     
    }
    return $_POST;
}

// Display any errors
add_action( 'admin_notices', 'admin_notice_handler' );
function admin_notice_handler() {
    $user_id = get_current_user_id();
    $admin_notices = get_user_meta($user_id, 'admin_notices', true);

    if(!empty($admin_notices)){
        $html = '';

        if(is_wp_error($admin_notices[0])){

            delete_user_meta($user_id, 'admin_notices');

            foreach($admin_notices AS $notice){

                $msgs = $notice->get_error_messages();

                if(!empty($msgs)){
                    $msg_type = $notice->get_error_data();
                    if(!empty($notice_type)){
                        $html .= '<div class="'.$msg_type.'">';
                    } else {                    
                        $html .= '<div class="error">';
                        $html .= '<p><strong>Validation errors</strong></p>';
                    }

                    foreach($msgs as $msg){
                        $html .= '<p>- '.$msg.'</p>';
                    }                    
                    $html .= '</div>';                   
                }
            }
        }

        echo $html;
    }
}
6
john23klipp

Vous pouvez capturer la soumission du formulaire en créant un petit plugin/ou en modifiant votre fichier de fonctions de thème, et vous pouvez le faire en utilisant un hook ajax. Dans le plug-in, vous devriez charger ceci sur la page d'édition du post:

jQuery(document).ready(function(){

jQuery('#post').submit(function(){
        var request = jQuery(this).serializeArray();
        request.Push({name: 'action', value: 'check_some_stuff'});

        jQuery.post(ajaxurl, request, function(response){
            if(response.error){
                response = jQuery.parseJSON(response);
            jQuery('#local-storage-notice').after('<div class="error">'+response.error+'</div>');
        });
                return false;
        } else {
            return true;
        }
    });

});

Lorsque vous renvoyez false, le formulaire ne sera plus soumis.

Le ajax appellera une fonction check_some_stuff . La request est envoyée sous la forme $ _POST. Vous pouvez ensuite valider tout ce que vous voulez côté serveur:

add_action( 'wp_ajax_check_some_stuff', 'check_some_stuff' );

public function check_some_stuff()
{
    //validate some stuff here
    $valid = false;
    if($valid){
        $results = array('msg'=>'You win');
        print json_encode($results);
    } else {
        $results = array('error'=>'<pre>'+print_r($_POST, true)+'</pre>');
        print json_encode($results);
    }
    die();
}

Je peux aller plus en détail sur la façon d'ajouter le javascript si vous avez besoin.

1
paxamus

Le moyen le plus simple - à mon avis - d'y parvenir est d'utiliser PHP: Sessions, donc le $_SESSION global ou quelque chose comme "WP Session Manager" . Lorsque vous utilisez des sessions, vous pouvez simplement ajouter vos données de publication à la variable de session avant la redirection et disposer des données après la redirection.

0
Nicolai

Cela ressemble à quelque chose que vous pourriez résoudre avec l'aide d'AJAX. Consultez la section "JavaScript, AJAX & jQuery" du manuel du plugin WordPress:

https://developer.wordpress.org/plugins/javascript/jquery/

Ne laissez pas le fait que ce soit un manuel de plug-ins vous irriter. Il peut être utile de créer un petit plugin pour cette tâche, sinon vous pouvez utiliser les instructions de votre functions.php.

Voici comment je procéderais après avoir lu les instructions du manuel:

  • J'utiliserais les événements de modification ou de flou des champs que vous souhaitez valider avec jQuery pour déclencher une demande ajax.
  • Ensuite, vous pouvez utiliser PHP pour valider les données fournies.
  • Et comme dernière étape, vous renvoyez un message d'erreur ou de succès que vous pouvez afficher dans votre backend WordPress.

Oui, cela nécessite quelques petites connaissances de jQuery, mais il n'y a pas d'enregistrement ni d'actualisation de page. Le manuel fournit de très bonnes explications, espérons que cela aide!

0
Fyn

Cela faisait un moment, mais je pensais qu'utiliser wp_die () puis appuyer sur le bouton Précédent afficherait de nouveau la page avec les données du formulaire.

Si tel est le cas, vous pouvez envoyer un message à l'aide de wp_die pour indiquer le problème, éventuellement comment le résoudre, et pour sélectionner le bouton Précédent dans leur navigateur, corrigez le problème, puis réessayez.

Une meilleure façon pourrait être de:

Utilisez le hook pre_post_update, faites votre validation, et ...

  1. Créez une liste de chaque champ non validé, éventuellement avec une explication.
  2. Changer tout ce qui échoue la validation pour qu'elle soit ce qu'elle était avant que l'utilisateur ne la change
  3. Écrivez une entrée méta d'utilisateur personnalisée contenant votre tableau d'erreurs
  4. Laissez les données de poste écrites (vous avez nettoyé les mauvaises données)
  5. Lors de l’affichage du formulaire, saisissez la méta utilisateur créée et utilisez-la pour remplacer les données affichées et fournir des notes sur ce qui ne va pas dans chaque champ.

La cinquième partie pourrait être un peu pénible, mais devrait être faisable en utilisant un filtre ou javascript.

Votre méta utilisateur enregistré pourrait ressembler à ceci:

$meta_value = array(
   'field_name' => array(
      'bad_value' => $users_bad_value,
      'problem' => 'Your data had this problem with it'
   )
);
update_user_meta( $user_id, "_edit_post_problems_{$post_id}", $meta_value );

N'oubliez pas de supprimer les métadonnées après l'avoir lue pendant le chargement de la page.

0
Privateer

L'enregistrement automatique est sur votre chemin.

Comment désactiver correctement REVISIONS et AUTOSAVE pour l'ensemble du site et éventuellement pour un type de publication personnalisé uniquement

(J'aurais simplement laissé un commentaire mais le crédit me manque.)

0
chrisdillon