web-dev-qa-db-ja.com

投稿メタ値として格納されているユーザーIDの表示名でカスタム投稿タイプリストテーブルを並べ替える

domicileという名前のカスタム投稿タイプがあります。各投稿(住所)には owner があります( author はありません)。所有者は、カスタムロールを持つユーザーです。 domicile投稿タイプの投稿メタ値(dmb_owner)としてユーザーIDを格納します。

所有者の表示名でリストテーブル(wp-admin/edit.php?post_type=domicile)を並べ替えるにはどうすればよいですか。

私のクラスの関連コードであるsetup_columns()initで呼び出されます。

/**
 * Manage columns for List Table.
 *
 * @wp-hook init
 * @return void
 */
protected function setup_columns()
{
    add_filter(
        "manage_edit-{$this->post_type}_columns",
        array ( $this, 'set_column_header' )
    );

    add_action(
        "manage_{$this->post_type}_posts_custom_column",
        array ( $this, 'render_columns' ),
        10,
        2
    );

    add_filter(
        "manage_edit-{$this->post_type}_sortable_columns",
        array ( $this, 'set_sortable_columns' )
    );

    add_filter(
        'request',
        array ( $this, 'prepare_orderby' )
    );
}

/**
 * Register column headers.
 *
 * @wp-hook manage_edit-{$this->post_type}_columns
 * @param  array $columns
 * @return array
 */
public function set_column_header( $columns )
{
    unset (
        $columns['author'],
        $columns['comments'],
        $columns['date']
    );
    $columns['owner'] = __( 'Owner', 't5_domicile_manager' );

    return $columns;
}

/**
 * Display cell content.
 *
 * @wp-hook manage_{$this->post_type}_posts_custom_column
 * @param string $column_name
 * @param int $post_id
 * @return void
 */
public function render_columns( $column_name, $post_id = 0 )
{
    if ( 'owner' === $column_name )
    {
        $owner_id = get_post_meta( $post_id, 'dmb_owner', TRUE );
        if ( $owner_id )
        {
            $owner = get_user_by( 'id', $owner_id );
            print $owner ? $owner->display_name : '<i>not set</i>';
        }
    }
}

/**
 * Register sortable columns
 *
 * @wp-hook manage_edit-{$this->post_type}_sortable_columns
 * @param array $columns
 * @return array
 */
public function set_sortable_columns( $columns )
{
    $columns['owner'] = 'owner';
    return $columns;
}

/**
 * Set custom sort order.
 *
 * @wp-hook request
 * @param  array $vars
 * @return array
 */
public function prepare_orderby( $vars )
{
    if ( isset ( $vars['orderby'] ) && 'owner' == $vars['orderby'] )
    {
        $vars = array_merge(
            $vars,
            array (
                'meta_key' => 'dmb_owner',
                'orderby'  => 'meta_value_num'
            )
        );
    }
    return $vars;
}

これはうまくいきますが、保存されたIDでソートされるので、明らかに間違っています。私はクエリをフィルタリングする必要があります - しかし私はそれをどのように正確にやるべきかよくわかりません。

タイトルですみませんが、これが見つかるようにしたいです。私は一生懸命捜したが何も役に立たなかった。

5
fuxia

「簡単」で、あまり良くない解決策は、ユーザーの表示名とIDを保存し、それに従ってソートすることです。明らかに、ユーザーの表示名を更新すると、そのユーザーが所有するすべての住所の更新が促されます。

あるいは、以下は何が機能するかの概要(未テスト)です。これは、WordPressにメタ値でソートするように指示し(WordPressがpostメタテーブルに結合するように)、post_clausesフィルタを使用してusersテーブルを結合し、表示名でソートすることを可能にします。

add_filter('posts_clauses', 'wpse58638_post_clauses',10,2);
function wpse58638_post_clauses( $clauses, $query ) {
    global $wpdb;
    if ( ! $query->is_main_query()
        || ! is_admin()
        || ! $query->get('post_type') == 'domicile'
        || ! $query->get('meta_key') == 'dmb_owner'
        || ! $query->get('orderby') == 'meta_value_num'
    ){
        return $clauses;
    }

    //Get sort order
    $order_dir = $query->get('order');
    $order_dir = ('asc' == $order_dir ? 'ASC' : 'DESC');

    //Join user table onto the postmeta table
    $clauses['join'] .= " LEFT JOIN {$wpdb->users} ON {$wpdb->prefix}postmeta.meta_value={$wpdb->users}.ID";

    //Replace orderby
    $clauses['orderby']  = " {$wpdb->users}.display_name $order_dir";

    return $clauses;
}
7
Stephen Harris

あなたはバックエンドでクエリにカスタムフィールドdmb_ownerを追加することができます、そしてあなたはあなたの標準的なフィルタでこれについてフィルタすることができます。

add_filter( 'query_vars', 'fb_query_vars_admin' );
/**
 * If needed: Allow meta queries in the admin
 */
function fb_query_vars_admin( $query_vars ) {

    // break off, if not in admin area
    if ( ! is_admin() )
        return $query_vars;

    $query_vars[] = 'dmb_owner'; // my key of custom field
    //$query_vars[] = 'meta_value'; // my value of custom field

    return $query_vars;
}

これが$query_vars内のこのカスタムフィールドで、あなたのメソッドprepare_orderby()のように使えるようになりました。

0
bueltge