2013-11-03 28 views
2

我在WordPress中有一堆帖子。這些帖子被稱爲「餐廳」類別。每個帖子已儲存有它像這樣一個自定義元的鍵/值:將WordPress帖子靠近經緯度排序

$post_geocode = get_post_meta($post->ID, 'geocode', true); 
// $post_geocode = '34.0510613,-118.244705' 

你必須登錄到WordPress的使用我的網站,所以每個用戶具有存儲他們的地理編碼,就像這樣:

$user_geocode = get_user_meta($user->ID, 'geocode', true); 
// $user_geocode = '34.043925,-118.2424291' 

因此,我希望能夠獲取帖子並對它們進行排名,以便他們接近用戶的位置。

理想情況下,它會使用WP Query類。但是如果需要,我很樂意改變地理編碼的存儲方式。

最好的答案會是這個樣子:

// This is how I manage the type of restaurant you'll see (eg: Mexican, Italian etc) 
$cat_query = array(
    'taxonomy' => 'category', 
    'field'  => 'slug', 
    'terms'  => $restaurant_category, 
    'operator' => 'IN' 
); 

// Go and get the posts 
$args = array(
    'post_type'   => 'post', 
    'post_status'  => 'publish', 
    'posts_per_page' => -20, 
    'geocode'    => $user_geocode, // WOuld love this to work!!! 
    'orderby'   => 'geocode', // Would love this to work!!! 
    'fields'   => 'ids', 
    'tax_query'   => array(
     'relation'  => 'AND', 
     $cat_query, 
    ) 
);   

$posts = get_posts($args); 

回答

2

如果您保存您的文章數據庫中的數據(你的座標分成兩個領域緯度和logitude),可以使用法律的大地形式餘弦找到點之間的距離。 Reference

COS(d/R)= COS(LAT1)COS(LAT2)COS(long2-long1)+ SIN(LAT1)SIN(LAT2)

凡土的R =半徑( 6367公里,3959英里)

以下SQL查詢將以千米爲單位提供距離,其中$ center_lat & $ center_lng是用戶位置。

$postids=$wpdb->get_col($wpdb->prepare("SELECT name, lat, lng, 
(6367 * acos(cos(radians(%f)) * cos(radians(lat)) * cos(radians(lng) - radians(%f)) + sin(radians(%f)) * sin(radians(lat)))) AS distance FROM mytable HAVING distance < %d ORDER BY distance LIMIT 0 , 5", 
$center_lat,$center_lng,$center_lat,$radius)); 
if ($postids) 
{ 
    foreach ($postids as $id) 
    { 
     echo $id->name; 
     echo $id->distance; 
     //etc 
    } 
} 

查詢是基於代碼我用here但隨着信息修改發現here。我無法訪問WordPress進行檢查。

+0

剛剛通過電子郵件與您聯繫,瞭解如何將其擴展爲插件。 –

0

你肯定會需要以不同的方式存儲你的值。當我做這個我用沿

CREATE TABLE `geo_db` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `post_id` int(11) DEFAULT NULL, 
    `lat` float DEFAULT NULL, 
    `lng` float DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `post_id` (`post_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; 

您還可以使用幾何類型的單個列線桌上的東西,但是這是好的比較地理點。然後,在你的插件,你會修改WP_Query使用

function geo_posts_fields($sql, WP_Query $wp_query){ 
    global $wpdb; 

    // get your user coords here. explode $user_geocode or store in custom db as well. 
    $lat = 45; 
    $lng = -122; 

    if($wp_query->query_vars['orderby'] == 'geocode') 
     $sql .= $wpdb->prepare(", ROUND((3959 * acos(cos(radians(geo_db.lat)) * cos(radians(%f)) 
           * cos(radians(%f) - radians(geo_db.lng)) + sin(radians(geo_db.lat)) 
           * sin(radians(%f)))), 1) AS `distance` ", $lat, $lng, $lat); 

    return $sql; 
} 

function geo_posts_join($sql, WP_Query $wp_query){ 
    global $wpdb; 

    if($wp_query->query_vars['orderby'] == 'geocode') 
     $sql .= " LEFT JOIN geo_db ON $wpdb->posts.ID = geo_db.post_id "; 

    return $sql; 
} 

function geo_posts_orderby($sql, WP_Query $wp_query){ 
    if($wp_query->query_vars['orderby'] == 'geocode') 
     $sql = " `distance` ASC, ".$sql; 

    return $sql; 
} 

function geo_posts_request($sql, WP_Query $wp_query){ 
    // just to see whats going on 
    var_dump($sql); 
    return $sql; 
} 


add_filter('posts_fields', 'geo_posts_fields', 10, 2); 
add_filter('posts_join', 'geo_posts_join', 10, 2); 
add_filter('posts_orderby', 'geo_posts_orderby', 10, 2); 
add_filter('posts_request', 'geo_posts_request', 10, 2); 

最後的SQL,你需要爲了使用排序依據與get_posts參數註冊查詢變種,我建議你做一個新的WP_Query

$geo_posts = new WP_Query(array(
    'post_type' => 'any', 
    'orderby' => 'geocode' 
)); 

while($geo_posts->have_posts()): $geo_post->the_post(); // etc