I am looking for some code where member can’t use the same title as another post already having or used.
e.g if there is a post with title “Amazing Australia Tour” than it should not allow to use the same title to same or other user.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Main Code
Please check the auxiliary code after this block
/*
* 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' );
}
Auxiliary Code
The method used to check if a new post/page is being created or not requires a post_meta that has to be applied to all previous posts/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');
}
}
This answer was assembled using:
- toscho’s answer to this question: Take excerpt of the content of the post and send it as the title to create new post
- Otto’s solution in the link provided by Ana Ban answer here: Passing error/warning messages from a meta box to “admin_notices”
- to solve the moment of creation of a new post/page, a variation of hereswhatidid answer to this question: Check for update vs new post on save_post action
- a good read about
post-new.phpis TheDeadMedic’s answer to this other one: Why does save_post action fire when creating a new post?
Method 2
I’ve been able to prevent same post Titles with Ajax. Here’s what I did:
on 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();
}
on my 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
}
});
}
});
});
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0