You are here

block_term.module in Block Visibility by Term 7

Controls block visibility by term.

File

block_term.module
View source
<?php

/**
 * @file
 * Controls block visibility by term.
 */

/**
 * Implements hook_form_FORMID_alter().
 *
 * Adds term specific visibility options to add block form.
 *
 * @see block_add_block_form()
 */
function block_term_form_block_add_block_form_alter(&$form, &$form_state) {
  block_term_form_block_admin_configure_alter($form, $form_state);
}

/**
 * Implements hook_form_FORMID_alter().
 *
 * Adds term specific visibility options to block configuration form.
 *
 * @see block_admin_configure()
 */
function block_term_form_block_admin_configure_alter(&$form, &$form_state) {
  drupal_add_js(drupal_get_path('module', 'block_term') . '/block_term.js');
  $block_term_restrict_vocab = variable_get('block_term_restrict_vocab', '');
  if (!empty($block_term_restrict_vocab) && is_numeric($block_term_restrict_vocab)) {
    $all_terms = taxonomy_get_tree($block_term_restrict_vocab);
    $selected_vocab = taxonomy_vocabulary_load($block_term_restrict_vocab);
    $vocabs = array(
      $selected_vocab->machine_name => $selected_vocab,
    );
  }
  else {
    $all_terms = entity_load('taxonomy_term');
    $vocabs = taxonomy_vocabulary_get_names();
  }
  foreach ($all_terms as $key => $term) {
    $term_name_prefix = '';
    if (isset($term->depth)) {
      for ($count = 0; $count < $term->depth; $count++) {
        $term_name_prefix .= '-';
      }
    }
    $vocabulary_machine_name = !empty($selected_vocab->machine_name) ? $selected_vocab->machine_name : $term->vocabulary_machine_name;
    $options[$vocabulary_machine_name][$term->tid] = $term_name_prefix . ' ' . $term->name;
  }
  $default_tid_options = db_query("SELECT tid FROM {block_term} WHERE module = :module AND delta = :delta", array(
    ':module' => $form['module']['#value'],
    ':delta' => $form['delta']['#value'],
  ))
    ->fetchCol();
  $form['visibility']['terms'] = array(
    '#type' => 'fieldset',
    '#title' => t('Terms'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'visibility',
    '#weight' => 6,
    '#description' => t('Show this block only on pages that display content with any of the given term(s). If you select no terms, there will be no term-specific limitation.'),
    '#tree' => TRUE,
  );
  if (isset($options)) {
    foreach ($options as $vocab => $terms) {
      $form['visibility']['terms'][$vocab]['tids'] = array(
        '#title' => $vocabs[$vocab]->name,
        '#type' => 'checkboxes',
        '#default_value' => $default_tid_options,
        '#options' => $terms,
      );
    }
  }
  $form['#submit'][] = 'block_term_form_block_admin_configure_submit';
}

/**
 * Form submit handler for block configuration form.
 *
 * @see block_term_form_block_admin_configure_alter()
 */
function block_term_form_block_admin_configure_submit($form, &$form_state) {
  db_delete('block_term')
    ->condition('module', $form_state['values']['module'])
    ->condition('delta', $form_state['values']['delta'])
    ->execute();
  $query = db_insert('block_term')
    ->fields(array(
    'tid',
    'module',
    'delta',
  ));

  // TODO: isn't there a cleaner way than this double foreach?
  foreach ($form_state['values']['terms'] as $vocab) {
    foreach (array_filter($vocab['tids']) as $tid) {
      $query
        ->values(array(
        'tid' => $tid,
        'module' => $form_state['values']['module'],
        'delta' => $form_state['values']['delta'],
      ));
    }
  }
  $query
    ->execute();
}

/**
 * Implements hook_block_list_alter().
 *
 * Check the term specific visibilty settings.
 * Remove the block if the visibility conditions are not met.
 */
function block_term_block_list_alter(&$blocks) {
  global $theme_key;

  // Build an array of terms for each block.
  $block_tids = array();
  $result = db_query('SELECT module, delta, tid FROM {block_term}');
  foreach ($result as $record) {
    $block_tids[$record->module][$record->delta][$record->tid] = TRUE;
  }
  $node = menu_get_object();
  if (!empty($node)) {
    $node_tids = array();

    // Get taxonomy_term_reference field names.
    $taxonomy_fields = db_query("SELECT field_name FROM {field_config} WHERE type = 'taxonomy_term_reference'");
    foreach ($taxonomy_fields as $field) {
      $terms = field_get_items('node', $node, $field->field_name);
      if (is_array($terms)) {
        foreach ($terms as $term) {
          $node_tids[$term['tid']] = TRUE;
        }
      }
    }
  }
  foreach ($blocks as $key => $block) {
    if (!isset($block->theme) || !isset($block->status) || $block->theme != $theme_key || $block->status != 1) {

      // This block was added by a contrib module, leave it in the list.
      continue;
    }

    // If a block has no terms associated, it is displayed for every term.
    // For blocks with terms associated, if the term does not match
    // the settings from this block, remove it from the block list.
    if (isset($block_tids[$block->module][$block->delta])) {
      if (!empty($node)) {

        // This is a node or node edit page.
        if (!array_intersect_key($block_tids[$block->module][$block->delta], $node_tids)) {

          // This block should not be displayed for this term.
          unset($blocks[$key]);
          continue;
        }
      }
      else {

        // This is not a node page, remove the block.
        unset($blocks[$key]);
        continue;
      }
    }
  }
}

/**
 * Implements hook_menu().
 */
function block_term_menu() {
  $items = array();
  $items['admin/config/system/block_term'] = array(
    'title' => 'Block Visiblity By Terms',
    'description' => 'Adjust default options for this module',
    'position' => 'right',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'block_term_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/**
 * Hook menu page argument callback.
 */
function block_term_settings($form_state) {
  $vocabs = taxonomy_vocabulary_get_names();
  $options = array();
  foreach ($vocabs as $item) {
    $options[$item->vid] = $item->name;
  }
  $form['block_term_restrict_vocab'] = array(
    '#type' => 'select',
    '#title' => t('Restrict terms on block settings to one vocabulary'),
    '#options' => $options,
    '#default_value' => variable_get('block_term_restrict_vocab', ''),
    '#empty_option' => t('- Select a vocabulary -'),
  );
  return system_settings_form($form);
}

Functions

Namesort descending Description
block_term_block_list_alter Implements hook_block_list_alter().
block_term_form_block_add_block_form_alter Implements hook_form_FORMID_alter().
block_term_form_block_admin_configure_alter Implements hook_form_FORMID_alter().
block_term_form_block_admin_configure_submit Form submit handler for block configuration form.
block_term_menu Implements hook_menu().
block_term_settings Hook menu page argument callback.