You are here

entityreference_current.module in Entityreference Current 7

Prepoplates entity reference values from Current Entity(Menu Object).

File

entityreference_current.module
View source
<?php

/**
 * @file
 * Prepoplates entity reference values from Current Entity(Menu Object).
 */

/**
 * Implements hook_ctools_plugin_directory().
 */
function entityreference_current_ctools_plugin_directory($module, $plugin) {
  if ($module == 'entityreference' || $module == 'ctools') {
    return 'plugins/' . $plugin;
  }
}

/**
 * Implements hook_field_create_instance().
 *
 * Add "default value function" setting to the field instance.
 * We have to do it from this hook, as we don't have another chance of setting
 * this option via the hook_field_info().
 */
function entityreference_current_field_create_instance($instance) {
  if (empty($instance['settings']['behaviors']['current']['status'])) {
    return;
  }
  $instance['default_value_function'] = 'entityreference_current_field_default_value';
  field_update_instance($instance);
}

/**
 * Implements hook_field_update_instance().
 */
function entityreference_current_field_update_instance($instance, $prior_instance) {
  if (empty($instance['settings']['behaviors']['current'])) {
    return;
  }
  if (isset($prior_instance['settings']['behaviors']['current']['status']) && $instance['settings']['behaviors']['current']['status'] == $prior_instance['settings']['behaviors']['current']['status']) {

    // Nothing changed.
    return;
  }
  $instance['default_value_function'] = !empty($instance['settings']['behaviors']['current']['status']) ? 'entityreference_current_field_default_value' : '';
  field_update_instance($instance);
}

/**
 * Implements hook_field_attach_form().
 */
function entityreference_current_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
  module_load_include('inc', 'entityreference_current');
  list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
  if (!empty($form_state['triggering_element']['#ajax'])) {

    // We are inside AJAX, so values can't be taken from Menu Object at the
    // moment.
    return;
  }

  // Check if there is a field that needs to be currentd attached to the
  // given entity.
  $found = FALSE;
  foreach (field_info_instances($entity_type, $bundle) as $instance) {
    if (!empty($instance['settings']['behaviors']['current']['status'])) {
      $found = TRUE;
      break;
    }
  }
  if (!$found) {
    return;
  }
  foreach (element_children($form_state['field']) as $field_name) {
    foreach ($form_state['field'][$field_name] as $lang => $value) {
      $instance = $value['instance'];
      if (empty($instance['settings']['behaviors']['current']['status'])) {
        continue;
      }
      $settings = $instance['settings']['behaviors']['current'];
      if (!empty($settings['skip_perm']) && user_access($settings['skip_perm']) || $id && empty($settings['action_on_edit'])) {

        // User has access to skip the action, or the entity is already
        // saved, but "Apply action on edit", is disabled.
        continue;
      }
      $field = $value['field'];

      // Store currentd values in the form state to make them persistent,
      // in case the form is rebuilt by AJAX requests.
      $field_name = $field['field_name'];
      if ($ids = entityreference_current_get_values($field, $instance)) {
        $form_state['entityreference_current'][$instance['entity_type']][$instance['bundle']][$field_name] = $ids;
      }
      if ($ids || $id && !empty($settings['action_on_edit'])) {

        // New entity with prepopualte values, or an existing entity,
        // we might need to disable/ hide the field.
        if ($settings['action'] == 'disable') {
          $form[$field_name][$lang]['#disabled'] = TRUE;
        }
        elseif ($settings['action'] == 'hide') {

          // We don't hide the field via hook_field_access(), as the
          // default value won't be set.
          $form[$field_name]['#access'] = FALSE;
        }
      }
      elseif (in_array($settings['fallback'], array(
        'form_error',
        'redirect',
      ))) {
        $message = t('Field @label must be populated via Menu Object.', array(
          '@label' => $instance['label'],
        ));
        if ($settings['fallback'] == 'form_error') {
          form_error($form, $message);
        }
        elseif ($settings['fallback'] == 'redirect') {
          drupal_set_message($message, 'notice');
          drupal_goto();
        }
      }
    }
  }
}

/**
 * Implements hook_field_access().
 */
function entityreference_current_field_access($op, $field, $entity_type, $entity, $account) {
  module_load_include('inc', 'entityreference_current');
  if ($op != 'edit' || $field['type'] != 'entityreference') {
    return;
  }
  if (empty($entity)) {

    // $entity might be NULL, so return early.
    // @see field_access().
    return;
  }
  list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
  if ($id) {

    // Entity is already saved.
    return;
  }
  $instance = field_info_instance($entity_type, $field['field_name'], $bundle);
  if (empty($instance['settings']['behaviors']['current']['status'])) {
    return;
  }
  $settings = $instance['settings']['behaviors']['current'];
  if (!empty($settings['skip_perm']) && user_access($settings['skip_perm'])) {
    return;
  }
  $ids = entityreference_current_get_values($field, $instance);
  if (!$ids && $settings['fallback'] == 'hide') {
    return FALSE;
  }
}

/**
 * Field default value callback.
 *
 * Set the default from the Menu Object context. This works even if the widget is
 * not shown, e.g. due to restricted field access.
 *
 * @todo Check field cardinality.
 */
function entityreference_current_field_default_value($entity_type, $entity, $field, $instance, $langcode) {
  module_load_include('inc', 'entityreference_current');
  $items = array();
  if ($ids = entityreference_current_get_values($field, $instance)) {
    $items = array();
    foreach ($ids as $id) {
      $items[] = array(
        'target_id' => $id,
      );
    }
  }
  return $items;
}