扩展WP查询:自定义地理位置元值有效,但TAX_QUERY中断

时间:2016-03-22 作者:Benjamin

我为地理位置搜索建立了一个自定义查询。我正在将每个自定义帖子类型中的lat和lng保存为元值。当lat和lng是唯一的搜索变量时,我的查询扩展成功返回结果。

问题:我还想在查询中添加tax\\u查询,以进一步选择帖子

Class to extend query:

class WP_Query_Geo extends WP_Query {

  function __construct( $args = array() ) {

    if(!empty($args[\'lat\'])) {

      $this->lat = $args[\'lat\'];
      $this->lng = $args[\'lng\'];
      $this->distance = $args[\'distance\'];
      $this->lat_meta_name = $args[ \'lat_meta_name\' ];
      $this->lng_meta_name = $args[ \'lng_meta_name\' ];
      $this->orderby = $args[ \'orderby\' ];
      $this->unit_of_measure = 3959;

      add_filter(\'posts_fields\', array($this, \'posts_fields\'));
      add_filter(\'posts_join\', array($this, \'posts_join\'));
      add_filter(\'posts_where\', array($this, \'posts_where\'));
      add_filter(\'posts_orderby\', array($this, \'posts_orderby\'));

    }

    parent::query($args);

    remove_filter(\'posts_fields\', array($this, \'posts_fields\'));
    remove_filter(\'posts_join\', array($this, \'posts_join\'));
    remove_filter(\'posts_where\', array($this, \'posts_where\'));
    remove_filter(\'posts_orderby\', array($this, \'posts_orderby\'));

  }

  function posts_fields($fields) {
    global $wpdb;
    $fields = $wpdb->prepare(" $wpdb->posts.*, pm1.meta_value, pm2.meta_value,
    ACOS(SIN(RADIANS(%f))*SIN(RADIANS(pm1.meta_value))+COS(RADIANS(%f))*COS(RADIANS(pm1.meta_value))*COS(RADIANS(pm2.meta_value)-RADIANS(%f))) * %d AS distance ", $this->lat, $this->lat, $this->lng, $this->unit_of_measure);
    return $fields;
  }

  function posts_join($join) {
    global $wpdb;
    $join .= " INNER JOIN $wpdb->postmeta pm1 ON ($wpdb->posts.id = pm1.post_id AND pm1.meta_key = \'".$this->lat_meta_name."\')";
    $join .= " INNER JOIN $wpdb->postmeta pm2 ON ($wpdb->posts.id = pm2.post_id AND pm2.meta_key = \'".$this->lng_meta_name."\')";
    return $join;
  }

  function posts_where($where) {
    global $wpdb;
    $where .= $wpdb->prepare(" HAVING distance < %d ", $this->distance);
    return $where;
  }

  function posts_orderby($orderby) {
    if($this->orderby == \'distance\') $orderby = " distance ASC, " . $orderby;
    return $orderby;
  }

}
nbsp;

Query:

$args = array(
    \'post_type\'      => \'custom\',
    \'posts_per_page\' => 15,
    \'post_status\'    => \'publish\',
    \'paged\'          => $page,
    \'orderby\'        => \'distance\',
    \'lat\'            => $lat,
    \'lng\'            => $lng,
    \'distance\'       => $distance,
);

$the_query = new WP_Query_Geo( $args );
nbsp;

以上工作。我一添加税务查询,就会收到一个错误。

Example tax query:

  $tax_query_args = array( \'relation\' => \'AND\' );
  $tax_to_push = array(
      \'taxonomy\' => \'custom-tax\',                
      \'field\'    => \'id\',                    
      \'terms\'    => array(1,2,3),
      \'operator\' => \'IN\'                   
  );
  array_push($tax_query_args, $tax_to_push);
  $args[\'tax_query\'] = $tax_query_args; 
nbsp;

Error Message:

WordPress database error You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'GROUP BY wp_posts.ID ORDER BY distance ASC, wp_posts.post_date DESC LIMIT 0, 15\' at line 4 for query
SELECT SQL_CALC_FOUND_ROWS wp_posts.*, pm1.meta_value, pm2.meta_value,\\n ACOS(SIN(RADIANS(42.407211))*SIN(RADIANS(pm1.meta_value))+COS(RADIANS(42.407211))*COS(RADIANS(pm1.meta_value))*COS(RADIANS(pm2.meta_value)-RADIANS(-71.382437))) * 3959 AS distance
FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_postmeta pm1 ON (wp_posts.id = pm1.post_id AND pm1.meta_key = \'office_lat\')
INNER JOIN wp_postmeta pm2 ON (wp_posts.id = pm2.post_id AND pm2.meta_key = \'office_lng\')
WHERE 1=1
    AND ( \\n wp_term_relationships.term_taxonomy_id IN (26)\\n)
    AND wp_posts.post_type = \'clinicians\'
    AND ((wp_posts.post_status = \'publish\'))
HAVING distance < 50
GROUP BY wp_posts.ID
ORDER BY distance ASC, wp_posts.post_date DESC
LIMIT 0, 15

2 个回复
SO网友:Benjamin

我发现了一个解决方案。我不知道这是否是最好的解决方案,但确实有效。

GROUP BY wp_posts.ID 导致我的查询出错。我不太明白为什么。理论上,我的查询应该返回没有它的重复帖子。。。但事实并非如此。因此,我将实时推送此代码,因为它正在按预期工作。

对于一致性,这是我添加到构造函数中的过滤器和相应函数:

add_filter(\'posts_groupby\', array($this, \'my_posts_groupby\'));

function my_posts_groupby($groupby) {
    global $wpdb;
    $groupby = "";
    return $groupby;
}
有关更多信息,请阅读Filter GROUP BY on WP ORG codex.

SO网友:Arek Mateusiak

找到问题的解决方案。。。WordPress将$groupby放在$where之后,--在您的示例中,它导致了一个MySQL错误,因为GROUP BY在MySQL语法中没有。解决方案是在posts\\U where函数:-)中的$where语句内添加GROUP BY