Skip to content
field.api.php 94.9 KiB
Newer Older
use Drupal\field\FieldUpdateForbiddenException;

 * Exposes "pseudo-field" components on fieldable entities.
 * Field UI's "Manage fields" and "Manage display" pages let users re-order
 * fields, but also non-field components. For nodes, these include the title,
 * poll choices, and other elements exposed by modules through hook_form() or
 * Fieldable entities or modules that want to have their components supported
 * should expose them using this hook. The user-defined settings (weight,
 * visible) are automatically applied on rendered forms and displayed
 * entities in a #pre_render callback added by field_attach_form() and
 * field_attach_view().
 *
 * @see _field_extra_fields_pre_render()
 * @see hook_field_extra_fields_alter()
 *   A nested array of 'pseudo-field' components. Each list is nested within
 *   the following keys: entity type, bundle name, context (either 'form' or
 *   'display'). The keys are the name of the elements as appearing in the
 *   renderable array (either the entity form or the displayed entity). The
 *   value is an associative array:
 *   - label: The human readable name of the component.
 *   - description: A short description of the component contents.
 *   - weight: The default weight of the element.
 */
function hook_field_extra_fields() {
  $extra['node']['poll'] = array(
    'form' => array(
      'choice_wrapper' => array(
        'label' => t('Poll choices'),
        'description' => t('Poll choices'),
        'weight' => -4,
      ),
      'settings' => array(
        'label' => t('Poll settings'),
        'description' => t('Poll module settings'),
        'weight' => -3,
      ),
    ),
    'display' => array(
      'poll_view_voting' => array(
        'label' => t('Poll vote'),
        'description' => t('Poll vote'),
        'weight' => 0,
      ),
      'poll_view_results' => array(
        'label' => t('Poll results'),
        'description' => t('Poll results'),
        'weight' => 0,
      ),
    )
  );
/**
 * Alter "pseudo-field" components on fieldable entities.
 *
 * @param $info
 *   The associative array of 'pseudo-field' components.
 *
 * @see hook_field_extra_fields()
 */
function hook_field_extra_fields_alter(&$info) {
  // Force node title to always be at the top of the list by default.
    if (isset($info['node'][$bundle->type]['form']['title'])) {
      $info['node'][$bundle->type]['form']['title']['weight'] = -20;
/**
 * @defgroup field_types Field Types API
 * @{
 * In the Field API, each field has a type, which determines what kind of data
 * (integer, string, date, etc.) the field can hold, which settings it provides,
 * and so on. The data type(s) accepted by a field are defined in
 * hook_field_schema(); other basic properties of a field are defined in
 * hook_field_info(). The other hooks below are called by the Field Attach API
 * to perform field-type-specific actions.
 *
 * The Field Types API also defines two kinds of pluggable handlers: widgets
 * and formatters. @link field_widget Widgets @endlink specify how the field
 * appears in edit forms, while @link field_formatter formatters @endlink
 * specify how the field appears in displayed entities.
 *
 * A third kind of pluggable handlers, storage backends, is defined by the
 * @link field_storage Field Storage API @endlink.
 * See @link field Field API @endlink for information about the other parts of
 * the Field API.
 */

/**
 * Define Field API field types.
 *
 * @return
 *   An array whose keys are field type names and whose values are arrays
 *   describing the field type, with the following key/value pairs:
 *   - label: The human-readable name of the field type.
 *   - description: A short description for the field type.
 *   - settings: An array whose keys are the names of the settings available
 *     for the field type, and whose values are the default values for those
 *     settings.
 *   - instance_settings: An array whose keys are the names of the settings
 *     available for instances of the field type, and whose values are the
 *     default values for those settings. Instance-level settings can have
 *     different values on each field instance, and thus allow greater
 *     flexibility than field-level settings. It is recommended to put settings
 *     at the instance level whenever possible. Notable exceptions: settings
 *     acting on the schema definition, or settings that Views needs to use
 *     across field instances (for example, the list of allowed values).
 *   - default_widget: The machine name of the default widget to be used by
 *     instances of this field type, when no widget is specified in the
 *     instance definition. This widget must be available whenever the field
 *     type is available (i.e. provided by the field type module, or by a module
 *     the field type module depends on).
 *   - default_formatter: The machine name of the default formatter to be used
 *     by instances of this field type, when no formatter is specified in the
 *     instance definition. This formatter must be available whenever the field
 *     type is available (i.e. provided by the field type module, or by a module
 *     the field type module depends on).
 *   - no_ui: (optional) A boolean specifying that users should not be allowed
 *     to create fields and instances of this field type through the UI. Such
 *     fields can only be created programmatically with field_create_field()
 *     and field_create_instance(). Defaults to FALSE.
 */
function hook_field_info() {
  return array(
    'text' => array(
      'label' => t('Text'),
      'description' => t('This field stores varchar text in the database.'),
      'settings' => array('max_length' => 255),
      'instance_settings' => array('text_processing' => 0),
      'default_widget' => 'text_textfield',
      'default_formatter' => 'text_default',
    ),
      'description' => t('This field stores long text in the database.'),
      'instance_settings' => array('text_processing' => 0),
      'default_widget' => 'text_textarea',
      'default_formatter' => 'text_default',
    ),
    'text_with_summary' => array(
      'label' => t('Long text and summary'),
      'description' => t('This field stores long text in the database along with optional summary text.'),
      'settings' => array('max_length' => ''),
      'instance_settings' => array('text_processing' => 1, 'display_summary' => 0),
      'default_widget' => 'text_textarea_with_summary',
      'default_formatter' => 'text_summary_or_trimmed',
    ),
/**
 * Perform alterations on Field API field types.
 *
 * @param $info
 *   Array of information on field types exposed by hook_field_info()
 *   implementations.
 */
function hook_field_info_alter(&$info) {
  // Add a setting to all field types.
  foreach ($info as $field_type => $field_type_info) {
    $info[$field_type]['settings'] += array(
      'mymodule_additional_setting' => 'default value',
    );
  }

  // Change the default widget for fields of type 'foo'.
  if (isset($info['foo'])) {
    $info['foo']['default widget'] = 'mymodule_widget';
  }
}

/**
 * Define the Field API schema for a field structure.
 *
 * This hook MUST be defined in .install for it to be detected during
 * installation and upgrade.
 *
 * @param $field
 *   A field structure.
 *   An associative array with the following keys:
 *   - columns: An array of Schema API column specifications, keyed by column
 *     name. This specifies what comprises a value for a given field. For
 *     example, a value for a number field is simply 'value', while a value for
 *     a formatted text field is the combination of 'value' and 'format'. It is
 *     recommended to avoid having the column definitions depend on field
 *     settings when possible. No assumptions should be made on how storage
 *     engines internally use the original column name to structure their
 *     storage.
 *   - indexes: (optional) An array of Schema API indexes definitions. Only
 *     columns that appear in the 'columns' array are allowed. Those indexes
 *     will be used as default indexes. Callers of field_create_field() can
 *     specify additional indexes, or, at their own risk, modify the default
 *     indexes specified by the field-type module. Some storage engines might
 *     not support indexes.
 *   - foreign keys: (optional) An array of Schema API foreign keys
 *     definitions.
function hook_field_schema($field) {
  if ($field['type'] == 'text_long') {
    $columns = array(
      'value' => array(
        'type' => 'text',
        'size' => 'big',
        'not null' => FALSE,
      ),
    );
  }
  else {
    $columns = array(
      'value' => array(
        'type' => 'varchar',
        'length' => $field['settings']['max_length'],
        'not null' => FALSE,
      ),
    );
  }
  $columns += array(
    'format' => array(
  return array(
    'columns' => $columns,
    'indexes' => array(
      'format' => array('format'),
    ),
    'foreign keys' => array(
      'format' => array(
        'table' => 'filter_format',
        'columns' => array('format' => 'format'),
      ),
    ),
 * Define custom load behavior for this module's field types.
 * Unlike most other field hooks, this hook operates on multiple entities. The
 * $entities, $instances and $items parameters are arrays keyed by entity ID.
 * For performance reasons, information for all available entity should be
 * Note that the changes made to the field values get cached by the field cache
 * for subsequent loads. You should never use this hook to load fieldable
 * entities, since this is likely to cause infinite recursions when
 * hook_field_load() is run on those as well. Use
 * hook_field_formatter_prepare_view() instead.
 * Make changes or additions to field values by altering the $items parameter by
 * reference. There is no return value.
 *
 * @param $entity_type
 *   The type of $entity.
 * @param $entities
 *   Array of entities being loaded, keyed by entity ID.
 * @param $field
 *   The field structure for the operation.
 *   Array of instance structures for $field for each entity, keyed by entity
 *   Array of field values already loaded for the entities, keyed by entity ID.
 *   Store your changes in this parameter (passed by reference).
 * @param $age
 *   FIELD_LOAD_CURRENT to load the most recent revision for all fields, or
 *   FIELD_LOAD_REVISION to load the version indicated by each entity.
function hook_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
  // Sample code from text.module: precompute sanitized strings so they are
  // stored in the field cache.
  foreach ($entities as $id => $entity) {
      // Only process items with a cacheable format, the rest will be handled
      // by formatters if needed.
      if (empty($instances[$id]['settings']['text_processing']) || filter_format_allowcache($item['format'])) {
        $items[$id][$delta]['safe_value'] = isset($item['value']) ? _text_sanitize($instances[$id], $langcode, $item, 'value') : '';
          $items[$id][$delta]['safe_summary'] = isset($item['summary']) ? _text_sanitize($instances[$id], $langcode, $item, 'summary') : '';
 * This hook is invoked before the field values are handed to formatters
 * for display, and runs before the formatters' own
 * hook_field_formatter_prepare_view().
 *
 * Unlike most other field hooks, this hook operates on multiple entities. The
 * $entities, $instances and $items parameters are arrays keyed by entity ID.
 * For performance reasons, information for all available entities should be
 * Make changes or additions to field values by altering the $items parameter by
 * reference. There is no return value.
 *
 * @param $entity_type
 *   The type of $entity.
 * @param $entities
 *   Array of entities being displayed, keyed by entity ID.
 * @param $field
 *   The field structure for the operation.
 *   Array of instance structures for $field for each entity, keyed by entity
 * @param $langcode
 *   The language associated to $items.
 *   $entity->{$field['field_name']}, or an empty array if unset.
function hook_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
  // Sample code from image.module: if there are no images specified at all,
  foreach ($entities as $id => $entity) {
    if (empty($items[$id]) && $field['settings']['default_image']) {
      if ($file = file_load($field['settings']['default_image'])) {
        $items[$id][0] = (array) $file + array(
          'is_default' => TRUE,
          'alt' => '',
          'title' => '',
        );
 * Validate this module's field data.
 *
 * If there are validation problems, add to the $errors array (passed by
 * reference). There is no return value.
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
 * @param $field
 *   The field structure for the operation.
 * @param $instance
 *   The instance structure for $field on $entity's bundle.
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
 *   The array of errors (keyed by field name, language code, and delta) that
 *   have already been reported for the entity. The function should add its
 *   errors to this array. Each error is an associative array with the following
 *   - error: An error code (should be a string prefixed with the module name).
 *   - message: The human readable message to be displayed.
function hook_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
  foreach ($items as $delta => $item) {
    if (!empty($item['value'])) {
      if (!empty($field['settings']['max_length']) && drupal_strlen($item['value']) > $field['settings']['max_length']) {
        $errors[$field['field_name']][$langcode][$delta][] = array(
          'error' => 'text_max_length',
          'message' => t('%name: the value may not be longer than %max characters.', array('%name' => $instance['label'], '%max' => $field['settings']['max_length'])),
        );
      }
    }
  }
}

/**
 * Define custom presave behavior for this module's field types.
 * Make changes or additions to field values by altering the $items parameter by
 * reference. There is no return value.
 *
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
 * @param $field
 *   The field structure for the operation.
 * @param $instance
 *   The instance structure for $field on $entity's bundle.
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
function hook_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  if ($field['type'] == 'number_decimal') {
    // Let PHP round the value to ensure consistent behavior across storage
    // backends.
    foreach ($items as $delta => $item) {
      if (isset($item['value'])) {
        $items[$delta]['value'] = round($item['value'], $field['settings']['scale']);
      }
    }
  }
 * Define custom insert behavior for this module's field data.
 * This hook is invoked from field_attach_insert() on the module that defines a
 * field, during the process of inserting an entity object (node, taxonomy term,
 * etc.). It is invoked just before the data for this field on the particular
 * entity object is inserted into field storage. Only field modules that are
 * storing or tracking information outside the standard field storage mechanism
 * need to implement this hook.
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
 * @param $field
 *   The field structure for the operation.
 * @param $instance
 *   The instance structure for $field on $entity's bundle.
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
function hook_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node' && $entity->status) {
    $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', ));
    foreach ($items as $item) {
      $query->values(array(
        'nid' => $entity->nid,
        'tid' => $item['tid'],
        'sticky' => $entity->sticky,
        'created' => $entity->created,
      ));
    }
    $query->execute();
  }
 * Define custom update behavior for this module's field data.
 * This hook is invoked from field_attach_update() on the module that defines a
 * field, during the process of updating an entity object (node, taxonomy term,
 * etc.). It is invoked just before the data for this field on the particular
 * entity object is updated into field storage. Only field modules that are
 * storing or tracking information outside the standard field storage mechanism
 * need to implement this hook.
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
 * @param $field
 *   The field structure for the operation.
 * @param $instance
 *   The instance structure for $field on $entity's bundle.
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
function hook_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node') {
    $first_call = &drupal_static(__FUNCTION__, array());

    // We don't maintain data for old revisions, so clear all previous values
    // from the table. Since this hook runs once per field, per object, make
    // sure we only wipe values once.
    if (!isset($first_call[$entity->nid])) {
      $first_call[$entity->nid] = FALSE;
      db_delete('taxonomy_index')->condition('nid', $entity->nid)->execute();
    }
    // Only save data to the table if the node is published.
    if ($entity->status) {
      $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created'));
      foreach ($items as $item) {
        $query->values(array(
          'nid' => $entity->nid,
          'tid' => $item['tid'],
          'sticky' => $entity->sticky,
          'created' => $entity->created,
        ));
      }
      $query->execute();
    }
  }
/**
 * Update the storage information for a field.
 *
 * This is invoked on the field's storage module from field_update_field(),
 * before the new field information is saved to the database. The field storage
 * module should update its storage tables to agree with the new field
 * information. If there is a problem, the field storage module should throw an
 * exception.
 *
 * @param $field
 *   The updated field structure to be saved.
 * @param $prior_field
 *   The previously-saved field structure.
 * @param $has_data
 *   TRUE if the field has data in storage currently.
 */
function hook_field_storage_update_field($field, $prior_field, $has_data) {
  if (!$has_data) {
    // There is no data. Re-create the tables completely.
    $prior_schema = _field_sql_storage_schema($prior_field);
    foreach ($prior_schema as $name => $table) {
      db_drop_table($name, $table);
    }
    $schema = _field_sql_storage_schema($field);
    foreach ($schema as $name => $table) {
      db_create_table($name, $table);
    }
  }
  else {
    // There is data. See field_sql_storage_field_storage_update_field() for
    // an example of what to do to modify the schema in place, preserving the
    // old data as much as possible.
  }
  drupal_get_schema(NULL, TRUE);
}

 * Define custom delete behavior for this module's field data.
 * This hook is invoked from field_attach_delete() on the module that defines a
 * field, during the process of deleting an entity object (node, taxonomy term,
 * etc.). It is invoked just before the data for this field on the particular
 * entity object is deleted from field storage. Only field modules that are
 * storing or tracking information outside the standard field storage mechanism
 * need to implement this hook.
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
 * @param $field
 *   The field structure for the operation.
 * @param $instance
 *   The instance structure for $field on $entity's bundle.
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
function hook_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
  foreach ($items as $delta => $item) {
    // For hook_file_references(), remember that this is being deleted.
    $item['file_field_name'] = $field['field_name'];
    // Pass in the ID of the object that is being removed so all references can
    // be counted in hook_file_references().
    $item['file_field_type'] = $entity_type;
    $item['file_field_id'] = $id;
    file_field_delete_file($item, $field, $entity_type, $id);
 * Define custom revision delete behavior for this module's field types.
 * This hook is invoked just before the data is deleted from field storage
 * in field_attach_delete_revision(), and will only be called for fieldable
 * types that are versioned.
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
 * @param $field
 *   The field structure for the operation.
 * @param $instance
 *   The instance structure for $field on $entity's bundle.
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
function hook_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
  foreach ($items as $delta => $item) {
    // For hook_file_references, remember that this file is being deleted.
    $item['file_field_name'] = $field['field_name'];
    if (file_field_delete_file($item, $field, $entity_type, $id)) {
 * Define custom prepare_translation behavior for this module's field types.
 *
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
 * @param $field
 *   The field structure for the operation.
 * @param $instance
 *   The instance structure for $field on $entity's bundle.
 * @param $langcode
 *   The language associated to $items.
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
 * @param $source_entity
 *   The source entity from which field values are being copied.
 * @param $source_langcode
 *   The source language from which field values are being copied.
function hook_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
  // If the translating user is not permitted to use the assigned text format,
  // we must not expose the source values.
  $field_name = $field['field_name'];
  $formats = filter_formats();
  $format_id = $source_entity->{$field_name}[$source_langcode][0]['format'];
  if (!filter_access($formats[$format_id])) {
    $items = array();
  }
/**
 * Define what constitutes an empty item for a field type.
 *
 * @param $item
 *   An item that may or may not be empty.
 * @param $field
 *   The field to which $item belongs.
 * @return
 *   TRUE if $field's type considers $item not to contain any data;
 *   FALSE otherwise.
 */
function hook_field_is_empty($item, $field) {
  if (empty($item['value']) && (string) $item['value'] !== '0') {
 * @} End of "defgroup field_types"
 */

/**
 * @defgroup field_widget Field Widget API
 * @{
 * Define Field API widget types.
 *
 * Field API widgets specify how fields are displayed in edit forms. Fields of a
 * given @link field_types field type @endlink may be edited using more than one
 * widget. In this case, the Field UI module allows the site builder to choose
 * which widget to use. Widget types are defined by implementing
 * hook_field_widget_info().
 * Widgets are @link forms_api_reference.html Form API @endlink
 * elements with additional processing capabilities. Widget hooks are typically
 * called by the Field Attach API during the creation of the field form
 * structure with field_attach_form().
 *
 * @see field
 * @see field_types
 * @see field_formatter
 */

/**
 * Expose Field API widget types.
 * @return
 *   An array describing the widget types implemented by the module.
 *   The keys are widget type names. To avoid name clashes, widget type
 *   names should be prefixed with the name of the module that exposes them.
 *   The values are arrays describing the widget type, with the following
 *   key/value pairs:
 *   - label: The human-readable name of the widget type.
 *   - description: A short description for the widget type.
 *   - field types: An array of field types the widget supports.
 *   - settings: An array whose keys are the names of the settings available
 *     for the widget type, and whose values are the default values for those
 *     settings.
 *   - behaviors: (optional) An array describing behaviors of the widget, with
 *     the following elements:
 *     - multiple values: One of the following constants:
 *       - FIELD_BEHAVIOR_DEFAULT: (default) If the widget allows the input of
 *         one single field value (most common case). The widget will be
 *         repeated for each value input.
 *       - FIELD_BEHAVIOR_CUSTOM: If one single copy of the widget can receive
 *         several field values. Examples: checkboxes, multiple select,
 *         comma-separated textfield.
 *     - default value: One of the following constants:
 *       - FIELD_BEHAVIOR_DEFAULT: (default) If the widget accepts default
 *         values.
 *       - FIELD_BEHAVIOR_NONE: if the widget does not support default values.
 *
 * @see hook_field_widget_info_alter()
 * @see hook_field_widget_form()
 * @see hook_field_widget_form_alter()
 * @see hook_field_widget_WIDGET_TYPE_form_alter()
 * @see hook_field_widget_error()
function hook_field_widget_info() {
    return array(
    'text_textfield' => array(
      'label' => t('Text field'),
      'field types' => array('text'),
      'settings' => array('size' => 60),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        'default value' => FIELD_BEHAVIOR_DEFAULT,
      ),
    ),
    'text_textarea' => array(
      'label' => t('Text area (multiple rows)'),
      'field types' => array('text_long'),
      'settings' => array('rows' => 5),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        'default value' => FIELD_BEHAVIOR_DEFAULT,
      ),
    ),
    'text_textarea_with_summary' => array(
      'label' => t('Text area with a summary'),
      'field types' => array('text_with_summary'),
      'settings' => array('rows' => 9, 'summary_rows' => 3),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        'default value' => FIELD_BEHAVIOR_DEFAULT,
      ),
    ),
  );
}

/**
 * Perform alterations on Field API widget types.
 *
 * @param $info
 *   Array of informations on widget types exposed by hook_field_widget_info()
 *   implementations.
 */
function hook_field_widget_info_alter(&$info) {
  // Add a setting to a widget type.
  $info['text_textfield']['settings'] += array(
    'mymodule_additional_setting' => 'default value',
  );

  // Let a new field type re-use an existing widget.
  $info['options_select']['field types'][] = 'my_field_type';
 * Field widget form elements should be based on the passed-in $element, which
 * contains the base form element properties derived from the field
 * configuration.
 * Field API will set the weight, field name and delta values for each form
 * element. If there are multiple values for this field, the Field API will
 *
 * Note that, depending on the context in which the widget is being included
 * (regular entity form, field configuration form, advanced search form...),
 * the values for $field and $instance might be different from the "official"
 * definitions returned by field_info_field() and field_info_instance().
 * Examples: mono-value widget even if the field is multi-valued, non-required
 * widget even if the field is 'required'...
 * Therefore, the FAPI element callbacks (such as #process, #element_validate,
 * #value_callback...) used by the widget cannot use the field_info_field()
 * or field_info_instance() functions to retrieve the $field or $instance
 * definitions they should operate on. The field_widget_field() and
 * field_widget_instance() functions should be used instead to fetch the
 * current working definitions from $form_state, where Field API stores them.
 *
 * Alternatively, hook_field_widget_form() can extract the needed specific
 * properties from $field and $instance and set them as ad-hoc
 * $element['#custom'] properties, for later use by its element callbacks.
 *
 * Other modules may alter the form element provided by this function using
 * hook_field_widget_form_alter().
 *   The form structure where widgets are being attached to. This might be a
 *   full form structure, or a sub-element of a larger form.
 *   An associative array containing the current state of the form.
 * @param $field
 *   The field structure.
 * @param $instance
 *   The field instance.
 * @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).
 *   A form element array containing basic properties for the widget:
 *   - #entity_type: The name of the entity the field is attached to.
 *   - #bundle: The name of the field bundle the field is contained in.
 *   - #field_name: The name of the field.
 *   - #language: The language the field is being edited in.
 *   - #field_parents: The 'parents' space for the field in the form. Most
 *       widgets can simply overlook this property. This identifies the
 *       location where the field values are placed within
 *       $form_state['values'], and is used to access processing information
 *       for the field through the field_form_get_state() and
 *       field_form_set_state() functions.
 *   - #columns: A list of field storage columns of the field.
 *   - #title: The sanitized element label for the field instance, ready for
 *     output.
 *   - #description: The sanitized element description for the field instance,
 *     ready for output.
 *   - #required: A Boolean indicating whether the element value is required;
 *     for required multiple value fields, only the first widget's values are
 *     required.
 *   - #delta: The order of this item in the array of subelements; see $delta
 *     above.
 *   The form elements for a single widget for this field.
 *
 * @see field_widget_field()
 * @see field_widget_instance()
 * @see hook_field_widget_form_alter()
 * @see hook_field_widget_WIDGET_TYPE_form_alter()
function hook_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
    '#type' => $instance['widget']['type'],
    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
  );
  return $element;
}

/**
 * Alter forms for field widgets provided by other modules.
 *
 * @param $element
 *   The field widget form element as constructed by hook_field_widget_form().
 * @param $form_state
 *   An associative array containing the current state of the form.
 * @param $context
 *   An associative array containing the following key-value pairs, matching the
 *   arguments received by hook_field_widget_form():
 *   - form: The form structure to which widgets are being attached. This may be
 *     a full form structure, or a sub-element of a larger form.
 *   - field: The field structure.
 *   - instance: The field instance structure.
 *   - langcode: The language associated with $items.
 *   - items: Array of default values for this field.
 *   - delta: The order of this item in the array of subelements (0, 1, 2, etc).
 */
function hook_field_widget_form_alter(&$element, &$form_state, $context) {
  // Add a css class to widget form elements for all fields of type mytype.
  if ($context['field']['type'] == 'mytype') {
    // Be sure not to overwrite existing attributes.
    $element['#attributes']['class'][] = 'myclass';
  }
}

/**
 * Alter widget forms for a specific widget provided by another module.
 *
 * Modules can implement hook_field_widget_WIDGET_TYPE_form_alter() to modify a
 * specific widget form, rather than using hook_field_widget_form_alter() and
 * checking the widget type.
 *
 * @param $element
 *   The field widget form element as constructed by hook_field_widget_form().
 * @param $form_state
 *   An associative array containing the current state of the form.
 * @param $context
 *   An associative array containing the following key-value pairs, matching the
 *   arguments received by hook_field_widget_form():
 *   - "form": The form structure where widgets are being attached to. This
 *     might be a full form structure, or a sub-element of a larger form.
 *   - "field": The field structure.
 *   - "instance": The field instance structure.
 *   - "langcode": The language associated with $items.
 *   - "items": Array of default values for this field.
 *   - "delta": The order of this item in the array of subelements (0, 1, 2,
 *     etc).
 *
 * @see hook_field_widget_form()
 * @see hook_field_widget_form_alter()
 */
function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $context) {
  // Code here will only act on widgets of type WIDGET_TYPE.  For example,
  // hook_field_widget_mymodule_autocomplete_form_alter() will only act on
  // widgets of type 'mymodule_autocomplete'.
  $element['#autocomplete_path'] = 'mymodule/autocomplete_path';
}

/**
 * Flag a field-level validation error.
 *
 * @param $element
 *   An array containing the form element for the widget. The error needs to be
 *   flagged on the right sub-element, according to the widget's internal
 *   structure.
 * @param $error
 *   An associative array with the following key-value pairs, as returned by
 *   hook_field_validate():
 *   - error: the error code. Complex widgets might need to report different
 *     errors to different form elements inside the widget.
 *   - message: the human readable message to be displayed.
 *   The form structure where field elements are attached to. This might be a
 *   full form structure, or a sub-element of a larger form.
 * @param $form_state
 *   An associative array containing the current state of the form.
function hook_field_widget_error($element, $error, $form, &$form_state) {
  form_error($element['value'], $error['message']);
}


/**
 * @} End of "defgroup field_widget"
 */


/**
 * @defgroup field_formatter Field Formatter API
 * @{
 * Define Field API formatter types.
 *
 * Field API formatters specify how fields are displayed when the entity to
 * which the field is attached is displayed. Fields of a given
 * @link field_types field type @endlink may be displayed using more than one
 * formatter. In this case, the Field UI module allows the site builder to
 * choose which formatter to use. Field formatters are defined by implementing
 * hook_field_formatter_info().
 *
 * @see field
 * @see field_types
 * @see field_widget
 */

 * Formatters handle the display of field values. Formatter hooks are typically
 * called by the Field Attach API field_attach_prepare_view() and
 * field_attach_view() functions.
 *
 * @return
 *   An array describing the formatter types implemented by the module.
 *   The keys are formatter type names. To avoid name clashes, formatter type
 *   names should be prefixed with the name of the module that exposes them.
 *   The values are arrays describing the formatter type, with the following
 *   key/value pairs:
 *   - label: The human-readable name of the formatter type.
 *   - description: A short description for the formatter type.
 *   - field types: An array of field types the formatter supports.
 *   - settings: An array whose keys are the names of the settings available