Extracting Distance from FacetWP Proximity Functio

2019-05-23 07:51发布

I am quite new to Wordpress & Php coding in general, I have a relatively simple theme that I have been working with that contains a custom post type that stores latitude and longitude. Each post is a listing a hotel listing within a directory. The theme I am using also integrates with FacetWP the faceting plugin for WordPress. It is possible for the user to search the site by typing a location of locating themselves, this happens using Googles Mapping functionality. When the search is submitted parameters are passed to an archive page:

http://localhost:8888/wowgoddess/listings/?fwp_location=43.653226%2C-79.38318429999998%2C10%2CToronto%252C%2520ON%252C%2520Canada&fwp_sort=distance

decoded this comes out as:

43.653226,-79.38318429999998,10,Toronto%2C%20ON%2C%20Canada

So form passes the archive the central latitude and longitude as well at the radius (10 miles).

The archive then uses this information to query the post type listings to return nearby locations.

What I really want to do is display the distance of each post from the central location in the archive / post overview page.

This should be possible as the theme has a sort by distance sort option. I just can't work out how to grab the calculated value and echo it in the page body. the php for the proximity function is:

<?php

if ( class_exists( 'FacetWP_Facet_Proximity' ) ) {
return;
}

class FacetWP_Facet_Proximity
{

/**
 * The ordered array of post IDs
 */
public $ordered_posts = array();


/**
 * An array containing each post ID and its distance
 */
public $distance = array();


function __construct() {
    $this->label = __( 'Proximity', 'fwp' );

    add_filter( 'facetwp_index_row', array( $this, 'index_latlng' ), 10, 2 );
    add_filter( 'facetwp_sort_options', array( $this, 'sort_options' ), 1, 2     );
    add_filter( 'facetwp_filtered_post_ids', array( $this, 'sort_by_distance' ), 10, 2 );
}


/**
 * Generate the facet HTML
 */
function render( $params ) {

    $output = '';
    $facet = $params['facet'];
    $value = $params['selected_values'];
    $unit = empty( $facet['unit'] ) ? 'mi' : $facet['unit'];

    $lat = empty( $value[0] ) ? '' : $value[0];
    $lng = empty( $value[1] ) ? '' : $value[1];
    $chosen_radius = empty( $value[2] ) ? '' : $value[2];
    $location_name = empty( $value[3] ) ? '' : urldecode( $value[3] );

    $radius_options = apply_filters( 'facetwp_proximity_radius_options', array( 10, 25, 50, 100, 250 ) );

    ob_start(); ?>
    <input type="text" id="facetwp-location" value="<?php echo $location_name;     ?>" placeholder="<?php _e( 'Enter location', 'fwp' ); ?>" />

    <select id="facetwp-radius">
        <?php foreach ( $radius_options as $radius ) : ?>
        <?php $selected = ( $chosen_radius == $radius ) ? ' selected' : ''; ?>
        <option value="<?php echo $radius; ?>"<?php echo $selected; ?>><?php echo "$radius $unit"; ?></option>
        <?php endforeach; ?>
    </select>

    <div style="display:none">
        <input type="text" class="facetwp-lat" value="<?php echo $lat; ?>" />
        <input type="text" class="facetwp-lng" value="<?php echo $lng; ?>" />
    </div>
<?php
    return ob_get_clean();
}


/**
 * Filter the query based on selected values
 */
function filter_posts( $params ) {
    global $wpdb;

    $facet = $params['facet'];
    $selected_values = $params['selected_values'];
    $unit = empty( $facet['unit'] ) ? 'mi' : $facet['unit'];
    $earth_radius = ( 'mi' == $unit ) ? 3959 : 6371;

    if ( empty( $selected_values ) || empty( $selected_values[0] ) ) {
        return 'continue';
    }

    $lat = (float) $selected_values[0];
    $lng = (float) $selected_values[1];
    $radius = (int) $selected_values[2];

    $sql = "
    SELECT DISTINCT post_id,
    ( $earth_radius * acos( cos( radians( $lat ) ) * cos( radians( facet_value ) ) * cos( radians( facet_display_value ) - radians( $lng ) ) + sin( radians( $lat ) ) * sin( radians( facet_value ) ) ) ) AS distance
    FROM {$wpdb->prefix}facetwp_index
    WHERE facet_name = '{$facet['name']}'
    HAVING distance < $radius
    ORDER BY distance";

    $this->ordered_posts = array();
    $this->distance = array();

    if ( apply_filters( 'facetwp_proximity_store_distance', false ) ) {
        $results = $wpdb->get_results( $sql );
        foreach ( $results as $row ) {
            $this->ordered_posts[] = $row->post_id;
            $this->distance[ $row->post_id ] = $row->distance;
        }
    }
    else {
        $this->ordered_posts = $wpdb->get_col( $sql );
    }

    return $this->ordered_posts;
}

Any assistance you can offer would be appreciated, I have tried reading up on wpquery and experimenting with that, but does not seem to be the way to go as distance is not a stored value, rather it is a calculation.

1条回答
做自己的国王
2楼-- · 2019-05-23 08:21

I received and answer to my question from Matt@wordpress.stackexchange. There is actually a FacetWP hook to add distance to page templates. A functions filter:

add_filter( 'facetwp_proximity_store_distance', '__return_true' );

and a bit of php to enable the functionality:

$distance = facetwp_get_distance();
if ( false !== $distance ) {
echo round( $distance, 1 );
echo " miles";
}

I hope this helps somebody, thanks again Matt

查看更多
登录 后发表回答