我已经做了很多研发工作;但在任何地方都找不到合适的答案。如果我需要进行mysql查询,那么这对我来说是一个非常小的任务。但尽管如此,我在WP并没有很好的实践经验,所以对问题的解决感到非常沮丧。
How to sort a wp_query by custom column that I added in wp_posts table.
$args = array(
/*\'base\' => \'%_%\',
\'format\' => \'?paged=%#%\',
\'total\' => 1,
\'current\' => 0,
\'show_all\' => false,
\'end_size\' => 1,
\'mid_size\' => 2,
\'prev_next\' => true,
\'prev_text\' => __(\'« Previous\'),
\'next_text\' => __(\'Next »\'),
\'type\' => \'plain\',
\'add_args\' => false,
\'add_fragment\' => \'\',
\'before_page_number\' => \'\',
\'after_page_number\' => \'\'*/
\'posts_per_page\' => 10,
\'post_type\' => array(\'food\', \'buffets\'),
\'meta_key\' => \'post_priority\',
\'orderby\' => \'meta_value_num\',
\'order\' => \'ASC\'
);
当我尝试使用这个时,实际上是按wp\\U Posteta表订购的
wp_postmeta.meta_value+0表示按Posteta表订购,而不是wp\\U post表
Post_priority is my custom column in wp_post table以下是我得到的查询结果:
"SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
WHERE 1=1 AND ( \\n wp_postmeta.meta_key = \'post_priority\'\\n)
AND wp_posts.post_type IN (\'food\', \'buffets\')
AND (wp_posts.post_status = \'publish\' OR wp_posts.post_author = 2
AND wp_posts.post_status = \'private\')
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value+0
ASC LIMIT 0, 10","posts"
SO网友:LeMike
我已经调查过了你的问题是WP_Query::parse_orderby()
作用用户Otto喜欢指出的是,您喜欢用作订单的所有内容都在那里进行了清理。不幸的是,它没有可以连接的过滤器。是的,如果你能在每个get\\U帖子中花费高昂的加入费用,那么最好使用一些meta\\u字段。如果没有,请记住menu_order
只要您不处理nav_menu_item
职位类型。
无论如何,我找到了两种解决方案,并想在这里分享。有关更多详细信息,请阅读https://wp-includes.org/296/custom-wp_posts-column-sortable/
扩展WP\\u Query最简洁的方法是编写自己的查询类:
<?php
class Enhanced_Post_Table_Query extends \\WP_Query {
/**
* Extend order clause with own columns.
*
* @param string $order_by
*
* @return bool|false|string
*/
protected function parse_orderby( $order_by ) {
$parent_orderby = parent::parse_orderby( $order_by );
if ( $parent_orderby ) {
// WordPress knew what to do => keep it like that
return $parent_orderby;
}
// whitelist some fields we extended
$additional_allowed = array(
\'something\',
);
if ( ! in_array( $order_by, $additional_allowed, true ) ) {
// not allowed column => early exit here
return false;
}
// Default: order by post field.
global $wpdb;
return $wpdb->posts . \'.post_\' . sanitize_key( $order_by );
}
}
现在,您可以使用自定义字段运行查询和排序:
$get_posts = new Enhanced_Post_Table_Query;
$get_posts->query(
array(
\'orderby\' => \'something\'
)
);
延迟筛选以覆盖内容,虽然有点脏,但它可以工作。由于没有直接的过滤器,因此您可以选择一个更晚的过滤器并操作查询(越晚越脏):
<?php
/**
* Add custom wp_posts column for sorting.
*
* @param string $order_clause SQL-Clause for ordering.
* @param WP_Query $query Query object.
*
* @return string Order clause like "wp_posts.post_foo DESC" or similar.
*/
function custom_column_sort_filter( $order_clause, $query ) {
// whitelist some fields we extended
$additional_allowed = array(
\'something\',
);
if (
! in_array(
$query->get(\'orderby\'),
$additional_allowed,
true
)
) {
// unknown column => keep it as before
return $order_clause;
}
global $wpdb;
return $wpdb->posts
. \'.post_\'
. sanitize_key( $query->get(\'orderby\') )
. \' \' . $query->get( \'order\' );
}
add_filter( \'posts_orderby\', \'custom_column_sort_filter\', 10, 2 );
现在,几乎每次调用get\\u posts都会了解您的自定义列:
get_posts(
[
\'orderby\' => \'something\',
// IMPORTANT:
\'suppress_filters\' => false,
]
);
但仅当设置了“suppress\\u filters”时。这应该被每个插件使用。通过preg\\u replace有更多的解决方案,但这些解决方案都很晚了,用REGEXP替换总是肮脏和危险的。
我希望你能做到这一点!