Skip to content

Instantly share code, notes, and snippets.

@wpscholar
Last active September 28, 2024 22:45
Show Gist options
  • Save wpscholar/ef8fe292b469f59aa9dde644b960c690 to your computer and use it in GitHub Desktop.
Save wpscholar/ef8fe292b469f59aa9dde644b960c690 to your computer and use it in GitHub Desktop.
Order WordPress posts based on their taxonomy name.
<?php
use WP_Query;
/**
* Class OrderPostsByTaxonomy
*
* @link https://scribu.net/wordpress/sortable-taxonomy-columns.html
*
* Handles the ordering of posts based on their associated taxonomy.
*/
class OrderPostsByTaxonomy {
/**
* The taxonomy used for ordering posts.
*
* @var string
*/
private $taxonomy;
/**
* Constructor.
*
* @param string $taxonomy The taxonomy to use for ordering posts.
*/
public function __construct( string $taxonomy ) {
$this->taxonomy = $taxonomy;
add_filter( 'posts_clauses', array( $this, 'posts_clauses' ), 10, 2 );
}
/**
* Modifies the SQL query clauses for custom post ordering.
*
* @param array $clauses The list of clauses for the query.
* @param WP_Query $query The WP_Query instance.
* @return array Modified clauses.
*/
public function posts_clauses( array $clauses, WP_Query $query ) {
global $wpdb;
$orderby = $query->get( 'orderby' );
if ( $this->taxonomy === $orderby || ( is_array( $orderby ) && array_key_exists( $this->taxonomy, $orderby ) ) ) {
$prefix = str_replace( array( ' ', '-' ), '_', $this->taxonomy );
$tr = esc_sql( "{$prefix}_term_relationships" );
$tt = esc_sql( "{$prefix}_term_taxonomy" );
$t = esc_sql( "{$prefix}_terms" );
$clauses['join'] .= <<<SQL
LEFT OUTER JOIN {$wpdb->term_relationships} AS {$tr} ON {$wpdb->posts}.ID={$tr}.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} AS {$tt} ON {$tr}.term_taxonomy_id={$tt}.term_taxonomy_id
LEFT OUTER JOIN {$wpdb->terms} AS {$t} ON {$tt}.term_id={$t}.term_id
SQL;
$clauses['where'] .= " AND (taxonomy = '{$this->taxonomy}' OR taxonomy IS NULL)";
$clauses['groupby'] = "{$tr}.object_id";
$clauses['orderby'] = "GROUP_CONCAT({$t}.name ORDER BY name ASC) ";
$clauses['orderby'] .= ( 'ASC' === strtoupper( $query->get( 'order' ) ) ) ? 'ASC' : 'DESC';
}
return $clauses;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment