Ordenar tabla de lista de tipos de publicación personalizada por nombre de visualización de un ID de usuario almacenado como valor meta de publicación

4

Tengo un tipo de publicación personalizado llamado domicile . Cada publicación (domicilio) tiene un propietario (no el autor ). Los propietarios son usuarios con un rol personalizado. Almaceno el ID de usuario como un valor meta de publicación ( dmb_owner ) para el tipo de publicación domicile .

¿Cómo ordeno la tabla de la lista ( wp-admin/edit.php?post_type=domicile ) por los nombres para mostrar de los propietarios?

El código relevante de mi clase, setup_columns() se llama en 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;
}

Esto ... funciona, pero obviamente está mal, porque se ordena por la ID almacenada. Tengo que filtrar la consulta, pero no estoy seguro de cómo exactamente debo hacer eso.

Lo siento por el título, pero quiero asegurarme de que se encontrará. Busqué mucho y no encontré nada útil.

    
pregunta fuxia 16.07.2012 - 09:09

2 respuestas

6

Una solución 'fácil' pero no muy buena es almacenar el nombre para mostrar del usuario, así como la identificación, y ordenar por eso. Obviamente, una actualización del nombre de usuario de un usuario solicitará una actualización de todos los domicilios que posee el usuario.

Alternativamente, lo siguiente es un resumen (no probado) de lo que debería funcionar. La idea es decirle a WordPress que ordene por el valor meta aún (de modo que WordPress se una a la tabla meta de publicación) y luego sea posible usar el filtro post_clauses para unirse a la tabla users y ordenar por nombre de visualización:

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;
}
    
respondido por el Stephen Harris 16.07.2012 - 12:26
0

Puedes agregar el campo personalizado dmb_owner a la consulta en el backend y luego puedes filtrar sobre esto con tus filtros estándar.

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

Ahora es este campo personalizado dentro de $query_vars y se puede usar, como su método prepare_orderby() .

    
respondido por el bueltge 16.07.2012 - 10:04

Lea otras preguntas en las etiquetas