'Search options', 'description' => 'Settings for Location Search module', 'page callback' => 'drupal_get_form', 'page arguments' => array('location_search_admin_settings'), 'file' => 'location_search.admin.inc', 'access arguments' => array('administer site configuration'), 'type' => MENU_LOCAL_TASK, 'weight' => 5, ); return $items; } /** * Implementation of hook_theme(). */ function location_search_theme() { return array( 'search_results_location' => array( 'arguments' => array('results' => NULL, 'type' => NULL), 'template' => 'search-results-location', ), 'search_result_location' => array( 'arguments' => array('result' => NULL, 'type' => NULL), 'template' => 'search-result-location', ), ); } /** * Implementation of hook_search(). (forwarded from location.module) */ 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); while ($row = db_fetch_object($result)) { $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); $result = db_query('SELECT nid, uid FROM {location_instance} WHERE lid = %d', $lid); $instance_links = array(); while ($row = db_fetch_array($result)) { $instance_links[] = $row; } location_invoke_locationapi($instance_links, 'instance_links'); $results[] = array( 'links' => $instance_links, 'location' => $loc, ); } return $results; } } function location_search_form_alter(&$form, &$form_state, $form_id) { if ($form_id == 'search_form' && arg(1) == 'location' && user_access('use advanced search')) { // @@@ Cache this. $result = db_query('SELECT DISTINCT country FROM {location}'); $countries = array('' => ''); while ($row = db_fetch_array($result)) { if (!empty($row['country'])) { $country = $row['country']; location_standardize_country_code($country); $countries[$country] = location_country_name($country); } } ksort($countries); drupal_add_js(drupal_get_path('module', 'location') .'/location_autocomplete.js'); // Keyword boxes: $form['advanced'] = array( '#type' => 'fieldset', '#title' => t('Advanced search'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#attributes' => array('class' => array('search-advanced')), ); $form['advanced']['country'] = array( '#type' => 'select', '#title' => t('Country'), '#options' => $countries, // Used by province autocompletion js. '#attributes' => array('class' => array('location_auto_country')), ); $form['advanced']['province'] = array( '#type' => 'textfield', '#title' => t('State/Province'), '#autocomplete_path' => 'location/autocomplete/'. variable_get('site_default_country', 'us'), // Used by province autocompletion js. '#attributes' => array('class' => array('location_auto_province')), ); $form['advanced']['city'] = array( '#type' => 'textfield', '#title' => t('City'), ); $form['advanced']['proximity'] = array( '#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => TRUE, '#title' => t('Proximity'), ); $form['advanced']['proximity']['map'] = array(); if (variable_get('location_search_map_address', 1)) { $form['advanced']['proximity']['locpick_address'] = array( '#type' => 'textfield', '#title' => t('Locate Address'), ); } $form['advanced']['proximity']['latitude'] = array( '#type' => 'textfield', '#title' => t('Latitude'), ); $form['advanced']['proximity']['longitude'] = array( '#type' => 'textfield', '#title' => t('Longitude'), ); $form['advanced']['proximity']['distance'] = array( '#type' => 'fieldset', '#title' => t('Distance'), ); $form['advanced']['proximity']['distance']['distance'] = array( '#type' => 'textfield', '#size' => 5, '#maxlength' => 5, ); $form['advanced']['proximity']['distance']['units'] = array( '#type' => 'select', '#options' => array( 'mi' => t('mi'), 'km' => t('km'), ), ); $form['advanced']['submit'] = array( '#type' => 'submit', '#value' => t('Advanced search'), '#prefix' => '