this is my geo_query extension of wp_query:
add_filter( 'posts_fields', 'willy_geo_fields', 10, 2 );
function willy_geo_fields( $fields, $q ) {
if ( isset(
$q->query_vars['geo_query']['latfrom'],
$q->query_vars['geo_query']['lngfrom'],
$q->query_vars['geo_query']['latto'],
$q->query_vars['geo_query']['lngto'],
$q->query_vars['geo_query']['distancefrom'],
$q->query_vars['geo_query']['distanceto']
) ) {
global $wpdb;
$fields .= $wpdb->prepare(", ( 6371 * acos( cos( radians( %f ) )
* cos( radians( metalatfrom.meta_value ) )
* cos( radians( metalngfrom.meta_value ) - radians( %f ) )
+ sin( radians( %f ) )
* sin( radians( metalatfrom.meta_value ) ) ) ) AS distancefrom
, ( 6371 * acos( cos( radians( %f ) )
* cos( radians( metalatto.meta_value ) )
* cos( radians( metalngto.meta_value ) - radians( %f ) )
+ sin( radians( %f ) )
* sin( radians( metalatto.meta_value ) ) ) ) AS distanceto
",
$q->query_vars['geo_query']['latfrom'],
$q->query_vars['geo_query']['lngfrom'],
$q->query_vars['geo_query']['latfrom'],
$q->query_vars['geo_query']['latto'],
$q->query_vars['geo_query']['lngto'],
$q->query_vars['geo_query']['latto'] );
}
return $fields;
}
add_filter( 'posts_join', 'willy_geo_join', 10, 2 );
function willy_geo_join( $join, $q) {
if ( isset(
$q->query_vars['geo_query']['latfrom'],
$q->query_vars['geo_query']['lngfrom'],
$q->query_vars['geo_query']['distancefrom'],
$q->query_vars['geo_query']['lngto'],
$q->query_vars['geo_query']['lngto'],
$q->query_vars['geo_query']['distanceto'] ) ) {
global $wpdb;
$join .= " INNER JOIN $wpdb->postmeta AS metalatfrom ON ( $wpdb->posts.ID = metalatfrom.post_id )";
$join .= " INNER JOIN $wpdb->postmeta AS metalngfrom ON ( $wpdb->posts.ID = metalngfrom.post_id )";
$join .= " INNER JOIN $wpdb->postmeta AS metalatto ON ( $wpdb->posts.ID = metalatto.post_id )";
$join .= " INNER JOIN $wpdb->postmeta AS metalngto ON ( $wpdb->posts.ID = metalngto.post_id )";
}
return $join;
}
add_filter( 'posts_where', 'willy_geo_where', 10, 2 );
function willy_geo_where( $where, $q ) {
if ( isset(
$q->query_vars['geo_query']['latfrom'],
$q->query_vars['geo_query']['lngfrom'],
$q->query_vars['geo_query']['distancefrom'],
$q->query_vars['geo_query']['latto'],
$q->query_vars['geo_query']['lngto'],
$q->query_vars['geo_query']['distanceto'] ) ) {
global $wpdb;
$where .= " AND metalatfrom.meta_key = 'latfrom'";
$where .= " AND metalngfrom.meta_key = 'lngfrom'";
$where .= " AND metalatto.meta_key = 'latto'";
$where .= " AND metalngto.meta_key = 'lngto'";
}
return $where;
}
add_filter( 'posts_groupby', 'willy_geo_distance', 10, 2 );
function willy_geo_distance( $groupby, $q ) {
if ( isset(
$q->query_vars['geo_query']['latfrom'],
$q->query_vars['geo_query']['lngfrom'],
$q->query_vars['geo_query']['distancefrom'],
$q->query_vars['geo_query']['latto'],
$q->query_vars['geo_query']['lngto'],
$q->query_vars['geo_query']['distanceto'] ) ) {
$compare = '<=';
if ( isset( $q->query_vars['geo_query']['compare'] )
&& in_array( $q->query_vars['geo_query']['compare'], array( '<', '<=', '>', '>=' ) ) ) {
$compare = $q->query_vars['geo_query']['compare'];
}
global $wpdb;
$groupby .= $wpdb->prepare( "$wpdb->posts.ID HAVING distancefrom <= %d AND distanceto <= %d ",
$q->query_vars['geo_query']['distancefrom'],
$q->query_vars['geo_query']['distanceto'] );
}
return false;
}
geo_query