'latlon'); $options['operator'] = array('default' => 'mbr'); $options['identifier'] = array('default' => 'dist'); $options['value'] = array( 'default' => array( 'latitude' => '', 'longitude' => '', 'city' => '', 'postal_code' => '', 'country' => '', 'search_distance' => 100, 'search_units' => 'mile', ), ); return $options; } function admin_summary() { return ''; } function operator_options() { return array( 'mbr' => t('Proximity (Rectangular)'), 'dist' => t('Proximity (Circular)'), ); } function expose_form_left(&$form, &$form_state) { parent::expose_form_left($form, $form_state); $form['expose']['type'] = array( '#parents' => array('options', 'type'), '#type' => 'select', '#title' => t('Form mode'), // @@@ Less stupid title? '#options' => array( 'latlon' => t('Latitude / Longitude input'), 'city' => t('City'), 'postal' => t('Postal Code / Country'), 'postal_default' => t('Postal Code (assume default country)'), ), //'#id' => 'edit-options-type', '#description' => t('FIXME'), '#default_value' => $this->options['type'], ); } function value_form(&$form, &$form_state) { $val = $this->value; // [11:44] If you load the page from scratch, $input for your identifier will be empty. // [11:44] So what's going on here is that for $_GET forms, there's no form id, no op button or anything, so they always appear to submit. // [11:45] FAPI doesn't quite get along with that; sometimes it handles the input being empty right and sometimes it doesn't. // [11:45] But if I set #default_value to a static string, it doesn't work either // [11:45] Right, fapi thinks the empty input is actually input, thus it overrides the default value. // [11:45] Ahh, hmm... // [11:46] So where would I go to clean it up? // [11:55] Bdragon: See views_handler_filter_string.inc line 174 // [11:55] Bdragon: That's how i address this problem. // [11:58] Hmm, OK if (!empty($form_state['exposed'])) { $identifier = $this->options['expose']['identifier']; if (!isset($form_state['input'][$identifier])) { // We need to pretend the user already inputted the defaults, because // fapi will malfunction otherwise. $form_state['input'][$identifier] = $this->value; } } $form['value'] = array( '#tree' => TRUE, ); $form['value']['latitude'] = array( '#type' => 'textfield', '#title' => t('Latitude'), '#default_value' => $this->value['latitude'], '#process' => array('views_process_dependency'), '#dependency' => array('edit-options-type' => array('latlon')), ); $form['value']['longitude'] = array( '#type' => 'textfield', '#title' => t('Longitude'), '#default_value' => $this->value['longitude'], '#process' => array('views_process_dependency'), '#dependency' => array('edit-options-type' => array('latlon')), ); $form['value']['city'] = array( '#type' => 'textfield', '#title' => t('City'), '#default_value' => $this->value['city'], '#process' => array('views_process_dependency'), '#dependency' => array('edit-options-type' => array('city')), ); $form['value']['postal_code'] = array( '#type' => 'textfield', '#title' => t('Postal code'), '#default_value' => $this->value['postal_code'], '#process' => array('views_process_dependency'), '#dependency' => array('edit-options-type' => array('postal', 'postal_default')), ); $form['value']['country'] = array( '#type' => 'select', '#title' => t('Country'), '#options' => array('' => '') + location_get_iso3166_list(), '#default_value' => $this->value['country'], '#process' => array('views_process_dependency'), '#dependency' => array('edit-options-type' => array('postal')), ); $form['value']['search_distance'] = array( '#type' => 'textfield', '#title' => t('Distance'), '#default_value' => $this->value['search_distance'], ); $form['value']['search_units'] = array( '#type' => 'select', '#options' => array( 'mile' => t('Miles'), 'km' => t('Kilometers'), ), '#default_value' => $this->value['search_units'], ); $form['value']['get_origin_from_url'] = array( '#type' => 'checkbox', '#default_value' => $this->value['get_origin_from_url'], '#title' => t('Obtain origin from url'), '#description' => t('Using this option will attempt to obtain a latitude and longitude from either the current node or user page.'), ); } function exposed_form(&$form, &$form_state) { parent::exposed_form($form, $form_state); $key = $this->options['expose']['identifier']; $type = $this->options['type']; // Remove unneeded fields when exposing the form. // It's shorter than redefining value_form. if ($type != 'latlon') { unset($form[$key]['latitude']); unset($form[$key]['longitude']); } if ($type != 'city') { unset($form[$key]['city']); } if ($type != 'postal' && $type != 'postal_default') { unset($form[$key]['postal_code']); } if ($type != 'postal') { unset($form[$key]['country']); } } // Used from the distance field. function calculate_coords() { if (!empty($this->value['latitude']) && !empty($this->value['longitude'])) { // If there are already coordinates, there's no work for us. return TRUE; } // @@@ Switch to mock location object and rely on location more? if ($this->options['type'] == 'postal' || $this->options['type'] == 'postal_default') { // Force default for country. if ($this->options['type'] == 'postal_default') { $this->value['country'] = variable_get('location_default_country', 'us'); } // Zip code lookup. if (!empty($this->value['postal_code']) && !empty($this->value['country'])) { $location = array('country'=> $this->value['country'], 'postal_code' => $this->value['postal_code']); $res = db_query("SELECT latitude, longitude FROM {zipcodes} WHERE"." zip = '%s' AND country = '%s'", $location['postal_code'], $location['country']); if ($r = db_fetch_array($res)) { $this->value['latitude'] = $r['latitude']; $this->value['longitude'] = $r['longitude']; } $coord = location_latlon_rough($location); if ($coord) { $this->value['latitude'] = $coord['lat']; $this->value['longitude'] = $coord['lon']; } else { return false; } } else { // @@@ Implement full address lookup? return false; } } if ($this->value['get_origin_from_url']) { if (arg(0) == 'node' && is_numeric(arg(1)) && $node = node_load(arg(1))) { $this->value['latitude'] = $node->location['latitude']; $this->value['longitude'] = $node->location['longitude']; } elseif (arg(0) == 'user' && is_numeric(arg(1)) && $user = user_load(arg(1))) { // @todo get user location } } if ($this->options['type'] == 'city') { // City lookup if (!empty($this->value['city'])) { $this->value['country'] = variable_get('location_default_country', 'us'); $location = array('country'=> $this->value['country'], 'city' => $this->value['city']); $coord = google_geocode_location($location); if ($coord) { $this->value['latitude'] = $coord['lat']; $this->value['longitude'] = $coord['lon']; } else { return false; } } } if (empty($this->value['latitude']) || empty($this->value['longitude'])) { return false; } return true; } function query() { $this->value['country'] = variable_get('location_default_country', 'us'); if (empty($this->value)) { return; } if (($this->options['type'] == 'city') && empty($this->value['city'])) { return; } if (($this->options['type'] == 'postal' || $this->options['type'] == 'postal_default') && empty($this->value['postal_code'])) { return; } if (!empty($this->value['postal_code'])) { // uk postcodes are weird - we need to make a special case: if ($this->value['country'] == 'uk') { $postcode = strtoupper(str_replace(' ','',$this->value['postal_code'])); if (preg_match("/^[A-Z]{1,2}[0-9]{2,3}[A-Z]{2}$/",$postcode) || preg_match("/^[A-Z]{1,2}[0-9]{1}[A-Z]{1}[0-9]{1}[A-Z]{2}$/",$postcode) || preg_match("/^GIR0[A-Z]{2}$/",$postcode)) { preg_match('/^[a-zA-Z]*[0-9 ]+/', $this->value['postal_code'], $matches); $this->value['postal_code'] = substr_replace(str_replace(' ', '', $matches[0]), '', -1); } } $res = db_query("SELECT latitude, longitude FROM {zipcodes} WHERE"." zip = '%s' AND country = '%s'", $this->value['postal_code'], $this->value['country']); if ($r = db_fetch_array($res)) { $this->value['latitude'] = $r['latitude']; $this->value['longitude'] = $r['longitude']; } } if (!empty($this->value['city'])) { $location = array('country'=> $this->value['country'], 'city' => $this->value['city']); $coord = google_geocode_location($location); if ($coord) { $this->value['latitude'] = $coord['lat']; $this->value['longitude'] = $coord['lon']; } } if (empty($this->value['search_distance'])) { $this->value['search_distance'] = 1; } $this->ensure_my_table(); $lat = $this->value['latitude']; $lon = $this->value['longitude']; $distance_meters = _location_convert_distance_to_meters($this->value['search_distance'], $this->value['search_units']); $latrange = earth_latitude_range($lon, $lat, $distance_meters); $lonrange = earth_longitude_range($lon, $lat, $distance_meters); // Add MBR check (always.) $this->query->add_where($this->options['group'], "$this->table_alias.latitude > %f AND $this->table_alias.latitude < %f AND $this->table_alias.longitude > %f AND $this->table_alias.longitude < %f", $latrange[0], $latrange[1], $lonrange[0], $lonrange[1]); if ($this->operator == 'dist') { // Add radius check. $this->query->add_where($this->options['group'], earth_distance_sql($lon, $lat, $this->table_alias) .' < %f', $distance_meters); } } }