web-dev-qa-db-fra.com

Comment valider des champs personnalisés dans un type de message personnalisé?

J'ai écrit un plugin qui crée un type d'article personnalisé avec des champs personnalisés. Pour empêcher les utilisateurs d'entrer des informations incorrectes, comment puis-je valider les données?

J'ai supposé que la fonction de hook save_post traiterait la validation de champ, mais je n'arrive pas à trouver un moyen simple d'afficher les erreurs à l'utilisateur.

Existe-t-il une fonction Wordpress intégrée pour cela? Quelle est la technique générale pour accomplir la validation de champ personnalisée?

6
Force Flow

Vous êtes sur la bonne voie. Je teste les champs dans le callback save_post, puis j'utilise admin notices pour afficher les erreurs à l'attention de l'utilisateur lorsqu'un champ ne parvient pas à être validé. Ils apparaissent uniquement dans une zone en surbrillance en haut de la page, tout comme les erreurs/messages générés par WordPress.

Voici un exemple simple de création d'un avis d'administrateur:

function my_admin_notice()
{
    ?>

    <div class="updated">
       <p>Aenean eros ante, porta commodo lacinia.</p>
    </div>

    <?php
}
add_action( 'admin_notices', 'my_admin_notice' );

Ce n'est pas très pratique, cependant. Dans une situation comme celle-ci, vous voulez simplement une fonction à laquelle vous pouvez transmettre un message. Quelque chose comme,

if( $pizza != 'warm' )
    $notices->enqueue( 'Pizza is not warm', 'error' );

Ainsi, vous pouvez écrire cette fonction enqueue() vous-même (avec une fonction permettant d’imprimer les avis), ou vous pouvez inclure une bibliothèque telle que IDAdminNotices .

Voici un exemple de un plugin que j'ai écrit . Cela utilise les fonctions de mise en file d'attente/d'impression de notification intégrées à la classe elle-même, plutôt que d'inclure une bibliothèque externe.

public function saveCustomFields( $postID )
{
    // ...

    if( filter_var( $_POST[ self::PREFIX . 'zIndex'], FILTER_VALIDATE_INT ) === FALSE )
    {
        update_post_meta( $post->ID, self::PREFIX . 'zIndex', 0 );
        $this->enqueueMessage( 'The stacking order has to be an integer.', 'error' );
    }   
    else
        update_post_meta( $post->ID, self::PREFIX . 'zIndex', $_POST[ self::PREFIX . 'zIndex'] );

    // ...
}
add_action( 'save_post',    array( $this, 'saveCustomFields' );
6
Ian Dunn

J'ai écrit un petit plugin qui non seulement valide les champs de saisie sur les types de publication personnalisés, mais supprime également la notification de l'administrateur par défaut, sans utiliser Javascript.

voici une partie du code

/ Filtres de validation

$title = $album->post_title;
if ( ! $title ) {
    $errors['title'] = "The title is required";
}

// if we have errors lets setup some messages
if (! empty($errors)) {

    // we must remove this action or it will loop for ever
    remove_action('save_post', 'album_save_post');

    // save the errors as option
    update_option('album_errors', $errors);

    // Change post from published to draft
    $album->post_status = 'draft';

    // update the post
    wp_update_post( $album );

    // we must add back this action
    add_action('save_post', 'album_save_post');

    // admin_notice is create by a $_GET['message'] with a number that wordpress uses to
    // display the admin message so we will add a filter for replacing default admin message with a redirect
    add_filter( 'redirect_post_location', 'album_post_redirect_filter' );
}

Vous pouvez voir le tutoriel complet ici

4
Kevin Phillips

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

Si vous utilisez ACF, sa validation est intégrée.

Toutefois, si vous devez valider des éléments extérieurs à ACF, tels que post_title, les choses se compliquent un peu.

En examinant le code principal de WordPress, plus particulièrement la fonction update_post() du wp-includes/post.php, 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' );
0
Lucas Bustamante