Ajouter une validation et la gestion des erreurs lors de la sauvegarde des champs personnalisés?

28

J'ai une fonction qui définit un champ personnalisé sur un type de publication. Dites que le champ est "subhead".

Lorsque la publication est enregistrée, je souhaite valider une entrée et afficher un message d'erreur sur l'écran de modification de la publication si nécessaire. Quelque chose comme:

// Handle post updating
function wpse_update_post_custom_values($post_id, $post) {

    // Do some checking...
    if($_POST['subhead'] != 'value i expect') {

        // Add an error here
        $errors->add('oops', 'There was an error.');

    }

    return $errors;

} 
add_action('save_post','wpse_update_post_custom_values',1,2);

J'essaie de lier ceci à l'action save_post, mais je ne vois pas comment gérer les erreurs. Aucun objet d'erreur ne semble avoir été passé dans la fonction, et si je crée et retourne mon propre objet WP_Error, il n'est pas respecté, quel que soit le mécanisme qui génère des erreurs sur la page de modification.

J'ai actuellement un message d'erreur sur la page à l'intérieur de ma méta-boîte personnalisée, mais ce n'est pas l'idéal. Je préfère avoir une grosse erreur rouge en haut, comme celle que WP affiche normalement.

Des idées?

UPDATE:

Sur la base de la réponse de @Denis, j’ai essayé différentes choses. Le stockage des erreurs en tant que global ne fonctionnait pas, car Wordpress effectue une redirection pendant le processus save_post, ce qui tue le global avant que vous ne puissiez l'afficher.

J'ai fini par les stocker dans un méta-champ. Le problème, c’est que vous devez les effacer, sinon ils ne disparaîtront pas lorsque vous naviguerez sur une autre page. J'ai donc dû ajouter une autre fonction attachée à admin_footer qui efface les erreurs.

Je ne m'attendais pas à ce que la gestion des erreurs pour quelque chose d'aussi courant (mettre à jour les messages) soit aussi maladroite. Est-ce que je manque quelque chose d'évident ou est-ce la meilleure approche?

// Handle post updating
function wpse_5102_update_post_custom_values($post_id, $post) {

    // To keep the errors in
    $errors = false;

    // Do some validation...
    if($_POST['subhead'] != 'value i expect') {

        // Add an error here
        $errors .= 'whoops...there was an error.';

    }

    update_option('my_admin_errors', $errors);

    return;

} 
add_action('save_post','wpse_5102_update_post_custom_values',1,2);


// Display any errors
function wpse_5102_admin_notice_handler() {

    $errors = get_option('my_admin_errors');

    if($errors) {

        echo '<div class="error"><p>' . $errors . '</p></div>';

    }   

}
add_action( 'admin_notices', 'wpse_5102_admin_notice_handler' );


// Clear any errors
function wpse_5102__clear_errors() {

    update_option('my_admin_errors', false);

}
add_action( 'admin_footer', 'wpse_5102_clear_errors' );
    
posée MathSmath 09.12.2010 - 22:57
la source

7 réponses

7

Stockez les erreurs dans votre classe ou dans une classe globale, éventuellement dans une métaphore ou une transitoire, et affichez-les dans les notifications de l'administrateur sur les requêtes POST. WP ne comporte aucun gestionnaire de message flash.

    
réponse donnée Denis de Bernardy 09.12.2010 - 23:02
la source
6

Je suggère d’utiliser des sessions car cela ne créera pas d’effets étranges lorsque deux utilisateurs effectuent des modifications simultanément. Alors voici ce que je fais:

Les sessions ne sont pas démarrées par wordpress. Vous devez donc démarrer une session dans votre plugin, functions.php ou même wp-config. .php:

if (!session_id())
  session_start();

Lorsque vous enregistrez l'article, ajoutez des erreurs et des avis à la session:

function my_save_post($post_id, $post) {
   if($something_went_wrong) {
     //Append error notice if something went wrong
     $_SESSION['my_admin_notices'] .= '<div class="error"><p>This or that went wrong</p></div>';
     return false; //might stop processing here
   }
   if($somthing_to_notice) {  //i.e. successful saving
     //Append notice if something went wrong
     $_SESSION['my_admin_notices'] .= '<div class="updated"><p>Post updated</p></div>';
   }

   return true;
} 
add_action('save_post','my_save_post');

Imprimez les notices et les erreurs, puis nettoyez les messages de la session:

function my_admin_notices(){
  if(!empty($_SESSION['my_admin_notices'])) print  $_SESSION['my_admin_notices'];
  unset ($_SESSION['my_admin_notices']);
}
add_action( 'admin_notices', 'my_admin_notices' );
    
réponse donnée davidn 14.06.2011 - 12:36
la source
5

Basé sur les pospi suggestion pour utiliser transitoires , je suis venu avec ce qui suit. Le seul problème est qu’il n’ya pas de crochet pour placer le message en dessous du h2 où les autres messages vont, alors j’ai dû faire un bidouillage jQuery pour le faire arriver.

Tout d’abord, enregistrez le message d’erreur dans votre gestionnaire save_post (ou similaire). Je lui donne une courte durée de vie de 60 secondes, il est donc suffisamment long pour que la redirection se produise.

