You are here

entityreference_rendered_widget.module in Entityreference Rendered Widget 7

Same filename and directory in other branches
  1. 8 entityreference_rendered_widget.module

Entityreference Rendered Widget module.

File

entityreference_rendered_widget.module
View source
<?php

/**
 * @file
 * Entityreference Rendered Widget module.
 */

/**
 * Implements hook_entity_info_alter().
 */
function entityreference_rendered_widget_entity_info_alter(&$info) {
  foreach ($info as $entity_type => $data) {
    $info[$entity_type]['view modes']['entityreference_rendered_widget'] = array(
      'label' => t('Entity Reference rendered display'),
      'custom settings' => TRUE,
    );
  }
}

/**
 * Implements hook_field_widget_info().
 */
function entityreference_rendered_widget_field_widget_info() {
  $widgets['rendered_display'] = array(
    'label' => t('Rendered display'),
    'description' => t('A custon widget for entityreference'),
    'field types' => array(
      'entityreference',
    ),
    'settings' => array(
      'custom_display_fields' => array(),
    ),
    'behaviors' => array(
      'multiple values' => FIELD_BEHAVIOR_CUSTOM,
      'default value' => FIELD_BEHAVIOR_DEFAULT,
    ),
  );
  return $widgets;
}

/**
 * Implements hook_field_widget_settings_form().
 */
function entityreference_rendered_widget_field_widget_settings_form($field, $instance) {
  $widget = $instance['widget'];
  $settings = $widget['settings'];
  if ($widget['type'] == 'rendered_display') {
    $target_type = $field['settings']['target_type'];

    // Get all view modes in entity type.
    $entity_info = entity_get_info($target_type);
    $view_modes = array_keys($entity_info['view modes']);
    $element['custom_display_fields'] = array(
      '#type' => 'select',
      '#title' => t('View mode displayed'),
      '#options' => drupal_map_assoc($view_modes),
      '#default_value' => isset($settings['custom_display_fields']) ? $settings['custom_display_fields'] : array(),
    );
    $element['label_display'] = array(
      '#type' => 'select',
      '#title' => t('Label display'),
      '#options' => array(
        'before' => 'Before rendered element',
        'after' => 'After rendered element',
        'hidden' => 'Hidden',
      ),
      '#default_value' => isset($settings['label_display']) ? $settings['label_display'] : 'before',
    );
    return $element;
  }
}

/**
 * Implements hook_field_widget_form().
 */
function entityreference_rendered_widget_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $widget = $instance['widget'];
  if ($widget['type'] == 'rendered_display') {
    $element['#type'] = 'item';

    // Custom validate function.
    $element['#element_validate'][] = 'entityreference_rendered_widget_validate';
    $entity_type = $field['settings']['target_type'];
    $handler = entityreference_get_selection_handler($field, $instance);
    $view_mode = $widget['settings']['custom_display_fields'];

    // Get all Referenceables Entities.
    $all_entities = $handler
      ->getReferencableEntities();

    // Build the path of the element.
    $parents_path = $field['field_name'];
    if (!empty($form['#parents'])) {
      $parents = $form['#parents'];
      $first_parent = array_shift($parents);
      $parents_path = $first_parent;
      if (!empty($parents)) {
        $parents_path .= '[' . implode('][', $parents) . ']';
      }
      $parents_path .= '[' . $field['field_name'] . ']';
    }

    // Get attached checkboxes in node.
    $attach = entityreference_rendered_widget_attach_fields($entity_type, $parents_path, $field, $langcode, $view_mode, $items, $all_entities, $widget['settings']['label_display']);
    if (empty($attach)) {

      // Default entities.
      $msg = t('There are no entities');

      // When has target bundles.
      if (isset($field['settings']['handler_settings']['target_bundles'])) {
        $entity_bundles = $field['settings']['handler_settings']['target_bundles'];
        $bundles = implode(',', $entity_bundles);
        $params = array(
          '@type' => $entity_type,
          '@bundles' => $bundles,
        );
        $msg = t('There are no entities of type @type and bundle @bundles', $params);
      }

      // Markup if no have results.
      $element[] = array(
        '#type' => 'markup',
        '#markup' => $msg,
      );
      return $element;
    }

    // Attach checkboxes in element.
    $element += $attach;
  }
  return $element;
}

