You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改WP Job Manager搜索结果排序:按地点距离由近到远

解决WP Job Manager搜索结果按距离由近到远排序的问题

要实现按距离搜索地点由近到远排序,我们需要结合Google Geocoding API转换地址为经纬度,再用Haversine公式计算职位与搜索地点的距离,最后修改查询排序逻辑。以下是具体步骤:

前提准备

确保你的WP Job Manager已经配置了Google Maps API,并且每个职位都存储了地理坐标元数据:

  • _geolocation_lat:职位纬度
  • _geolocation_lng:职位经度
    如果还没配置,先在WP Job Manager设置中填入你的Google API密钥,确保地理定位功能正常工作。

修改get_job_listings函数逻辑

基于你提供的代码,我们需要添加距离计算和排序的逻辑:

1. 获取搜索地点的经纬度并过滤有效职位

在处理search_location的代码块中,先调用Google Geocoding API把搜索地址转换为经纬度,同时过滤掉没有地理坐标的职位:

if ( ! empty( $args['search_location'] ) ) {
    // 获取搜索地点的经纬度
    $api_key = '你的Google API密钥'; // 替换成实际密钥
    $geocode_url = "https://maps.googleapis.com/maps/api/geocode/json?address=" . urlencode( $args['search_location'] ) . "&key=" . $api_key;
    $geocode_response = wp_remote_get( $geocode_url );
    
    $search_lat = $search_lng = null;
    if ( ! is_wp_error( $geocode_response ) ) {
        $geocode_data = json_decode( wp_remote_retrieve_body( $geocode_response ), true );
        if ( isset( $geocode_data['status'] ) && $geocode_data['status'] === 'OK' ) {
            $search_lat = $geocode_data['results'][0]['geometry']['location']['lat'];
            $search_lng = $geocode_data['results'][0]['geometry']['location']['lng'];
        }
    }

    // 原有的地点搜索逻辑
    $location_meta_keys = array( 'geolocation_formatted_address', '_job_location', 'geolocation_state_long' );
    $location_search = array( 'relation' => 'OR' );
    foreach ( $location_meta_keys as $meta_key ) {
        $location_search[] = array(
            'key' => $meta_key,
            'value' => $args['search_location'],
            'compare' => 'like'
        );
    }
    // 添加过滤:只保留有地理坐标的职位,避免计算错误
    $location_search[] = array( 'key' => '_geolocation_lat', 'compare' => 'EXISTS' );
    $location_search[] = array( 'key' => '_geolocation_lng', 'compare' => 'EXISTS' );
    
    $query_args['meta_query'][] = $location_search;

    // 如果成功获取到经纬度,添加距离排序过滤器
    if ( isset( $search_lat ) && isset( $search_lng ) ) {
        // 传递坐标到过滤器
        global $current_search_coords;
        $current_search_coords = array( 'lat' => $search_lat, 'lng' => $search_lng );

        add_filter( 'posts_join', 'job_manager_add_distance_join' );
        add_filter( 'posts_orderby', 'job_manager_add_distance_orderby', 10, 2 );
    }
}

2. 定义距离计算的过滤器函数

在函数外部(比如主题的functions.php或者自定义插件中)添加以下两个过滤器函数,用来修改SQL查询的JOIN和ORDER BY部分:

function job_manager_add_distance_join( $join ) {
    global $wpdb;
    // 关联纬度和经度的元数据表
    $join .= " LEFT JOIN {$wpdb->postmeta} AS lat_meta ON {$wpdb->posts}.ID = lat_meta.post_id AND lat_meta.meta_key = '_geolocation_lat' ";
    $join .= " LEFT JOIN {$wpdb->postmeta} AS lng_meta ON {$wpdb->posts}.ID = lng_meta.post_id AND lng_meta.meta_key = '_geolocation_lng' ";
    return $join;
}

function job_manager_add_distance_orderby( $orderby, $query ) {
    global $wpdb, $current_search_coords;
    
    if ( ! isset( $current_search_coords ) ) {
        return $orderby;
    }

    $search_lat = $current_search_coords['lat'];
    $search_lng = $current_search_coords['lng'];

    // 使用Haversine公式计算距离(单位:公里,若要英里替换6371为3959)
    $distance_calc = "(((acos(sin((" . $search_lat . "*pi()/180)) * sin((lat_meta.meta_value*pi()/180)) + cos((" . $search_lat . "*pi()/180)) * cos((lat_meta.meta_value*pi()/180)) * cos(((" . $search_lng . " - lng_meta.meta_value)*pi()/180)))) * 180/pi()) * 60 * 1.1515 * 1.60934)";

    // 设置按距离升序排序(由近到远),保留原排序作为 fallback
    $orderby = $distance_calc . " ASC, " . $orderby;

    // 用完后移除过滤器,避免影响其他查询
    remove_filter( 'posts_join', 'job_manager_add_distance_join' );
    remove_filter( 'posts_orderby', 'job_manager_add_distance_orderby', 10, 2 );

    return $orderby;
}

3. 调整默认排序参数

在wp_parse_args之后添加逻辑,确保有搜索地点时优先按距离排序:

// 如果有搜索地点,覆盖默认排序规则
if ( ! empty( $args['search_location'] ) ) {
    $args['orderby'] = 'distance';
    $args['order'] = 'ASC';
}

注意事项

  • API密钥权限:确保你的Google API密钥启用了Geocoding API,并且设置了正确的域名限制,避免被滥用。
  • 性能优化:如果职位数量较多,建议给_geolocation_lat和_geolocation_lng元字段添加数据库索引,提升查询速度。
  • 错误处理:代码中已经加入了基础的错误处理(比如API请求失败的情况),你可以根据需要扩展,比如提示用户无法获取地点坐标。

内容的提问来源于stack exchange,提问作者user246750

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:42:17