Trier la table de liste de types de publication personnalisée par nom complet d'un ID utilisateur stocké en tant que valeur de publication

4

J'ai un type de publication personnalisé nommé domicile . Chaque poste (domicile) a un propriétaire (et non l’ auteur ). Les propriétaires sont des utilisateurs dotés d'un rôle personnalisé. Je stocke l'identifiant de l'utilisateur en tant que méta-valeur post ( dmb_owner ) pour le type post domicile .

Comment trier la liste ( wp-admin/edit.php?post_type=domicile ) par les noms d'affichage des propriétaires?

Le code correspondant à ma classe, setup_columns() est appelé le 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;
}

Cela… fonctionne, mais il est évidemment faux, car il effectue le tri en fonction de l'ID stocké. Je dois filtrer la requête - mais je ne sais pas exactement comment je devrais le faire.

Désolé pour le titre, mais je veux m'assurer qu'il sera trouvé. J'ai cherché très fort et je n'ai rien trouvé d'utile.

    
posée fuxia 16.07.2012 - 09:09

2 réponses

6

Une solution 'facile' mais pas très bonne consiste à stocker le nom d'affichage de l'utilisateur ainsi que son identifiant et à les trier. De toute évidence, une mise à jour du nom d'affichage d'un utilisateur entraînerait une mise à jour de tout le domicile de l'utilisateur.

Alternativement, ce qui suit est un aperçu (non testé) de ce qui devrait fonctionner. L'idée est de dire à WordPress de trier la méta-valeur (pour que WordPress rejoigne la table meta), puis d'utiliser le filtre post_clauses pour rejoindre la table users et trier par nom complet:

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;
}
    
réponse donnée Stephen Harris 16.07.2012 - 12:26
0

Vous pouvez ajouter le champ personnalisé dmb_owner à la requête dans le backend, puis filtrer à ce sujet avec vos filtres standard.

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;
}

Ce champ personnalisé se trouve-t-il à l'intérieur du $query_vars et peut être utilisé, comme votre méthode prepare_orderby() .

    
réponse donnée bueltge 16.07.2012 - 10:04

Lire d'autres questions sur les étiquettes