/**
 * Return attached checkboxes.
 *
 * @param string $entity_type
 *   String containing the type of entity.
 * @param string $parents_path
 *   String parents_path.
 * @param array $field
 *   Array contains field.
 * @param string $langcode
 *   String language.
 * @param array $items
 *   (Optional) Array of all marked items.
 * @param array $all_entities
 *   (Optional) Array containing all entities.
 *
 * @return array
 *   Array to be added to Element.
 */
function entityreference_rendered_widget_attach_fields($entity_type, $parents_path, array $field, $langcode, $view_mode, array $items = array(), array $all_entities = array(), $label_display = 'before') {
  $type = 'radio';
  if ($field['cardinality'] != 1) {

    // Change type.
    $type = 'checkbox';
  }

  // Define empty array.
  $rows = array();

  // Add any value if radio type.
  if ($type == 'radio') {
    $name = $field['field_name'] . "[{$langcode}][0][target_id]";

    // Any values.
    $rows[0]['target_id'] = array(
      '#type' => $type,
      '#delta' => 0,
      '#return_value' => NULL,
      '#default_value' => entityreference_rendered_widget_checkbox_default_value(0, $items),
      '#title' => t('- Any -'),
      '#name' => $name,
    );
  }
  $delta = 1;
  foreach ($all_entities as $ids) {
    $ids = array_keys($ids);

    // Load entities.
    $entities = entity_load($entity_type, $ids);
    foreach ($entities as $entity_id => $entity) {
      $label = $label_display == 'hidden' ? '' : '<div class="entity-label">' . entity_label($entity_type, $entity) . '</div>';
      $entity_view = entity_view($entity_type, array(
        $entity,
      ), $view_mode);
      $suffix = '<div class="view-mode">';
      $suffix .= drupal_render($entity_view) . '</div>';
      $title = $label_display == 'before' ? $label . $suffix : $suffix . $label;
      $rows[$delta] = array(
        'target_id' => array(
          '#type' => $type,
          '#delta' => $delta,
          '#return_value' => $entity_id,
          '#default_value' => entityreference_rendered_widget_checkbox_default_value($entity_id, $items),
          '#title' => $title,
        ),
      );

      // Set same name if radio button.
      if (isset($name)) {
        $rows[$delta]['target_id']['#name'] = $name;
      }
      ++$delta;
    }
  }
  return $rows;
}

/**
 * Get Default values of items.
 *
 * @param array $items
 *   (Optional) Saved items.
 *
 * @return array
 *   Default values.
 */
function entityreference_rendered_widget_default_values(array $items = array()) {
  $default_values = array();
  foreach ($items as $record) {
    $default_values[] = $record['target_id'];
  }
  return drupal_map_assoc($default_values);
}

/**
 * Return default value of checkbox.
 *
 * @param int $entity_id
 *   Id of current items.
 * @param array $items
 *   (Optional) Saved items.
 *
 * @return int
 *   Default value or 0 if empty.
 */
function entityreference_rendered_widget_checkbox_default_value($entity_id, array $items = array()) {
  $default_values = entityreference_rendered_widget_default_values($items);
  if (in_array($entity_id, $default_values)) {
    return $entity_id;
  }
  return 0;
}

/**
 * Validate checkboxes elements.
 */
function entityreference_rendered_widget_validate($element, &$form_state, $form) {
  array_pop($element['#parents']);
  $input = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
  $langcode = $element['#language'];
  $field_name = $element['#field_name'];
  $field = field_info_field($field_name);
  if ($field['cardinality'] == 1) {
    $input[$langcode] = array(
      $input[$langcode][0],
    );
    form_set_value($element, $input, $form_state);
  }
  else {

    // Initial value.
    $empty = TRUE;
    foreach ($input[$langcode] as $key => $values) {
      if (!empty($values['target_id'])) {
        $empty = FALSE;
      }
      else {
        $input[$langcode][$key]['target_id'] = NULL;
      }
    }

    // Verify if required field.
    if ($element['#required']) {

      // Message if field is empty.
      if ($empty) {
        $array_error = array(
          '@field' => $element['#title'],
        );
        form_set_error($element['#field_name'], t('@field is required.', $array_error));
      }
    }
    form_set_value($element, $input, $form_state);
  }
}