web-dev-qa-db-fra.com

Comment puis-je vérifier si la même publication n'a pas été utilisée avant la publication?

Pour un agenda indie rock, j'ai créé des messages d'événement. Avec l'aide de javascript, les valeurs de champs personnalisés (bandes, lieux et informations de date cueillies dans des zones de sélection) sont copiées comme titre de publication lors de la publication ou de la mise à jour du message. . Problème: si un autre utilisateur crée une nouvelle publication en choisissant exactement les mêmes valeurs de champs personnalisés, une autre publication contenant exactement le même slug est créée. Et si deux publications avec le même slug sont créées, elles conduisent toutes les deux à une page d'erreur 404 jusqu'à ce que l'une d'entre elles soit supprimée manuellement. Ma question: existe-t-il un moyen de "valider" le slug de publication en le comparant aux anciens posts de la base de données? Merci de votre aide !

3
Pierre

La méthode Ajax (un peu sale, mais vous pouvez facilement l'améliorer)

Dans votre functions.php (ou dans un plugin, ou partout ailleurs):

function my_ajax_update(){
    if (isset($_POST['title'])){
        global $wpdb;
        $title = esc_sql($_POST['title']);
        if(!$title) return;
        $page = $wpdb->get_results("
            SELECT *
            FROM $wpdb->posts
            WHERE post_title LIKE '$title'
            AND post_type = 'event'
            AND post_status = 'publish'
            LIMIT 1
        ");
        if ($page) echo "This title already exists !";
    }
}
add_action("wp_ajax_check_double_post", "my_ajax_update");

Et quelque part dans votre template metabox (ou chargé via une action):

jQuery(document).ready(function($){
    var the_title = $('#title').val();
    $('#publish').click(function(e){
        e.preventDefault();
        $.post(
            ajaxurl,
            {
                action:"check_double_post",
                title: the_title
            },
            function(data){
                if ((data) != 0) {
                    message = $('<div id="message" class="error below-h2" />').html('<p>Warning, this title already exists!</p>')
                    $('h2').after(message);
                    $('#ajax-loading').hide();
                    $('#publish').removeClass('button-primary-disabled');
                }
                else {
                    $(this).submit();
                }
            }
        );
    });
});
2
Volpeo

Vous seriez surpris de voir à quel point celui-ci est délicat. Le plus proche que je reçois est accroché à l'action save_post. Il semble n'y avoir aucune action à prendre qui empêche la publication de sauvegarder, toutes les actions pour update_post() et write_post() ne semblent pas permettre d'interférence directe; l’option très simple et rapide que j’ai imaginée implique donc de mourir à l’intérieur du crochet. Malgré cela, la publication est enregistrée avec le nom dupliqué, quel que soit notre décès.

function check_post_title( $pid ) {
    $post = get_post( $pid );
    $events = get_posts( 's='.$post->post_title.'&post_type=event' );

    foreach( (array)$events as $event ) {
        if ( $event->ID == $post->ID ) continue;
        if ( $event->post_title == $post->post_title ) die('Oh noes! A post with this title already exits, go back and change it, please.');
    }
}

add_action( 'save_post', 'check_post_title' );

L'action save_post fournit au hook l'ID de publication de la publication enregistrée. Ensuite, les événements sont recherchés à l'aide de l'argument 's', comme vous le feriez à l'aide de la recherche WordPress classique sur vos pages. Les événements sont ensuite itérés et si un message ayant un identifiant autre que le message vérifié est trouvé avec un titre qui correspond à ce message vérifié, il meurt.

Quelque chose de plus utile et moins dépouillé impliquerait un message personnalisé lors de la publication du message.

function check_post_title( $pid ) {
    $post = get_post( $pid );
    $events = get_posts( 's='.$post->post_title.'&post_type=event' );

    foreach( (array)$events as $event ) {
        if ( $event->ID == $post->ID ) continue;
        if ( $event->post_title == $post->post_title ) {
            add_filter( 'redirect_post_location', 'event_exists' );
        }
    }
}

/* Alter the message */
function event_exists( $redirect_url ) {
    $messages = array( 'message=1', 'message=2' );
    return str_replace( $messages, 'message=100', $redirect_url );
}

/* Add a custom event message */
function custom_event_message( $messages ) {
    $messages['post']['100'] = 'Oh noes! An event with this name already exists, so go ahead and pick another.';
    return $messages;
}

add_filter( 'post_updated_messages', 'custom_event_message' );

add_action( 'save_post', 'check_post_title' );

C'est une solution rapide, quelque chose d'encore plus compliqué exigerait peut-être que le message sauvegardé qui vient d'enfreindre la règle de non-duplication des titres ait son titre modifié et réenregistré par la fonction, ce qui le transforme en quelque chose comme 'DUPLICATE!! [le titre ici] 'et changer le statut de la publication pour revenir à' en attente '.

Le message jaune semble être assez subtile et peut ne pas être remarqué par les éditeurs, mourir semble attirer davantage l'attention.

J'espère que cela vous aide et ne vous a pas trop dérouté. Il peut y avoir de meilleures solutions au problème, espérons que quelqu'un viendra nous aider à améliorer la solution. Toutes les idées seront appréciées à ce stade.

1
soulseekah

Au lieu de faire votre propre requête, pourquoi ne pas simplement utiliser la fonction post_exists ()? Il prend le post_title, le contenu et la date (optionnel). Cette fonction ne teste pas le post_type, mais il est rare que vous ayez le même post_title sur votre contenu.

Cordialement, Rahe.

0
Rahe