if($has_error)
{
  set_transient( "acme_plugin_error_msg_$post_id", $error_msg, 60 );
}

Ensuite, récupérez ce message d'erreur au prochain chargement de la page et affichez-le. Je le supprime également pour qu'il ne s'affiche pas deux fois.

add_action('admin_notices', 'acme_plugin_show_messages');

function acme_plugin_show_messages()
{
  global $post;
  if ( false !== ( $msg = get_transient( "acme_plugin_error_msg_{$post->ID}" ) ) && $msg) {
    delete_transient( "acme_plugin_error_msg_{$post->ID}" );
    echo "<div id=\"acme-plugin-message\" class=\"error below-h2\"><p>$msg</p></div>";
  }
}

Étant donné que admin_notices est déclenché avant que le contenu de la page principale ne soit généré, la notification n'indique pas où vont les autres messages post-édition. J'ai donc dû utiliser ce jQuery pour le déplacer ici:

jQuery('h2').after(jQuery('#acme-plugin-message'));

Etant donné que l'ID de publication fait partie du nom temporaire, cela devrait fonctionner dans la plupart des environnements multi-utilisateurs, sauf lorsque plusieurs utilisateurs modifient simultanément la même publication.

    
réponse donnée Joshua Coady 15.09.2012 - 23:55
la source
1

Pourquoi ne validez-vous pas votre champ à l'aide de Javascript? Je pense que ce serait la meilleure approche pour cela.

    
réponse donnée Horttcore 10.12.2010 - 09:10
la source
1

En essayant d’utiliser le script ci-dessus, j’ai rencontré un problème étrange. Deux messages sont affichés sur l'écran d'édition après la mise à jour. L'un montre l'état du contenu de la sauvegarde précédente et un autre du courant. Par exemple, si je sauvegarde correctement le message et commets ensuite une erreur, le premier est "erreur" et le second est "ok" - bien qu'ils soient générés dans le même temps. Si je modifie le script et que je n’ajoute qu’un seul message (par exemple, "erreur"), lancez une mise à jour avec "erreur", puis une autre avec "ok", le message "erreur" reste (s’affiche pour la deuxième fois). Je dois économiser avec "ok" encore une fois pour m'en débarrasser. Je ne sais vraiment pas ce qui ne va pas, je l'ai testé sur trois serveurs locaux différents et le même problème se pose. Si quelqu'un a une idée ou une suggestion, aidez-nous!

    
réponse donnée jlub 08.09.2011 - 18:57
la source
1

Lorsque save_post est exécuté, la publication a déjà été enregistrée dans la base de données.

En examinant le code principal de WordPress, plus particulièrement la fonction wp-includes/post.php de update_post() , il n’existe aucun moyen intégré d’intercepter une demande avant son enregistrement dans la base de données.

Cependant, nous pouvons accrocher pre_post_update et utiliser header() et get_post_edit_link() pour empêcher la publication de la publication.

<?php

/**
*   Performs custom validation on custom post type "Site"
*/
function custom_post_site_save($post_id, $post_data) {
    # If this is just a revision, don't do anything.
    if (wp_is_post_revision($post_id))
        return;

    if ($post_data['post_type'] == 'site') {
        # In this example, we will deny post titles with less than 5 characters
        if (strlen($post_data['post_title'] < 5)) {
            # Add a notification
            update_option('my_notifications', json_encode(array('error', 'Post title can\'t be less than 5 characters.')));
            # And redirect
            header('Location: '.get_edit_post_link($post_id, 'redirect'));
            exit;
        }
    }
}
add_action( 'pre_post_update', 'custom_post_site_save', 10, 2);

/**
*   Shows custom notifications on wordpress admin panel
*/
function my_notification() {
    $notifications = get_option('my_notifications');

    if (!empty($notifications)) {
        $notifications = json_decode($notifications);
        #notifications[0] = (string) Type of notification: error, updated or update-nag
        #notifications[1] = (string) Message
        #notifications[2] = (boolean) is_dismissible?
        switch ($notifications[0]) {
            case 'error': # red
            case 'updated': # green
            case 'update-nag': # ?
                $class = $notifications[0];
                break;
            default:
                # Defaults to error just in case
                $class = 'error';
                break;
        }

        $is_dismissable = '';
        if (isset($notifications[2]) && $notifications[2] == true)
            $is_dismissable = 'is_dismissable';

        echo '<div class="'.$class.' notice '.$is_dismissable.'">';
           echo '<p>'.$notifications[1].'</p>';
        echo '</div>';

        # Let's reset the notification
        update_option('my_notifications', false);
    }
}
add_action( 'admin_notices', 'my_notification' );
    
réponse donnée Lucas Bustamante 29.07.2018 - 23:54
la source
0

J'ai écrit un plug-in qui ajoute une gestion des erreurs flash pour les écrans de post-édition et empêche la publication de posts tant que les champs requis ne sont pas renseignés:

enlace

Il vous permet de rendre obligatoires les champs de publication, mais vous pouvez utiliser l'API fournie pour créer des champs personnalisés obligatoires avec un message d'erreur personnalisable et une fonction de validation. Il vérifie par défaut si le champ est vide ou non.

    
réponse donnée sanchothefat 19.11.2012 - 11:00
la source

Lire d'autres questions sur les étiquettes