You are here

search_restrict.module in Search Restrict 7

Restrict by role who can search for each content type.

File

search_restrict.module
View source
<?php

// $Id$

/**
 * @file
 * Restrict by role who can search for each content type.
 */

/**
 * Implements hook_permission().
 */
function search_restrict_permission() {
  return array(
    'administer search_restrict' => array(
      'title' => t('Administer search restrict'),
    ),
  );
}

/**
 * Implements hook_form_FORM_alter().
 */
function search_restrict_form_node_type_form_alter(&$form, &$form_state) {
  search_restrict_content_type_form($form);
}

/**
 * Alter content type forms to include search restrict options.
 */
function search_restrict_content_type_form(&$form) {
  $roles = user_roles();
  natcasesort($roles);
  $exclude_all_option = t('Exclude all roles from search');
  $roles = array(
    '-1' => $exclude_all_option,
  ) + $roles;
  $content_type_restrictions = variable_get('search_restrict_content_type', array());
  $content_type_restrictions += array(
    $form['#node_type']->type => array(),
  );
  $form['search_restrict'] = array(
    '#type' => 'fieldset',
    '#title' => t('Search Restrict'),
    '#description' => t('Select which user roles can search for this content type. By default all roles can search unless "%exclude_all_option" is selected, which overrides all other role restrictions.', array(
      '%exclude_all_option' => $exclude_all_option,
    )),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
    '#access' => user_access('administer search_restrict'),
  );
  $form['search_restrict']['search_restrict_roles'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Roles'),
    '#description' => t('If all checkboxes are unselected then everyone can search.'),
    '#options' => $roles,
    '#default_value' => $content_type_restrictions[$form['#node_type']->type],
  );

  // Use custom submit function to avoid a query at time of search to get the
  // list of content types.
  // Add to front of array so that we can clear search_restrict_roles_<content_type>.
  array_unshift($form['#submit'], 'search_restrict_content_type_form_submit');
}

/**
 *  use custom submit function to avoid a query at time of search to get the list of content types
 */
function search_restrict_content_type_form_submit($form, &$form_state) {
  $content_type_restrictions = variable_get('search_restrict_content_type', array());
  $content_type_restrictions[$form_state['values']['type']] = $form_state['values']['search_restrict_roles'];
  variable_set('search_restrict_content_type', $content_type_restrictions);
  unset($form_state['values']['search_restrict_roles']);
}

/**
 * Implements hook_query_node_access_alter().
 */
function search_restrict_query_node_access_alter(QueryAlterableInterface $query) {
  global $user;
  if ($user->uid == 1) {
    return;
  }
  $search = FALSE;
  $node = FALSE;
  foreach ($query
    ->getTables() as $alias => $table) {
    if ($table['table'] == 'search_index') {
      $search = $alias;
    }
    elseif ($table['table'] == 'node') {
      $node = $alias;
    }
  }
  if ($node && $search) {
    $excluded_content_types = _search_restrict_excluded_content_types();
    if (!empty($excluded_content_types)) {
      $query
        ->condition($node . '.type', array(
        $excluded_content_types,
      ), 'NOT IN');
    }
  }
}

/**
 * Implements hook_form_alter().
 */
function search_restrict_form_alter(&$form, $form_state, $form_id) {
  switch ($form_id) {
    case 'search_form':
      if (array_key_exists('advanced', $form)) {
        $form['#after_build'][] = '_search_restrict_advanced_form';
      }
      break;
  }
}

/**
 * Remove restricted content types from the advanced search form. We use
 * after_build due to the method the node module uses to add the advanced
 * search options. 
 */
function _search_restrict_advanced_form($form, &$form_state) {
  global $user;
  if ($user->uid == 1) {
    return $form;
  }
  $content_type_restrictions = variable_get('search_restrict_content_type', array());
  $role_ids = array_keys($user->roles);
  foreach ($content_type_restrictions as $type => $roles) {
    $access = FALSE;
    foreach ($roles as $role_id => $selected) {
      if (!empty($selected) && in_array($role_id, $role_ids)) {
        $access = TRUE;
        break;
      }
    }
    if (!$access) {
      unset($form['advanced']['type']['#options'][$type]);
      unset($form['advanced']['type'][$type]);
    }
  }
  return $form;
}

/**
 * Return an array of content types to be excluded for role(s) this user has.
 */
function _search_restrict_excluded_content_types() {
  global $user;
  $excluded_content_types = array();
  $content_type_restrictions = variable_get('search_restrict_content_type', array());
  foreach ($content_type_restrictions as $type => $roles) {
    $roles = array_filter($roles);
    if (empty($roles)) {
      continue;
    }
    elseif (array_key_exists('-1', $roles) || !count(array_intersect_key($roles, $user->roles))) {
      $excluded_content_types[] = $type;
    }
  }
  return $excluded_content_types;
}

Functions

Namesort descending Description
search_restrict_content_type_form Alter content type forms to include search restrict options.
search_restrict_content_type_form_submit use custom submit function to avoid a query at time of search to get the list of content types
search_restrict_form_alter Implements hook_form_alter().
search_restrict_form_node_type_form_alter Implements hook_form_FORM_alter().
search_restrict_permission Implements hook_permission().
search_restrict_query_node_access_alter Implements hook_query_node_access_alter().
_search_restrict_advanced_form Remove restricted content types from the advanced search form. We use after_build due to the method the node module uses to add the advanced search options.
_search_restrict_excluded_content_types Return an array of content types to be excluded for role(s) this user has.