WordPress不使用插件实现一键复制文章页面功能

这次要实现的功能是在 WordPress 后台的文章列表中,添加一键复制文章的按钮。完整地复制一篇文章,除了要复制文章内容外,还要复制文章所有的分类信息和关联字段,这是复制功能的核心。另外要实现这个功能还要带上一些后台的交互,为了避免不小心点到这个按钮徒增不必要的数据,还需要做个二次确认框,效果是这样的。

WordPress不使用插件实现一键复制文章页面功能
先要通过 post_row_actions 钩子增加一个”Duplicate”按钮(其实是个链接)

function brain1981_duplicate_post_link( $actions, $post ) {
	if (current_user_can('edit_posts')) {
		$actions['duplicate'] = '<a href="###" data-url="'. wp_nonce_url('admin.php?action=brain1981_duplicate_post&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce' ) . '" title="Duplicate it" rel="permalink" class="duplicate-trigger">Duplicate</a>';
	}
	return $actions;
}
add_filter('post_row_actions', 'brain1981_duplicate_post_link', 30, 2 );

点击这个按钮弹出确认框,用 JS 实现,代码通过 admin_footer 钩子插入。

function brain1981_add_duplicate_script() {
	$screen = get_current_screen();
	$parent_base = $screen->parent_base;
	if ( $parent_base=='edit' ) {
		echo '<script>jQuery(function(){jQuery(".duplicate-trigger").on("click",function(){ var url=jQuery(this).data("url"); if(window.confirm("duplicate it?")) location.href=url; })})</script>';
	}
}
add_filter('admin_footer', 'brain1981_add_duplicate_script');

接下来就是核心,复制文章和所有的字段、分类信息

function brain1981_duplicate_post(){
	global $wpdb;
	if ( !( isset($_REQUEST['post']) && isset($_REQUEST['action']) && $_REQUEST['action']=='brain1981_duplicate_post' ) ) {
		wp_die('Error!');
	}
 
	//secure check
	if ( !isset( $_GET['duplicate_nonce'] ) || !wp_verify_nonce( $_GET['duplicate_nonce'], basename( __FILE__ ) ) )
		return;
 
	//需要复制的文章
	$post_id = absint( $_REQUEST['post'] );
	$post = get_post( $post_id );
 
	//指派作者为当前复制者
	$current_user = wp_get_current_user();
	$post_author = $current_user->ID;
 
	//不改变作者
	$post_author=$post->post_author;
 
	if (isset( $post ) && $post != null) {
		//建立文章数据
		$args = array(
			'ping_status'    => $post->ping_status,
			'post_author'    => $post_author,
			'post_content'   => $post->post_content,
			'post_excerpt'   => $post->post_excerpt,
			'post_name'      => $post->post_name,
			'post_parent'    => $post->post_parent,
			'post_password'  => $post->post_password,
			'post_title'     => $post->post_title,
			'post_type'      => $post->post_type,
			'to_ping'        => $post->to_ping,
			'menu_order'     => $post->menu_order,
			'comment_status' => $post->comment_status,
			'post_status'    => 'draft'
		);
		//建立文章
		$new_post_id = wp_insert_post( $args ); 
 
		//复制文章分类数据
		$taxonomyArr = get_object_taxonomies($post->post_type);
		foreach ($taxonomyArr as $taxonomy) {
			$post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
			wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
		}
 
		//SQL查询复制文章自定义字段CPM
		$post_meta_data = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
		if (count($post_meta_data)!=0) {
			$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
			foreach ($post_meta_data as $meta_info) {
				$meta_key = $meta_info->meta_key;
				if( $meta_key == '_wp_old_slug' ) continue;
				$meta_value = addslashes($meta_info->meta_value);
				$sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
			}
			$sql_query.= implode(" UNION ALL ", $sql_query_sel);
			$wpdb->query($sql_query);
		}
 
		//如果有必要,可在复制完成后直接跳转到新的post编辑页面
		wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
		exit;
	} else {
		wp_die('Can not find the original post: ' . $post_id);
	}
}
add_action( 'admin_action_brain1981_duplicate_post', 'brain1981_duplicate_post' );

这样整个功能就完成了,不过目前只能复制文章和自定义文章,如果需要在页面列表也实现同样功能,再增加这个钩子即可:

add_filter('page_row_actions', 'brain1981_duplicate_post_link', 30, 2);

 

(0)
上一篇 2022-04-12 14:44
下一篇 2022-04-13 13:53

相关推荐