您可以使用过滤器posts_orderby
. 举个简单的例子:
add_filter(\'posts_orderby\', \'apply_sql_on_order\', 10, 2 );
function apply_sql_on_order($orderby, $query) {
if(is_array($query->query_vars["orderby"]) && array_key_exists("apply_sql", $query->query_vars["orderby"])) {
$orderby = preg_replace("/(.*) (ASC|DESC)/", $query->query_vars["orderby"]["apply_sql"] . "($1) $2", $orderby);
}
return $orderby;
}
$query = new WP_Query( array(
\'meta_query\' => array(
\'state_clause\' => array(
\'key\' => \'state\'
),
),
\'orderby\' => array(
\'state_clause\' => \'DESC\',
"apply_sql" => "LTRIM"
)
) );
会把你从
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 (
wp_postmeta.meta_key = \'state\'
) AND wp_posts.post_type = \'post\' AND (wp_posts.post_status = \'publish\') GROUP BY wp_posts.ID ORDER BY CAST(wp_postmeta.meta_value AS CHAR) DESC LIMIT 0, 10
至
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 (
wp_postmeta.meta_key = \'state\'
) AND wp_posts.post_type = \'post\' AND (wp_posts.post_status = \'publish\') GROUP BY wp_posts.ID ORDER BY LTRIM(CAST(wp_postmeta.meta_value AS CHAR)) DESC LIMIT 0, 10
WP只会忽略orderby数组中的“apply\\u sql”,因为它在这个WP\\u查询的上下文中不是有效的order子句。
这显然是一个非常粗糙的版本,如果在orderby
. 在这种情况下,不进行某种抽象,只让过滤器回调操作SQL可能更容易。
如果您想对此进行扩展,查看源代码可能会有所帮助。大部分魔法都发生在parse_orderby
在WP\\U查询中。您可以创建自己的版本,基本上模仿它,并在旁边添加一些奇特的东西(可能未设置orderby
在查询时使用pre_get_posts
然后将幻想的order子句添加回posts_orderby
).