<?php

/**
 * @file
 * Vocabulary Permissions Per Role
 *
 * Allows adding to/editing terms of/removing terms from vocabularies per role.
 */

/**
 * Implementation of hook_menu_alter().
 */
function vppr_menu_alter(&$items) {
  // Taxonomy overview page: http://d6.l/admin/content/taxonomy
  $items['admin/content/taxonomy']['access callback'] = '_vppr_access_taxonomy';
  $items['admin/content/taxonomy']['page callback'] = '_vppr_page_taxonomy_overview';
  // Add terms: http://d6.l/admin/content/taxonomy/$vid/add/term
  $items['admin/content/taxonomy/%taxonomy_vocabulary/add/term']['access callback'] = '_vppr_access_vocabulary';
  $items['admin/content/taxonomy/%taxonomy_vocabulary/add/term']['access arguments'] = array(3);
  // Reorder terms: http://d6.l/admin/content/taxonomy/$vid
  $items['admin/content/taxonomy/%taxonomy_vocabulary']['access callback'] = '_vppr_access_vocabulary';
  $items['admin/content/taxonomy/%taxonomy_vocabulary']['access arguments'] = array(3);
  // Edit and delete terms: http://d6.l/admin/content/taxonomy/edit/term/$tid - warning: there's only a tid arg!
  $items['admin/content/taxonomy/edit/term']['access callback'] = '_vppr_access_term';
  $items['admin/content/taxonomy/edit/term']['access arguments'] = array(5);
}

/**
 * VPPR's access callback for taxonomy overview page (main entry point).
 *
 * Grants access to taxonomy overview page even if $user has access to any of
 * the vocabularies.
 */
function _vppr_access_taxonomy() {
  if (user_access('administer taxonomy')) {
    return TRUE;
  }
  global $user;
  $perms = variable_get('vppr_perms', array(array()));
  foreach ($perms as $perm) {
    $diff = array_intersect(array_keys($perm), array_keys($user->roles));
    if (!empty($diff)) {
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * VPPR's access callback for vocabularies (add and reorder terms).
 */
function _vppr_access_vocabulary($vocab) {
  if (user_access('administer taxonomy')) {
    return TRUE;
  }
  global $user;
  $perms = variable_get('vppr_perms', array(array()));
  foreach ($user->roles as $rid => $role) {
    if (isset($perms[$vocab->vid]) && isset($perms[$vocab->vid][$rid]) && $perms[$vocab->vid][$rid]) {
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * VPPR's access callback for term ID's (edit and delete terms).
 */
function _vppr_access_term($tid) {
  if (user_access('administer taxonomy')) {
    return TRUE;
  }
  $term = taxonomy_get_term($tid);
  // Speed up things if there is no such term.
  if (!$term) {
    return FALSE;
  }
  global $user;
  $perms = variable_get('vppr_perms', array(array()));
  foreach ($user->roles as $rid => $role) {
    if (isset($perms[$term->vid]) && isset($perms[$term->vid][$rid]) && $perms[$term->vid][$rid]) {
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Implementation of hook_perm().
 */
function vppr_perm() {
  return array('administer VPPR');
}

/**
 * Implementation of hook_menu().
 */
function vppr_menu() {
  $items = array();
  $items['admin/settings/vppr'] = array(
    'title' => 'Vocabulary permissions',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('vppr_form_admin_settings_vppr'),
    'access arguments' => array('administer VPPR'),
    'file' => 'vppr.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/**
 * Implementation of hook_theme().
 */
function vppr_theme() {
  return array(
    'vppr_form_admin_settings_vppr' => array(
      'arguments' => array('form' => array()),
      'file' => 'vppr.admin.inc',
    ),
  );
}

/**
 * Page callback for taxonomy overview.
 *
 * Displays the form core ships if $user has 'administer taxonomy' permission,
 * or a simple list that mimics the same otherwise. Rationale: don't display
 * even a stripped-down form if we don't need a form but only a
 * nicely-formatted list.
 *
 * @see taxonomy_overview_vocabularies()
 */
function _vppr_page_taxonomy_overview($form_id) {
  // If $user has 'administer taxonomy', then do not do anything, just bail
  // out early with the untouched form.
  if (user_access('administer taxonomy')) {
    return drupal_get_form($form_id);
  }
  $header = array(
    t('Name'),
    t('Type'),
    array(
      'data' => t('Operations'),
      'colspan' => '2',
    ),
  );
  $rows = array();
  $vocabularies = taxonomy_get_vocabularies();
  foreach ($vocabularies as $vocabulary) {
    if (!_vppr_access_vocabulary($vocabulary)) {
      continue;
    }
    $types = array();
    foreach ($vocabulary->nodes as $type) {
      $node_type = node_get_types('name', $type);
      $types[] = $node_type ? check_plain($node_type) : check_plain($type);
    }
    $rows[] = array(
      check_plain($vocabulary->name),
      implode(', ', $types),
      l(t('list terms'), "admin/content/taxonomy/$vocabulary->vid"),
      l(t('add terms'), "admin/content/taxonomy/$vocabulary->vid/add/term"),
    );
  }
  if (empty($rows)) {
    $rows[] = array(array('data' => t('No vocabularies available.'), 'colspan' => '4'));
  }
  return theme('table', $header, $rows);
}
