功能概述
在 WordPress 后台发布或更新文章时,系统会自动检查文章标题是否与已发布的文章重复。如果检测到重复标题,系统将阻止文章发布,并将其状态改为“草稿”,同时向管理员显示错误提示。
实现代码
将以下 PHP 代码添加到当前主题的 functions.php 文件末尾即可。
/**
* 发表文章时禁止与已存在的标题相重复
* Modify from Plugin: Duplicate Title Validate
* Description: this plugin help , not allow publish Duplicate Title .
* Author: hasan movahed
* Reviser: INLOJV
* Version: 1.0
* Author URI: http://www.wallfa.com
* Reviser URI: http://www.inlojv.com
*/
// 发表文章页面,前端抓取标题并使用AJAX发送请求
add_action( 'admin_print_footer_scripts', 'duplicate_titles_enqueue_scripts', 100 );
function duplicate_titles_enqueue_scripts() {
?>
prepare(
"SELECT post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = %s AND post_title = %s AND ID != %d",
$post_type,
$title,
$post_id
);
$results = $wpdb->get_results($titles);
if($results) {
echo "". __( '此标题已存在,请换一个标题!' , '' ) ." ";
} else {
echo ''.__( '恭喜,此标题未与其他文章标题重复!' , '').'';
}
die();
}
// 检测后端标题并且避免同名文章更新草稿
add_action( 'publish_post','duplicate_titles_wallfa_bc' ) ;
function duplicate_titles_wallfa_bc( $post ){
global $wpdb ;
$title = sanitize_text_field( $_POST['post_title'] ) ;
$post_id = intval( $post ) ;
$wtitles = $wpdb->prepare(
"SELECT post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'post' AND post_title = %s AND ID != %d",
$title,
$post_id
) ;
$wresults = $wpdb->get_results( $wtitles ) ;
if ( $wresults ){
$wpdb->update( $wpdb->posts, array( 'post_status' => 'draft' ), array( 'ID' => $post ) ) ;
$arr_params = array( 'message' => '10', 'wallfaerror' => '1' ) ;
$location = add_query_arg( $arr_params , get_edit_post_link( $post , 'url' ) ) ;
wp_redirect( $location ) ;
exit ;
}
}
/// 文章提交更新后的提示
add_action( 'admin_notices', 'not_published_error_notice' );
function not_published_error_notice() {
if( isset($_GET['wallfaerror']) && $_GET['wallfaerror'] == 1 ){
?>
代码说明与改进
原始代码存在一些安全性和健壮性问题,已在上方代码中修正:
- SQL 注入防护:原始代码直接将用户输入的标题和 ID 拼接进 SQL 语句,存在严重安全风险。修正后的代码使用
$wpdb->prepare()函数对查询参数进行预处理和转义。 - 数据验证:使用
sanitize_text_field()和intval()函数对从$_POST接收的数据进行清理和验证。 - 条件判断修复:修正了
not_published_error_notice函数中isset()的使用方式,避免潜在的错误。 - 支持自定义文章类型:修正了后端 AJAX 处理函数,使其能够正确处理并查询前端传递的
post_type参数,而不仅仅是默认的“post”类型。
工作原理
- 前端实时检查:在文章编辑页面,当标题输入框 (
#title) 内容发生变化时,通过 AJAX 向后台发送请求,检查标题是否重复,并即时显示结果(绿色为可用,红色为重复)。 - 后端发布拦截:当用户点击“发布”按钮时,
publish_post钩子会触发最终检查。如果发现重复标题,系统会将文章状态强制改为“草稿”,并重定向回编辑页面,同时显示错误通知。 - 错误提示:在文章列表或编辑页面顶部显示醒目的红色错误信息,提醒用户标题重复。
注意事项
- 此功能仅检查已发布(publish)状态的文章标题,草稿、定时发布等状态的文章不会被计入重复检查。
- 代码中包含了禁用自动保存的功能,这可能会影响部分用户的编辑体验。如果不需要,可以移除最后
disable_autosave相关的两行代码。 - 如果您的站点使用了文章别名(slug)作为固定链接的一部分,即使标题重复,也可以通过设置不同的文章别名来发布文章(如错误提示所述)。
- 建议在添加代码前,备份您的
functions.php文件。