Skip Navigation

[Resolved] Prevent duplicate post titles from being created

This support ticket is created 5 years, 1 month ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

No supporters are available to work today on Toolset forum. Feel free to create tickets and we will handle it as soon as we are online. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
- 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Asia/Karachi (GMT+05:00)

This topic contains 17 replies, has 2 voices.

Last updated by duongN-3 5 years, 1 month ago.

Assisted by: Waqar.

Author
Posts
#1361045

Tell us what you are trying to do?
Prevent editors from submitting duplicate post titles through Post forms.

Is there any documentation that you are following?
https://toolset.com/forums/topic/check-posted-data-to-avoid-duplicated-entries/#post-589870

Is there a similar example that we can see?
N/A

What is the link to your site?
Not implemented yet

I'm using the below code, but haven't implemented yet.

add_filter('cred_form_validate','func_validate_title',10,2);
function func_validate_title($error_fields, $form_data){

//field data are field values and errors
list($fields,$errors)=$error_fields;
//uncomment this if you want to print the field values
//print_r($fields);
//validate if specific form

if ($form_data['id']==33531){
$args = array(
'meta_query' => array(
array('key' => 'post_title',
'value' => $_POST['post_title']['timestamp']
)),
'post_type' => 'drama',
'posts_per_page' => -1
);
$posts = get_posts($args);

//check if title value is already on the database
if (count($posts) > 0){
//set error message for my_field
$errors['post_title']='Wrong Value';
}
}

//return result
return array($fields,$errors);
}

#1361079

Hi there,

Thank you for contacting us and I'd be happy to assist.

The code snippet that you've referenced was suggested for a post title saved in a specific format.

