How to Disable Duplicate Post Titles

By default, you can create posts with the same title in WordPress. And as it turned out, it's not so easy to change it. In any case, I could not find a suitable hook for such a task.

Therefore I had to use not quite suitable filter wp_insert_post_empty_content, which, however, perfectly copes with the task.

// Disallow Same Post Title .
add_filter( 'wp_insert_post_empty_content', 'disallow_same_post_title', 10, 2 );

/**
 * Prohibits publish posts with the same title (if such a title
 * already exists for the current post type).
 *
 * The function is designed to be used on a hook:
 *
 *     add_filter( 'wp_insert_post_empty_content', 'disallow_same_post_title', 10, 2 );
 *
 * @param bool  $false
 * @param array $postarr
 *
 * @return bool
 *
 * @author Kama (wp-kama.com)
 */
function disallow_same_post_title( $false, $postarr ){
	global $wpdb;

	// do only for publish post status
	if( $postarr['post_status'] !== 'publish' ){
		return $false;
	}

	$AND = [
		$wpdb->prepare(
			'post_title = %s AND post_type = %s AND post_status = %s',
			$postarr['post_title'], $postarr['post_type'], 'publish'
		)
	];

	// set not post ID if it`s update
	if( ! empty( $postarr['ID'] ) ){
		$AND[] = $wpdb->prepare( "ID != %d", $postarr['ID'] );
	}

	// duplicate post_title
	$dupl_post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE ". implode( ' AND ', $AND ) );

	if( $dupl_post_id ){

		// change error message
		add_filter( 'wp_error_added',
			function( $code, $message, $data, $that ) use ( $dupl_post_id ){
				$code === 'empty_content'
				&& $that->errors[ $code ] = [
					sprintf(
						'Duplicate title! Post with such title already exists: %s',
						get_permalink( $dupl_post_id )
					)
				];
			},
			10, 4
		);

		return true; // stop
	}

	return $false;
}