Files
medicalalert-web-reloaded/wp/wp-content/plugins/relevanssi-premium/premium/proximity.php
Tony Volpe 4eb982d7a8 Merged in feature/from-pantheon (pull request #16)
code from pantheon

* code from pantheon
2024-01-10 17:03:02 +00:00

190 lines
5.5 KiB
PHP

<?php
/**
* /premium/proximity.php
*
* @package Relevanssi_Premium
* @author Mikko Saari
* @license https://wordpress.org/about/gpl/ GNU General Public License
* @see https://www.relevanssi.com/
*/
add_action( 'init', 'relevanssi_enable_proximity_sorting' );
/**
* Adds the proximity sorting filters.
*
* If the relevanssi_proximity_sorting filter returns true, adds the required
* filters to make the proximity searching work.
*/
function relevanssi_enable_proximity_sorting() {
/**
* Controls whether the proximity searching is enabled or not.
*
* @param boolean If true, enable proximity sorting. Default false.
*/
if ( apply_filters( 'relevanssi_proximity_sorting', false ) ) {
add_filter( 'relevanssi_results', 'relevanssi_add_distance', 1 );
add_filter( 'relevanssi_search_params', 'relevanssi_pick_up_coordinates', 10, 2 );
}
}
/**
* Counts the distances to the found posts.
*
* The coordinates from each post come from the relevanssi_proximity_coordinates
* filter hook based on the post ID. The comparison coordinates come from the
* global $relevanssi_coordinates variable, filtered by the
* relevanssi_proximity_comparison filter hook. The coordinates need to be in
* the floating point format, separated with a comma, latitude first.
*
* The distance for each post to the comparison coordinates is stored to the
* global $relevanssi_distance array for the post ID.
*
* @uses relevanssi_get_distance()
*
* @param array $doc_weight An array of post ID => weight pairs. This function
* ignores the weight and only cares about the post ID.
*
* @return array The $doc_weight array untouched.
*/
function relevanssi_add_distance( $doc_weight ) {
global $relevanssi_coordinates;
/**
* Filters the comparison coordinates Relevanssi uses.
*
* @param string The coordinates in "latitude, longitude" format.
*/
$compare_coordinates = apply_filters(
'relevanssi_proximity_comparison',
$relevanssi_coordinates // // phpcs:ignore WordPress.Security.NonceVerification
);
if ( ! $compare_coordinates ) {
return $doc_weight;
}
list( $latitude_from, $longitude_from ) = explode( ',', $compare_coordinates );
$latitude_from = floatval( $latitude_from );
$longitude_from = floatval( $longitude_from );
global $relevanssi_distance;
$relevanssi_distance = array();
foreach ( array_keys( $doc_weight ) as $post_id ) {
/**
* Filters the coordinates for each post.
*
* @param string The coordinates.
* @param int The post ID.
*/
$hit_coordinates = apply_filters(
'relevanssi_proximity_coordinates',
'',
$post_id
);
if ( ! $hit_coordinates ) {
/**
* Filters the default distance for posts without coordinates.
*
* @param int The default distance, default PHP_INT_MAX.
*/
$default_distance = apply_filters(
'relevanssi_proximity_default_distance',
PHP_INT_MAX
);
$relevanssi_distance[ $post_id ] = $default_distance;
}
list( $latitude_to, $longitude_to ) = explode( ',', $hit_coordinates );
$latitude_to = floatval( $latitude_to );
$longitude_to = floatval( $longitude_to );
$distance = relevanssi_get_distance(
$latitude_from,
$longitude_from,
$latitude_to,
$longitude_to
);
$relevanssi_distance[ $post_id ] = $distance;
}
return $doc_weight;
}
/**
* Calculates the great-circle distance between two points.
*
* Uses the Haversine formula.
*
* @param float $latitude_from Latitude of start point in [deg decimal].
* @param float $longitude_from Longitude of start point in [deg decimal].
* @param float $latitude_to Latitude of target point in [deg decimal].
* @param float $longitude_to Longitude of target point in [deg decimal].
*
* @return float Distance between points in kilometers.
*/
function relevanssi_get_distance( float $latitude_from, float $longitude_from, float $latitude_to, float $longitude_to ): float {
$earth_radius = 6371;
$lat_from = deg2rad( $latitude_from );
$lon_from = deg2rad( $longitude_from );
$lat_to = deg2rad( $latitude_to );
$lon_to = deg2rad( $longitude_to );
$lat_delta = $lat_to - $lat_from;
$lon_delta = $lon_to - $lon_from;
$angle = 2 * asin(
sqrt(
pow( sin( $lat_delta / 2 ), 2 )
+ cos( $lat_from ) * cos( $lat_to )
* pow( sin( $lon_delta / 2 ), 2 )
)
);
return $angle * $earth_radius;
}
/**
* Returns the distances for compared posts.
*
* Gets the distances from the $relevanssi_distance global array.
*
* @param object $post_a The first post object.
* @param object $post_b The second post object.
*
* @return array Array containing the distance to post A and to post B. Default
* value is 0.
*/
function relevanssi_get_proximity_values( $post_a, $post_b ) {
global $relevanssi_distance;
$distance_to_a = $relevanssi_distance[ $post_a->ID ] ?? 0;
$distance_to_b = $relevanssi_distance[ $post_b->ID ] ?? 0;
return array( $distance_to_a, $distance_to_b );
}
/**
* Takes the 'coordinates' query variable and stores it to a global variable.
*
* Stores the comparison coordinates from the 'coordinates' query variable in
* the $relevanssi_coordinates global variable, because that is the easiest way
* to access that data in the relevanssi_add_distance() function.
*
* @see relevanssi_add_distance().
*
* @param array $params The search parameters; ignored.
* @param WP_Query $query The query object.
*
* @return array The search parameters untouched.
*/
function relevanssi_pick_up_coordinates( $params, $query ) {
global $relevanssi_coordinates;
$relevanssi_coordinates = $query->query_vars['coordinates'];
return $params;
}