You are here

geolocation.module in Geolocation Field 6

File

geolocation.module
View source
<?php

// $Id$

/**
 * @file
 */

//==========================================//

// DEFINING A FIELD

//==========================================//

/**
 * Implementation of hook_field_info().
 */
function geolocation_field_info() {
  return array(
    // The machine name of the field,
    // no more than 32 characters.
    'geolocation_latlng' => array(
      // The human-readable label of the field that will be
      // seen in the Manage fields screen.
      'label' => t('Geolocation'),
      // A description of what type of data the field stores.
      'description' => t('Geolocation input.'),
    ),
  );
}

/**
 * Implementation of hook_field_settings().
 */
function geolocation_field_settings($op, $field) {
  switch ($op) {
    case 'form':

      // Create the form element to be used on the field
      // settings form. Field settings will be the same for
      // all shared instances of the same field and should
      // define the way the value will be stored
      // in the database.
      break;
    case 'save':

      // Return an array of the names of the field settings
      // defined by this module. These are the items that
      // CCK will store in the field definition
      // and they will be available in the $field array.
      // This should match the items defined in 'form' above.
      break;
    case 'database columns':

      // Define the database storage for this field using
      // the same construct used by schema API. Most fields
      // have only one column, but there can be any number
      // of different columns. After the schema API values,
      // add two optional values to each column,
      //  'views', to define a Views field
      //  'sortable', to add a Views sort field
      $columns = array(
        'lat' => array(
          'description' => 'Stores the latitude value',
          'type' => 'float',
          'size' => 'big',
          'not null' => TRUE,
          'default' => 0,
        ),
        'lng' => array(
          'description' => 'Stores the longitude value',
          'type' => 'float',
          'size' => 'big',
          'not null' => TRUE,
          'default' => 0,
        ),
        'lat_sin' => array(
          'description' => 'Stores the sine of latitude',
          'type' => 'float',
          'not null' => TRUE,
          'default' => 0,
        ),
        'lat_cos' => array(
          'description' => 'Stores the cosine of latitude',
          'type' => 'float',
          'not null' => TRUE,
          'default' => 0,
        ),
        'lng_rad' => array(
          'description' => 'Stores the radian longitude',
          'type' => 'float',
          'not null' => TRUE,
          'default' => 0,
        ),
      );
      return $columns;
    case 'views data':

      // Optional: Make changes to the default $data array
      // created for Views. Omit this if no changes are
      // needed, use it to add a custom handler or make
      // other changes.
      // Start with the $data created by CCK
      // and alter it as needed. The following
      // code illustrates how you would retrieve
      // the necessary data.
      $data = content_views_field_views_data($field);
      $db_info = content_database_info($field);
      $table_alias = content_views_tablename($field);
      $field_data = $data[$table_alias][$field['field_name'] . '_value'];

      // Make changes to $data as needed here.
      return $data;
  }
}

/**
 * Implementation of hook_field().
 */
function geolocation_field($op, &$node, $field, &$items, $teaser, $page) {
  switch ($op) {
    case 'presave':
      foreach ($items as $delta => $item) {

        // Precalculate some goodness.
        $item['lat_sin'] = sin(deg2rad($item['lat']));
        $item['lat_cos'] = cos(deg2rad($item['lat']));
        $item['lng_rad'] = deg2rad($item['lng']);
        $items[$delta] = $item;
      }
      break;
    case 'validate':

      // Do validation on the field values here. The widget
      // will do its own validation and you cannot make any
      // assumptions about what kind of widget has been used,
      // so don't validate widget values, only field values.
      if (is_array($items)) {
        foreach ($items as $delta => $item) {

          // The error_element is needed so that CCK can
          // set an error on the right sub-element when
          // fields are deeply nested in the form.
          $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
          if (!empty($item['lat']) || !empty($item['lng'])) {
            if (!is_numeric($item['lat'])) {
              form_set_error($error_element, t('Invalid Latitude.'));
            }
            if (!is_numeric($item['lng'])) {
              form_set_error($error_element, t('Invalid Longitude.'));
            }
          }
        }
      }
      return $items;
    case 'sanitize':

      // This is where you make sure that user-provided
      // data is sanitized before being displayed.
      foreach ($items as $delta => $item) {
        $geolocation['lat'] = check_plain($item['lat']);
        $geolocation['lng'] = check_plain($item['lng']);
        $items[$delta]['safe'] = $geolocation;
      }
  }
}

/**
 * Implementation of hook_content_is_empty().
 *
 * CCK has no way to know if something like a zero is
 * an empty value or a valid value, so return
 * TRUE or FALSE to a populated field $item array.
 * CCK uses this to remove empty multi-value elements
 * from forms.
 */
function geolocation_content_is_empty($item, $field) {
  if (empty($item['lat'])) {
    return TRUE;
  }
  if (empty($item['lng'])) {
    return TRUE;
  }
  return FALSE;
}

//==========================================//

// DEFINING A FORMATTER

//==========================================//

/**
 * Implementation of hook_theme().
 */
