'location/autocomplete', 'access' => user_access('access content'), 'callback' => '_location_autocomplete', 'type' => MENU_CALLBACK, ); $items[] = array( 'path' => 'admin/settings/location', 'title' => t('Location'), 'description' => t('Settings for Location module'), 'callback' => 'drupal_get_form', 'callback arguments' => array('location_admin_settings'), 'access' => user_access('administer site configuration') ); $items[] = array( 'path' => 'admin/settings/location/main', 'title' => t('Main settings'), 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items[] = array( 'path' => 'admin/settings/location/maplinking', 'title' => t('Map links'), 'callback' => 'drupal_get_form', 'callback arguments' => array('location_map_link_options_form'), 'access' => user_access('administer site configuration'), 'type' => MENU_LOCAL_TASK, 'weight' => 1 ); $items[] = array( 'path' => 'admin/settings/location/geocoding', 'title' => t('Geocoding options'), 'callback' => 'location_geocoding_options_page', 'access' => user_access('administer site configuration'), 'type' => MENU_LOCAL_TASK, 'weight' => 2 ); } return $items; } /** * Implementation of hook_perm(). */ function location_perm() { return array( 'submit latitude/longitude', 'administer user locations', 'set own user location', 'view own user location', 'view all user locations', ); } /** * Temporary function to signify that this Location.module is using the 3.x api * on Drupal 5. */ function location_newapi() { return TRUE; } /** * Implementation of hook_help(). * * @TODO: check/fix this: admin/content/configure/types (still use %? still same url?) */ function location_help($section) { switch ($section) { case 'admin/help#location': $output = '
'. t('The location module allows you to associate a geographic location with content and users. Users can do proximity searches by postal code. This is useful for organizing communities that have a geographic presence.') .'
'; $output .= ''. t('To administer locative information for content, use the content type administration page. To support most location enabled features, you will need to install the country specific include file. To support postal code proximity searches for a particular country, you will need a database dump of postal code data for that country. As of June 2007 only U.S. and German postal codes are supported.') .'
'; $output .= t('You can
'. t('For more information please read the configuration and customization handbook Location page.', array('@location' => 'http://www.drupal.org/handbook/modules/location/')) .'
'; return $output; } } /** * Implementation of hook_elements(). */ function location_elements() { return array( 'location_element' => array( '#input' => FALSE, '#process' => array('_location_expand_location' => array()), '#tree' => TRUE, '#location_settings' => array(), '#attributes' => array('class' => 'location'), //'#theme' => 'location_element', ), 'location_settings' => array( '#input' => FALSE, '#process' => array('_location_expand_location_settings' => array()), '#collapsible' => TRUE, '#collapsed' => TRUE, '#tree' => TRUE, ), ); } /** * Implementation of hook_simpletest(). */ function location_simpletest() { $dir = drupal_get_path('module', 'location') .'/tests'; $tests = file_scan_directory($dir, '\.test$'); return array_keys($tests); } /** * Implementation of hook_cron(). */ function location_cron() { if (variable_get('location_garbagecollect', TRUE)) { // Perform garbage collection on locations. db_query('DELETE FROM {location} WHERE lid NOT IN (SELECT lid FROM {location_instance})'); } } // @@@ Page callback functions. // @TODO Remove in Drupal 6 and use the menu system to load the files instead. /** * Callback for admin settings form. */ function location_admin_settings() { require_once(drupal_get_path('module', 'location') .'/location.admin.inc'); return _location_admin_settings(); } /** * Callback for map link page of admin settings form. */ function location_map_link_options_form() { require_once(drupal_get_path('module', 'location') .'/location.admin.inc'); return _location_map_link_options_form(); } /** * Process a location element. */ function _location_expand_location($element) { drupal_add_css(drupal_get_path('module', 'location') .'/location.css'); $value = is_array($element['#value']) ? $element['#value'] : array(); $element['#tree'] = TRUE; // @@@ This will make it a simple fieldset instead of calling the theme function... $element['#type'] = 'fieldset'; if (!isset($element['#title'])) { $element['#title'] = t('Location'); } if (empty($element['#location_settings'])) { $element['#location_settings'] = array(); //@@@ Get some sort of sane default? } if (!isset($element['#default_value']) || $element['#default_value'] == 0) { $dummy = ''; $element['#default_value'] = location_invoke_locationapi($dummy, 'default values'); } // Keep track of the LID. // @@@ For some reason, hidden seems to work best. $element['lid'] = array( '#type' => 'hidden', '#value' => isset($element['#default_value']['lid']) ? $element['#default_value']['lid'] : FALSE, ); $location_settings = $element['#location_settings']; $fields = location_field_names(); foreach ($fields as $field => $title) { if (!isset($element[$field])) { // @@@ Permission check hook? if ($location_settings[$field] != 0) { $element[$field] = location_invoke_locationapi($element['#default_value'][$field], 'field_expand', $field, $location_settings[$field], $element['#default_value']); } } } if (user_access('submit latitude/longitude')) { $element['locpick'] = array(); $element['locpick']['user_latitude'] = array( '#type' => 'textfield', '#title' => t('Latitude'), '#default_value' => isset($element['#default_value']['locpick']['user_latitude']) ? $element['#default_value']['locpick']['user_latitude'] : '', '#size' => 16, '#attributes' => array('class' => 'container-inline'), '#maxlength' => 20, ); $element['locpick']['user_longitude'] = array( '#type' => 'textfield', '#title' => t('Longitude'), '#default_value' => isset($element['#default_value']['locpick']['user_longitude']) ? $element['#default_value']['locpick']['user_longitude'] : '', '#size' => 16, '#maxlength' => 20, '#description' => t('If you wish to supply your own latitude/longitude, you may do so here. Leaving these fields blank means that the system will determine a latitude/longitude for you, if possible.'), ); if (function_exists('gmap_get_auto_mapid') && variable_get('location_usegmap', FALSE)) { $mapid = gmap_get_auto_mapid(); $map = gmap_parse_macro(variable_get('location_locpick_macro', '[gmap]')); $map['behavior']['locpick'] = TRUE; $map['behavior']['collapsehack'] = TRUE; $element['locpick']['user_latitude']['#map'] = $mapid; gmap_widget_setup($element['locpick']['user_latitude'], 'locpick_latitude'); $element['locpick']['user_longitude']['#map'] = $mapid; gmap_widget_setup($element['locpick']['user_longitude'], 'locpick_longitude'); $element['locpick']['map'] = array( '#type' => 'markup', '#weight' => -1, '#value' => theme('gmap', array('#map' => $mapid, '#settings' => $map)), ); } } return $element; } /** * Theme the location element. * @ingroup themable */ function theme_location_elementzzz($element) { drupal_add_css(drupal_get_path('module', 'location') .'/location.css'); /* // @@@ This *DEFINATELY* needs revisited. foreach (element_children($element) as $field_name) { $row = array(); if ($element[$field_name]['#type'] == 'markup') { $row[] = array('data' => $element[$field_name]['#value'], 'colspan' => 2); } elseif ($element[$field_name]['#type'] != 'hidden') { $required = !empty($element[$field_name]['#required']) ? '*' : ''; $row[] = array('align' => 'right', 'data' => '"); unset($element[$field_name]['#title']); $description = $element[$field_name]['#description']; $row[] = array('align' => 'left', 'data' => drupal_render($element[$field_name])); $rows[] = array( 'data' => $row, 'class' => 'odd' ); } } $output = theme('table', NULL, $rows); $output .= drupal_render($element); return $output;*/ if ($element['#collapsible']) { drupal_add_js('misc/collapse.js'); if (!isset($element['#attributes']['class'])) { $element['#attributes']['class'] = ''; } $element['#attributes']['class'] .= ' collapsible'; if ($element['#collapsed']) { $element['#attributes']['class'] .= ' collapsed'; } } return '\n"; /* $element['#type'] = 'fieldset'; return theme('form_element', $element, $element['#children']); return drupal_render($element); return theme_fieldset($element); return theme('fieldset', $element, $element['#children']); */ } function _location_expand_location_settings($element) { $value = is_array($element['#value']) ? $element['#value'] : array(); $element['#tree'] = TRUE; $element['#type'] = 'fieldset'; if (!isset($element['#title'])) { $element['#title'] = t('Location Fields'); } if (!isset($element['#default_value']) || $element['#default_value'] == 0) { $element['#default_value'] = array(); } // Force #tree on. $element['#tree'] = TRUE; $defaults = location_invoke_locationapi($element, 'collection default'); $defaults = array_merge($defaults, $element['#default_value']); $fields = location_field_names(); // Options for fields. $options = array( t('Do not collect'), t('Allow'), t('Require'), ); foreach ($fields as $field => $title) { $element[$field] = array( '#type' => 'radios', '#title' => $title, '#default_value' => $defaults[$field], '#options' => $options, '#tree' => TRUE, ); } return $element; } function theme_location_settings($element) { return theme('form_element', $element, $element['#children']); } function location_field_names() { static $fields; if (empty($fields)) { $dummy = ''; $fields = location_invoke_locationapi($dummy, 'fields'); } return $fields; } /** * Implementation of hook_locationapi(). */ function location_locationapi(&$obj, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) { switch ($op) { case 'fields': return array('name' => t('Location name'), 'street' => t('Street location'), 'additional' => t('Additional'), 'city' => t('City'), 'province' => t('State/Province'), 'postal_code' => t('Postal code'), 'country' => t('Country')); case 'collection default': return array('name' => 1, 'street' => 1, 'city' => 0, 'province' => 0, 'postal_code' => 0, 'country' => 1); case 'default values': return array( 'name' => '', 'street' => '', 'additional' => '', 'city' => '', 'province' => '', 'postal_code' => '', 'country' => variable_get('location_default_country', 'us'), 'latitude' => 0, 'longitude' => 0, 'source' => LOCATION_LATLON_UNDEFINED, 'is_primary' => 0, // @@@ ); case 'validate': if (!empty($obj['country'])) { if (!empty($obj['province'])) { $provinces = location_get_provinces($obj['country']); $found = FALSE; $p = strtoupper($obj['province']); foreach ($provinces as $k => $v) { if ($p == strtoupper($k) || $p == strtoupper($v)) { $found = TRUE; break; } } if (!$found) { form_error($a3['province'], t('The specified province was not found in the specified country.')); } } } // Can't specify just latitude or just longitude. if (_location_floats_are_equal($obj['locpick']['user_latitude'], 0) xor _location_floats_are_equal($obj['locpick']['user_longitude'], 0)) { $ref = &$a3['locpick']['user_latitude']; if (_location_floats_are_equal($obj['locpick']['user_longitude'], 0)) { $ref = &$a3['locpick']['user_longitude']; } form_error($ref, t('You must fill out both latitude and longitude or you must leave them both blank.')); } break; case 'field_expand': switch ($a3) { case 'name': return array( '#type' => 'textfield', '#title' => t('Location name'), '#default_value' => $obj, '#size' => 64, '#maxlength' => 64, '#description' => t('e.g. a place of business, venue, meeting point'), '#attributes' => NULL, '#required' => ($a4 == 2), ); case 'street': return array( '#type' => 'textfield', '#title' => t('Street'), '#default_value' => $obj, '#size' => 64, '#maxlength' => 64, '#required' => ($a4 == 2), ); case 'additional': return array( '#type' => 'textfield', '#title' => t('Additional'), '#default_value' => $obj, '#size' => 64, '#maxlength' => 64, // @@@ Err, #required? ); case 'city': return array( '#type' => 'textfield', '#title' => t('City'), '#default_value' => $obj, '#size' => 64, '#maxlength' => 64, '#description' => NULL, '#attributes' => NULL, '#required' => ($a4 == 2), ); case 'province': drupal_add_js(drupal_get_path('module', 'location') .'/location_autocomplete.js'); return array( '#type' => 'textfield', '#title' => t('State/Province'), '#autocomplete_path' => 'location/autocomplete/'. $a5['country'], '#default_value' => $obj, '#size' => 64, '#maxlength' => 64, '#description' => NULL, '#attributes' => array('class' => 'location_auto_province'), '#required' => ($a4 == 2), ); case 'country': $options = array_merge(array('' => t('Please select'), 'xx' => 'NOT LISTED'), location_get_iso3166_list()); return array( '#type' => 'select', '#title' => t('Country'), '#default_value' => $obj, '#options' => $options, '#description' => NULL, '#required' => ($a4 == 2), '#attributes' => array('class' => 'location_auto_country'), ); case 'postal_code': return array( '#type' => 'textfield', '#title' => t('Postal code'), '#default_value' => $obj, '#size' => 16, '#maxlength' => 16, '#required' => ($a4 == 2), ); } break; case 'isunchanged': if ($a3 == 'latitude' || $a3 == 'longitude') { if (_location_floats_are_equal($obj[$a3], $a4)) { return TRUE; } } if ($a3 == 'country') { // Consider ' ' and '' to be equivilent, due to us storing country // as char(2) in the database. if (trim($obj[$a3]) == trim($a4)) { return TRUE; } } break; } } function location_geocoding_parameters_page($country_iso, $service) { drupal_set_title(t('Configure parameters for %service geocoding', array('%service' => $service))); $breadcrumbs = drupal_get_breadcrumb(); $breadcrumbs[] = l('location', 'admin/settings/location'); $breadcrumbs[] = l('geocoding', 'admin/settings/location/geocoding'); $countries = location_get_iso3166_list(); $breadcrumbs[] = l($countries[$country_iso], 'admin/settings/location/geocoding', array(), NULL, $country_iso); drupal_set_breadcrumb($breadcrumbs); return drupal_get_form('location_geocoding_parameters_form', $country_iso, $service); } function location_geocoding_parameters_form($country_iso, $service) { location_load_country($country_iso); $geocode_settings_form_function_specific = 'location_geocode_'. $country_iso .'_'. $service .'_settings'; $geocode_settings_form_function_general = $service .'_geocode_settings'; if (function_exists($geocode_settings_form_function_specific)) { return system_settings_form($geocode_settings_form_function_specific()); } location_load_geocoder($service); if (function_exists($geocode_settings_form_function_general)) { return system_settings_form($geocode_settings_form_function_general()); } else { return system_settings_form(array( '#type' => 'markup', '#value' => t('No configuration parameters are necessary, or a form to take such paramters has not been implemented.') )); } } // @@@ Convert to menu system in D6. function location_geocoding_options_page() { $iso = arg(4); $service = arg(5); if (!empty($iso) || !empty($service)) { return location_geocoding_parameters_page($iso, $service); } return drupal_get_form('location_geocoding_options_form'); } function location_geocoding_options_form() { $form = array(); $form['countries'] = array(); // First, we build two arrays to help us figure out on the fly whether a specific country is covered by a multi-country geocoder, // and what the details of the multi-country geocoder are // (1) Get list of geocoders $general_geocoders_list = location_get_general_geocoder_list(); // (2) get data about each geocoder and the list of coutnries covered by each geocoder $general_geocoders_data = array(); $general_geocoders_countries = array(); foreach ($general_geocoders_list as $geocoder_name) { location_load_geocoder($geocoder_name); $info_function = $geocoder_name .'_geocode_info'; if (function_exists($info_function)) { $general_geocoders_data[$geocoder_name] = $info_function(); } $countries_function = $geocoder_name .'_geocode_country_list'; if (function_exists($countries_function)) { $general_geocoders_countries[$geocoder_name] = $countries_function(); } } foreach (location_configured_countries() as $country_iso => $country_name) { location_load_country($country_iso); $geocoding_options = array(); $form['countries'][$country_iso] = array( '#type' => 'markup', '#value' => '' ); $form['countries'][$country_iso]['label_'. $country_iso] = array( '#type' => 'markup', '#value' => ''. t('NOTE:') .' '. t('Locations fields you choose to require will only be required for the first location if you have allowed more than one location to be submitted for this node type.') .'
' ); $form['location']['location_fields'] = array( '#type' => 'location_settings', '#default_value' => variable_get('location_fields_'. $type, array()), ); $form['location']['location_fields']['location_country'] = array( '#type' => 'radios', '#title' => t('Country names'), '#description' => t('The selection of a country can be hidden and/or forced to a default country selection by going to the location settings page and checking the box marked "Hide country selection" and selecting a country from the drop down select labelled "Default country selection".', array('@location_settings' => url('admin/settings/location'))), '#default_value' => variable_get('location_country_'. $type, 1), '#options' => array( 1 => t('Use'), 2 => t('Require') ), ); $form['location']['rss'] = array( '#type' => 'fieldset', '#title' => t('RSS Settings'), '#description' => t('Here, you can change how locative data affects RSS feeds on nodes.'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['location']['rss']['location_rss'] = array( '#type' => 'select', '#title' => t('RSS mode'), '#description' => t('Select how to use locations in RSS feeds for this content type.'), '#options' => array( 'none' => t('None (Do not put locational data in RSS feeds)'), 'w3c' => t('W3C Geo (deprecated)'), 'w3c_bugcompat' => t('Location 1.x-2.x compatible (buggy W3C)'), 'simple' => t('GeoRSS-Simple'), 'gml' => t('GeoRSS GML'), ), '#default_value' => variable_get('location_rss_'. $type, 'w3c'), // @@@ Historical default. ); $form['location']['display'] = array( '#type' => 'fieldset', '#title' => t('Display Settings'), '#description' => t('Here, you can change how locative data appears in nodes when viewed.'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['location']['display']['location_display_teaser'] = array( '#type' => 'checkbox', '#title' => 'Display location in teaser view', '#default_value' => variable_get('location_display_teaser_'. $type, TRUE), ); $form['location']['display']['location_display_full'] = array( '#type' => 'checkbox', '#title' => 'Display location in full view', '#default_value' => variable_get('location_display_full_'. $type, TRUE), ); // @@@ THIS IS NOT GOOD. --Bdragon // clear the views cache in case anything was changed if (function_exists('views_invalidate_cache')) { views_invalidate_cache(); } } /** * Custom submit function to save location settings properly. */ function _location_node_type_save_submit($form_id, &$form_values) { variable_set('location_fields_'. $form_values['type'], $form_values['location_fields']); // Prevent the "normal" submit handler from stomping our variable. unset($form_values['location_fields']); } function _location_node_form_alter($form_id, &$form) { $node = $form['#node']; $location_fields = array(); $required_fields = array(); foreach (array_keys(location_field_names()) as $field_name) { $workflow_setting = variable_get('location_'. $field_name .'_'. $node->type, $field_name == 'country' ? 1 : 0); if ($workflow_setting) { $location_fields[] = $field_name; if ($workflow_setting == 2) { $required_fields[] = $field_name; } } } $numloc = isset($node->locations) ? count($node->locations) : 0; $location_form_count = min(count($node->locations) + variable_get('location_defaultnum_'. $node->type, 1), variable_get('location_maxnum_'. $node->type, 1)); if ($location_form_count) { $form['locations'] = array( '#type' => 'fieldset', '#title' => format_plural($location_form_count, 'Location', 'Locations'), '#tree' => TRUE, '#attributes' => array_merge(is_array($form['locations']['#attributes']) ? $form['locations']['#attributes'] : array(), array('class' => 'locations')), '#weight' => variable_get('location_weight_'. $form['type']['#value'], 9), '#collapsible' => variable_get('location_collapsible_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE, '#collapsed' => variable_get('location_collapsed_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE, ); // If there is only one location, hide the outer fieldset. if (variable_get('location_maxnum_'. $form['type']['#value'], 0) == 1) { $form['locations']['#type'] = 'markup'; } $settings = variable_get('location_fields_'. $node->type, array()); for ($i = 0; $i < $location_form_count; $i++) { $form['locations'][$i] = array( '#type' => 'location_element', '#title' => t('Location #%number', array('%number' => $i + 1)), '#default_value' => isset($node->locations[$i]) ? $node->locations[$i] : NULL, '#location_settings' => $settings, ); } if ($location_form_count == 1) { $form['locations'][0]['#title'] = t('Location'); } } } function _location_user_settings_form_alter($form_id, &$form) { $form['user_locations'] = array( '#type' => 'fieldset', '#title' => t('User locations'), ); $form['user_locations']['collection'] = array( '#type' => 'fieldset', '#title' => t('Collection settings'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['user_locations']['collection']['location_user_weight'] = array( '#type' => 'weight', '#title' => t('Location weight'), '#default_value' => variable_get('location_user_weight', 9), '#description' => t('Weight of the location box in the input form. Lowest values will be displayed higher in the form.'), ); $form['user_locations']['collection']['location_user_collapsible'] = array( '#type' => 'checkbox', '#title' => t('Collapsible'), '#default_value' => variable_get('location_user_collapsible', 1), '#description' => t('Make the location box collapsible.') ); $form['user_locations']['collection']['location_user_collapsed'] = array( '#type' => 'checkbox', '#title' => t('Collapsed'), '#default_value' => variable_get('location_user_collapsed', 1), '#description' => t('Display the location box collapsed.') ); $form['user_locations']['location_user_fields'] = array( '#type' => 'location_settings', '#default_value' => variable_get('location_user_fields', array()), ); /* $form['location']['location_fields']['location_country'] = array( '#type' => 'radios', '#title' => t('Country names'), '#description' => t('The selection of a country can be hidden and/or forced to a default country selection by going to the location settings page and checking the box marked "Hide country selection" and selecting a country from the drop down select labelled "Default country selection".', array('@location_settings' => url('admin/settings/location'))), '#default_value' => variable_get('location_country_'. $type, 1), '#options' => array( 1 => t('Use'), 2 => t('Require') ), ); */ } /** * Implementation of hook_form_alter(). */ function location_form_alter($form_id, &$form) { switch ($form_id) { case 'location_geocoding_options_form': // Fix the submit handler. if (!is_array($form['#submit'])) { $form['#submit'] = array('system_settings_form_submit' => array()); } array_unshift($form['#submit'], array('location_geocoding_options_form_submit' => array())); break; case 'node_type_form': // Add the options to the Node Type form _location_node_type_form_alter($form_id, $form); break; case 'user_admin_settings': // Add user locations settings. _location_user_settings_form_alter($form_id, $form); break; } // Add the Location fields on the Node edit form if (isset($form['type']['#value']) && $form['type']['#value'] .'_node_form' == $form_id && variable_get('location_maxnum_'. $form['type']['#value'], 0)) { // @@@ This is a workaround for some bad interactions with usernode. // @@@ Remove it as soon as we can figure out what's going on. if ($form_id == 'usernode_node_form') { return; } _location_node_form_alter($form_id, $form); } } /** * Validation function for node settings form. * Logically, the default number of locations per node cannot * be bigger than the max locations. * * @ingroup $form */ function location_node_settings_validate($form_id, $form_values) { if (!empty($form['location_maxnum']) && empty($form['location_defaultnum'])) { form_set_error('location_defaultnum', t("You must have at least 1 default location-form enabled if you are going to allow locations to be submitted for nodes of this type. If you don't intend to allow locations to be submitted for nodes of this type, set the maximum number of locations allowed for this type to 0.")); } elseif ($form['location_defaultnum'] > $form['location_maxnum']) { form_set_error('location_defaultnum', t("Your default number of location-forms that show up can't be greater than the maximum number of locations allowed for this node type.")); } } /** * Implementation of hook_nodeapi(). */ function location_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { switch ($op) { case 'validate': if (!empty($a3)) { return location_validate_form($a3['locations'], $node->locations); } break; case 'delete revision': db_query('DELETE FROM {location_instance} WHERE vid = %d', $node->vid); break; case 'delete': db_query('DELETE FROM {location_instance} WHERE nid = %d', $node->nid); break; case 'load': $locations = location_load_locations($node->vid); $location = count($locations) ? $locations[0] : array(); return array('locations' => $locations, 'location' => $location); case 'insert': case 'update': if (!empty($node->locations)) { db_query('DELETE FROM {location_instance} WHERE vid = %d', $node->vid); foreach ($node->locations as $location) { $lid = location_save($location, TRUE); if ($lid) { db_query('INSERT INTO {location_instance} (nid, vid, lid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $lid); } } } break; case 'view': if (variable_get('location_display_location', 1)) { if (($a3 && variable_get('location_display_teaser_'. $node->type, TRUE)) || (!$a3 && variable_get('location_display_full_'. $node->type, TRUE))) { // Get the list of suppressed countries $countries = variable_get('location_suppress_country', 0) ? array('country') : array(); // Show all locations if ($output = theme('locations', $node->locations, $countries)) { $node->content['locations'] = array( '#type' => 'markup', '#value' => $output, ); } } } break; case 'rss item': $items = array(); $mode = variable_get('location_rss_'. $node->type, 'w3c'); // @@@ Historical default. if ($mode == 'none') { return; } if (is_array($node->locations)) { foreach ($node->locations as $location) { if (!is_null($location['lat']) && !is_null($location['lon'])) { switch ($mode) { // W3C Basic Geo Vocabulary case 'w3c': $items[] = array( 'key' => 'geo:Point', 'namespace' => array('geo' => 'xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"'), 'value' => array( array('key' => 'geo:lat', 'value' => $location['lat']), array('key' => 'geo:long', 'value' => $location['lon']), ), ); break; // Location 1.x-2.x bug compatible. // W3C Basic Geo Vocabulary with a misspelled longitude tag. case 'w3c_bugcompat': $items[] = array( 'key' => 'geo:Point', 'namespace' => array('geo' => 'xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"'), 'value' => array( array('key' => 'geo:lat', 'value' => $location['lat']), array('key' => 'geo:lon', 'value' => $location['lon']), ), ); break; // GeoRSS-Simple case 'simple': $items[] = array( 'key' => 'georss:point', 'namespace' => array('georss' => 'xmlns:georss="http://www.georss.org/georss"'), 'value' => "$location[lat] $location[lon]", ); break; // case 'gml': $items[] = array( 'key' => 'georss:where', 'namespace' => array( 'georss' => 'xmlns:georss="http://www.georss.org/georss"', 'gml' => 'xmlns:gml="http://www.opengis.net/gml"', ), 'value' => array( 'gml:Point' => array( 'gml:pos' => "$location[lat] $location[lon]", ), ), ); break; } } } } return $items; } } /** * Load associated locations. * * @param $id The identifier to match. (An integer.) * @param $key The search key for {location_instance} (usually vid or uid.) * @return An array of loaded locations. */ function location_load_locations($id, $key = 'vid') { $result = db_query('SELECT lid FROM {location_instance} WHERE '. db_escape_table($key) .' = %d', $id); $locations = array(); while ($lid = db_fetch_object($result)) { $locations[] = location_load_location($lid->lid); } return $locations; } /** * Load a single location by lid. * * @param $lid Location ID to load. * @return A location array. */ function location_load_location($lid) { $location = db_fetch_array(db_query('SELECT * FROM {location} WHERE lid = %d', $lid)); // @@@ Just thought of this, but I am not certain it is a good idea... if (empty($location)) { $location = array('lid' => $lid); } if (isset($location['source']) && $location['source'] == LOCATION_LATLON_USER_SUBMITTED) { // Set up location chooser or lat/lon fields from the stored location. $location['locpick'] = array( 'user_latitude' => $location['latitude'], 'user_longitude' => $location['longitude'], ); } $location['province_name'] = ''; $location['country_name'] = ''; if (!empty($location['country'])) { $location['country_name'] = location_country_name($location['country']); if (!empty($location['province'])) { $location['province_name'] = location_province_name($location['country'], $location['province']); } } $location = array_merge($location, location_invoke_locationapi($location, 'load', $lid)); return $location; } /** * Returns an array of countries whose locations will be allowed entry * into the site's location system. The array returned is an associative * array where the keys are the ISO codes (see location.inc) and the values * are the shortened English names. */ function location_get_configured_countries() { $configured_countries = variable_get('location_configured_countries', array('us' => 1)); $configured_countries = is_array($configured_countries) ? $configured_countries : array('us' => 1); $return = array(); foreach ($configured_countries as $country => $enabled) { if ($enabled) { $return[] = $country; } } return $return; } // @@@ There are significant changes in the megapatch. /** * Implementation of hook_user(). */ function location_user($op, &$edit, &$account, $category = NULL) { global $user; switch ($op) { case 'load': $account->locations = location_load_locations($account->uid, 'uid'); $account->location = count($account->locations) ? $account->locations[0] : array(); break; case 'insert': case 'update': if (!empty($edit['locations'])) { db_query('DELETE FROM {location_instance} WHERE uid = %d', $account->uid); foreach ($edit['locations'] as $location) { $lid = location_save($location, TRUE); if ($lid) { db_query('INSERT INTO {location_instance} (uid, lid) VALUES (%d, %d)', $account->uid, $lid); } } } unset($edit['locations']); break; case 'delete': db_query('DELETE FROM {location_instance} WHERE uid = %d', $account->uid); break; case 'form': if ($category == 'account') { if ((($user->uid == $account->uid) && user_access('set own user location')) || user_access('administer user locations')) { // @@@ Multiple locations? $settings = variable_get('location_user_fields', array()); $form['locations'] = array( '#tree' => TRUE, ); $form['locations'][0] = array( '#type' => 'location_element', '#title' => t('Location'), '#default_value' => isset($account->locations[0]) ? $account->locations[0] : NULL, '#attributes' => array('class' => 'location'), '#collapsible' => variable_get('location_user_collapsible', FALSE), '#collapsed' => variable_get('location_user_collapsed', FALSE), '#weight' => variable_get('location_user_weight', 1), '#location_settings' => $settings, '#description' => t('Enter as much of your address as you are comfortable with. Your address will only be viewable by those who have the appropriate permissions. The site will be able to automatically link you to driving directions and other features if it already knows your address.'), ); return $form; } } break; case 'view': if ((($user->uid == $account->uid) && user_access('view own user location')) || user_access('administer users') || user_access('view all user locations') || user_access('administer user locations')) { // @@@ if (variable_get('location_display_location', 1) && isset($account->locations) && count($account->locations)) { $items[] = array( 'value' => theme('location', $account->location), 'class' => 'location', ); // @@@ if (user_access('submit latitude/longitude')) { if (!empty($account->location['latitude']) && !empty($user->location['longitude'])) { // @@@ Theme! $items[] = array( 'title' => t('Coordinates'), 'value' => t('lat: %latitude', array('%latitude' => $account->location['latitude'])) .'