为了完成这一点,不需要执行高估的查询量。您仍然可以使用only 一个查询,the_posts
过滤器和一些PHP可以根据需要对代码进行排序。
我认为这是我在你的问题中读到的自定义查询,因此我们可以执行以下操作:
首先,我们想介绍一种定制WP_Query
参数,以便我们可以使用该参数作为the_posts
滤器我们将此参数称为nwpse_custom_sort
它的值为true
为了触发过滤器
接下来,我们将使用the_posts
过滤根据自定义字段对帖子进行排序,然后根据自定义字段对这些帖子进行随机排序,最后返回已排序的帖子
虽然代码只是一些注释
该代码未经测试,至少需要PHP 5.4
我用过get_post_meta()
要在使用ACF时返回每篇文章的自定义字段值,可能需要将其调整为使用get_field()
. 我不熟悉ACF,所以您需要对该部分进行排序。尽管如此,逻辑仍将保持不变
请记住,查询自定义字段不会在缓存时产生额外的查询,因此这是一种非常精简、优化的方法,可以实现您的最终目标
这是自定义查询的代码。基本上只需将额外的参数添加到自定义页面模板中的查询参数中
// Run your query normally
$args = [
\'wpse_custom_sort\' => true, // This parameter will trigger or the_posts filter
// Your query args here
];
$q = new WP_Query( $args );
// Your loop as normal
现在,我们将运行过滤器(
这将进入functions.php
或者最好是自定义插件)/**
* Function to flatten a multidimentional array (for later use)
*
* Credit to zdenko
* @link https://gist.github.com/kohnmd/11197713
*/
function flatten_array( $arg )
{
return is_array( $arg )
?
array_reduce( $arg, function ( $c, $a )
{
return array_merge( $c, flatten_array( $a ) );
}, [] )
:
[$arg];
}
// The the_posts filter
add_filter( \'the_posts\', function ( $posts, $q )
{
// First we need remove our filter
remove_filter( current_filter(), __FUNCTION__ );
// Check if our custom parameter is set and is true, if not, bail early
if ( true !== $q->get( \'wpse_custom_sort\' ) )
return $posts;
// Before we do any work, and to avoid WSOD, make sure that the flatten_array function exists
if ( !function_exists( \'flatten_array\' ) )
return $posts;
// Our custom parameter is available and true, lets continue
// Loop through the posts
$major_array = [];
foreach ( $posts as $p ) {
$meta = get_post_meta(
$p->ID,
\'pkg_id\',
true
);
// Bail if we do not have a $meta value, just to be safe
if ( !$meta )
continue;
// Sanitize the value
$meta = filter_var( $meta, FILTER_SANITIZE_STRING );
// Lets build our array
$major_array[$meta][] = $p;
}
// Make sure we have a value for $major_array, if not, bail
if ( !$major_array )
return $posts;
// Lets randomize the posts under each custom field
$sorted = [];
foreach ( $major_array as $field )
$sorted[] = shuffle( $field );
// Lets flatten and return the array of posts
$posts = flatten_array( $sorted );
return array_values( $posts );
}, 10, 2 );