You are here

empty_fields.module in Empty fields 7

Same filename and directory in other branches
  1. 8 empty_fields.module
  2. 7.2 empty_fields.module

Contains the implementation for the empty_fields module.

File

empty_fields.module
View source
<?php

/**
 * @file
 * Contains the implementation for the empty_fields module.
 */

/**
 * Implements hook_field_formatter_info_alter().
 */
function empty_fields_field_formatter_info_alter(&$info) {
  foreach ($info as $formatter_key => &$formatter) {

    // Some formatters do not have any settings.
    if (!isset($formatter['settings'])) {
      $formatter['settings'] = array();
    }
    $formatter['settings'] += array(
      'display_empty' => '',
      'custom_text' => '',
      'empty_callback' => '',
    );
  }
}

/**
 * Implements hook_field_formatter_settings_summary_alter().
 */
function empty_fields_field_formatter_settings_summary_alter(&$summary, $context) {
  $display = $context['instance']['display'][$context['view_mode']];
  $settings = $display['settings'];
  $summary = empty($summary) ? '' : $summary . '<br />';
  $settings += array(
    'display_empty' => '',
  );
  switch ($settings['display_empty']) {
    case 'text':
      $summary .= t('Displays empty field with custom text: %text', array(
        '%text' => $settings['custom_text'],
      ));
      break;
    case 'callback':
      $callback = empty_fields_get_empty_field_callbacks($settings['empty_callback']);
      if (function_exists($callback['callback'])) {
        $summary .= t('Displays empty field using the callback: %text', array(
          '%text' => $callback['label'],
        ));
      }
      else {
        $summary .= t('Displays empty field using the callback: <em>Missing callback</em>');
      }
      break;
    case 'default':
      $summary .= t('Displays empty field using default');
      break;
    default:
      $summary .= t('Empty field is hidden');
      break;
  }
}

/**
 * Implements hook_field_formatter_settings_form_alter().
 */
function empty_fields_field_formatter_settings_form_alter(&$settings_form, $context) {
  $field = $context['field'];
  $display = $context['instance']['display'][$context['view_mode']];
  $settings = $display['settings'];
  $settings_form['display_empty'] = array(
    '#type' => 'select',
    '#title' => t('Empty display options'),
    '#default_value' => $settings['display_empty'],
    '#options' => array(
      '' => t('Do not display'),
      'text' => t('Display value'),
      'callback' => t('Callback'),
      'default' => t('Display default value (if set)'),
    ),
  );

  // We can not nest this field, so use a prefix / suffix with padding to help
  // to provide context.
  $settings_form['custom_text'] = array(
    '#type' => 'textfield',
    '#title' => t('Custom value'),
    '#default_value' => $settings['custom_text'],
    '#description' => t('This populates the field with the specificied empty value.'),
    '#states' => array(
      'visible' => array(
        ':input[name="fields[' . $field['field_name'] . '][settings_edit_form][settings][display_empty]"]' => array(
          'value' => 'text',
        ),
      ),
    ),
    '#prefix' => '<div style="padding: 0 2em;">',
    '#suffix' => '</div>',
    '#maxlength' => 255,
  );
  $callbacks = empty_fields_get_empty_field_callbacks();
  if (empty($callbacks)) {
    unset($settings_form['display_empty']['#options']['callback']);
  }
  else {
    $options = array();
    foreach ($callbacks as $key => $info) {
      $options[$key] = $info['label'];
    }
    $settings_form['empty_callback'] = array(
      '#type' => 'select',
      '#title' => t('Custom callbacks'),
      '#default_value' => $settings['empty_callback'],
      '#options' => $options,
      '#states' => array(
        'visible' => array(
          ':input[name="fields[' . $field['field_name'] . '][settings_edit_form][settings][display_empty]"]' => array(
            'value' => 'callback',
          ),
        ),
      ),
      '#prefix' => '<div style="padding: 0 2em;">',
      '#suffix' => '</div>',
    );
  }
}

/**
 * Implements hook_field_attach_view_alter().
 */
