web-dev-qa-db-ja.com

同じ投稿タイトルを許可しない

私は、メンバーがすでに持っているまたは使った別の投稿と同じタイトルを使うことができないようなコードを探しています。

たとえば、「Amazing Australia Tour」というタイトルの投稿がある場合は、同じユーザーまたは他のユーザーに同じタイトルを使用することは許可されません。

4
pixelngrain

メインコード

このブロックの後の補助コードを確認してください

/*
 * 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' );
}

補助コード

新しい投稿/ページが作成されているかどうかをチェックするために使用される方法は、すべての以前の投稿/ページに適用される必要があるpost_metaを必要とします。

/*
 * 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');
    }
}

この答えは、次のようにまとめられています。

4
brasofilo

私は同じ投稿タイトルをAjaxで防ぐことができました。これが私がしたことです:

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();
}

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