web-dev-qa-db-fra.com

Interdire le même titre de poste

Je suis à la recherche d'un code pour lequel un membre ne peut pas utiliser le même titre qu'un autre message déjà utilisé ou utilisé.

par exemple, s'il existe un article intitulé "Amazing Australia Tour", il ne devrait pas permettre d'utiliser le même titre pour le même utilisateur ou pour un autre utilisateur.

4
pixelngrain

Code principal

Veuillez vérifier le code auxiliaire après ce bloc

/*
 * Prevent Duplicated Titles
 *
 */

if( is_admin() ) // check if we are in the administrative area
{
    add_action( 'save_post', 'wpse_54258_check_for_duplicate_title', 11, 2 );
    add_action( 'admin_head-post.php', 'wpse_54258_check_for_notice' );
}

/*
 * Checks for more than one post with the same title
 *
 * Adds filter redirect_post_location if duplicate title found
 *
 */

function wpse_54258_check_for_duplicate_title( $post_id, $post )
{
    // HERE, FURTHER FILTERING CAN BE DONE, RESTRICT USERS, POST_TYPES, ETC
    if ( 
        ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        or ! current_user_can( 'edit_post', $post_id )
        or wp_is_post_revision( $post )
        // ADD OTHER FILTERS, LIKE post_type
    )
    { // Noting to do.
        return;
    }

    $termid = get_post_meta($post_id, '_is_dup', true);
    if ( '' != $termid ) 
    {
        // it's a new record
        $count_dups = 0;
        update_post_meta($post_id, '_is_dup', 'new-post-check');
    } 
    else 
    {
        $count_dups = 1;
    }

    // NO CHECKING IS BEING DONE REGARDING UPPER AND LOWERCASES, NOR FOR HTML TAGS
    global $wpdb;
    $title_exists = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = '$post->post_title' AND post_status = 'publish'") );

    if( count($title_exists) > $count_dups ) 
        add_filter('redirect_post_location','wpse_54258_add_error_query_var');
}


/*
 * Removes the previous applied filter and adds error var to the redirect
 *
 */

function wpse_54258_add_error_query_var( $loc ) 
{
    remove_filter( 'redirect_post_location','wpse_54258_add_error_query_var' );
    return add_query_arg( 'duplicated_title', 123, $loc );
}


/*
 * Error checking after saving the post
 *
 */

function wpse_54258_check_for_notice()
{
    if( isset( $_GET['duplicated_title'] ) )
        add_action( 'admin_notices', 'wpse_54258_display_error_message' );
}

/*
 * Actual error message for duplicated post titles
 *
 */
function wpse_54258_display_error_message()
{ ?>
    <div class="error fade">ERROR</div>
    <?php
    remove_action( 'admin_notices', 'wpse_54258_display_error_message' );
}

Code auxiliaire

La méthode utilisée pour vérifier si un nouvel article/une nouvelle page est créé ou non nécessite un post_meta qui doit être appliqué à tous les précédents articles/pages.

/*
 * Update ALL PUBLISHED posts and pages with the controller post_meta required by the main code
 *
 * Important: Run Only Once 
 * -> Paste in functions.php
 * -> Remove the comment to add_action
 * -> Visit any administrative page
 * -> Delete or disable this code
 * 
 */
//add_action('admin_init','wpse_54258_run_only_once');
function wpse_54258_run_only_once()
{   
    global $wpdb;
    $allposts = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_status = 'published'" );
    foreach( $allposts as $pt )
    {
        update_post_meta( $pt->ID, '_is_dup', 'new-post-check');
    }
}

Cette réponse a été assemblée en utilisant:

4
brasofilo

J'ai pu empêcher les mêmes titres de poste avec Ajax. Voici ce que j'ai fait:

sur functions.php

// 1. Enqueue my admin script
function add_my_admin_script(){
    wp_enqueue_script('admin_script', get_template_directory_uri() . '/js/admin_script.js', array('jquery'));
    //
    wp_localize_script( 'admin_script', 'ajax_object',
        array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'we_value' => 1234 ) );
}
add_action('admin_enqueue_scripts', 'add_my_admin_script');   

// 2. The Function to check Post Titles
/************/
// Check Titles
/************/
add_action( 'wp_ajax_my_action', 'my_action_callback' );

function my_action_callback() {
    global $wpdb;
    $title_exists = $wpdb->get_results( 
        "
        SELECT ID
        FROM $wpdb->posts
        WHERE  
            post_title LIKE '" . $_POST['this_convidado_title'] . "'
        AND
            post_type = '" . $_POST['post_type'] .  "'    
        "
    );
    if($_POST['post_ID'] != ""){
        foreach ($title_exists as $key => $this_id) {
            if($_POST['post_ID'] == $this_id->ID){
                $this_is_the_post = $this_id->ID;
            }
        }
    }
    if($this_is_the_post){
        echo (count($title_exists)-1);
    } else {
        echo count($title_exists);
    }
    die();
}

sur mon admin_script.js

jQuery(document).ready(function($) {
    "use strict";
    $( "#title" ).change(function() {
        if($(this).val() !== ""){
            var this_post_id;
            this_post_id = "";
            if($("#post_ID").val()){
                this_post_id = $("#post_ID").val();
            }
            var data = {
                'action': 'my_action',
                'this_convidado_title': $(this).val(),
                'post_type': 'your_post_type',
                'post_ID' : this_post_id
            };
            // We can also pass the url value separately from ajaxurl for front end AJAX implementations
            jQuery.post(ajax_object.ajax_url, data, function(response) {
                if(response > 0){
                    alert('There is a post with this same Title!');
                    $("#title").val("");
                    $("#post").submit();
                    // I do the form#post submission because I could not find the trigger to use the autosave - would be better with the auto save
                    // This is needed to avoid save post drafts with the unwanted title
                }
            });
        }
    });
});   
2
pierrepierre