You are here

taxonomy_access_fix.module in Taxonomy access fix 7

This file contains all hooks and callbacks for extra/improved Taxonomy permissions.

File

taxonomy_access_fix.module
View source
<?php

/**
 * @file
 * This file contains all hooks and callbacks for extra/improved Taxonomy
 * permissions.
 */

/**
 * Implements hook_form_FORM_ID_alter() for taxonomy_overview_vocabularies().
 *
 * Form URI: `admin/structure/taxonomy`.
 *
 * @see theme_taxonomy_overview_vocabularies()
 */
function taxonomy_access_fix_form_taxonomy_overview_vocabularies_alter(&$form, &$form_state) {

  // Admin: don't fix anything.
  if (user_access('administer taxonomy')) {
    return TRUE;
  }

  // Empty text for unauthorized functions.
  $empty = array(
    '#type' => 'markup',
    '#markup' => '&nbsp;',
  );

  // Others: remove some vocabularies.
  foreach (element_children($form) as $vid) {
    if (is_numeric($vid) && ($vocabulary = $form[$vid]['#vocabulary'])) {

      // No access at all?
      if (!taxonomy_access_fix_access('list terms', $vocabulary)) {

        // Unfortunately, just setting #access isn't enough.
        $form[$vid]['#access'] = FALSE;
        unset($form[$vid]);
        continue;
      }

      // Definitely no "edit vocabulary" access.
      $form[$vid]['edit']['#access'] = FALSE;

      // Maybe no "add terms" access.
      if (!taxonomy_access_fix_access('add terms', $vocabulary)) {
        $form[$vid]['add']['#access'] = FALSE;
      }
    }
  }

  // Remove "Save" button.
  $form['actions']['#access'] = FALSE;
}

/**
 * Implements hook_form_FORM_ID_alter() for taxonomy_overview_terms().
 */
function taxonomy_access_fix_form_taxonomy_overview_terms_alter(&$form, &$form_state) {

  // Admin: don't fix anything.
  if (user_access('administer taxonomy')) {
    return TRUE;
  }

  // Wrong part of the form (ie. reset): bail out.
  if (!isset($form['#vocabulary'])) {
    return;
  }
  $vocabulary = $form['#vocabulary'];
  $vid = $vocabulary->vid;
  $can_edit = user_access('edit terms in ' . $vid);
  $can_delete = user_access('delete terms in ' . $vid);

  // Hide edit links
  foreach (element_children($form) as $item) {
    $item =& $form[$item];

    // Term items are index like 'tid:14:0', so don't check that; check for #term.
    if (isset($item['#term'])) {
      if (!$can_edit) {
        $item['edit']['#access'] = FALSE;
      }
      if ($can_delete) {

        // Maybe someday...
      }
    }
    unset($item);
  }

  // Hide Save and Reset buttons
  if (!taxonomy_access_fix_access('reorder', $vocabulary)) {
    $form['actions']['submit']['#access'] = $form['actions']['reset_alphabetical']['#access'] = FALSE;
  }
}

/**
 * Implements hook_permission().
 *
 * Adds 1 permission per vocabulary: `add terms to VOCABULARY_ID`.
 */
function taxonomy_access_fix_permission() {
  $permissions = array();
  foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) {
    $permissions['add terms in ' . $vid] = array(
      'title' => t('Add terms in %vocabulary', array(
        '%vocabulary' => $vocabulary->name,
      )),
    );
  }
  return $permissions;
}

/**
 * Implements hook_menu_alter().
 *
 * Changes access callbacks and arguments for **some** (dubious) Taxonomy
 * admin pages:
 *
 * * Vocabulary overview: if you have access to >= 1 vocabulary.
 * * Vocabulary's terms overview: if you have access to edit or delete
 *   terms in this vocabulary.
 * * Add vocabulary term: if you have the new "add terms in X" permission.
 *
 * @see taxonomy_access_fix_access()
 */
function taxonomy_access_fix_menu_alter(&$items) {

  // Vocabularies list.
  $item =& $items['admin/structure/taxonomy'];
  $item['access callback'] = 'taxonomy_access_fix_access';
  $item['access arguments'] = array(
    'index',
  );

  // Terms list in vocabulary.
  $item =& $items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name'];
  $item['access callback'] = 'taxonomy_access_fix_access';
  $item['access arguments'] = array(
    'list terms',
    3,
  );

  // Add term to vocabulary.
  $item =& $items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/add'];
  $item['access callback'] = 'taxonomy_access_fix_access';
  $item['access arguments'] = array(
    'add terms',
    3,
  );
}

/**
 * Creates an access callback for custom vocabulary access.
 *
 * @see taxonomy_access_fix_permission()
 * @see http://api.drupal.org/api/drupal/modules--taxonomy--taxonomy.module/function/taxonomy_permission/7
 */
function taxonomy_access_fix_access($op, $vocabulary = NULL) {

  // Admin: always.
  if (user_access('administer taxonomy')) {
    return TRUE;
  }

  // Others: well, that depends.
  switch ($op) {
    case 'index':

      // Only if they have >= 1 vocabulary access.
      foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) {
        if (user_access('edit terms in ' . $vid) || user_access('delete terms in ' . $vid) || user_access('add terms in ' . $vid)) {
          return TRUE;
        }
      }
      break;
    case 'list terms':
      if ($vocabulary) {
        $vid = $vocabulary->vid;
        if (user_access('edit terms in ' . $vid) || user_access('delete terms in ' . $vid) || user_access('add terms in ' . $vid)) {
          return TRUE;
        }
      }
      break;
    case 'reorder':

      // If you can list terms, you can reorder. Not logic, but backward compatibility.
      return taxonomy_access_fix_access('list terms', $vocabulary);
    case 'add terms':
      if ($vocabulary) {
        $vid = $vocabulary->vid;
        if (user_access('add terms in ' . $vid)) {
          return TRUE;
        }
      }
      break;
  }
}