Skip to content

Instantly share code, notes, and snippets.

@remcotolsma
Created June 8, 2016 08:39
Show Gist options
  • Save remcotolsma/7277b716762e56267a9d293022d8140a to your computer and use it in GitHub Desktop.
Save remcotolsma/7277b716762e56267a9d293022d8140a to your computer and use it in GitHub Desktop.
WordPress custom table with post locations and query to select posts within distance.
<?php
function wkd_sync_location_to_table( $post_id ) {
// Sync locations
global $wpdb;
$location_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->wkd_post_locations WHERE post_id = %d;", $post_id ) );
$format = array(
'post_id' => '%d',
'lat' => '%f',
'lng' => '%f',
);
$data = array(
'post_id' => $post_id,
'lat' => get_post_meta( $post_id, '_wkd_mortician_lat', true ),
'lng' => get_post_meta( $post_id, '_wkd_mortician_lng', true ),
);
if ( $location_id ) {
$result = $wpdb->update( $wpdb->wkd_post_locations, $data, array( 'id' => $location_id ), $format );
} else {
$result = $wpdb->insert( $wpdb->wkd_post_locations, $data, $format );
if ( $result ) {
$location_id = $wpdb->insert_id;
}
}
}
/**
* Posts clauses
*
* http://codex.wordpress.org/WordPress_Query_Vars
* http://codex.wordpress.org/Custom_Queries
*
* @param array $pieces
* @param WP_Query $query
* @return string
*/
function wkd_locations_posts_clauses( $pieces, $query ) {
global $wpdb;
// Fields
$fields = ',
location.id AS location_id,
location.lat AS location_lat,
location.lng AS location_lng
';
// Join
$join = "
LEFT JOIN
$wpdb->wkd_post_locations AS location
ON $wpdb->posts.ID = location.post_id
";
// Order by
$orderby = $pieces['orderby'];
// Location
$latitude = $query->get( 'latitude' );
$longitude = $query->get( 'longitude' );
if ( ! empty( $latitude ) && ! empty( $longitude ) ) {
$radius = 6371; // KM
$latitude1 = $wpdb->prepare( '%f', $latitude );
$latitude2 = 'location.lat';
$longitude1 = $wpdb->prepare( '%f', $longitude );
$longitude2 = 'location.lng';
$d = "$radius * ACOS( COS( RADIANS( $latitude1 ) ) * COS( RADIANS( $latitude2 ) ) * COS( RADIANS( $longitude1 ) - RADIANS( $longitude2 ) ) + SIN( RADIANS( $latitude1 ) ) * SIN( RADIANS( $latitude2 ) ) )";
$fields .= ",
$d AS distance
";
// Where
// @see http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
$distance = $query->get( 'distance' );
if ( ! empty( $distance ) ) {
$pieces['groupby'] .= $wpdb->prepare( ' HAVING distance < %f', $distance );
}
// Order by
$order = $query->get( 'order' );
switch ( $query->get( 'orderby' ) ) {
case 'distance':
$orderby = 'distance ' . $order;
break;
}
}
$pieces['fields'] .= $fields;
$pieces['join'] .= $join;
$pieces['orderby'] = $orderby;
return $pieces;
}
add_filter( 'posts_clauses', 'wkd_locations_posts_clauses', 20, 2 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment