正如前面所指出的,随机排序和搜索是非常昂贵的操作,所以让我们看看如何对该问题进行排序。
因为您只需要自定义帖子类型中的一个帖子,所以我们只需要一个随机ID,可以传递给get_post()
为了得到想要的职位。我们不会从db中随机获取帖子,而是查询所有自定义帖子类型(或至少所有帖子ID),将其保存到瞬态中,然后我们可以从该选项中选择一个随机ID。
让我们看看一些代码:(这将进入函数。php)
function get_random_id( $post_type = \'\' )
{
$q = [];
// Make sure we have a post type set, check if it exists and sanitize
$post_type = filter_var( $post_type, FILTER_SANITIZE_STRING );
if ( !$post_type )
return $q;
if ( !post_type_exists( $post_type ) )
return $q;
// The post type exist and is valid, lets continue
$transient_name = \'rand_ids_\' . md5( $post_type );
// Get the transient, if we have one already
if ( false === ( $q = get_transient ( $transient_name ) ) ) {
$args = [
\'post_type\' => $post_type,
\'posts_per_page\' => -1,
\'fields\' => \'ids\', // get only post ID\'s
// Add any additional arguments
];
$q = get_posts( $args );
// Set the transient
set_transient( $transient_name, $q, 30*DAY_IN_SECONDS );
} // endif get_transient
return $q;
}
现在,我们已经将所有自定义的post类型ID保存到瞬态中。这将极大地提高性能。过渡期设置为30天,因此我们需要在发布新的自定义帖子类型帖子后立即刷新并重新创建过渡期。
让我们使用transition_post_status
动作挂钩:(这将进入functions.php)
add_action( \'transition_post_status\', function ( $new_status, $old_status, $post )
{
// Make sure we only target our specific post type
if ( \'advertising\' !== $post->post_type )
return;
global $wpdb;
// Delete the transients
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient%_rand_ids_%\')" );
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient_timeout%_rand_ids_%\')" );
// Lets rebuild the transient
get_random_id( $post->post_type );
}, 10, 3 );
我们只剩下从我们的
get_random_id()
函数并将其传递给
get_post()
获取post对象
// Get the array of post ID\'s
$post_type_posts = get_random_id( \'advertising\' );
// Make sure we have posts
if ( $post_type_posts ) {
// Get the post object of the id first in line
shuffle( $post_type_posts );
$single_post = get_post( $post_type_posts[0] );
// Display the post content
}
这样可以节省大量资源,比简单地让SQL从DB中随机选择一篇文章要快得多
例如,您的广告注入器过滤器可以如下所示
add_filter( \'the_content\', \'prefix_insert_post_ads\' );
function prefix_insert_post_ads( $content ) {
// checkbox to show ad, default true
if ( get_field(\'show_advertisement\') ) {
if ( is_single() &&
! is_admin()
) {
// Get the array of post ID\'s
$post_type_posts = get_random_id( \'advertising\' );
// Make sure we have posts
if ( $post_type_posts ) {
// Get the post object of the id first in line
shuffle( $post_type_posts );
$random_ad = get_post( $post_type_posts[0] );
// Display the post content
$link = addhttp( get_field(\'advertisement_link\', $random_ad->ID));
$image = get_field(\'upload_advertisement\', $random_ad->ID);
// get html
$ad_code = \'<a href="\'.$link.\'" target="_blank"><img src="\'.$image.\'" /></a>\';
// show ad after # paragraphs
$show_after = get_field(\'advertisement_show_after\');
// return appended $content
return prefix_insert_after_paragraph( $ad_code, $show_after, $content );
}
}
}
return $content;
}