web-dev-qa-db-ja.com

ユーザーIDの配列の順序と一致するようにWP_User_Queryの結果を順序付ける方法

私は自分のデータベースからユーザのリストを取得するためにWP_User_Queryを使っています。特定のユーザーにはincludeパラメーターを使用してのみ表示しています。例えば:

$args = array(
    'include' => array( 1, 3, 5, 99, 61, 24, 12 ),
    'count_total' => true,
    'search' => sanitize_text_field( $_GET['phrase'] )
);

$query = new WP_User_Query( $args );
foreach( $query->results as $user ) {
    echo $user->ID . '<br />';
}

結果は現在user_login順に並べられています。私の目的はincludeパラメータで使用されているユーザーIDで結果を並べることです。たとえば、5人のユーザーが返される場合(ユーザーID 1、5、99、61、および12とします)、次の順序で結果を出力するにはforeachループが必要です。

1
5
99
61
12

注意してくださいクエリが実行された後にusort()を使ってみました(ここで を参照してください )が、実際のクエリ結果を注文する必要があります。クエリの実行後にクエリ結果を並べ替えることはしたくありません。

参照: http://codex.wordpress.org/Class_Reference/WP_User_Query

2
henrywright

更新:

WordPress 4.1以降のWP_User_Queryクラスはそれをサポートします:

'orderby' => 'include'

WordPress 4.7以降では次のものもサポートされています。

'orderby' => 'login__in'

そして

'orderby' => 'nicename__in'

そのため、以下で説明するように、フィルタを介して実装する必要はなくなりました。

前の回答:

これはあなたのために働くのだろうか?

add_action( 'pre_user_query', 'wpse_order_by_include_values' )
$query = new WP_User_Query( $args );
remove_action( 'pre_user_query', 'wpse_order_by_include_values' )

どこで

function wpse_order_by_include_values( $q )
{
    if( isset( $q->query_vars['include'] ) )
    {
        $values = join( ',', $q->query_vars['include'] );
        $q->query_orderby = 'ORDER BY FIELD( ID,' . $values . ' )';         
    }
}

mySQLで FIELD() 関数を使用する。 MySQLのdocページのコメントにここにいくつかの使用例 があります

更新:

より柔軟にするために、このミニプラグインを使用することができます。

/**
 * Support the 'orderby' => '_include' parameter for the WP_User_Query 
 * to order by the values in the include array.
 * 
 * @see http://wordpress.stackexchange.com/a/167095/26350
 */

add_action( 'pre_user_query', function( $q ) {

    if( 
        isset( $q->query_vars['orderby'] )
        && '_include' === $q->query_vars['orderby']
        && isset( $q->query_vars['include'] ) 
        && count( $q->query_vars['include'] ) > 0 
    )
    {
        global $wpdb;
        $users_in = join( ',', array_map( 'absint', $q->query_vars['include'] ) );
        $q->query_orderby = 'ORDER BY FIELD( {$wpdb->users}.ID,' . $users_in . ' )';
    }

});

将来コアがinclude値を使用する場合に備えて、アンダースコアプレフィックス_includeを使用します。 更新:これを調整したので、今ではpost__inクラスのWP_Query順序付けの場合とほぼ同じです。

今、あなたは単に使うことができます:

$args = array(
    'include'     => array( 1, 3, 5, 99, 61, 24, 12 ),
    'count_total' => true,
    'search'      => sanitize_text_field( $_GET['phrase'] )
    'orderby'     => '_include',                               //<-- our new value
);

$query = new WP_User_Query( $args );

include配列で並べる.

5
birgire

上記の答えに提供される1つの代替案は、引数内の'orderby' => 'meta_value'で簡単にソートできるメタ値を持つ列(メタキー)を追加することです。

これは私が各ユーザーにメタ値を追加するために書いた関数です。 $my_order_ids = array( 3, 4, 6, 2, 5 );は、クエリでユーザーをソートする昇順を決定するため、ここに含めます。

function my_order_column() {
// Defines the user IDs to be updated.
// Use the desired order when you define this.
$my_order_ids = array( 3, 4, 6, 2, 5 );

    // Runs only when $my_order_ids has changed by comparing  
    // it to _transient_my_order_column. 
    if (false === get_transient('my_order_column') ||
        get_transient('my_order_column') !== $my_order_ids) {

        // Updates _transient_my_order_column
        set_transient('my_order_column', $my_order_ids);

        // The first user
        $order_id = 1;
        // Add an integer value for each user 
        foreach ($my_order_ids as $user_id) {

        // Sets/updates the value of my_user_order
        update_user_meta( $user_id, 'my_user_order', $order_id );

        // Confirms that the new value of my_user_order matches the 
        // current value of $order_id
        if ( get_user_meta($user_id,  'my_user_order', true ) != $order_id )
            wp_die('An error occurred');

            $order_id++;
        }
    ?><div class="updated">
        <p><?php echo var_dump($my_order_ids) . '<br />Updated!'; ?></p>
    </div><?php
    }
}

add_action( 'admin_notices', 'my_order_column' );

これはforeachループを使用して各ユーザーのmy_user_orderキーに新しい整数値を追加し、毎回1ずつ増やします。あとでソートしたい順に$my_order_idsを定義するだけです。

一時的なものであるため、$my_order_idsの値が変更された場合にのみ更新が実行されます(つまり、ユーザーを1回だけ更新します)。トランジェントが失われた場合に予期せず実行されないようにするために、add_action( 'admin_notices', 'my_order_column' );をコメントアウトすることをお勧めします。

新しいカスタムメタキーとメタ値が設定されたので、クエリをこのように順序付けするために問題なく使用できます。

function my_user_query() {

$args = array(
    'orderby' => 'meta_value',     /***************************************/
    'order' => 'ASC',              /***Added orderby, order and meta_key***/
    'meta_key' => 'my_user_order', /***************************************/
    // Note: 'include' does not affect how output will be ordered. 
    // array( 6, 5, 3, 2, 4 ) would still be ordered by meta_value.
    'include' => array( 3, 4, 6, 2, 5 ),
    'count_total' => true,
    'search' => sanitize_text_field( $_GET['phrase'] )
);

$query = new WP_User_Query( $args );

    ?>
    <div class="updated">
        <p><?php foreach( $query->results as $user ) {
        echo $user->ID . '<br />'; } ?></p>
    </div>
    <?php  wp_reset_query();
}

add_action( 'admin_notices', 'my_user_query' );

上記の例では、次の出力が管理者通知として表示されます。

3
4
6
2
5
1
iyrin