function location_search_search_execute in Location 7.5
Same name and namespace in other branches
- 7.3 contrib/location_search/location_search.module \location_search_search_execute()
Implements hook_search_execute().
File
- contrib/
location_search/ location_search.module, line 85 - Location search interface.
Code
function location_search_search_execute($keys = NULL, $conditions = NULL) {
$proximity = FALSE;
$lids = array();
// Determine whether this is a fulltext search or not.
$fulltext = $keys;
$fulltext = search_expression_insert($fulltext, 'country');
$fulltext = search_expression_insert($fulltext, 'province');
$fulltext = search_expression_insert($fulltext, 'city');
$fulltext = search_expression_insert($fulltext, 'from');
$fulltext = empty($fulltext) ? FALSE : TRUE;
if ($fulltext) {
// Fuzzy search -- Use the fulltext routines against the indexed locations.
$query = db_select('search_index', 'i')
->extend('SearchQuery')
->extend('PagerDefault');
$query
->join('location', 'l', 'l.lid = i.sid');
$query
->searchExpression($keys, 'node');
// Insert special keywords.
$query
->setOption('country', 'l.country');
$query
->setOption('province', 'l.province');
$query
->setOption('city', 'l.city');
// setOption() can't handle the complexity of this so do it manually.
if ($value = search_expression_extract($keys, 'from')) {
// Set up a proximity search.
$proximity = TRUE;
list($lat, $lon, $dist, $unit) = explode(',', $value);
$distance_meters = _location_convert_distance_to_meters($dist, $unit);
// MBR query to make it easier on the database.
$latrange = earth_latitude_range($lon, $lat, $distance_meters);
$lonrange = earth_longitude_range($lon, $lat, $distance_meters);
$query
->condition('l.latitude', array(
$latrange[0],
$latrange[1],
), 'BETWEEN');
$query
->condition('l.longitude', array(
$lonrange[0],
$lonrange[1],
), 'BETWEEN');
// Distance query to finish the job.
$query
->where(earth_distance_sql($lon, $lat) . ' < ' . $distance_meters);
// Override the scoring mechanism to use calculated distance
// as the scoring metric.
$query
->addExpression(earth_distance_sql($lon, $lat, 'l'), 'distance');
$query
->orderBy('distance', 'DESC');
$query->searchExpression = search_expression_insert($query->searchExpression, 'from');
}
// Only continue if the first pass query matches.
if (!$query
->executeFirstPass()) {
return array();
}
}
else {
$query = db_select('location', 'l')
->extend('PagerDefault');
// sid is the alias so that our results match the fulltext search results.
$query
->addField('l', 'lid', 'sid');
// Insert special keywords.
if ($value = search_expression_extract($keys, 'country')) {
$query
->condition('l.country', $value);
}
if ($value = search_expression_extract($keys, 'province')) {
$query
->condition('l.province', $value);
}
if ($value = search_expression_extract($keys, 'city')) {
$query
->condition('l.city', $value);
}
// This is almost duplicated from the fulltext search above because if it
// were refactored out it would make the code a little less clean and a
// little harder to understand.
if ($value = search_expression_extract($keys, 'from')) {
// Set up a proximity search.
$proximity = TRUE;
list($lat, $lon, $dist, $unit) = explode(',', $value);
$distance_meters = _location_convert_distance_to_meters($dist, $unit);
// MBR query to make it easier on the database.
$latrange = earth_latitude_range($lon, $lat, $distance_meters);
$lonrange = earth_longitude_range($lon, $lat, $distance_meters);
$query
->condition('l.latitude', array(
$latrange[0],
$latrange[1],
), 'BETWEEN');
$query
->condition('l.longitude', array(
$lonrange[0],
$lonrange[1],
), 'BETWEEN');
// Distance query to finish the job.
$query
->where(earth_distance_sql($lon, $lat) . ' < ' . $distance_meters);
// Override the scoring mechanism to use calculated distance
// as the scoring metric.
$query
->addExpression(earth_distance_sql($lon, $lat, 'l'), 'distance');
$query
->orderBy('distance', 'DESC');
}
}
// Load results.
$found = $query
->limit(10)
->execute();
foreach ($found as $item) {
$lids[] = $item->sid;
}
$results = array();
foreach ($lids as $lid) {
$loc = location_load_location($lid);
$result = db_query('SELECT nid, uid, genid FROM {location_instance} WHERE lid = :lid', array(
':lid' => $lid,
), array(
'fetch' => PDO::FETCH_ASSOC,
));
$instance_links = array();
foreach ($result as $row) {
$instance_links[] = $row;
}
location_invoke_locationapi($instance_links, 'instance_links');
$results[] = array(
'links' => $instance_links,
'location' => $loc,
);
}
return $results;
}