function empty_fields_field_attach_view_alter(&$result, $context) {
  if (empty($context['view_mode']) || empty($context['display']) || $context['view_mode'] != $context['display']) {
    return;
  }
  $view_mode = $context['view_mode'];
  $entity_type = $context['entity_type'];
  $entity = $context['entity'];
  $language = $context['language'];
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
  $rendered_elements = element_children($result);
  foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) {

    // Do not add field that is hidden in current display.
    $display = field_get_display($instance, $view_mode, $entity);
    if ($display['type'] == 'hidden' || empty($display['settings']['display_empty'])) {
      continue;
    }

    // Some field types still render, so double check that these have content.
    // To date, this is limited to the text fields that always save even if
    // empty.
    $field = field_info_field($field_name);

    // But firstly, check if the user can access the field.
    if (!field_access('view', $field, $entity_type, $entity)) {
      continue;
    }
    if (in_array($field_name, $rendered_elements)) {
      switch ($field['type']) {
        case 'text':
        case 'text_with_summary':
        case 'text_summary_or_trimmed':
          foreach (element_children($result[$field_name]) as $delta) {
            if (!empty($result[$field_name][$delta]['#markup']) || strlen($result[$field_name][$delta]['#markup'])) {
              continue 3;
            }
          }
          break;
        default:
          continue 2;
      }
    }
    $markup = '';
    switch ($display['settings']['display_empty']) {
      case 'text':
        if (!empty($display['settings']['custom_text'])) {
          global $user;
          $args = array(
            $entity_type => $entity,
            'user' => $user,
          );
          $markup = t($display['settings']['custom_text']);
          $markup = token_replace($markup, $args, array(
            'clear' => TRUE,
          ));
          $markup = filter_xss_admin($markup);
        }
        break;
      case 'callback':
        $markup = FALSE;
        if ($callback = empty_fields_get_empty_field_callbacks($display['settings']['empty_callback'])) {
          $func = $callback['callback'];
          if (function_exists($func)) {
            $field_context = $context;
            $field_context['display'] = $display;
            $field_context['instance'] = $instance;
            $field_context['field'] = $field;
            $markup = $func($field_name, $field_context);
          }
        }
        if ($markup === FALSE || is_null($markup)) {
          continue 2;
        }
        break;
      case 'default':
        $items = field_get_default_value($entity_type, $entity, $field, $instance, $language);
        $items = _field_filter_items($field, $items);
        if (!empty($items)) {

          // Too late to allow other modules to alter the results, so only
          // display the first item.
          $item = array_shift($items);
          $element = field_view_value($entity_type, $entity, $field_name, $item, $display, $language);
          if ($element) {
            $result[$field_name] = array(
              '#theme' => 'field',
              '#title' => $instance['label'],
              '#label_display' => $display['label'],
              '#field_type' => $field['type'],
              '#field_name' => $field_name,
              '#bundle' => $bundle,
              '#object' => $entity,
              '#items' => array(
                0 => $item,
              ),
              '#entity_type' => $entity_type,
              '#weight' => $display['weight'],
              '0' => $element,
            );
          }
        }

      // Fall through.
      default:
        continue 2;
    }
    $result[$field_name] = array(
      '#theme' => 'field',
      '#title' => $instance['label'],
      '#label_display' => $display['label'],
      '#field_type' => $field['type'],
      '#field_name' => $field_name,
      '#bundle' => $bundle,
      '#object' => $entity,
      '#items' => array(
        0 => array(
          'value' => $markup,
        ),
      ),
      '#entity_type' => $entity_type,
      '#weight' => $display['weight'],
      0 => array(
        '#markup' => $markup,
      ),
    );
  }
}

/**
 * Get all the empty field callbacks via hook_empty_field_callbacks().
 */
function empty_fields_get_empty_field_callbacks($callback = NULL) {
  $info =& drupal_static(__FUNCTION__);
  if (!isset($info)) {
    $cid = "empty_fields:" . $GLOBALS['language']->language;
    if ($cache = cache_get($cid)) {
      $info = $cache->data;
    }
    else {
      $info = module_invoke_all('empty_field_callbacks');
      drupal_alter('empty_field_callbacks', $info);
      cache_set($cid, $info);
    }
  }
  if (isset($callback)) {
    return isset($info[$callback]) ? $info[$callback] : NULL;
  }
  return $info;
}