After a short sleepless night with this running through my head, I have a solution that works. I’m not sure if it’s the best solution but for those that may have a similar problem, here’s what I did.
First, I abandoned trying to use the WordPress request
filter for this particular ordering. Instead, I used the WP posts_clauses filter as follows:
add_filter( 'posts_clauses', 'my_posts_clauses_filter', 20, 1 );
function my_posts_clauses_filter( $pieces )
{
global $wpdb;
if ( isset( $_GET[ 'post_type' ] )
and isset( $_GET[ 'orderby' ] )
and 'person' == $_GET[ 'post_type' ]
and 'person_school' == $_GET[ 'orderby' ]
and ( 'ASC' == $_GET[ 'order' ] or 'DESC' == $_GET[ 'order' ] )
)
{
$pieces[ 'join' ] .= " INNER JOIN {$wpdb->postmeta} my_postmeta1 ON ( {$wpdb->posts}.ID = my_postmeta1.post_id AND my_postmeta1.meta_key = 'person-school-id' )";
$pieces[ 'join' ] .= " INNER JOIN {$wpdb->posts} my_posts1 ON ( my_posts1.ID = my_postmeta1.meta_value )";
$pieces[ 'orderby' ] = 'my_posts1.post_title ' . $_GET[ 'order' ];
}
return $pieces;
}
That’s it.
Once note of caution. This could have unintended consequences. I had another routine that used WP_Query to return a list of all schools for filtering. After adding the above posts_clauses
filter, my get all schools routine was not returning anything when the $_GET
entries were set. I got around this by surrounding the WP_Query request with a remove_filter
and add_filter
for the above posts_clauses
filter.