FINAL suepr merge step : added all modules to this super repos

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-19 16:46:59 +02:00
7585 changed files with 1723356 additions and 18 deletions

View File

@@ -0,0 +1,16 @@
name = Location Add Another
description = Allows you to quickly add locations directly from a node without having to click 'edit' first.
dependencies[] = location
dependencies[] = location_node
package = Location
core = 7.x
files[] = location_addanother.module
files[] = location_addanother.install
; Information added by drupal.org packaging script on 2012-02-18
version = "7.x-3.x-dev"
core = "7.x"
project = "location"
datestamp = "1329524299"

View File

@@ -0,0 +1,30 @@
<?php
/**
* @file
* Install, update and uninstall functions for the location_addanother module.
*/
/**
* Implementshook_install().
*/
function location_addanother_install() {
// Change weight so we execute after location.
db_update('system')
->fields(array(
'weight' => 1,
))
->condition('name', 'location_addanother')
->condition('type', 'module')
->execute();
}
/**
* Implementshook_uninstall().
*/
function location_addanother_uninstall() {
$result = db_query("SELECT name FROM {variable} WHERE name LIKE 'location_addanother_%'")->fetchCol();
foreach ($result as $row) {
variable_del($row->name);
}
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* @file
* "Add location from node view" functionality.
* Split from main location.module in version 3.
*/
/**
* Implements hook_node_view().
*/
function location_addanother_node_view($node, $view_mode) {
if (variable_get('location_addanother_' . $node->type, 0) && count($node->locations) < variable_get('location_maxnum_' . $node->type, 0) && $view_mode == 'full' && node_access('update', $node)) {
$addanother_form = drupal_get_form('location_addanother_form', $node);
$node->content['location_addanother'] = array(
'#type' => 'markup',
'#markup' => drupal_render($addanother_form),
);
}
}
/**
* Implements hook_form_FORM_ID_alter().
* Alter the node_type_form form.
*/
function location_addanother_form_node_type_form_alter(&$form, &$form_state, $form_id) {
$type = $form['#node_type']->type;
$form['location_settings']['multiple']['location_addanother'] = array(
'#type' => 'checkbox',
'#title' => t('Add another location from node view page'),
'#default_value' => variable_get('location_addanother_' . $type, 0),
'#description' => t('Display the "Add another location" option on the node view page.'),
);
}
/**
* Form to display directly on a node view for "quick location add" functionality.
*/
function location_addanother_form($form, &$form_state, &$node) {
$settings = variable_get('location_settings_node_' . $node->type, array());
$form['location'] = array(
'#type' => 'location_element',
'#title' => t('Add another location'),
'#default_value' => NULL,
'#location_settings' => $settings['form']['fields'],
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['location']['nid'] = array(
'#type' => 'hidden', // @@@ See if we can get away with value-ing this.
'#value' => $node->nid,
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Add location'),
'#weight' => 50,
);
return $form;
}
/**
* Validation function for "add another location" form.
*/
function location_addanother_form_validate($form, &$form_state) {
$location = $form_state['values']['location'];
$node = node_load($location['nid']);
unset($location['nid']);
if (!(variable_get('location_addanother_' . $node->type, 0) && count($node->locations) < variable_get('location_maxnum_' . $node->type, 0) && node_access('update', $node))) {
form_set_error('location', t("You don't have permission to add a location to this node, or the node has the maximum number of locations already."));
}
}
/**
* Submission function for "add another location" form.
*/
function location_addanother_form_submit($form, &$form_state) {
$location = $form_state['values']['location'];
$node = node_load($location['nid']);
$locations = $node->locations;
unset($location['nid']);
$locations[] = $location;
location_save_locations($locations, array('nid' => $node->nid, 'vid' => $node->vid));
return 'node/' . $node->nid;
}
/**
* Implements hook_node_type_delete().
* Synchronize our settings.
*/
function hook_node_type_delete($info) {
variable_del('location_addanother_' . $info->type);
}
/**
* Implements hook_node_type_update().
* Synchronize our settings.
*/
function hook_node_type_update($info) {
if (!empty($info->old_type) && $info->old_type != $info->type) {
$setting = variable_get('location_addanother_' . $info->old_type, 0);
variable_del('location_addanother_' . $info->old_type);
variable_set('location_addanother_' . $info->type, $setting);
}
}

View File

@@ -0,0 +1,15 @@
name = Location CCK
description = Defines a Location field type.
dependencies[] = location
package = CCK
core = 7.x
files[] = location_cck.module
files[] = location_cck.install
; Information added by drupal.org packaging script on 2012-02-18
version = "7.x-3.x-dev"
core = "7.x"
project = "location"
datestamp = "1329524299"

View File

@@ -0,0 +1,48 @@
<?php
/**
* @file
* Install, update and uninstall functions for the location_cck module.
*/
/**
* Drupal 6 location_cck 3.x update.
*/
function location_cck_update_6301() {
// Create a temporary table to fix some location_instance data.
$schema = drupal_get_schema('location_instance');
$schema['description'] = 'Temp table to repair data integrity of location_instance table.';
unset($schema['indexes']);
db_create_table('location_instance_tmp', $schema);
// Populate the temporary table.
$join_select = db_select('location_instance', 'li');
$join_select->addExpression("SUBSTRING_INDEX(genid, ':', -1)", 'genvid');
$join_select->fields('li', array('lid', 'genid'));
$insert_select = db_select('node', 'n')
->fields('n', array('nid', 'vid'))
->fields('l', array('genid', 'lid'))
->join($join_select, 'l', 'n.vid = l.genvid');
db_insert('location_instance_tmp')
->fields(array('nid', 'vid', 'genid', 'lid'))
->from($insert_select)
->execute();
// Update the location_instance table.
db_delete('location_instance')
->condition('genid', 'cck:%', 'LIKE')
->execute();
$insert_select = db_select('location_instance_tmp', 'lit')
->fields('lit', array('nid', 'vid', 'genid', 'lid'));
db_insert('location_instance')
->fields(array('nid', 'vid', 'genid', 'lid'))
->from($insert_select)
->execute();
// Remove the temporary table.
db_drop_table('location_instance_tmp');
}

View File

@@ -0,0 +1,617 @@
<?php
/**
* @file
* Defines location field type.
*/
/**
* Implements hook_theme().
*/
function location_cck_theme() {
return array(
'location_cck_field_all' => array(
'variables' => array(
'location' => NULL,
'hide' => array(),
'field' => NULL,
'instance' => NULL,
),
),
'location_cck_field_map' => array(
'variables' => array(
'locations' => NULL,
'field' => NULL,
'instance' => NULL,
),
),
'location_cck_field_popup' => array(
'variables' => array(
'location' => NULL,
'instance' => NULL,
),
),
);
}
/**
* Implements hook_field_info().
*/
function location_cck_field_info() {
return array(
'location' => array(
'label' => t('Location'),
'description' => t('Store a location.module location.'),
'settings' => array(),
'instance_settings' => array(),
'default_widget' => 'location',
'default_formatter' => 'location_default',
),
);
}
/**
* Implement hook_field_settings_form().
*/
function location_cck_field_settings_form($field, $instance, $has_data) {
$settings = isset($field['settings']['location_settings']) ? $field['settings']['location_settings'] : array();
$form = array();
$form['location_settings'] = location_settings($settings);
// Multiple is handled by CCK.
unset($form['location_settings']['multiple']);
// CCK handles weight, and collapsibility is not changeable.
unset($form['location_settings']['form']['weight']);
unset($form['location_settings']['form']['collapsible']);
unset($form['location_settings']['form']['collapsed']);
unset($form['location_settings']['display']['weight']);
// We want to see the settings, so uncollapse them.
$form['location_settings']['#collapsible'] = FALSE;
$form['location_settings']['form']['#collapsed'] = FALSE;
$form['location_settings']['display']['#collapsed'] = FALSE;
// Add some GMap settings, if GMap is enabled.
if (module_exists('gmap')) {
$form['gmap_macro'] = array(
'#type' => 'textarea',
'#title' => t('GMap Macro'),
'#rows' => 2,
'#maxlength' => 500,
'#description' => t('A macro to be used as a base map for this field. This map will be recentered on the location, so the center is not that important.'),
'#default_value' => !empty($field['settings']['gmap_macro']) ? $field['settings']['gmap_macro'] : '[gmap ]',
);
$options = gmap_get_marker_titles();
$form['gmap_marker'] = array(
'#type' => 'select',
'#title' => t('GMap marker'),
'#options' => $options,
'#default_value' => !empty($field['settings']['gmap_marker']) ? $field['settings']['gmap_marker'] : 'drupal',
);
}
else {
// Preserve existing data, apply defaults even if gmap is disabled.
$form['gmap_macro'] = array(
'#type' => 'value',
'#value' => !empty($field['settings']['gmap_macro']) ? $field['settings']['gmap_macro'] : '[gmap ]',
);
$form['gmap_marker'] = array(
'#type' => 'value',
'#value' => !empty($field['settings']['gmap_marker']) ? $field['settings']['gmap_marker'] : 'drupal',
);
}
return $form;
}
/**
* Implements hook_field_settings().
*/
function location_cck_field_settings($op, $field) {
switch ($op) {
case 'views data':
// We want to for the most part use the CCK stuff, but we also want to
// patch in a relationship so location's views support can target
// cck fields directly.
$table = content_views_tablename($field);
$db_info = content_database_info($field);
$field_alias = $db_info['columns']['lid']['column'];
$data = content_views_field_views_data($field);
$data[$table][$field_alias]['relationship'] = array(
'base' => 'location',
'field' => 'lid',
'handler' => 'views_handler_relationship',
'label' => t('Location'), // @@@ Some sort of better name?
);
return $data;
}
}
/**
* Implement hook_field_schema().
*/
function location_cck_field_schema($field) {
switch ($field['type']) {
case 'location':
$columns = array(
'lid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => FALSE,
),
);
break;
}
return array(
'columns' => $columns,
'indexes' => array('lid' => array('lid')),
);
}
/**
* Implement hook_field_insert().
*/
function location_cck_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
if ($entity_type == 'node') {
if (!empty($items)) {
// Store instances of locations by field name and vid.
$criteria = array(
'genid' => 'cck:' . $field['field_name'] . ':' . $entity->vid,
'vid' => $entity->vid,
'nid' => $entity->nid,
);
location_save_locations($items, $criteria);
}
}else{
if (!empty($items)) {
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
// Store instances of locations by field name and vid.
$criteria = array(
'genid' => 'field:' . $field['field_name'] . ':' . $entity_type . ':' . $id,
'vid' => $vid ? $vid : $id,
'nid' => $id,
);
location_save_locations($items, $criteria);
}
}
}
/**
* Implement hook_field_update().
*/
function location_cck_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
if ($entity_type == 'node') {
if (!empty($items)) {
// Store instances of locations by field name and vid.
$criteria = array(
'genid' => 'cck:' . $field['field_name'] . ':' . $entity->vid,
'vid' => $entity->vid,
'nid' => $entity->nid,
);
location_save_locations($items, $criteria);
}
}else{
if (!empty($items)) {
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
// Store instances of locations by field name and vid.
$criteria = array(
'genid' => 'field:' . $field['field_name'] . ':' . $entity_type . ':' . $id,
'vid' => $vid ? $vid : $id,
'nid' => $id,
);
location_save_locations($items, $criteria);
}
}
}
/**
* Implement hook_field_delete().
*/
function location_cck_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
if ($entity_type == 'node') {
// @TODO: Fix this properly.
// Use the CCK storage to figure out the vids that need to be deleted,
// and clean up all the applicable references.
// $db_info = content_database_info($field);
// $result = db_query('SELECT vid FROM {' . $db_info['table'] . '} WHERE nid = :nid', array(':nid' => $node->nid));
$result = db_query('SELECT vid FROM {node_revision} WHERE nid = :nid', array(':nid' => $entity->nid));
foreach ($result as $row) {
$genid = 'cck:' . $field['field_name'] . ':' . $row->vid;
$locs = array();
location_save_locations($locs, array('genid' => $genid));
}
}else {
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
$genid = 'field:' . $field['field_name'] . ':' . $entity_type . ':' . $id;
$locs = array();
location_save_locations($locs, array('genid' => $genid));
}
}
/**
* Implement hook_field_delete_revision().
*/
function location_cck_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
if ($entity_type == 'node') {
$genid = 'cck:' . $field['field_name'] . ':' . $entity->vid;
$locs = array();
location_save_locations($locs, array('genid' => $genid));
}else{
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
$genid = 'field:' . $field['field_name'] . ':' . $entity_type . ':' . $id;
$locs = array();
location_save_locations($locs, array('genid' => $genid));
}
}
/**
* Implement hook_field_validate().
*/
function location_cck_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
// @@@ Fixme
}
/**
* Implement hook_field_load().
*/
function location_cck_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
// if ($entity_type == 'node') {
foreach ($entities as $id => $entity) {
foreach ($items[$id] as $delta => $item) {
$location = array();
// Load the location if it exists.
// If we are previewing a new node it will not.
if (!empty($item['lid'])) {
$location = location_load_location($item['lid']);
}
// Combine the item with the location loaded from the database.
// This will allow $item to display in the case of previewing a node.
$items[$id][$delta] = array_merge($location, $item);
}
}
// }
}
/**
* Implements hook_field().
*/
function location_cck_field($op, &$node, $field, &$items, $teaser, $page) {
switch ($op) {
case 'sanitize':
// Get the location information for the lid if it hasn't already been
// loaded (in the hook_field() load $op using location_load_location()).
// This is necessary for Views and any other modules that use the
// content_format() function to render CCK fields because content_format()
// doesn't call the "load" $op.
foreach ($items as $delta => $item) {
if (!isset($item['latitude'])) {
$items[$delta] = array_merge($items[$delta], location_load_location($item['lid']));
}
}
break;
}
}
/**
* Implementation of hook_field_formatter_info().
*/
function location_cck_field_formatter_info() {
$info = array(
'location_default' => array(
'label' => t('Default (address)'),
'field types' => array('location'),
),
);
if (module_exists('gmap')) {
$info['location_all'] = array(
'label' => t('Address with map'),
'field types' => array('location'),
);
$info['location_map'] = array(
'label' => t('Map only'),
'field types' => array('location'),
);
// @@@ How to do in D7?
$info['location_multiple'] = array(
'label' => t('Multiple field values on a single map'),
'field types' => array('location'),
);
}
return $info;
}
/**
* Implements hook_field_formatter_view().
* @Todo: This.
*/
function location_cck_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$settings = $field['settings']['location_settings'];
$hide = (isset($settings['display']['hide'])) ? array_keys(array_filter($settings['display']['hide'])) : array();
switch ($display['type']) {
case 'location_default':
foreach ($items as $delta => $item) {
if (!empty($item['lid']) || !empty($entity->in_preview)) {
$element[$delta]['#theme'] = 'location';
$element[$delta]['#location'] = $item;
$element[$delta]['#hide'] = $hide;
}
}
break;
case 'location_all':
foreach ($items as $delta => $item) {
if (!empty($item['lid']) || !empty($entity->in_preview)) {
$element[$delta]['#theme'] = 'location_cck_field_all';
$element[$delta]['#location'] = $item;
$element[$delta]['#hide'] = $hide;
$element[$delta]['#field'] = $field;
$element[$delta]['#instance'] = $instance;
}
}
break;
case 'location_map':
foreach ($items as $delta => $item) {
if (!empty($item['lid']) || !empty($entity->in_preview)) {
$element[$delta]['#theme'] = 'location_cck_field_map';
$element[$delta]['#locations'] = array($item);
$element[$delta]['#field'] = $field;
$element[$delta]['#instance'] = $instance;
}
}
break;
case 'location_multiple':
$element[0]['#theme'] = 'location_cck_field_map';
$element[0]['#locations'] = $items;
$element[0]['#field'] = $field;
$element[0]['#instance'] = $instance;
break;
}
return $element;
}
/**
* Implements hook_field_widget_info().
*/
function location_cck_field_widget_info() {
return array(
'location' => array(
'label' => t('Location Field'),
'field types' => array('location'),
),
);
}
/**
* Implement hook_field_widget_form().
*/
function location_cck_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
if ($field['type'] == 'location') {
$settings = $field['settings']['location_settings'];
// Load location data for existing locations.
if ($form_state['rebuild'] && !empty($form_state['values'][$field['field_name']][$langcode][$delta])) {
$location = $form_state['values'][$field['field_name']][$langcode][$delta];
}
elseif (isset($items[$delta]['lid']) && $items[$delta]['lid']) {
$location = location_load_location($items[$delta]['lid']);
}
// Load location data passed by cck.
else if (isset($items[$delta]) && is_array($items[$delta]) && !empty($items[$delta])) {
// Initialize empty location.
$location = location_empty_location($settings);
foreach ($items[$delta] as $k => $v) {
$location[$k] = $v;
}
// We can't trust that CCK is giving us the right information.
// It can't tell us whether $items is defaults or multistep values.
// Location *needs* the defaults to match the initial field values,
// so we re-calculate the defaults here and stash them into the settings.
// @@@ There is still a bug here!
// If you go back and edit something, and you hadn't set a location the
// first time, CCK fails to set up the defaults properly!
// I'm just going to leave it like that for now, because I don't know how
// to work around it.
$temp = NULL; //content_default_value($form, $form_state, $field, 0);
if (is_array($temp) && isset($temp[$delta]) && is_array($temp[$delta])) {
foreach ($temp[$delta] as $k => $v) {
$settings['form']['fields'][$k]['default'] = $v;
}
}
// unset($location['location_settings']);
// unset($location['locpick']);
}
else {
$location = location_empty_location($settings);
}
$element = array(
'#type' => 'location_element',
'#has_garbage_value' => TRUE,
'#value' => '',
'#title' => t($instance['label']),
'#description' => t($instance['description']),
'#required' => $instance['required'],
'#location_settings' => $settings,
'#default_value' => $location,
);
return $element;
}
}
/**
* Implements hook_field_is_empty().
*/
function location_cck_field_is_empty($item, $field) {
$fields = array();
if (location_is_empty($item, $fields)) {
return TRUE;
}
return FALSE;
}
/**
* Return both an address and a map for an individual item.
*/
function theme_location_cck_field_all($variables) {
$content = theme('location', array('location' => $variables['location'], 'hide' => $variables['hide']));
$content .= theme_location_cck_field_map(array('locations' => array($variables['location']), 'field' => $variables['field'], 'instance' => $variables['instance']));
return $content;
}
/**
* Alternate function to return a map with all
* multiple values in the same map.
*/
function theme_location_cck_formatter_combined($variables) {
$location = $variables['element'];
$field = content_fields($element['#field_name'], $element['#type_name']);
$locations = $element['#items'];
return theme_location_cck_field_map(array('locations' => $locations, 'field' => $field));
}
/**
* Generate a GMap map for one or more location field values.
*
* Mostly just cut and paste from gmap_location
* block view.
*/
function theme_location_cck_field_map($variables) {
$locations = $variables['locations'];
$field = $variables['field'];
$instance = $variables['instance'];
$count = 0;
$content = '';
foreach ($locations as $location) {
if (location_has_coordinates($location)) {
$count++;
$markername = isset($field['settings']['gmap_marker']) ? $field['settings']['gmap_marker'] : 'drupal';
$markers[] = array(
'latitude' => $location['latitude'],
'longitude' => $location['longitude'],
'markername' => $markername,
'offset' => $count-1,
'text' => theme('location_cck_field_popup', array('location' => $location, 'instance' => $instance)),
);
}
}
if (!empty($markers)) {
$macro = !empty($field['settings']['gmap_macro']) ? $field['settings']['gmap_macro'] : '[gmap ]';
$map = array_merge(gmap_defaults(), gmap_parse_macro($macro));
$map['latitude'] = $markers[0]['latitude'];
$map['longitude'] = $markers[0]['longitude'];
$map['markers'] = $markers;
$map['id'] = gmap_get_auto_mapid();
// Render a map element.
$location_map = array(
'#type' => 'gmap',
'#gmap_settings' => $map,
);
$content = drupal_render($location_map);
}
return $content;
}
/**
* Theme the GMap popup text for the field.
*/
function theme_location_cck_field_popup($variables) {
$location = $variables['location'];
$instance = $variables['instance'];
$hide = (isset($field['location_settings']['display']['hide'])) ? array_keys(array_filter($field['location_settings']['display']['hide'])) : array();
// Don't use a map link in a popup!
// We're making the name into a title.
$hide[] = 'map_link';
$hide[] = 'name';
$markertitle = $instance['label'];
if (!empty($location['name'])) {
$markertitle = $location['name'];
}
return '<h4>'. $markertitle .'</h4>'. theme('location', array('location' => $location, 'hide' => $hide));
}
/**
* Implements hook_token_list().
*/
function location_cck_token_list($type = 'all') {
if ($type == 'field') {
$tokens = array();
$fields = location_field_names(TRUE);
// @@@ We really need to rethink fields in location..
unset($fields['locpick']);
foreach ($fields as $k => $v) {
$tokens['location'][$k] = $v;
}
return $tokens;
}
}
/**
* Implements hook_token_values().
*/
function location_cck_token_values($type, $object = NULL) {
if ($type == 'field') {
$tokens = array();
$item = $object[0];
if ($item['lid']) {
// If the location exists, we need to set up the tokens.
$location = array(
// There is no way to find out which elements to hide because $item does not contain
// the 'location_settings' element, so for now, just set it to be an empty array.
// See http://drupal.org/node/463618 for more infomation.
'hide' => array(),
'location' => location_load_location($item['lid']),
);
// @@@ This is rather silly, but I can't think of anything better at the moment.
$variables = array('location' => $location);
template_preprocess_location($variables);
$fields = location_field_names(TRUE);
// @@@ We really need to rethink fields in location..
unset($fields['locpick']);
foreach ($fields as $k => $v) {
if (isset($location[$k])) {
$tokens[$k] = $location[$k];
}
else {
$tokens[$k] = '';
}
}
}
return $tokens;
}
}
/**
* Implements hook_locationapi().
*/
function location_cck_locationapi(&$obj, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) {
switch ($op) {
case 'instance_links':
foreach ($obj as $k => $v) {
if (substr($v['genid'], 0, 4) == 'cck:') {
$data = explode(':', $v['genid']);
$obj[$k]['href'] = 'node/' . $data[2];
$obj[$k]['title'] = t('CCK location');
$obj[$k]['type'] = t('CCK location');
}
}
}
}

