WordPress ユーザー一覧をカスタムフィールドでソートして取得

WordPress.org 日本語フォーラムで、ユーザー一覧をカスタムフィールドでソートして取得するような内容のトピックが立っていたので、レスしようと調べ、いざ書き込もうとしたら、解決済みになっていた・・・。

せっかく調べたので、ここに記しておきます。

ここでは、カスタムフィールドの名前を「kana」とします。

その1

「kana」でソートした一覧を取得するには、下記のようなコードになります。

$users = get_users( array(
	'orderby' => 'meta_value',
	'order' => 'ASC',
	'meta_key' => 'kana',
) );

ただし、この場合「kana」が設定されていないユーザーは取得されません。

その2

「kana」が設定されているユーザーも含める場合は、下記のようなコードになります。

$users = get_users( array(
	'orderby' => 'meta_value',
	'order' => 'ASC',
	'meta_query' => array(
		'relation' => 'OR',
		array( 'key' => 'kana', 'compare' => 'EXISTS' ),
		array( 'key' => 'kana', 'compare' => 'NOT EXISTS' ),
	)
) );

ただし、これには問題がありまして「kana」が設定されていないユーザーが先頭に来てしまいます。また、クエリーの効率も良くないです。

その3

「kana」が設定されていないユーザーを後方にしたい場合は、下記のようなコードが考えられます。

$users = get_users( array(
	'orderby' => 'meta_value',
	'order' => 'ASC',
	'meta_key' => 'kana',
) );
$users2 = get_users( array(
	'meta_query' => array( array( 'key' => 'kana', 'compare' => 'NOT EXISTS' ) ),
) );
array_splice( $users, count( $users ), 0, $users2 );

これは、ちょっと効率が良くないような気がします。

その4

次は効率を考えて、直接 SQL クエリーを指定して取得してみたいと思います。

$query = "SELECT * FROM {$wpdb->users} a LEFT JOIN {$wpdb->usermeta} b ON b.user_id=a.ID AND b.meta_key = 'kana' ORDER BY b.meta_value IS NULL ASC, b.meta_value ASC";
$users = $wpdb->get_results( $query );

これも問題がありまして、get_users 関数で取得するユーザー情報のオブジェクトとはプロパティが異なるオブジェクトになってしまいます。

最後に

もっとよい方法がありそうなのですが、今回はここまでにしておきます(諦めます?)。

コメント

  • autant38 より:

    記事を拝見させていただきました。
    解りやすくて参考にさせていただいてます。
    今ユーザー一覧を出力する際に、カスタムフィールドで設定した、「ふりがな(yomi)」を利用して、あ行か行さ行に分類できるようにしたいのですが、良い方法はないでしょうか?
    現在は、以下のように設定しております。
    /*————-
    ユーザー数の取得と設定
    ——————–*/
    $total_users = count_users();
    $total_users = $total_users[‘total_users’];
    $paged = get_query_var(‘paged’);
    $number = 20; // 1ページに表示したいユーザー数
    $args = array(
    ‘orderby’=>’meta_value’,
    ‘order’=>’ASC’,
    ‘meta_key’=>’yomi’,
    ‘exclude’ => array(1075,1076),
    ‘offset’ => $paged ? ( ($paged – 1) * $number) : 0,
    ‘number’ => $number,);
    $users = get_users( $args );
    良いご提案あれば、ご教示願います。

    • 石鷹 より:

      こんにちは
      SQL の WHERE 句で “LEFT(meta_value,1) IN (‘あ’,’い’,’う’,’え’,’お’)” のようにすればいいかな(もっといい方法がありそうですが・・・)。
      例)
      $kanas = array(
      ‘あ行’ => ‘"あ","い","う","え","お"’,
      ‘か行’ => ‘"か","き","く","け","こ","が","げ","ぐ","げ","ご"’,
      ‘さ行’ => ‘"さ","し","す","せ","そ","ざ","じ","ず","ぜ","ぞ"’,
      ‘た行’ => ‘"た","ち","つ","て","と","だ","ぢ","づ","で","ど"’,
      ‘な行’ => ‘"な","に","ぬ","ね","の"’,
      ‘は行’ => ‘"は","ひ","ふ","へ","ほ","ば","び","ぶ","べ","ぼ","ぱ","ぴ","ぷ","ぺ","ぽ"’,
      ‘ま行’ => ‘"ま","み","む","め","も"’,
      ‘や行’ => ‘"や","ゆ","よ"’,
      ‘ら行’ => ‘"ら","り","る","れ","ろ"’,
      ‘わ行’ => ‘"わ","を","ん"’
      );

      $user_per_page = 10;
      $paged = get_query_var( ‘paged’) ? get_query_var( ‘paged’, 1 ) : 1;
      $offset = ( $paged – 1 ) * $user_per_page;

      $kana = $kanas[‘ま行’];

      $users = $wpdb->get_results( "
      SELECT *
      FROM {$wpdb->users}
      LEFT JOIN {$wpdb->usermeta} ON user_id=ID AND meta_key=’yomi’
      WHERE LEFT(meta_value,1) IN ({$kana})
      ORDER BY meta_value IS NULL ASC, meta_value ASC
      LIMIT {$offset},{$user_per_page}
      ", OBJECT );

コメントを残す

メールアドレスが公開されることはありません。

日本語でコメントを入力してください。