$example = new WP_Query( array(
? ? 'post_type' ? ? ? ?=> 'procedure',
? ? 'posts_per_page' ? => -1,
? ? 'post_status' ? ? ?=> array( 'publish' ),
? ? 'orderby' ? ? ? ? ?=> 'procedure_category',
? ? 'tax_query' => array(
? ? ? ? array(
? ? ? ? ? ? 'taxonomy' => 'procedure_category',
? ? ? ? ? ? 'operator' => 'EXISTS',
? ? ? ? )
? ? )
) );
in mu-plugins
function core_order_by_taxonomy_get_taxonomy( $wp_query ) {
if ( !isset( $wp_query->query_vars['orderby'] ) )
return false;
$orderby = explode( ' ', (string)$wp_query->query_vars['orderby'] );
foreach( get_taxonomies() as $tax ) {
if ( in_array( $tax, $orderby ) )
return $tax;
}
return false;
}
add_filter( 'posts_clauses', 'core_order_by_taxonomy', PHP_INT_MAX, 2);
function core_order_by_taxonomy( $clauses, $wp_query ) {
global $wpdb;
$taxonomy = core_order_by_taxonomy_get_taxonomy( $wp_query );
if ( !$taxonomy )
return $clauses;
$clauses['fields'] .= ', CAST(term_order_meta.meta_value AS UNSIGNED) AS term_order_int';
$clauses['join'] .= <<<SQL
LEFT OUTER JOIN {$wpdb->term_relationships} AS term_order_rel ON {$wpdb->posts}.ID = term_order_rel.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} AS term_order_tax ON term_order_tax.term_id = term_order_rel.term_taxonomy_id
LEFT OUTER JOIN {$wpdb->terms} AS term_order_terms ON term_order_terms.term_id = term_order_tax.term_id
LEFT OUTER JOIN {$wpdb->termmeta} AS term_order_meta ON (term_order_meta.term_id = term_order_terms.term_id AND term_order_meta.meta_key = '_order_{$taxonomy}' )
SQL;
$clauses['where'] .= " AND taxonomy = '{$taxonomy}'";
$clauses['groupby'] = "term_order_rel.object_id";
$clauses['orderby'] = trim( "COALESCE(term_order_int, ~0) ASC, " . $clauses['orderby'], ',');
return $clauses;
}
add_filter( 'the_posts', 'core_order_by_taxonomy_final', 10, 2 );
function core_order_by_taxonomy_final( $posts, $wp_query ) {
$taxonomy = core_order_by_taxonomy_get_taxonomy( $wp_query );
if ( !$taxonomy )
return $posts;
$order_posts = array();
foreach( $posts as $post ) {
$terms = get_the_terms( $post, $taxonomy );
foreach( $terms as $term ) {
$order = get_post_meta( $post->ID, '_order_' . $term->slug, true );
if ( empty( $order ) )
$order = PHP_INT_MAX;
$order_posts[ $term->slug ][] = array( 'order' => $order, 'post' => $post );
}
}
$posts = array();
foreach( $order_posts as $term => $val ) {
usort( $val, fn($a, $b) => $a['order'] <=> $b['order'] );
$order_posts[ $term ] = $val;
}
foreach( $order_posts as $term => $val ) {
foreach( $val as $p ) {
$posts[] = $p['post'];
}
}
return $posts;
}