問題描述
我需要排序 (自定義)2 個自定義字段值的帖子…
自定義字段名稱 1:is_sponsored [值可以是 1 或 0]
自定義字段名稱 2:sfp_date [timestamp aka 當前發佈日期以秒為單位]
「is_sponsored」 值為 1 的帖子需要在頂部,按 DESC 的 「sfp_date」 的順序排列。 「is_sponsored」 值為 0 的所有其他帖子都應按照降序 (由 「sfp_date」) 列出。
我有這樣的東西:
$sfp_query_args = array(
'tax_query' => array(
array(
'taxonomy' => 'sfp_posts',
'terms' => array( 1, 5, 8 )
)
),
'post_type' => 'sfpposts',
'post_status' => 'publish',
'showposts' => 15,
'paged' => $paged,
'meta_key' => 'sfp_date',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
'key' => 'is_sponsored',
'value' => 2,
'type' => 'NUMERIC',
'compare' => '<='
)
);
$wp_q = new WP_Query( $sfp_query_args );
… 但不工作有任何想法嗎?
編輯注意:這是一個小插件,應該顯示查詢的外觀,因為我們可能沒有可用的數據集來測試。
<?php
/** Plugin Name: (#67600) Dump Query parts */
function wpse67600_dump_query_parts( $pieces )
{
echo '<pre>'.var_export( $pieces, true ).'</pre>';
return $pieces;
}
add_filter( 'posts_clauses', 'wpse67600_dump_query_parts' );
OP 請添加此處的插入輸出 – 使用”edit” 鏈接。
Dameer 編輯
好的,跟蹤請求和許多解決方法後,我已經提出了以下內容:
如果我簡化了”$sfp_query_args”,結果是接近所需要的,但是,無法排序帖子保持原樣。這裏是:
$sfp_query_args1 = array(
'tax_query' => array( array( 'taxonomy' => 'sfp_post_category', 'terms' => $cat_id_arr ) ),
'post_type' => 'sfpposts',
'post_status' => 'publish',
'showposts' => (int)$per_page,
'paged' => $paged,
'meta_key' => 'is_sponsored',
'orderby' => 'meta_value date'
);
-
* orderby 有兩個屬性:meta_value 和 date *
所以 $ wpdb-> 請求與查詢中的上述參數如下所示:
SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID
FROM $wpdb->posts
INNER JOIN $wpdb->term_relationships
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
INNER JOIN $wpdb->postmeta
ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE 1=1
AND $wpdb->posts.post_type = 'sfpposts'
AND ($wpdb->posts.post_status = 'publish')
AND ($wpdb->postmeta.meta_key = 'is_sponsored' )
GROUP BY $wpdb->posts.ID
ORDER BY $wpdb->postmeta.meta_value, $wpdb->posts.post_date DESC
LIMIT 0, $per_page
最後,為了能夠通過 meta_value 進行排序,查詢應該只設置一個小的區別:
SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID
FROM $wpdb->posts
INNER JOIN $wpdb->term_relationships
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
INNER JOIN $wpdb->postmeta
ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE 1=1
AND $wpdb->posts.post_type = 'sfpposts'
AND ($wpdb->posts.post_status = 'publish')
AND ($wpdb->postmeta.meta_key = 'is_sponsored' )
GROUP BY $wpdb->posts.ID
ORDER BY $wpdb->postmeta.meta_value [!ORDER MISSING!], $wpdb->posts.post_date DESC
LIMIT 0, $per_page
請發現 [!ORDER MISSING!] 佔位符。我想上面應該解釋問題出在哪裏。
最佳解決方案
好的,最後的解決方法是分割查詢:
$sfp_query_args = array(
'tax_query' => array( array( 'taxonomy' => 'sfp_post_category', 'terms' => $cat_id_arr ) ),
'meta_key' => 'is_sponsored',
'post_type' => 'sfpposts',
'post_status' => 'publish',
'showposts' => (int)$per_page,
'paged' => $paged
);
… 並使用”posts_orderby” 過濾器修改 ORDER 部分:
add_filter( 'posts_orderby', 'sfp_modify_orderby' );
function sfp_modify_orderby( $orderby ) {
if( !is_admin() && is_tax( 'sfp_post_category' ) ) {
global $wpdb;
$orderby = " $wpdb->postmeta.meta_value DESC, $wpdb->posts.post_date DESC ";
}
return $orderby;
}
為了防止’posts_orderby’ 影響任何其他查詢 (側邊欄或頁腳),最可能需要在頁面上的循環之後刪除過濾器。所以這裏有另一個功能放在”functions.php” 中:
function sfp_remove_orderby_filter() {
remove_filter( 'posts_orderby', 'sfp_modify_orderby' );
}
… 並在頁面上使用我們的查詢丟棄過濾器:
if( have_posts() ) : while( have_posts() ) : the_post();
// code
endwhile;
else :
// code
endif;
sfp_remove_orderby_filter();
希望是有道理的!
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。