For general validation to avoid duplicate post titles, you can simplify that snippet as:
( ref: https://toolset.com/documentation/programmer-reference/cred-api/#cred_form_validate )


add_filter('cred_form_validate','func_validate_title',10,2);
function func_validate_title($error_fields, $form_data){

	//field data are field values and errors
	list($fields,$errors)=$error_fields;
	//uncomment this if you want to print the field values
	//print_r($fields);
	//validate if specific form

	if ($form_data['id']==33531){

		$title = $_POST['post_title'];

		$args = array("post_type" => "drama", "name" => $title);

		$query = get_posts( $args );

		if (count($query) > 0){
		//set error message for my_field
			$errors['post_title']='Wrong Value';
		}
	}

	//return result
	return array($fields,$errors);
}

I hope this helps and For more personalized assistance around custom code, you can also consider hiring a professional from our list of recommended contractors:
https://toolset.com/contractors/

regards,
Waqar

#1361153

Thanks for the updated snippet.
I've tried adding this to my functions.php in my theme and in a separate custom plugin, but it's not working as expected.
To test, I created a "drama" type post from the front-end hidden link, but the post form doesn't show any error.

Can you help?
Thank you.

#1361237

Hi,

Thanks for writing back.

The example code snippet, only checks for the titles of the posts with the status "Published", whereas, on your website, many of the posts are in the "Pending" state.

If your goal is to extend the title check to published and pending both statuses, you can update the line:


$args = array("post_type" => "drama", "name" => $title);

To:


$args = array("post_type" => "drama", "name" => $title, "post_status" => array('publish', 'pending'));

Here is a guide on the WordPress post statuses:
https://wordpress.org/support/article/post-status/

regards,
Waqar

#1361467

Hi Waqar,

I've updated the code to include the above, but it still doesn't solve the problem of errors not showing up on the form.
How can I have the error show up for that specific field?

I'd like to extend this code to include other post types and template IDs as well.
I've edited the code as below, but unsure about what to do with this line for the form data ID:

    if ($form_data['id']==33531){

Updated code:

add_filter('cred_form_validate','func_validate_title',10,2);
function func_validate_title($error_fields, $form_data){
 
    //field data are field values and errors
    list($fields,$errors)=$error_fields;
    //uncomment this if you want to print the field values
    //print_r($fields);
    //validate if specific form
 
    if ($form_data['id']==33531){
 
        $title = $_POST['post_title'];
        $args = array("post_type" => array('drama', 'special', 'movie', 'person', 'fansubber'), "name" => $title, "post_status" => array('publish', 'pending'));
        $query = get_posts( $args );
 
        if (count($query) > 0){
        //set error message for my_field
            $errors['post_title']='This is a dupe! Do not pass go!';
        }
    }
 
    //return result
    return array($fields,$errors);
}

Thank you!

#1361909

Hi,

During troubleshooting, I found a couple of issues with your form and the code snippet:

1. In the "JS editor" tab of the form "Add Drama", I noticed some HTML and shortcode text added, which is not correct.
Screenshot: hidden link

That section should only hold valid scripts and the current text should be removed from there.

2. The code snippet for the title validation is added in the custom plugin file "dramaotaku-plugin/dramaotaku-plugin.php".

But the following line is not commented:


print_r($fields);

Screenshot: hidden link

This line should be removed or commented out, for the form to work properly since it is a dynamic form, set to use AJAX submission.


//print_r($fields);

3. To extend this snippet to work for multiple forms, you can replace the check for a single form ID with an "in_array" function that checks for multiple IDs.
( ref: hidden link )

Current line:


if ($form_data['id']==33531){

Updated line:


$forms_array =  array( 33531, 33533, 33535 );

if (in_array($form_data['id'], $forms_array)) {

regards,
Waqar

#1362275

Hi Waqar,

I've followed your steps, but the content is still being submitted and no error is thrown about a duplicate title.

Here's the code that I have:

/* Validate CRED Forms */
add_filter('cred_form_validate','func_validate_title',10,2);
function func_validate_title($error_fields, $form_data){
 
    //field data are field values and errors
    list($fields,$errors)=$error_fields;
    //uncomment this if you want to print the field values
    //print_r($fields);
    //validate if specific form
 
$forms_array =  array( 33531, 33564, 33555, 33560, 33535 );
if (in_array($form_data['id'], $forms_array)) {
        $title = $_POST['post_title'];
        $args = array("post_type" => "drama", "name" => $title, "post_status" => array('publish', 'pending'));
        $query = get_posts( $args );
        if (count($query) > 0){
        //set error message for my_field
            $errors['post_title']='Duplicate Title! Add another!';
        }
    }
 
    //return result
    return array($fields,$errors);
}
#1362401

Hi,

This is strange that the same code works on my test website, but not on yours.

It seems the issue is something specific to your website and I'll recommend making a complete backup copy of the website and then test this code snippet, with all other non-Toolset plugins and custom code removed/disabled.

To rule out any code conflict from the theme, you can also temporarily switch to a default theme like Twenty Nineteen.

Once this validation snippet works, you can start adding back the removed items, one-by-one.

If the issue still persists, you're welcome to share a clone/snapshot of your website for further investigation.
https://toolset.com/faq/provide-supporters-copy-site/

Please let me know how it goes and your next reply will be private.

regards,
Waqar

#1365189

Hi,

Thank you for sharing these details, but unfortunately, the link to Dropbox files is not complete/correct.

Here is a guide on sharing the files/folders from Dropbox:
hidden link

Note: Your next reply will be private.

regards,
Waqar

#1366045

I can't provide a backup using Duplicator because it just kills my server. Is there another way?

#1366197

Hi,

With your permission, I can try to create and download Duplicator package with minimal settings, directly from your website.

Or if that doesn't work, I can create and download a backup file using the already installed "All-in-One WP Migration" plugin.

Sounds good?

regards,
Waqar

#1366863

Hi Waqar,

I created a backup last night using All-in-One WP Migration. Can I send you a download link to that backup?

Thanks.

#1367075

Hi,

I can download the backup file directly from your website's admin area, so you don't have to share its link.

I'll keep you updated on the progress.

regards,
Waqar

#1367599

Thank you!

#1368925

Hi,

Thank you for waiting, while I performed some further troubleshooting.

I apologize for the confusion since the "name" parameter in the "get_posts" function, checks for the post slugs and not the post title.

This is the reason that the function was not working as expected for all posts.

To make this work, I'll recommend replacing the old code snippet with the new one:


/* Validate CRED Forms */
add_filter('cred_form_validate','func_validate_title',10,2);
function func_validate_title($error_fields, $form_data){
    
    list($fields,$errors)=$error_fields;
    
    $forms_array =  array( 33531, 33564, 33555, 33560, 33535 );

    if (in_array($form_data['id'], $forms_array)) {

        // get the title from the form
        $title = $_POST['post_title'];

        // query to get the posts to compare
        $args = array( "post_type" => "drama", "posts_per_page" => -1, "post_status" => array('publish', 'pending') );
        $query = get_posts( $args );

        if (count($query) > 0){

            //set error message for the title field if a post of the same title exists
            foreach ($query as $post) {
                if (strtolower($post->post_title) == strtolower($title)) {
                    $errors['post_title']='Duplicate Title! Add another!';
                    break; 
                }
            }
        }
    }
 
    //return result
    return array($fields,$errors);
}

This should do the trick.

regards,
Waqar