WP_USER_QUERY BY META_KEY,即数组

时间:2014-09-26 作者:Christine Cooper

我已设置名为的用户元数据achievements 它是一个包含各种数值的数组。使用WP_User_Query, 我想在此名为points.

以下内容:

$args = array(
    \'order\' => \'DESC\',
    \'orderby\' => \'meta_value_num\',
    \'meta_key\' => \'achievements\',
    \'number\' => $no,
    \'offset\' => $offset
);
。。。如果工作achievements 将是一个数值。如何更改$args 数组以键为目标points 在元数据键内achievements.

运行print_r() 属于achievements 对于用户返回:

Array ( [x1] => 74 [x2] => 383 [x3] => 457 [x4] => 81 [points] => 301 [x5] => 382 [x6] => 12 )

2 个回复
最合适的回答,由SO网友:birgire 整理而成

您可以使用separate 用户元密钥:

x1, ..., x6, points
而不是阵列:

achievements
简化WP_User_Query() 使用,不必将序列化数组作为用户元值处理。

但我想您已经考虑过这种设置,并希望避免;-)

折衷的办法是只移动points 超出achievements 数组转换为一个单独的元密钥。

Update:

当用户数量相对较少时,我们可以使用以下(未经测试的)PHP排序:

$users2points = array();

$args = array(
    \'meta_key\' => \'achievements\',
    \'number\'   => $no,
    \'offset\'   => $offset
);

$users = get_users( $args );

foreach( (array) $users as $user )
{
    $meta = get_user_meta( \'achievements\', $user->ID );
    if( isset( $meta[\'points\'] )
        $users2points[$user->ID] = $meta[\'points\'];
}

asort( $users2points, SORT_NUMERIC );

print_r( $users2points );

Update 2:

下面是另一个更冒险的PHP排序,它将直接在$users 的数组WP_User 对象:

$args = array(
    \'meta_key\' => \'achievements\',
    \'number\'   => $no,
    \'offset\'   => $offset
);

$users = get_users( $args );

foreach( (array) $users as $user )
{
    $meta = get_user_meta( \'achievements\', $user->ID );

    // Here we assume the points values are greater or equal to 0:
    $user->points = ( isset( $meta[\'points\'] ) ?  $meta[\'points\'] : 0;
}

/*
usort( $users, function( $a, $b ) {
    return gmp_cmp( $a->points, $b->points );
});
*/

// The gmp_cmp() might suffer from a memory leak,
// according to some PHP bug reports,
// so let\'s use this instead:    

usort( $users, function( $a, $b ) {
    if( $a->points === $b->points )
        return 0;
    else
        return ( $a->points > $b->points ) ? 1 : -1;
});


print_r( $users );

SO网友:bonger

使用SQL的一种方法是SUBSTRLOCATE 要选择序列化值,请执行以下操作:

function wpse162668_pre_user_query( $query ) {
    if ( ( $orderby = $query->get( \'orderby\' ) ) != \'achievements_points\' ) {
        return $query;
    }
    global $wpdb;

    $order = $query->get( \'order\' );
    $points_str = \'s:6:"points";i:\';
    $query->query_fields .= $wpdb->prepare(
        \', SUBSTR(wp_usermeta.meta_value, LOCATE(%s, wp_usermeta.meta_value) + %d)+0 AS \' . $orderby,
        $points_str, strlen( $points_str )
    );
    $query->query_orderby = \'ORDER BY \' . $orderby . \' \' . $order . \', user_login ASC\';

    return $query;
}
然后更改$args orderby\'orderby\' => \'achievements_points\' 并将get_users 使用过滤器:

add_filter( \'pre_user_query\', \'wpse162668_pre_user_query\', 10, 2 );
$users = get_users( $args );
remove_filter( \'pre_user_query\', \'wpse162668_pre_user_query\', 10 );
转换为整数(+0) works cos MySQL只会忽略尾随的非数字内容。由于将WPAlchemy\\u MetaBox类与repeat group一起使用,我在不同的组合中使用了很多这种方法(在posteta上,而不是在usermeta上),尽管它可能会变得非常混乱。

结束

相关推荐

为什么在home.php中导航时,分页会变成空白页面?

在学习如何从头开始构建WordPress主题时,我在尝试编写home.php. 我遇到的问题是分页。在文章的最后一页之后,它不再停止/禁用按钮,而是启用按钮并单击后加载/page/# 使用index.php 文件,此时仅为<?php get_header(); ?> 和<?php get_footer(); ?>. 我测试过的功能<?php next_posts_link(); ?> 和<?php echo get_next_posts_link(); ?&g