You are here

function farm_map_geofield_field_widget_form in farmOS 7

Implements hook_field_widget_form().

File

modules/farm/farm_map/farm_map_geofield/farm_map_geofield.module, line 160
Farm Map Geofield integration.

Code

function farm_map_geofield_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {

  // Start with the Geofield WKT widget.
  $instance['widget']['type'] = 'geofield_wkt';
  $element = geofield_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);

  // Get the geometry (as WKT), from form state input (if available), or from
  // the saved field value.
  $wkt = '';
  if (!empty($form_state['input'][$field['field_name']][$langcode][$delta]['geom'])) {
    $wkt = $form_state['input'][$field['field_name']][$langcode][$delta]['geom'];
  }
  elseif (!empty($items[$delta]['geom'])) {
    $wkt = $items[$delta]['geom'];
  }

  // Add a farmOS map instance with the WKT and drawing controls.
  $element['map'] = array(
    '#type' => 'farm_map',
    '#map_name' => 'farm_map_geofield_widget',
    '#wkt' => $wkt,
    '#edit' => TRUE,
  );

  // Move the geometry field below the map.
  $element['geom']['#weight'] = 100;

  // Time to deal with optional geocoder integration
  // Conditionally add geocoder button.
  $parents = array_merge($element['#field_parents'], array(
    $element['#field_name'],
    $langcode,
    $delta,
  ));
  $field_name = $field['field_name'];
  $id_prefix = implode('-', array_merge($parents, array(
    $field_name,
    $delta,
  )));
  $wrapper_id = drupal_html_id($id_prefix . '-use-geocoder-wrapper');
  $is_settings_form = isset($form['#title']) && $form['#title'] == t('Default value');
  $settings = $instance['widget']['settings'];
  if (!$is_settings_form && !empty($settings['use_geocoder']) && !empty($settings['geocoder_field'])) {
    if ($settings['geocoder_field'] == $element['#field_name']) {

      // Extra field.
      $element['geocoder_input'] = array(
        '#type' => 'textfield',
        '#title' => t('Geocode'),
        '#description' => t('Enter the place to geocode.'),
      );
      $label = $element['geocoder_input']['#title'];
    }
    elseif ($field = field_info_instance($instance['entity_type'], $settings['geocoder_field'], $instance['bundle'])) {
      $label = $field['label'];
    }
    else {
      switch ($settings['geocoder_field']) {
        case 'title':
          $label = t('Title');
          break;
        case 'name':
          $label = t('Name');
          break;
        default:
          $label = $settings['geocoder_field'];
      }
    }
    $element['#prefix'] = '<div id="' . $wrapper_id . '">';
    $element['#suffix'] = '</div>';
    $element['use_geocoder'] = array(
      '#type' => 'submit',
      '#name' => strtr($id_prefix, '-', '_') . '_use_geocoder',
      '#value' => t('Find using @field field', array(
        '@field' => $label,
      )),
      '#attributes' => array(
        'class' => array(
          'field-use-geocoder-submit',
        ),
      ),
      // Avoid validation errors for e.g. required fields but do pass the value
      // of the geocoder field.
      '#limit_validation_errors' => array(),
      '#ajax' => array(
        'callback' => 'farm_map_geofield_geocode_ajax_callback',
        'wrapper' => $wrapper_id,
        'effect' => 'fade',
      ),
      '#submit' => array(
        'farm_map_geofield_use_geocoder_submit',
      ),
      '#weight' => 101,
    );
  }

  // Add the element to an array, because it's the format that
  // FIELD_BEHAVIOR_CUSTOM expects.

  /**
   * @todo
   * This is necessary due to a legacy decision that was made in early farmOS
   * development, when we were using the OpenLayers module. The farmOS Geofield
   * (field_farm_geofield) was set up with a cardinality of -1 (allowing
   * unlimited values), and the OpenLayers Geofield widget was configured to
   * save all features as a combined geometry. So, even though the field was
   * configured to allow unlimited values, only one value was ever saved. And
   * only one value was/is ever needed. So in the future, when we move to Drupal
   * 8, we should plan to change the cardinality to 1. The decision was made to
   * leave it as -1 in 7.x-1.x, because changing it would cause a change to the
   * REST API (which expects an array of geometries, even though only one should
   * ever be provided).
   *
   * Using FIELD_BEHAVIOR_CUSTOM and wrapping the element in an array is the
   * same approach that the openlayers_geofield module takes.
   */
  $full_element = array(
    $element,
  );

  // Return the widget element.
  return $full_element;
}