You are here

function _location_search in Location 7.4

Same name and namespace in other branches
  1. 5.3 contrib/location_search/location_search.module \_location_search()
  2. 6.3 contrib/location_search/location_search.module \_location_search()

Implementation of hook_search(). (forwarded from location.module)

1 call to _location_search()
location.module in ./location.module
Location module main routines. An implementation of a universal API for location manipulation. Provides functions for postal_code proximity searching, deep-linking into online mapping services. Currently, some options are configured through an…

File

contrib/location_search/location_search.module, line 45
Location search interface.

Code

function _location_search($op = 'search', $keys = null) {
  switch ($op) {
    case 'name':
      return t('Locations');
    case 'reset':
      db_query('DELETE FROM {location_search_work}');
      db_query('INSERT INTO {location_search_work} (lid) (SELECT lid FROM {location})');
      break;
    case 'status':
      $total = db_result(db_query('SELECT COUNT(lid) FROM {location}'));
      $remaining = db_result(db_query('SELECT COUNT(lid) FROM {location_search_work}'));
      return array(
        'remaining' => $remaining,
        'total' => $total,
      );
    case 'search':
      $proximity = FALSE;
      $arguments1 = array();
      $conditions1 = '1 = 1';

      // This gets rewritten for proximity searches.
      $select2 = 'i.relevance AS score';
      $join2 = '';
      $sort_parameters = 'ORDER BY score DESC';
      if ($country = search_query_extract($keys, 'country')) {
        $countries = array();
        foreach (explode(',', $country) as $c) {
          $countries[] = "l.country = '%s'";
          $arguments1[] = $c;
        }
        $conditions1 .= ' AND (' . implode(' OR ', $countries) . ')';
        $keys = search_query_insert($keys, 'country');
      }
      if ($province = search_query_extract($keys, 'province')) {
        $provinces = array();
        foreach (explode(',', $province) as $p) {
          $provinces[] = "l.province = '%s'";
          $arguments1[] = $p;
        }
        $conditions1 .= ' AND (' . implode(' OR ', $provinces) . ')';
        $keys = search_query_insert($keys, 'province');
      }
      if ($city = search_query_extract($keys, 'city')) {
        $conditions1 .= " AND (l.city = '%s')";
        $arguments1[] = $city;
        $keys = search_query_insert($keys, 'city');
      }
      if ($from = search_query_extract($keys, 'from')) {

        // Set up a proximity search.
        $proximity = TRUE;
        list($lat, $lon, $dist, $unit) = explode(',', $from);
        $distance_meters = _location_convert_distance_to_meters($dist, $unit);

        // MBR query to make it easier on the database.
        $conditions1 .= " AND l.latitude > %f AND l.latitude < %f AND l.longitude > %f AND l.longitude < %f";
        $latrange = earth_latitude_range($lon, $lat, $distance_meters);
        $lonrange = earth_longitude_range($lon, $lat, $distance_meters);
        $arguments1[] = $latrange[0];
        $arguments1[] = $latrange[1];
        $arguments1[] = $lonrange[0];
        $arguments1[] = $lonrange[1];

        // Distance query to finish the job.
        $conditions1 .= ' AND ' . earth_distance_sql($lon, $lat) . ' < %f';
        $arguments1[] = $distance_meters;

        // Override the scoring mechanism to use calculated distance
        // as the scoring metric.
        $join2 = 'INNER JOIN {location} l ON i.sid = l.lid';
        $select2 = earth_distance_sql($lon, $lat, 'l') . ' AS distance';
        $sort_parameters = 'ORDER BY distance ASC';
        $keys = search_query_insert($keys, 'from');
      }
      $lids = array();
      if (empty($keys)) {

        // Non-fulltext search. We will be skipping the built-in logic.
        $add = '';
        if ($proximity) {
          $add = ', ' . earth_distance_sql($lon, $lat, 'l') . ' AS distance';
        }
        $query = "SELECT l.lid{$add} FROM {location} l WHERE {$conditions1}";
        $countquery = "SELECT COUNT(*) FROM {location} l WHERE {$conditions1}";
        $result = pager_query($query, 10, 0, $countquery, $arguments1);
        foreach ($result as $row) {
          $lids[] = $row->lid;
        }
      }
      else {

        // Fuzzy search -- Use the fulltext routines against the indexed locations.
        $find = do_search($keys, 'location', 'INNER JOIN {location} l ON l.lid = i.sid ', $conditions1 . (empty($where1) ? '' : ' AND ' . $where1), $arguments1, $select2, $join2, array(), $sort_parameters);
        foreach ($find as $item) {
          $lids[] = $item->sid;
        }
      }
      $results = array();
      foreach ($lids as $lid) {
        $loc = location_load_location($lid);
        $instance_links = array();
        while ($row = db_query('SELECT nid, uid FROM {location_instance} WHERE lid = :lid', array(
          ':lid' => $lid,
        ))
          ->fetchAssoc()) {
          $instance_links[] = $row;
        }
        location_invoke_locationapi($instance_links, 'instance_links');
        $results[] = array(
          'links' => $instance_links,
          'location' => $loc,
        );
      }
      return $results;
  }
}