如何按自定义字段对“query_posts”函数进行排序,同时通过另一个自定义字段限制帖子

StackOverflow https://stackoverflow.com/questions/4111255

  •  29-09-2019
  •  | 
  •  

我正在使用以下函数查询 WP 中的一系列帖子:

<?php 
$thirtydays = date('Y/m/d', strtotime('+30 days'));
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
query_posts( array( 
    'post_type' => array('post', 'real-estate'), 
    'meta_key' => 'Time          Available', 
    'meta_compare' => '<=', 
    'meta_value' => $thirtydays, 
    'paged' => $paged )); 
?>

这部分工作正常。它基本上会提取我所有的房地产帖子,但只返回“可用时间”为 30 天或更短的结果。

我还需要使用另一个自定义字段“价格”中的数据按从低到高的升序对帖子进行排序。

每当我添加标准时 'orderby' => 'meta_value', 'meta_key' => 'Price' 30 天内不再显示结果。

有什么办法可以将这两者结合起来吗?是否可以添加一个按钮来重新运行查询并按价格、卧室等排序?或者这对 WP 来说太具体了?

有帮助吗?

解决方案

我相信这会提供您想要的您所需要的。这是一个叫做 PostsOrderedByMetaQuery 延伸 WP_Query 并接受新的论点 'orderby_meta_key' 和 'orderby_order':

class PostsOrderedByMetaQuery extends WP_Query {
  var $posts_ordered_by_meta = true;
  var $orderby_order = 'ASC';
  var $orderby_meta_key;
  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    add_filter('posts_orderby',array(&$this,'posts_orderby'),10,2);
    $this->posts_ordered_by_meta = true;
    $this->orderby_meta_key = $args['orderby_meta_key'];
    unset($args['orderby_meta_key']);
    if (!empty($args['orderby_order'])) {
      $this->orderby_order = $args['orderby_order'];
      unset($args['orderby_order']);
    }
    parent::query($args);
  }
  function posts_join($join,$query) {
    if (isset($query->posts_ordered_by_meta)) {
      global $wpdb;
      $join .=<<<SQL
INNER JOIN {$wpdb->postmeta} postmeta_price ON postmeta_price.post_id={$wpdb->posts}.ID
       AND postmeta_price.meta_key='{$this->orderby_meta_key}'
SQL;
    }
    return $join;
  }
  function posts_orderby($orderby,$query) {
    if (isset($query->posts_ordered_by_meta)) {
      global $wpdb;
      $orderby = "postmeta_price.meta_value {$this->orderby_order}";
    }
    return $orderby;
  }
}

你可以这样称呼它:

$thirtydays = date('Y/m/d', strtotime('+30 days'));
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$query = new PostsOrderedByMetaQuery(array(
  'post_type' => array('post', 'real-estate'),
  'meta_key' => 'Time Available',
  'meta_compare' => '<=',
  'meta_value' => $thirtydays,
  'paged' => $paged,
  'orderby_meta_key' => 'Price',
  'orderby_order'    => 'DESC',
));
foreach($query->posts as $post) {
  echo " {$post->post_title}\n";
}

您可以复制 PostsOrderedByMetaQuery 类到你的主题 functions.php 文件,或者您可以在 .php 您可能正在编写的插件的文件。

如果你想快速测试一下我已经发布了 代码的独立版本 到要点,您可以下载并复制到您的网络服务器的根目录 test.php, ,根据您的用例进行修改,然后使用如下 URL 从浏览器请求 http://example.com/test.php.

希望这可以帮助。

-麦克风

附:这个答案是 与我刚刚在 WordPress Answers 上给出的答案非常相似, ,这是 StackOverflow 的姊妹网站,每天都有很多像我这样的 WordPress 爱好者在这里回答问题。你可能想要 也看到那个答案 因为它有更多的解释并且因为你可能想看看 WordPress 答案. 。希望您考虑将您的 WordPress 问题发布到 那里 将来也是吗?

其他提示

因为 'orderby' => 'meta_value' 需要 meta_key, , 和你的 meta_key 已经使用了比较,我认为您无法做到这一点。 meta_key 仅接受单个值,而不接受选项数组。这绝对是一个限制,如果您找不到解决方案,我鼓励您打开请求。

至于重新运行查询的按钮,您只需重新加载页面并传递查询变量即可更改排序。不幸的是,您仍然必须解决问题的第一部分。

更新

您总是可以使用PHP自己对返回的数组进行分类。

另外,不确定您在可用的时间内检查什么,但是您可以注册一个可能有助于您对查询进行自定义的过滤器 add_filter('posts_where', ...); http://codex.wordpress.org/function_reference/query_posts

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top