function geolocation_theme() {
  return array(
    // Themes for the formatters.
    'geolocation_formatter_default' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'geolocation_formatter_latitude' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'geolocation_formatter_longitude' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
  );
}

/**
 * Implementation of hook_field_formatter_info().
 *
 * All fields should have a 'default' formatter.
 * Any number of other formatters can be defined as well.
 * It's nice for there always to be a 'plain' option
 * for the raw value, but that is not required.
 *
 */
function geolocation_field_formatter_info() {
  return array(
    'default' => array(
      'label' => t('DEFAULT: Simple text-based formatter'),
      'field types' => array(
        'geolocation_latlng',
      ),
    ),
    'latitude' => array(
      'label' => t('Latitude text-based formatter'),
      'field types' => array(
        'geolocation_latlng',
      ),
    ),
    'longitude' => array(
      'label' => t('Longitude text-based formatter'),
      'field types' => array(
        'geolocation_latlng',
      ),
    ),
  );
}

/**
 * Theme function for 'default' geolocation field formatter.
 *
 * $element['#item']: the sanitized $delta value for the item,
 * $element['#field_name']: the field name,
 * $element['#type_name']: the $node->type,
 * $element['#formatter']: the $formatter_name,
 * $element'#node']: the $node,
 * $element['#delta']: the delta of this item, like '0',
 *
 */
function theme_geolocation_formatter_default($element) {
  return '<p>' . t('Geolocation is @lat, @lng', array(
    '@lat' => $element['#item']['lat'],
    '@lng' => $element['#item']['lng'],
  )) . '</p>';
}
function theme_geolocation_formatter_latitude($element) {
  return $element['#item']['lat'];
}
function theme_geolocation_formatter_longitude($element) {
  return $element['#item']['lng'];
}

//==========================================//

// DEFINING A WIDGET

//==========================================//

/**
 * Implementation of hook_widget_info().
 *
 * Here we indicate that the content module will handle
 * the default value and multiple values for these widgets.
 */
function geolocation_widget_info() {
  return array(
    'geolocation_text' => array(
      'label' => t('Latitude/Longitude'),
      'field types' => array(
        'geolocation_latlng',
      ),
    ),
  );
}

/**
 * Implementation of hook_widget_settings().
 */
function geolocation_widget_settings($op, $widget) {
  switch ($op) {
    case 'form':

      // Create the form element to be used on the widget
      // settings form. Widget settings can be different
      // for each shared instance of the same field and
      // should define the way the value is displayed to
      // the user in the edit form for that content type.
      break;
      return NULL;
    case 'save':

      // Return an array of the names of the widget settings
      // defined by this module. These are the items that
      // CCK will store in the widget definition and they
      // will be available in the $field['widget'] array.
      // This should match the items defined in 'form' above.
      break;
      return NULL;
  }
}

/**
 * Implementation of hook_widget().
 *
 * Attach a single form element to the form.
 *
 * CCK core fields only add a stub element and builds
 * the complete item in #process so reusable elements
 * created by hook_elements can be plugged into any
 * module that provides valid $field information.
 *
 * Custom widgets that don't care about using hook_elements
 * can be built out completely at this time.
 *
 * If there are multiple values for this field and CCK is
 * handling multiple values, the content module will call
 * this function as many times as needed.
 *
 * @param $form
 *   the entire form array,
 *   $form['#node'] holds node information
 * @param $form_state
 *   the form_state,
 *   $form_state['values'][$field['field_name']]
 *   holds the field's form values.
 * @param $field
 *   the field array
 * @param $items
 *   array of default values for this field
 * @param $delta
 *   the order of this item in the array of
 *   subelements (0, 1, 2, etc)
 *
 * @return
 *   the form item for a single element for this field
 */
function geolocation_widget(&$form, &$form_state, $field, $items, $delta = 0) {
  $lat_value = isset($items[$delta]['lat']) ? $items[$delta]['lat'] : '';
  $lng_value = isset($items[$delta]['lng']) ? $items[$delta]['lng'] : '';
  $element['lat'] = array();
  $element['lng'] = array();
  $element['lat'] += array(
    '#title' => t('Latitude'),
    '#type' => 'textfield',
    '#default_value' => $lat_value,
    '#size' => 30,
    '#maxlength' => 30,
  );
  $element['lng'] += array(
    '#title' => t('Longitude'),
    '#type' => 'textfield',
    '#default_value' => $lng_value,
    '#size' => 30,
    '#maxlength' => 30,
  );
  return $element;
}

Functions

Namesort descending Description
geolocation_content_is_empty Implementation of hook_content_is_empty().
geolocation_field Implementation of hook_field().
geolocation_field_formatter_info Implementation of hook_field_formatter_info().
geolocation_field_info Implementation of hook_field_info().
geolocation_field_settings Implementation of hook_field_settings().
geolocation_theme Implementation of hook_theme().
geolocation_widget Implementation of hook_widget().
geolocation_widget_info Implementation of hook_widget_info().
geolocation_widget_settings Implementation of hook_widget_settings().
theme_geolocation_formatter_default Theme function for 'default' geolocation field formatter.
theme_geolocation_formatter_latitude
theme_geolocation_formatter_longitude