View File

@@ -0,0 +1,16 @@
name = Location Fax
package = Location
description = Allows you to add a fax number to a location.
dependencies[] = location
core = 7.x
files[] = location_fax.module
files[] = location_fax.install
files[] = location_fax.views.inc
; Information added by drupal.org packaging script on 2012-02-18
version = "7.x-3.x-dev"
core = "7.x"
project = "location"
datestamp = "1329524299"

View File

@@ -0,0 +1,115 @@
<?php
/**
* @file
* Install, update and uninstall functions for the location_fax module.
*/
/**
* Implements hook_schema().
*/
function location_fax_schema() {
$schema['location_fax'] = array(
'description' => 'location_fax.module {location} supplementary table.',
'fields' => array(
'lid' => array(
'description' => '{location}.lid',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'fax' => array(
'description' => 'Fax number',
'type' => 'varchar',
'length' => 31,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array('lid'),
);
return $schema;
}
/**
* Implements hook_install().
*/
function location_fax_install() {
// Change weight so we execute after location.
db_update('system')
->fields(array(
'weight' => 1,
))
->condition('name', 'location_fax')
->condition('type', 'module')
->execute();
}
/**
* Location 3.0 update 1.
* Fix pgsql -- The table definition was broken.
*/
function location_fax_update_5300() {
if (!db_table_exists('location_fax')) {
$schema['location_fax'] = array(
'description' => 'location_fax.module {location} supplementary table.',
'fields' => array(
'lid' => array(
'description' => '{location}.lid',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'fax' => array(
'description' => 'Fax number',
'type' => 'varchar',
'length' => 31,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array('lid'),
);
db_create_table('location_fax', $schema['location_fax']);
}
}
/**
* Location 3.0 update 2.
* Change weight of module.
*/
function location_fax_update_5301() {
// This update was moved to update 5302.
}
/**
* Location 3.0 update 2.
* Change weight of module.
*/
function location_fax_update_5302() {
// Change weight.
db_update('system')
->fields(array(
'weight' => 1,
))
->condition('name', 'location_fax')
->condition('type', 'module')
->execute();
}
/**
* Drupal 6 updates.
*/
function location_fax_update_6301() {
db_change_field('location_fax', 'fax', 'fax', array(
'description' => 'Fax number',
'type' => 'varchar',
'length' => 31,
'not null' => TRUE,
'default' => '',
));
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* @file
* Add fax number fields to Location address.
*/
/**
* Implements hook_locationapi().
*/
function location_fax_locationapi(&$location, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'fields':
return array('fax' => t('Fax number'));
case 'defaults':
return array(
'fax' => array('default' => '', 'collect' => 0, 'weight' => 30),
);
case 'field_expand':
if ($a3 == 'fax') {
return array(
'#type' => 'textfield',
'#title' => t('Fax number'),
'#size' => 31,
'#maxlength' => 31,
'#description' => NULL,
'#required' => ($a4 == 2),
'#default_value' => $location,
);
}
break;
case 'save':
db_delete('location_fax')
->condition('lid', $location['lid'])
->execute();
if (!empty($location['fax'])) {
db_insert('location_fax')
->fields(array(
'lid' => $location['lid'],
'fax' => $location['fax'],
))
->execute();
}
break;
case 'load':
$fields = array();
$fax = db_query('SELECT fax FROM {location_fax} WHERE lid = :lid', array(':lid' => $location['lid']))->fetchField();
$fields['fax'] = $fax ? $fax : '';
return $fields;
case 'delete':
db_delete('location_fax')
->condition('lid', $location['lid'])
->execute();
break;
}
}
/**
* Implements hook_views_api().
*/
function location_fax_views_api() {
return array(
'api' => 3,
);
}
/**
* Implements hook_token_list().
*/
function location_fax_token_list($type = 'all') {
if ($type == 'node' || $type == 'user' || $type == 'all') {
$tokens['location']['location-fax_N'] = t('Location Fax number (If there are multiple locations per node, N is the iteration, starting with 0)');
return $tokens;
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* @file
* Views 3 support for Location Fax.
*/
/**
* Implements hook_views_data().
*/
function location_fax_views_data() {
// ----------------------------------------------------------------
// location_fax table -- basic table information.
// Define the base group of this table. Fields that don't
// have a group defined will go into this field by default.
$data['location_fax']['table']['group'] = t('Location');
// Join location_fax to all the tables that would be useful
$data['location_fax']['table']['join'] = array(
// location_fax links to location via lid.
'location' => array(
'left_field' => 'lid',
'field' => 'lid',
),
// location_fax links to node through location_instance via lid.
'node' => array(
'left_table' => 'location_instance',
'left_field' => 'lid',
'field' => 'lid',
),
// location_fax links to node_revision through location_instance via lid.
'node_revision' => array(
'left_table' => 'location_instance',
'left_field' => 'lid',
'field' => 'lid',
),
// location_fax links to users through location_instance via lid.
'users' => array(
'left_table' => 'location_instance',
'left_field' => 'lid',
'field' => 'lid',
),
);
// ----------------------------------------------------------------
// location_fax table -- fields
$data['location_fax']['fax'] = array(
'title' => t('Fax'),
'help' => t('The fax number of the selected location.'),
'field' => array(
'click sortable' => TRUE,
),
'argument' => array(
'handler' => 'views_handler_argument_string',
'empty field name' => t('None'),
),
'filter' => array(
'handler' => 'views_handler_filter_string',
'allow empty' => TRUE,
),
);
return $data;
}

View File

@@ -0,0 +1,15 @@
name = Location Generate
description = Bulk assign random latitude and longitudes to nodes.
package = Development
dependencies[] = devel_generate
dependencies[] = location
core = 7.x
files[] = location_generate.module
; Information added by drupal.org packaging script on 2012-02-18
version = "7.x-3.x-dev"
core = "7.x"
project = "location"
datestamp = "1329524299"

View File

@@ -0,0 +1,90 @@
<?php
/**
* @file
* Generate random locations.
*/
/**
* Implements hook_node_presave().
*/
function location_generate_node_presave($node) {
// Devel.module bulk node generation.
if (isset($node->devel_generate)) {
// Argh, we inherit a broken rand() on windows because devel_generate
// calls array_rand()...
// http://bugs.php.net/bug.php?id=45301
srand((double) microtime() * 1000000);
$sources = array(LOCATION_LATLON_USER_SUBMITTED, LOCATION_LATLON_GEOCODED_APPROX, LOCATION_LATLON_GEOCODED_EXACT);
$results = $node->devel_generate;
if ($results['add_locations']) {
$countries = location_get_iso3166_list();
$numlocs = rand(0, (int) variable_get('location_maxnum_' . $node->type, 0));
$node->locations = array();
for ($i = 0; $i < $numlocs; $i++) {
$country_code = array_rand($countries);
$provinces = location_get_provinces($country_code);
$province_code = array_rand($provinces);
$location = array(
'lid' => NULL,
'name' => devel_create_greeking(mt_rand(1, 4), TRUE),
'street' => location_generate_generate_street(),
'additional' => '',
'city' => devel_generate_word(mt_rand(5, 15)),
'province' => $province_code,
'postal_code' => mt_rand(1000, 99999),
'country' => $country_code,
'latitude' => (float) ((mt_rand(0, 120000) - 60000) / 1000),
'longitude' => (float) ((mt_rand(0, 360000) - 180000) / 1000),
'source' => $sources[rand(0, 2)],
'inhibit_geocode' => TRUE,
);
$settings = variable_get('location_settings_node_' . $node->type, array());
$location['location_settings'] = $settings;
$node->locations[] = $location;
}
}
}
}
/**
* Implements hook_form_FORM_ID_alter().
* Alter the devel_generate_content_form form.
*/
function location_generate_form_devel_generate_content_form_alter(&$form, &$form_state) {
$form['add_locations'] = array(
'#type' => 'checkbox',
'#title' => t('Add locations to each node.'),
'#description' => t('Added by location_generate.module'),
'#default_value' => FALSE,
);
if (!isset($form['submit']['#weight'])) {
$form['submit']['#weight'] = 1;
}
}
/**
* Helper function to generate street values.
*/
function location_generate_generate_street() {
$type = array(
'Street' => 'Street',
'Road' => 'Road',
'Boulevard' => 'Boulevard',
'Way' => 'Way',
'Terrace' => 'Terrace',
'Row' => 'Row',
'Lane' => 'Lane',
'Place' => 'Place',
'Close' => 'Close',
'Court' => 'Court',
'Alley' => 'Alley',
'Crescent' => 'Crescent',
'Parkway' => 'Parkway',
);
return mt_rand(1, 9999) . ' ' . devel_create_greeking(mt_rand(1, 3), TRUE) . ' ' . array_rand($type);
}

View File

@@ -0,0 +1,16 @@
name = Location Phone
package = Location
description = Allows you to add a phone number to a location.
dependencies[] = location
core = 7.x
files[] = location_phone.module
files[] = location_phone.install
files[] = location_phone.views.inc
; Information added by drupal.org packaging script on 2012-02-18
version = "7.x-3.x-dev"
core = "7.x"
project = "location"
datestamp = "1329524299"

View File

@@ -0,0 +1,120 @@
<?php
/**
* @file
* Install, update and uninstall functions for the location_phone module.
*/
/**
* Implements hook_schema().
*/
function location_phone_schema() {
$schema['location_phone'] = array(
'description' => 'location_phone.module {location} supplementary table.',
'fields' => array(
'lid' => array(
'description' => '{location}.lid',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'phone' => array(
'description' => 'Phone number',
'type' => 'varchar',
'length' => 31,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array('lid'),
);
return $schema;
}
/**
* Implements hook_install().
*/
function location_phone_install() {
// Change weight.
db_update('system')
->fields(array(
'weight' => 1,
))
->condition('name', 'location_phone')
->condition('type', 'module')
->execute();
}
/**
* Location 3.0 update 1.
* Fix pgsql -- The table definition was broken.
*/
function location_phone_update_5300() {
if (!db_table_exists('location_phone')) {
$schema['location_phone'] = array(
'description' => 'location_phone.module {location} supplementary table.',
'fields' => array(
'lid' => array(
'description' => '{location}.lid',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'phone' => array(
'description' => 'Phone number',
'type' => 'varchar',
'length' => 31,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array('lid'),
);
db_create_table('location_phone', $schema['location_phone']);
}
else {
// If the table WAS created (i.e. user manually fixed bug and reinstalled), g/c the postal_code column.
if (db_field_exists('location_phone', 'postal_code')) {
db_drop_field('location_phone', 'postal_code');
}
}
}
/**
* Location 3.0 update 2.
* Change weight of module.
*/
function location_phone_update_5301() {
// This update was moved to update 5302.
}
/**
* Location 3.0 update 2.
* Change weight of module.
*/
function location_phone_update_5302() {
// Change weight.
db_update('system')
->fields(array(
'weight' => 1,
))
->condition('name', 'location_phone')
->condition('type', 'module')
->execute();
}
/**
* Drupal 6 updates.
*/
function location_phone_update_6301() {
db_change_field('location_phone', 'phone', 'phone', array(
'description' => 'Phone number',
'type' => 'varchar',
'length' => 31,
'not null' => TRUE,
'default' => '',
));
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* @file
* Add phone number fields to Location address.
*/
/**
* Implements hook_locationapi().
*/
function location_phone_locationapi(&$location, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'fields':
return array('phone' => t('Phone number'));
case 'defaults':
return array(
'phone' => array('default' => '', 'collect' => 0, 'weight' => 25),
);
case 'field_expand':
if ($a3 == 'phone') {
return array(
'#type' => 'textfield',
'#title' => t('Phone number'),
'#size' => 31,
'#maxlength' => 31,
'#description' => NULL,
'#required' => ($a4 == 2),
'#default_value' => $location,
);
}
break;
case 'save':
db_delete('location_phone')
->condition('lid', $location['lid'])
->execute();
if (!empty($location['phone'])) {
db_insert('location_phone')
->fields(array(
'lid' => $location['lid'],
'phone' => $location['phone'],
))
->execute();
}
break;
case 'load':
$fields = array();
$phone = db_query('SELECT phone FROM {location_phone} WHERE lid = :lid', array(':lid' => $location['lid']))->fetchField();
$fields['phone'] = $phone ? $phone : '';
return $fields;
case 'delete':
db_delete('location_phone')
->condition('lid', $location['lid'])
->execute();
break;
}
}
/**
* Implements hook_views_api().
*/
function location_phone_views_api() {
return array(
'api' => 3,
);
}
/**
* Implements hook_token_list().
*/
function location_phone_token_list($type = 'all') {
if ($type == 'node' || $type == 'user' || $type == 'all') {
$tokens['location']['location-phone_N'] = t('Location Phone number (If there are multiple locations per node, N is the iteration, starting with 0)');
return $tokens;
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* @file
* Views 3 support for Location Phone.
*/
/**
* Implements hook_views_data().
*/
function location_phone_views_data() {
// ----------------------------------------------------------------
// location_phone table -- basic table information.
// Define the base group of this table. Fields that don't
// have a group defined will go into this field by default.
$data['location_phone']['table']['group'] = t('Location');
// Join location_phone to all the tables that would be useful
$data['location_phone']['table']['join'] = array(
// location_phone links to location via lid.
'location' => array(
'left_field' => 'lid',
'field' => 'lid',
),
// location_phone links to node through location_instance via lid.
'node' => array(
'left_table' => 'location_instance',
'left_field' => 'lid',
'field' => 'lid',
),
// location_phone links to node_revision through location_instance via lid.
'node_revision' => array(
'left_table' => 'location_instance',
'left_field' => 'lid',
'field' => 'lid',
),
// location_phone links to users through location_instance via lid.
'users' => array(
'left_table' => 'location_instance',
'left_field' => 'lid',
'field' => 'lid',
),
);
// ----------------------------------------------------------------
// location_phone table -- fields
$data['location_phone']['phone'] = array(
'title' => t('Phone'),
'help' => t('The phone number of the selected location.'),
'field' => array(
'click sortable' => TRUE,
),
'argument' => array(
'handler' => 'views_handler_argument_string',
'empty field name' => t('None'),
),
'filter' => array(
'handler' => 'views_handler_filter_string',
'allow empty' => TRUE,
),
);
return $data;
}

View File

@@ -0,0 +1,547 @@
Note: This is currently broken and outdated.
The location search api is not ready for location 3.
This file describes the public API for the CivicSpace location system as defined by
in the library implemented by "location.inc" and its supporting files.
For a example of this API's usage, please consult "location.module"
FUNCTION SPECIFICATIONS DESCRIBED IN THIS FILE:
----------------------------------------------
location_nearby_postalcodes_bylocation(): A function that searches for postal codes within a specified search-radius
for a specified location.
location_nearby_postalcodes_bylatlon(): A function that searches for postal codes within a specified search-radius for
a specified latitude and longitude.
location_get_postalcode_data(): A function that takes a (postalcode,country) pair an returns lat/lon, city, province. This
function is meant to replace location_latlon_rough(); see below.
location_latlon_rough(): A function that returns the latitude and longitude of the specified postal-code/country pair.
This latitude and longitude will be of the approximate center of the postal-code's area. This function
will soon be removed from the API as it has been replaced by the more comprehensive
location_get_postalcode_data() described above. [TO BE DEPRECATED]
location_latlon_exact(): A function that returns the latitude and longitude of the given full location. Typically implemented
on top of a web-service. [TO BE IMPLEMENTED]
location_map_link(): A function that returns, based on the site configuration, either NULL or 1 or more deep-links to mapping
web sites for the parameter location array.
location_driving_directions_link(): A function that returns, given 2 locationes, a deep-link to Yahoo! Maps or some other site
that provides driving directions. The site chosen depends on the implementation at the country-level.
location_form(): A function that generates a form for collecting locative information. Depending on the parameters,
it can collect just the postal code and country or a full location or whatever fields are specified
in its parameters.
location_proximity_form(): A function that generates a form for collecting proximity search parameters.
location_valid(): A function for validating locationes. [TO BE SPECIFIED]
theme_location(): A function that takes in an location and themes it. (e.g., $output .= theme('location', $location)).
location_distance_between(): A function that, given a pair of lat/lon pairs, returns the distance between them.
location_form2api(): A function that, given an location submitted via a form generated by location_form, converts the
submitted location into a form to be used by the rest of the API.
location_api2form(): A function that, given an location in the standard array format (see "IMPORTANT NOTES" below)
returns an location in a format that can be passed to location_form in order to render the
form with the appropriate prefilled values.
"[TO BE SPECIFIED]" => Function spec has not been completed and may possibly be eliminated from spec.
"[TO BE IMPLEMENTED]" => Function spec exists but is to be implemented in a future release.
"[TO BE DEPRECATED]" => This function will soon be removed from the API.
----------------------------------------------
IMPORTANT NOTES:
----------------
Formats
---
In the following API, a 'location' is merely an associative array with the following keys:
'street' => A string for the street portion of an location
'additional' => A string for the additional street portion of an location
'province' => An upper-case, standard postal abbreviation of a state/province/territory
'postal_code' => A string or integer for the postal code
'country' => The lower-case of the ISO 3166 two-letter alpha code (e.g., 'us' for U.S., 'ca' for Canada).
For locations that are passed to location_form() for the $prefilled_values parameter, the same format applies
except that the 'province' field is the concatenation of the country code, '-', and the province abbreviation.
For example, 'CA' is the value for California for all purposes, but when passing this in a location for prefilled
values, it should be 'us-CA'. There are two functions to help convert back and forth between these formats:
location_form2api() and location_api2form(). These are described further below.
Delegation
---
With the exception of location_form() and location_proximity_form(), the calls to functions listed here are, in the end,
dispatched to country-specific location libraries which are implemented in country-specific '.inc' files. For example,
location_latlon_rough(), when given a U.S. location, really returns a result that is determined by call to
"location_latlon_rough_us()" which is implemented in the file "location.us.inc".
Current Implementation
---
Currently, the only country supported is the United States. For the future, however, there will be documentation for how to
implement a country-specific include file that can be plugged into the system to support these calls for new countries. This
scheme will revolve around method signatures for a handful of simple-to-write functions.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_nearby_postalcodes_bylocation($location, $distance, $distance_unit = 'km');
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes an location and a distance and returns an array of all postal-codes (from all countries that are supported)
within the specified distance of the specified location.
@param $location
An associative array where
'street' => the street location
'additional' => extra street location or building name or hall or something like that.
'city' => a city name
'province' => province code as defined by the country specific include file
'country' => lower-cased two-letter ISO 3166 code (REQUIRED)
'postal_code' => the postal_code
@param $distance
The number portion of the distance; it is forced to an integer ceiling
@param $distance_unit
The unit of distance being used for the distance being submitted.
Valid arguments for $distance_unit are 'mile' and 'km'. If something other than one of
these unit types is submitted for this argument, it is forced to 'km'.
@return
An array where
-> the keys are a postive integer ranking of the search result's closeness to the parameter $postal_code
with 1 being assigned to the nearest postal code
-> the values are an associative array where
'postal_code' => A postal code that fell within the search-radius given by $distance and $distance_unit.
'country' => The two-letter ISO code for the home-country of this particular postal_code search result.
'city' => The city to which this postal code belongs.
'province' => The province to which this postal code belongs.
'lon' => The longitude coordinate of the approximate center of the area covered by 'postal_code'
'lat' => The latitude coordinate of the approximate center of the area covered by 'postal_code'
'distance' => The number of 'km's or 'mile's that are between the approximate center of the area of
the $postal_code parameter and that of the 'postal_code' in this subarray
'distance_unit' => The unit of distance specified by 'scalar'
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_nearby_postalcodes_bylatlon($lon, $lat, $distance, $distance_unit = 'km');
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes a latitude, longitude, and a distance, and returns all postal_codes within
@param $lon
A floating point of the longitude coordinate of the search point
@param $lat
A floating point of the latitude coordinate of the search point
@param $distance
The number portion of the distance; it is forced to an integer ceiling
@param $distance_unit
The unit of distance being used for the distance being submitted.
Valid arguments for $distance_unit are 'mile' and 'km'. If something other than one of
these unit types is submitted for this argument, it is forced to 'km'.
@return
An array where
-> the keys are a contatenation of the country's ISO code and the postal code. For example, if
one of the search results is for postal code "94803" in the United States, the key is then "us94803"
-> the values are an associative array where
'postal_code' => A postal code that fell within the search-radius given by $distance and $distance_unit.
'country' => The two-letter ISO code for the home-country of this particular postal_code search result.
'lon' => The longitude coordinate of the approximate center of the area covered by 'postal_code'
'lat' => The latitude coordinate of the approximate center of the area covered by 'postal_code'
'distance' => The number of 'km's or 'mile's that are between the approximate center of the area of the
$postal_code parameter and that of the 'postal_code' in this array
'distance_unit' => The unit of distance specified by 'distance'
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_get_postalcode_data($location = array()); +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes a location and uses the combination of postal code and country to return an array that gives the
city, province, and lat/lon dat for that postal code.
@param $location
An associative array $location where
'street' => the street portion of the location
'additional' => additional street portion of the location
'province' => the province, state, or territory
'country' => lower-cased two-letter ISO code (REQUIRED)
'postal_code' => international postal code (REQUIRED)
@return
NULL if data cannot be found.
Otherwise, an associative array where
'lat' => is a floating point of the latitude coordinate of this location
'lon' => is a floating point of the longitude coordinate of this location
'city' => is a string for the city this postalcode is in (or the most recognized city at the given postal)
'province' => the province of the given postal code.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_latlon_rough($location = array()); +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes an location and returns a "rough" latitude/longitude pair based on the postal code
data available for the given country.
@param $location
An associative array $location where
'street' => the street portion of the location
'additional' => additional street portion of the location
'province' => the province, state, or territory
'country' => lower-cased two-letter ISO code (REQUIRED)
'postal_code' => international postal code (REQUIRED)
@return
NULL if data cannont be found.
Otherwise, an associative array where
'lat' => is a floating point of the latitude coordinate of this location
'lon' => is a floating point of the longitude coordinate of this location
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_latlon_exact($location = array()); +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Currently, this is not a priority until there is an implementable use for exact longitude,
latitude coordinates for an location. The idea is that this call will eventually retrieve
information through a web-service. Whereas location_latlon_rough() returns an approximate
lat/lon pair based strictly on the postal code where this lat/lon pair is pulled from a
database table, this function is intended to send the entire location to a web-service and
to retrieve exact lat/lon coordinates.
@param $location
An array where
-> the key values are 'street', 'additional', 'province', 'country', 'postal_code'
-> the values are:
'street' => the string representing the street location (REQUIRED)
'additional' => the string representing the additional street location portion in the location form
'city' => the city name (REQUIRED)
'province' => the province code defined in the country-specific include file
'country' => the lower-case of the two-letter ISO code (REQUIRED)
'postal_code' => the postal-code (REQUIRED)
@return
NULL if the delegated-to function that does the actual look-up does not exist.
If the appropriate function exists, then this function returns an associative array where
'lon' => A floating point number for the longitude coordinate of the parameter location
'lat' => A floating point number for the latitude coordinate of the parameter location
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_map_link($location = array(), $link_text = 'See map'); +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Get deep-links to a mapping services such as Yahoo! Maps or MapQuest (actual providers depend on configuration
of location module) given a location. The call is delegated based on the 'country' value in the $location parameter.
@param $location
An associative array where
'street' => A string representing the street location
'additional' => A string for any additional portion of the street location
'city' => A string for the city name
'province' => The standard postal abbreviation for the province
'country' => The two-letter ISO code for the country of the location (REQUIRED)
'postal_code' => The international postal code for the location
@return
NULL if there are not mapping providers configured for the country or if no links could be generated.
A string of the form "See map: Yahoo! Maps, MapQuest" where Yahoo! Maps and Mapquest are links to the
given location and can be replaced with other options (e.g., Google) available in the location module settings.
The idea is to encode the appropriate parameters as HTTP GET variables to the URL.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_driving_directions_link($locationA = array(), $locationB = array(), $link_text = 'Get directions');
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes two locationes and tries to return a deep-link to driving directions.
Parameters:
@param $locationA
An associative array that represents an location where
'street' => the street portions of the location
'additional' => additional street portion of the location
'city' => the city name
'province' => the province, state, or territory
'country' => lower-cased two-letter ISO code (REQUIRED)
'postal_code' => the postal code
@param $locationB
An associative array that represents an location in the same way that
parameter $locationA does.
@param $link_text
The text of the HTML link that is to be generated.
@return
A deep-link to driving directions on Yahoo! or some other mapping service, if enough fields are filled in the parameters.
A deep-link to a form for driving directions with information pre-filled if not enough, but some fields are filled in the parameters.
The empty string if no information is provided (or if so little information is provided that there is no function to which to delegate
the call.
We dispatch the call to a country-specific function. The country-specific function, in this case,
will be the one reflected by the country parameter of the first function. We require that
both locationes supplied have a country field at the minimum.
The country-specific functions will ultimately decide, with the parameters given, whether to
to link to a form for driving directions is provided, where this form will be
pre-populated with whatever values were available or whether to link directly to the driving
directions themselves if enough fields are filled for each location.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_form($fields = array(), $prefilled_values = array(), $required_fields = array(), $description = '', $form_name = 'location', $function = NULL);
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Generates a Drupal HTML form for collecting locationes.
@param $fields
An array of values where each value is one of 'street', 'city', 'province', 'postal_code', or 'country'.
The presence of values in this array determines which fields will be served in the location form generated
by a call to this function. If this array is empty, all fields are generated.
@param $prefilled_values
An associative array where
-> Each key is one of the location fields: 'street', 'additional', 'city', 'province', 'postal_code', 'country'
-> Each value is a prefilled value for the given field. ..... ))
@param $required_fields
An array of values that are required. Each string can be one of 'street', 'city', 'postal_code', 'province', or 'country'.
The presence of values in this array determines which fields will be marked as 'required'. Validation (i.e., making sure
a required value is actually filled in is the responsibility of the caller)
@param $description
A text description of specifically what location is being collected by the form to be served.
@param $form_name
An additional parameter to help prevent HTML input name collisions. If the caller is using this
function to generate more than 1 location form on a page, then the generated name for each HTML input's
"name" attribute will go by the value supplied for $form_name. This parameter is defaulted to 'location'
For example, if $form_name == 'xyz' and there is a 'street' field in the form to be served,
the "name" attribute for the HTML <input> will be "edit[xyz][street]"
@param $function
A string that tells location_form() which location API function will be using the location submitted via the
generated form. For example, if $function == 'latlon_rough', then the returned location_form (if it includes
a country field) will only generate a list of countries in the HTML select for which function location_latlon_rough()
is supported. To figure out which countries these are, we check to see which of the configured countries have existing
functions to support the call. In this case, we would check to see if there existed a function called "location_latlon_rough_us()"
before listing the United States in the HTML SELECT for the generated location form. $function is defaulted to NULL.
If $function is NULL, the HTML SELECT that is generated will list all countries.
@return
An location form based on the parameters specified. If the $fields array is empty, then the
function returns a form in which all possible fields are served as optional form items.
EXAMPLES:
-> The following call returns a form that only contains fields for a postal_code and country where
the postal_code is required:
---
$form = location_form(array('postal_code', 'country'), array(), array('postal_code', 'country'), 'Permanent location')
---
The form returned by this call is generated with calls to Drupal's 'form_' functions:
$form = form_textfield('Postal Code', 'location][postal_code', '', 64, 64, NULL, NULL, TRUE);
-------------------------------------------------------------------------------------------------
-> The following call returns a form that contains fields for a street, province, and postal_code,
but the street, city, and province fields are optional while postal_code is required:
---
$form = location_form(array('street', 'city', 'province', 'postal_code'), array(), array('postal_code'));
---
-> The form returned by this call is generated with the following calls to Drupal's 'form_' functions:
$form = form_textfield('Street', 'location][street', '', 64, 64);
$form .= form_textfield('Additional', 'location][additional', '', 64, 64);
// The 'Additional' field is always and only generated when 'street' is specified as one of the fields.
// The 'Additional' field is always optional whether or not 'Street' is required.
$form .= form_textfield('City', 'location][city', '', 64, 64);
$form .= _location_province_select_options(); // defined below
$form .= form_textfield('Postal Code', 'location][postal_code', '', 64, 64, NULL, NULL, TRUE);
------------------------------------------------------------------------------------------------
For the following examples, assume we have the following two locationes:
(1) $locationA = ('street' => '2010 Broadway St', 'city' => 'Redwood City', 'province' => 'CA', 'postal_code' => '94063', 'country' => 'us');
(2) $locationB = ('street' => '2010 Broadway St', 'city' => 'Redwood City', 'province' => 'us-CA', 'postal_code' => '94063', 'country' => 'us');
-> The following calls return the exact same form that contains fields for a street, province, postal_code, where prefilled
values are submitted to the form.
$form = location_form(array('street', 'city', 'province', 'postal_code', 'country'), $locationB, array('street', 'city', 'province', 'postal_code', country'), '', 'home_location');
$form = location_form(array('street', 'city', 'province', 'postal_code', 'country'), location_api2form($locationA), array('street', 'city', 'province', 'postal_code', 'country'), '', 'home_location');
-> The form returned by these call is ultimately generated with the following calls to Drupal's 'form_' functions:
$form = textfield('Street', 'home_location][street', '2010 Broadway St.', 64, 64, NULL, NULL, TRUE);
$form .= textfield('Additional', 'home_location][additional', 'Attn: Ankur Rishi', 64, 64, NULL, NULL, TRUE);
$form .= textfield('City', 'home_location][city', 'Redwood City', 64, 64, NULL, NULL, TRUE);
$form .= _location_province_select_options(TRUE, 'us-CA', 'home_location');
$form .= textfield('Postal Code', 'home_location][postal_code', '94063', 64, 64, NULL, NULL, TRUE);
$form .= _location_country_select_options(TRUE, 'us', 'home_location');
Note that in both cases, the first and third argument can take the same array since all the fields are being required.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_proximity_form($location_form = '', $label = '', $description = '', $prefilled_values = array(), $form_name = 'location');
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
This function generates a form for doing proximity searches within a certain distance
of a specified point.
Depending on the context within which this function is called, the search-point can either
be user-supplied via the location form that is passed (if one is available) or done within
a search-point extracted from a contact table or some other location source specified by
the programmer calling this function.
@param $location_form
An optional location form, preferably generated by location_form(). If the script processing this
form also needs a user-supplied location, this parameter is used to specify a form for collecting the
search-point about which this search is being done. If the caller does not supply a form, it is
assumed that the caller already has a search point in mind and that this will be made clear in
the $description parameter.
@param $label
The label you want to apply to the form group that is returned (passed as $legend param to form_group()).
@param $description
A text description of what is being searched for (e.g., 'Find all upcoming events near you.')
@param $prefilled_values
An associative array for prefilled values for the proximity search parameters, where
'distance' => is the prefilled int value to be selected for the distance scalar
'distance_unit' => is 'km' or 'mile'
@param $form_name
An additional parameter to help prevent HTML input name collisions. If the caller is using this
function to generate more than 1 location proximity form on a page, then the generated name for
each HTML input's "name" attribute will be $form_name. Allowing the caller to pass $form_name allows
the caller the flexibility of using more than one location proximity search form on one page.
@return
An HTML form (generated by Drupal form functions) that lets users specify proximity search parameters that include distance,
the unit of distance, and a search-point if the optional $location_form parameter is passed. If one is not passed,
the caller of this function will be assumed to already have one.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function theme_location($location = array()); +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Generates HTML for the passed location.
@param $location
An associative array where
'street' => A string representing the street location
'additional' => A string for any additional portion of the street location
'city' => A string for the city name
'province' => The standard postal abbreviation for the province
'country' => The two-letter ISO code for the country of the location (REQUIRED)
'postal_code' => The international postal code for the location
@return
An HTML string with special tags for locationes.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_distance_between($latlonA = array(), $latlonB = array(), $distance_unit = 'km'); +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Given two points in lat/lon form, returns the distance between them.
@param $latlonA
An associative array where
'lon' => is a floating point of the longitude coordinate for the point given by latlonA
'lat' => is a floating point of the latitude coordinate for the point given by latlonB
@param $latlonB
Another point formatted like $latlonB
@param $distance_unit
A string that is either 'km' or 'mile'.
If neither 'km' or 'mile' is passed, the parameter is forced to 'km'
@return
NULL if sense can't be made of the parameters.
An associative array where
'scalar' => Is the distance between the two lat/lon parameter points
'distance_unit' => Is the unit of distance being represented by 'scalar'.
This will be 'km' unless 'mile' is passed for the $distance_unit param
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_form2api($location = array()); +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@param $location
An associative array that has been submitted by an HTML form generated by location_form().
@return
An associative array in which the submitted values are modified to pass to the location API
as the $location parameter (excepting location_form()).
This means changing the province field to remove the country code and dash.
For example: California is served by the key 'us-CA' in the location form and this is what is passed when it is
submitted through a form generated by location_form().
This is changed to 'CA' in the returned array.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_api2form($location = array()); +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Inverse of location_form2api()
@param $location
An associative array that can be passed as the $location parameter to the location API.
@return
An associative array with the same values modified so that the array can be passed as the
$prefilled_values parameter to location_api2form()
Meant to take the standard location array format used by the public API (minus the form generating functions) and convert them
into values that can be used by location_form() to fill in the prefilled values.

View File

@@ -0,0 +1,36 @@
<?php
/**
* @file
* Administration related forms for the location_search module.
*/
/**
* Admin settings form.
*
* @ingroup form
*/
function location_search_admin_settings($form, &$form_state) {
$gmap = module_exists('gmap');
$form['location_search_map'] = array(
'#type' => 'checkbox',
'#title' => t('Use map to pick search coordinates'),
'#return_value' => 1,
'#default_value' => variable_get('location_search_map', 1),
'#description' => $gmap ? t('Requires the gmap module.') : t('You must install the gmap module to enable this feature.'),
'#disabled' => !$gmap,
);
$form['location_search_map_address'] = array(
'#type' => 'checkbox',
'#title' => t('Add geocoding address field to search map'),
'#return_value' => 1,
'#default_value' => variable_get('location_search_map_address', 1),
);
$form['location_search_map_macro'] = array(
'#type' => 'textfield',
'#title' => t('Macro for search map'),
'#default_value' => variable_get('location_search_map_macro', '[gmap |behavior=+collapsehack]'),
);
return system_settings_form($form);
}

View File

@@ -0,0 +1,17 @@
name = Location Search
package = Location
description = Advanced search page for locations.
dependencies[] = search
dependencies[] = location
core = 7.x
files[] = location_search.module
files[] = location_search.install
files[] = location_search.admin.inc
; Information added by drupal.org packaging script on 2012-02-18
version = "7.x-3.x-dev"
core = "7.x"
project = "location"
datestamp = "1329524299"

View File

@@ -0,0 +1,84 @@
<?php
/**
* @file
* Install, update and uninstall functions for the location_search module.
*/
/**
* Implements hook_schema().
*/
function location_search_schema() {
$schema['location_search_work'] = array(
'description' => 'List of lids to index.',
'fields' => array(
'lid' => array(
'description' => 'Primary Key: location ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'primary key' => array('lid'),
);
return $schema;
}
/**
* Implements hook_install().
*/
function location_search_install() {
// Force reindexing.
$insert_select = db_select('location', 'l');
$insert_select->addField('l', 'lid');
db_insert('location_search_work')
->fields(array('lid'))
->from($insert_select)
->execute();
}
/**
* Implements hook_uninstall().
*/
function location_search_uninstall() {
variable_del('location_search_map');
variable_del('location_search_map_address');
variable_del('location_search_map_macro');
}
/**
* Rewritten location_search -- Uses the fulltext engine.
*/
function location_search_update_5300() {
// Create our worklist table.
$schema['location_search_work'] = array(
'description' => 'List of lids to index.',
'fields' => array(
'lid' => array(
'description' => 'Primary Key: location ID.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'primary key' => array('lid'),
);
db_create_table('location_search_work', $schema['location_search_work']);
// Force reindexing.
$insert_select = db_select('location', 'l');
$insert_select->addField('l', 'lid');
db_insert('location_search_work')
->fields(array('lid'))
->from($insert_select)
->execute();
// Remove unused variables.
variable_del('location_suppress_country');
variable_del('location_search_distance_unit');
}

View File

@@ -0,0 +1,416 @@
<?php
/**
* @file
* Location search interface.
*/
/**
* Implements hook_menu().
*/
function location_search_menu() {
$items['admin/settings/location/search'] = array(
'title' => '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;
}
/**
* Implements hook_theme().
*/
function location_search_theme() {
return array(
'search_result_location' => array(
'variables' => array(
'result' => NULL,
'module' => NULL,
),
'template' => 'search_result_location',
),
);
}
/**
* Implements hook_search_info().
*/
function location_search_search_info() {
return array(
'title' => 'Locations',
'path' => 'location',
);
}
/**
* Implements hook_search_access().
*/
function location_search_search_access() {
return user_access('access content');
}
/**
* Implements hook_search_reset().
*/
function location_search_search_reset() {
db_delete('location_search_work')->execute();
$insert_select = db_select('location', 'l');
$insert_select->addField('l', 'lid');
db_insert('location_search_work')
->fields(array('lid'))
->from($insert_select)
->execute();
}
/**
* Implements hook_search_status().
*/
function location_search_search_status() {
$total = db_query('SELECT COUNT(lid) FROM {location}')->fetchField();
$remaining = db_query('SELECT COUNT(lid) FROM {location_search_work}')->fetchField();
return array('remaining' => $remaining, 'total' => $total);
}
/**
* Implements hook_search_execute().
*/
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;
}
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}', array(), array('fetch' => PDO::FETCH_ASSOC));
$countries = array('' => '');
foreach ($result as $row) {
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('location_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'),
),
);
if (variable_get('location_search_map', 1)) {
$map_fields = array(
'latitude' => 'latitude',
'longitude' => 'longitude',
);
if (variable_get('location_search_map_address', 1)) {
$map_fields['address'] = 'locpick_address';
}
if (module_exists('gmap')) {
$form['advanced']['proximity']['map']['#value'] = gmap_set_location(variable_get('location_search_map_macro', '[gmap |behavior=+collapsehack]'), $form['advanced']['proximity'], $map_fields);
}
}
$form['advanced']['submit'] = array(
'#type' => 'submit',
'#value' => t('Advanced search'),
'#prefix' => '<div class="action">',
'#suffix' => '</div>',
);
$form['#validate'][] = 'location_search_validate';
}
}
function location_search_validate($form, &$form_state) {
$values = $form_state['values'];
// Initialise using any existing basic search keywords.
$keys = $values['processed_keys'];
if (!empty($values['country'])) {
$keys = search_expression_insert($keys, 'country', $values['country']);
if (!empty($values['province'])) {
$keys = search_expression_insert($keys, 'province', location_province_code($values['country'], $values['province']));
}
}
if (!empty($values['city'])) {
$keys = search_expression_insert($keys, 'city', $values['city']);
}
if (!empty($values['latitude']) && !empty($values['longitude']) && !empty($values['distance'])) {
$keys = search_expression_insert($keys, 'from', $values['latitude'] .','. $values['longitude'] .','. $values['distance'] .','. $values['units']);
}
if (!empty($keys)) {
form_set_value($form['basic']['processed_keys'], trim($keys), $form_state);
}
}
/**
* Implements hook_update_index().
*/
function location_update_index() {
$limit = (int)variable_get('search_cron_limit', 100);
$result = db_query_range('SELECT lid FROM {location_search_work}', 0, $limit);
foreach ($result as $row) {
$loc = location_load_location($row->lid);
$text = theme('location', array('location' => $loc, 'hide' => array())); // @@@ hide?
search_index($row->lid, 'location', $text);
db_delete('location_search_work')
->condition('lid', $row->lid)
->execute();
}
}
/**
* Implements hook_locationapi().
*/
function location_search_locationapi(&$obj, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) {
if ($op == 'save') {
// Ensure the changed location is in our work list.
db_delete('location_search_work')
->condition('lid', $obj['lid'])
->execute();
db_insert('location_search_work')
->fields(array(
'lid' => $obj['lid'],
))
->execute();
}
if ($op == 'delete') {
search_reindex($obj['lid'], 'location');
}
}
/**
* Implements hook_search_page().
*/
function location_search_search_page($results) {
$output['prefix']['#markup'] = '<ol class="search-results">';
foreach ($results as $entry) {
$output[] = array(
'#theme' => 'search_result_location',
'#result' => $entry,
'#module' => 'location',
);
}
$output['suffix']['#markup'] = '</ol>' . theme('pager');
return $output;
}
function template_preprocess_search_result_location(&$variables) {
$result = $variables['result'];
$variables['links_raw'] = array();
foreach ($result['links'] as $link) {
if (isset($link['title']) && isset($link['href'])) {
$variables['links_raw'][] = $link;
}
}
$variables['location_raw'] = $result['location'];
$variables['location'] = theme('location', array('location' => $result['location'], 'hide' => array())); // @@@ hide?
$variables['links'] = theme('links', array('links' => $variables['links_raw']));
// Provide alternate search result template.
$variables['theme_hook_suggestions'][] = 'search_result_' . $variables['module'];
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* @file search_result_location.tpl.php
* Theme a location search result.
*
* Available variables:
* - $links: A themed set of links to all the objects that reference this location.
* - $location: A themed location.
*/
?>
<dt class="title">
<?php print $links; ?>
</dt>
<dd>
<?php print $location; ?>
</dd>

View File

@@ -0,0 +1,16 @@
name = Location Taxonomy
description = Associate locations with taxonomy terms.
dependencies[] = location
dependencies[] = taxonomy
package = Location
core = 7.x
files[] = location_taxonomy.module
files[] = location_taxonomy.install
; Information added by drupal.org packaging script on 2012-02-18
version = "7.x-3.x-dev"
core = "7.x"
project = "location"
datestamp = "1329524299"

View File

@@ -0,0 +1,19 @@
<?php
/**
* @file
* Install, update and uninstall functions for the location_taxonomy module.
*/
/**
* Implements hook_uninstall().
*/
function location_taxonomy_uninstall() {
// @@@ Delete data?
// Delete vocabulary location settings.
$result = db_query("SELECT name FROM {variable} WHERE name LIKE 'location_taxonomy_%'")->fetchCol();
foreach ($result as $var) {
variable_del($var);
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* @file
* Associate locations with taxonomy terms.
*/
/**
* NOTE: At the moment, you'll have to do your own theming.
* To load locations for a tid:
* $locations = location_load_locations('taxonomy:'. $tid, 'genid');
*/
/**
* Implements hook_taxonomy_vocabulary_delete().
*/
function location_taxonomy_taxonomy_vocabulary_delete($vocabulary) {
variable_del('location_taxonomy_' . $vocabulary->vid);
}
/**
* Implements hook_taxonomy_term_delete().
*/
function location_taxonomy_taxonomy_term_delete($term) {
$locations = array();
location_save_locations($locations, array('genid' => 'taxonomy:' . $term->tid));
}
/**
* Implements hook_form_alter().
*/
function location_taxonomy_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'taxonomy_form_vocabulary') {
$settings = array();
if (isset($form['vid'])) {
$settings = variable_get('location_taxonomy_' . $form['vid']['#value'], array());
}
$form['location_settings'] = location_settings($settings);
$form['#submit'][] = 'location_taxonomy_vocabulary_form_submit';
}
if ($form_id == 'taxonomy_form_term') {
$vid = $form['vid']['#value'];
$settings = variable_get('location_taxonomy_' . $vid, FALSE);
if ($settings && $settings['multiple']['max']) {
$locations = array();
if (isset($form['tid']) && $form['tid']['#value']) {
$locations = location_load_locations('taxonomy:' . $form['tid']['#value'], 'genid');
}
$form['locations'] = location_form($settings, $locations);
$form['#submit'][] = 'location_taxonomy_term_form_submit';
}
}
// Move the Save and Delete buttons down below our additions.
if ($form_id == 'taxonomy_form_vocabulary' || $form_id == 'taxonomy_form_term') {
if (isset($form['submit']['#weight'])) {
$form['submit']['#weight']++;
}
else {
$form['submit']['#weight'] = 1;
}
if (isset($form['delete'])) {
if (isset($form['delete']['#weight'])) {
$form['delete']['#weight'] += 2;
}
else {
$form['delete']['#weight'] = 2;
}
}
}
}
/**
* Submit handler for the vocabulary add/edit form.
*/
function location_taxonomy_vocabulary_form_submit($form, &$form_state) {
if (isset($form_state['values']['location_settings'])) {
variable_set('location_taxonomy_' . $form_state['values']['vid'], $form_state['values']['location_settings']);
}
}
/**
* Submit handler for the term add/edit form.
*/
function location_taxonomy_term_form_submit($form, &$form_state) {
$settings = variable_get('location_taxonomy_' . $form_state['values']['vid'], FALSE);
if ($settings && $settings['multiple']['max']) {
location_save_locations($form_state['values']['locations'], array('genid' => 'taxonomy:' . $form_state['values']['tid']));
}
}
/**
* Implements hook_locationapi().
*/
function location_taxonomy_locationapi(&$obj, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) {
switch ($op) {
case 'instance_links':
foreach ($obj as $k => $v) {
if (substr($v['genid'], 0, 9) == 'taxonomy:') {
$data = explode(':', $v['genid']);
$obj[$k]['href'] = 'taxonomy/term/' . $data[1];
$obj[$k]['title'] = t('Term location');
$obj[$k]['type'] = t('Taxonomy location');
}
}
}
}