Commit 78314dc0 authored by Jess's avatar Jess
Browse files

Issue #1339828 by xjm: Allow disallowed default values to be ignored on node creation.

parent 1374ad0c
Loading
Loading
Loading
Loading
+111 −105
Changes for taxonomy_access.module: 111 added lines, 105 removed lines.
Original line number Diff line number Diff line
@@ -300,6 +300,7 @@ function taxonomy_access_field_info_alter(&$info) {
       $entity->uid = $account->uid;
     }
   }

   list($entity_id, , $bundle) = entity_extract_ids($entity_type, $entity);
   if ($entity_id) {
     // Load the entity.
@@ -482,35 +483,127 @@ function taxonomy_access_field_widget_taxonomy_autocomplete_form_alter(&$element
}

/**
 * Implements hook_field_widget_WIDGET_TYPE_form_alter().
 * Implements hook_field_widget_form_alter().
 *
 * This implements the create grant for select widgets.
 * This implements the create grant for options widgets:
 * 1. Denies access if the user cannot alter the field values.
 * 2. Attaches jQuery to disable values disallowed by create.
 * 3. Adds the disallowed values from (2) to the element so they are available
 *    to the custom validator.
 * 4. Adds the custom validator.
 *
 * We use jQuery to disable the options because of FAPI limitations:
 * @see
 *   _taxonomy_access_configure_options_widget()
 *   http://drupal.org/node/284917
 * @see
 *   http://drupal.org/node/342316
 * @see
 *   http://drupal.org/node/12089
 */
function taxonomy_access_field_widget_options_select_form_alter(&$element, &$form_state, $context) {
function taxonomy_access_field_widget_form_alter(&$element, &$form_state, $context) {
  // Only act on taxonomy fields.
  if ($context['field']['type'] != 'taxonomy_term_reference') {
    return;
  }
  _taxonomy_access_configure_options_widget($element, $context['field']['cardinality']);
  // Only act on options widgets.
  $widget = $context['instance']['widget']['type'];
  if (!in_array($widget, array('options_buttons', 'options_select'))) {
    return;
  }

/**
 * Implements hook_field_widget_WIDGET_TYPE_form_alter().
 *
 * This implements the create grant for checkbox/radio widgets.
 *
 * @see
 *   _taxonomy_access_configure_options_widget()
 */
function taxonomy_access_field_widget_options_buttons_form_alter(&$element, &$form_state, $context) {
  // Only act on taxonomy fields.
  if ($context['field']['type'] != 'taxonomy_term_reference') {
    return;
  // Check for an existing entity ID.
  $entity_id = 0;
  if (!empty($form_state['build_info']['args'][0])) {
    $info = entity_get_info($context['instance']['entity_type']);
    $pseudo_entity = (object) $form_state['build_info']['args'][0];
    if (isset($pseudo_entity->{$info['entity keys']['id']})) {
      $entity_id = $pseudo_entity->{$info['entity keys']['id']};
    }
  }
  // Enforce that list grants do not filter our queries.
  taxonomy_access_disable_list();

  // Collect a list of terms and determine which are allowed
  $tids = array_keys($element['#options']);

  // Ignore the "none" option if present.
  $key = array_search('_none', $tids);
  if ($key !== FALSE) {
    unset($tids[$key]);
  }

  $allowed_tids = taxonomy_access_create_allowed($tids);
  $disallowed_tids = taxonomy_access_create_disallowed($tids);

  // If no options are allowed, deny access to the field.
  if (empty($allowed_tids)) {
    $element['#access'] = FALSE;
  }

  // On node creation, simply remove disallowed default values.
  if (!$entity_id) {
    $disallowed_defaults = array();
    if (is_array($element['#default_value'])) {
      foreach ($element['#default_value'] as $key => $value) {
        if (in_array($value, $disallowed_tids)) {
          unset($element['#default_value'][0]);
        }
      }
    }
    elseif (in_array($element['#default_value'], $disallowed_tids)) {
      unset($element['#default_value']);
    }
  }
  // If the node already exists, check:
  // 1. Whether the field already has the maximum number of values
  // 2. Whether all of these values are disallowed.
  // If both these things are true, then the user cannot edit the field's
  // value, so disallow access.
  else {
    $defaults =
      is_array($element['#default_value'])
      ? $element['#default_value']
      : array($element['#default_value'])
      ;

    $disallowed_defaults =
      array_intersect($defaults, $disallowed_tids);

    if ($context['field']['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
      if (sizeof($disallowed_defaults) >= $context['field']['cardinality']) {
        $element['#access'] = FALSE;
      }
    }
  }

  // If there are disallowed, terms, add CSS and JS for jQuery.
  // We use jQuery because FAPI does not currently support attributes
  // for individual options.
  if (!empty($disallowed_tids)) {

    // Add a css class to the field that we can use in jQuery.
    $class_name = 'tac_' . $element['#field_name'];
    $element['#attributes']['class'][] = $class_name;

    // Add js for disabling create options.
    $settings[] = array(
      'field' => $class_name,
      'disallowed_tids' => $disallowed_tids,
      'disallowed_defaults' => $disallowed_defaults,
    );
    $element['#attached']['js'][] =
      drupal_get_path('module', 'taxonomy_access') . '/tac_create.js';
    $element['#attached']['js'][] = array(
      'data' => array('taxonomy_access' => $settings),
      'type' => 'setting',
    );
  }
  _taxonomy_access_configure_options_widget($element, $context['field']['cardinality']);

  $element['#disallowed_defaults'] = $disallowed_defaults;
  $element['#element_validate'] = array('taxonomy_access_options_validate');

  // Re-enable list grants.
  taxonomy_access_enable_list();
}


@@ -1705,93 +1798,6 @@ function _taxonomy_access_term_options($field) {
  return $options;
}


/**
 * Helper function for hook_field_widget_form_alter() on options widgets.
 *
 * This implements the create grant for options widgets:
 * 1. Denies access if the user cannot alter the field values.
 * 2. Attaches jQuery to disable values disallowed by create.
 * 3. Adds the disallowed values from (2) to the element so they are available
 *    to the custom validator.
 * 4. Adds the custom validator.
 *
 * We use JQuery to disable the options because of FAPI limitations:
 * @see
 *   http://drupal.org/node/284917
 * @see
 *   http://drupal.org/node/342316
 * @see
 *   http://drupal.org/node/12089
 */
function _taxonomy_access_configure_options_widget(&$element, $field_size) {
  // Enforce that list grants do not filter our queries.
  taxonomy_access_disable_list();

  // Collect a list of terms and determine which are allowed
  $tids = array_keys($element['#options']);

  // Ignore the "none" option if present.
  $key = array_search('_none', $tids);
  if ($key !== FALSE) {
    unset($tids[$key]);
  }

  $allowed_tids = taxonomy_access_create_allowed($tids);
  $disallowed_tids = taxonomy_access_create_disallowed($tids);

  // If no options are allowed, deny access to the field.
  if (empty($allowed_tids)) {
    $element['#access'] = FALSE;
  }

  // If the field already has the maximum number of values, and all of these
  // values are disallowed, deny access to the field.
  $defaults =
    is_array($element['#default_value'])
    ? $element['#default_value']
    : array($element['#default_value'])
    ;

  $disallowed_defaults =
    array_intersect($defaults, $disallowed_tids);
  if ($field_size != FIELD_CARDINALITY_UNLIMITED) {
    if (sizeof($disallowed_defaults) >= $field_size) {
      $element['#access'] = FALSE;
    }
  }

  // If there are disallowed, terms, add CSS and JS for jQuery.
  // We use jQuery because FAPI does not currently support attributes
  // for individual options.
  if (!empty($disallowed_tids)) {

    // Add a css class to the field that we can use in jQuery.
    $class_name = 'tac_' . $element['#field_name'];
    $element['#attributes']['class'][] = $class_name;

    // Add js for disabling create options.
    $settings[] = array(
      'field' => $class_name,
      'disallowed_tids' => $disallowed_tids,
      'disallowed_defaults' => $disallowed_defaults,
    );
    $element['#attached']['js'][] =
      drupal_get_path('module', 'taxonomy_access') . '/tac_create.js';
    $element['#attached']['js'][] = array(
      'data' => array('taxonomy_access' => $settings),
      'type' => 'setting',
    );
  }

  $element['#disallowed_defaults'] = $disallowed_defaults;
  $element['#element_validate'] = array('taxonomy_access_options_validate');

  // Re-enable list grants.
  taxonomy_access_enable_list();

}

/**
 * Validation to process option sets, which may have some terms disabled.
 *