it-swarm.com.de

Sortieren Sie die Listentabelle für benutzerdefinierte Beitragstypen nach dem Anzeigenamen einer Benutzer-ID, die als Beitrags-Metawert gespeichert ist

Ich habe einen benutzerdefinierten Beitragstyp mit dem Namen domicile. Jeder Beitrag (Domizil) hat einen Eigentümer (nicht den Autor ). Eigentümer sind Benutzer mit einer benutzerdefinierten Rolle. Ich speichere die Benutzer-ID als Post-Meta-Wert (dmb_owner) für den Post-Typ domicile.

Wie sortiere ich die Listentabelle (wp-admin/edit.php?post_type=domicile) nach den Anzeigenamen der Eigentümer?

Der relevante Code aus meiner Klasse setup_columns() heißt 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;
}

Das… funktioniert, ist aber offensichtlich falsch, weil es nach der gespeicherten ID sortiert. Ich muss die Abfrage filtern, bin mir aber nicht sicher, wie genau ich das tun soll.

Entschuldigung für den Titel, aber ich möchte sicherstellen, dass dies gefunden wird. Ich habe sehr intensiv gesucht und nichts brauchbares gefunden.

5
fuxia

Eine 'einfache', aber nicht sehr gute Lösung besteht darin, den Anzeigenamen sowie die ID des Benutzers zu speichern und danach zu sortieren. Offensichtlich würde eine Aktualisierung des Anzeigenamens eines Benutzers eine Aktualisierung des gesamten Domizils des Benutzers veranlassen.

Alternativ ist das Folgende eine Übersicht (ungetestet) dessen, was funktionieren sollte. Die Idee ist, WordPress anzuweisen, weiterhin nach dem Meta-Wert zu sortieren (damit WordPress der Post-Meta-Tabelle beitritt) und dann den post_clauses-Filter zu verwenden, um die users-Tabelle zu verbinden und nach dem Anzeigenamen zu sortieren:

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

Sie können der Abfrage im Backend das benutzerdefinierte Feld dmb_owner hinzufügen und anschließend mit Ihren Standardfiltern danach filtern.

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

Jetzt befindet sich dieses benutzerdefinierte Feld im $query_vars und kann wie Ihre Methode prepare_orderby() verwendet werden.

0
bueltge