it-swarm.com.de

Ordnen Sie die Beiträge nach Taxonomie und Meta-Wert

Es ist möglich, Posts von Meta Value zu bestellen .

Es ist möglich, Beiträge mit mehr als einem Wert zu bestellen .

Und dank des Codes unten ist es möglich, nach Taxonomie zu bestellen.

Aber wie kann ich den Code unten ändern, um nach Taxonomie UND meta_value zu bestellen?

Zur functions.php hinzugefügt

function orderby_tax_clauses( $clauses, $wp_query ) {
global $wpdb;
$taxonomies = get_taxonomies();
foreach ($taxonomies as $taxonomy) {
    if ( isset( $wp_query->query['orderby'] ) && $taxonomy == $wp_query->query['orderby']     ) {
            $clauses['join'] .=<<<SQL
LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb-    >term_relationships}.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
SQL;
            $clauses['where'] .= " AND (taxonomy = '{$taxonomy}' OR taxonomy IS NULL)";
            $clauses['groupby'] = "object_id";
            $clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
            $clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get('order') ) ) ?     'ASC' : 'DESC';
        }
    }
    return $clauses;
}

    add_filter('posts_clauses', 'orderby_tax_clauses', 10, 2 );

Zur index.php hinzugefügt

<?php $args = array(
'post_type' => 'custom_post_type',
'posts_per_page' => -1,
'meta_key' => '_EventStartDate',
'orderby' => 'taxonomy_cat',
'order' => asc
);
$the_query = new WP_Query( $args );

if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query-    >the_post(); ?>

etc. etc.

Ändern funktioniert nicht

'orderby' => 'taxonomy_cat meta_value',
3
Chris

In Ihrem Code gibt es

if ( isset( $wp_query->query['orderby'] ) && $taxonomy == $wp_query->query['orderby'] 

das lässt deinen code nicht mit mehreren auftragsfeldern funktionieren, denn wenn du das einstellst

'orderby' => 'taxonomy_cat meta_value'

dann ist $taxonomy == $wp_query->query['orderby'] niemals wahr.

Darüber hinaus finde ich, dass die Schleifenbildung aller Taxonomien nur mit dem Ziel, die zu ordnende Taxonomie zu finden, wenig performant und nicht sehr zuverlässig ist.

Deshalb habe ich Ihren Code ein wenig überarbeitet: Wenn Sie eine Taxonomie bestellen möchten, sollte Ihr Argument ungefähr so ​​lauten:

'orderby' => 'taxonomy.taxonomy_cat'

dank des 'taxonomy.' ist die Taxonomie leicht zu erkennen und es besteht keine Notwendigkeit, alle Taxonomien zu durchlaufen.

Danach erlaubt WordPress, nur ein Argument als 'order'-Argument zu übergeben. Wenn Sie also mehrere 'orderby'-Argumente übergeben, kann das Ergebnis nicht das erwartete sein.

Deshalb habe ich Ihren Code bearbeitet, um ein zusätzliches Argument zu akzeptieren: 'ordertax'. Dies ist natürlich optional. Wenn Sie es nicht übergeben, wird das Argument 'order' verwendet. Es wird auch ignoriert, wenn 'orderby' kein Taxonomieargument enthält. Wenn Sie mehrere 'orderby'-Argumente verwenden, ohne 'ordertax' zu übergeben, sind alle Argumente in der Reihenfolge des 'order'-Arguments (oder der Standardeinstellung 'DESC') angeordnet

'orderby' => 'taxonomy.taxonomy_cat meta_value',
'order' => 'ASC'

bedeutet "ORDERBY taxonomy_cat ASC, meta_value ASC" mit

'orderby' => 'taxonomy.taxonomy_cat meta_value',
'ordertax' => 'DESC'
'order' => 'ASC'

bedeutet "ORDERBY taxonomy_cat DESC, meta_value ASC".

Nun hier der Code:

function orderby_tax_clauses( $clauses, $wp_query ) {
  $orderby_arg = $wp_query->get('orderby');
  if ( ! empty( $orderby_arg ) && substr_count( $orderby_arg, 'taxonomy.' ) ) {
    global $wpdb;
    $bytax = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC)";
    $array = explode( ' ', $orderby_arg ); 
    if ( ! isset( $array[1] ) ) {
      $array = array( $bytax, "{$wpdb->posts}.post_date" );
      $taxonomy = str_replace( 'taxonomy.', '', $orderby_arg );
    } else {
      foreach ( $array as $i => $t ) {
        if ( substr_count( $t, 'taxonomy.' ) )  {
          $taxonomy = str_replace( 'taxonomy.', '', $t );
          $array[$i] = $bytax;
        } elseif ( $t === 'meta_value' || $t === 'meta_value_num' ) {
          $cast = ( $t === 'meta_value_num' ) ? 'SIGNED' : 'CHAR';
          $array[$i] = "CAST( {$wpdb->postmeta}.meta_value AS {$cast} )";
        } else {
          $array[$i] = "{$wpdb->posts}.{$t}";
        }
      }
    }
    $order = strtoupper( $wp_query->get('order') ) === 'ASC' ? ' ASC' : ' DESC';
    $ot = strtoupper( $wp_query->get('ordertax') );
    $ordertax = $ot === 'DESC' || $ot === 'ASC' ? " $ot" : " $order";
    $clauses['orderby'] = implode(', ',
      array_map( function($a) use ( $ordertax, $order ) {
        return ( strpos($a, 'GROUP_CONCAT') === 0 ) ? $a . $ordertax : $a . $order;
      }, $array )
    );
    $clauses['join'] .= " LEFT OUTER JOIN {$wpdb->term_relationships} ";
    $clauses['join'] .= "ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id";
    $clauses['join'] .= " LEFT OUTER JOIN {$wpdb->term_taxonomy} ";
    $clauses['join'] .= "USING (term_taxonomy_id)";
    $clauses['join'] .= " LEFT OUTER JOIN {$wpdb->terms} USING (term_id)";
    $clauses['groupby'] = "object_id";
    $clauses['where'] .= " AND (taxonomy = '{$taxonomy}' OR taxonomy IS NULL)";
  }
  return $clauses;
}

Benutze es so:

$args = array(
  'post_type'      => 'custom_post_type',
  'posts_per_page' => -1,
  'meta_key'       => '_EventStartDate',
  'orderby'        => 'taxonomy.taxonomy_cat meta_value',
  'ordertax'       => 'ASC',
  'order'          => 'DESC'
);

add_filter( 'posts_clauses', 'orderby_tax_clauses', 10, 2 );
$the_query = new WP_Query( $args );
remove_filter( 'posts_clauses', 'orderby_tax_clauses', 10, 2 );

Beachten Sie, dass die Verwendung meines Codes (genau wie Ihres) mit einer WP_Query, die eine Taxonomie-Abfrage enthält, Probleme verursachen kann. Aus diesem Grund ist es wichtig, den Filter zu entfernen, nachdem Sie ihn verwendet haben.

4
gmazzap