php WordPress地理产品。取决于ACF的位置元素。替换产品搜索以包括距离查询。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php WordPress地理产品。取决于ACF的位置元素。替换产品搜索以包括距离查询。相关的知识,希望对你有一定的参考价值。

class WP_Query_Geo extends WP_Query {
  private $lat = NULL;
  private $lng = NULL;
  private $distance = NULL;

  /**
   * Constructor - adds necessary filters to extend Query hooks
   */
  public function __construct( $args = array() ) {
    // Extract Latitude
    if(!empty($args['lat'])) {
      $this->lat = $args['lat'];
    }
    // Extract Longitude
    if(!empty($args['lng'])) {
      $this->lng = $args['lng'];
    }
    // Extract Longitude
    if(!empty($args['distance'])) {
      $this->distance = $args['distance'];
    }
    // unset lat/long
    unset($args['lat'], $args['lng'], $args['distance']);

    add_filter('posts_fields', array($this, 'posts_fields'), 10, 2);
    add_filter('posts_join', array($this, 'posts_join'), 10, 2);
    add_filter('posts_where', array($this, 'posts_where'), 10, 2);
    add_filter('posts_orderby', array($this, 'posts_orderby'), 10, 2);
    add_filter('posts_distinct', array($this, 'posts_distinct'), 10, 2);

    parent::query($args);

    // Remove filters so only WP_GeoQuery queries this way
    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'));
    remove_filter('posts_distinct', array($this, 'posts_distinct'));
  }

  /**
   * Return only distinct results
   */
  public function posts_distinct() {
    return "DISTINCT";
  }

  /**
   * Selects the distance from a haversine formula
   */
  public function posts_fields($fields) {
    global $wpdb;
    if(!empty($this->lat) && !empty($this->lng)) {
      $fields .= sprintf(", ( 6371 * acos(
          cos( radians(%s) ) *
          cos( radians( latitude.meta_value ) ) *
          cos( radians( longitude.meta_value ) - radians(%s) ) +
          sin( radians(%s) ) *
          sin( radians( latitude.meta_value ) )
        ) ) AS distance ", $this->lat, $this->lng, $this->lat);
    }
    $fields .= ", latitude.meta_value AS latitude ";
    $fields .= ", longitude.meta_value AS longitude ";
    echo '<pre>FIELDS: ' . $fields . '</pre>';
    return $fields;
  }


  /**
   * Makes joins as necessary in order to select lat/long metadata
   */
  public function posts_join($join, $query) {
    global $wpdb;
    $join .= " INNER JOIN {$wpdb->postmeta} AS latitude ON {$wpdb->posts}.ID = latitude.post_id ";
    $join .= " INNER JOIN {$wpdb->postmeta} AS longitude ON {$wpdb->posts}.ID = longitude.post_id ";
    echo '<pre>JOIN: ' . $join . '</pre>';
    return $join;
  }

  /**
   * Adds where clauses to compliment joins
   */
  public function posts_where($where) {
    $where .= ' AND latitude.meta_key="lat" ';
    $where .= ' AND longitude.meta_key="lng" ';
    if(!empty($this->lat) && !empty($this->lng) && !empty($this->distance)) {
      if(is_numeric($this->distance)) {
        $where .= sprintf(' HAVING distance <= %s ', $this->distance);
      }
    }
    echo '<pre>WHERE: ' . $where . '</pre>';
    return $where;
  }
  
  /**
   * Adds where clauses to compliment joins
   */
  public function posts_orderby($orderby) {
    if(!empty($this->lat) && !empty($this->lng)) {
      $orderby = " distance ASC, " . $orderby;
    }
    return $orderby;
  }

}

// Override product search to include post_meta lat/lng, order by distance (if search provides location)
add_action('pre_get_posts','product_location_search_filter');
function product_location_search_filter( $query ) {
  if ( !is_admin() && is_post_type_archive('product') && $query->is_search ) {
    # How do I get search terms up in dis?
    $args = array(
      'post_type'       => $query->get('post_type') ,
      'posts_per_page'  => 20,
      'fields'          => 'all',
      'lat'             => $_REQUEST['lat'],
      'lng'             => $_REQUEST['lng'],
      'distance'        => $_REQUEST['dist'],
      # UNCOMMENTING THIS MAKES THE SKY FALL. But why?
      #'s' => $_REQUEST['s']
    );

    $geo_query = new WP_Query_Geo( $args );

    # Actually affect search query
    global $wp_query;
    $wp_query = $geo_query;
  }
}

以上是关于php WordPress地理产品。取决于ACF的位置元素。替换产品搜索以包括距离查询。的主要内容,如果未能解决你的问题,请参考以下文章

在 functions.php (WordPress) 中包含 ACF

Wordpress ACF 显示关系问题

php WordPress:在ACF字段中搜索,functions.php

Wordpress ACF php 关系

php 使用ACF,wpfeatherlight和WordPress的砌体网格。

php ACF自定义字段作为WordPress帖子标题