You are here

ccl_blocks.module in Custom Contextual Links 7

Same filename and directory in other branches
  1. 8 ccl_blocks/ccl_blocks.module

Implments support for CCL on blocks.

File

ccl_blocks/ccl_blocks.module
View source
<?php

/**
 * @file
 * Implments support for CCL on blocks.
 */

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Add additional form elements to the main CCL add/edit form.
 */
function ccl_blocks_form_ccl_add_form_alter(&$form, &$form_state, $form_id) {

  // Check if we are in edit mode.
  if (isset($form_state['clid'])) {
    $clid = $form_state['clid'];
    $link = $form_state['link'];
  }
  else {
    $clid = 0;
  }

  // Add blocks as an option for links.
  $form['options_group']['ccl_type']['#options']['block'] = t('Block');

  // Follow the naming conventions outlined here
  // in order to avoid naming conflicts.
  $form['options_group']['block_global'] = array(
    '#type' => 'checkbox',
    '#title' => t('Add this link to all blocks'),
    '#default_value' => $clid && isset($link->options['block_global']) ? $link->options['block_global'] : -1,
    '#states' => array(
      'visible' => array(
        ':input[name="ccl_type"]' => array(
          'value' => 'block',
        ),
      ),
    ),
  );
  $options = _ccl_blocks_get_info();
  $form['options_group']['block_select'] = array(
    '#type' => 'select',
    '#multiple' => TRUE,
    '#size' => min(12, count($options)),
    '#title' => t('Blocks'),
    '#description' => t('Select the block(s) this link should be added to.'),
    '#options' => $options,
    '#default_value' => $clid && isset($link->options['block_select']) ? $link->options['block_select'] : -1,
    '#states' => array(
      'visible' => array(
        ':input[name="block_global"]' => array(
          'checked' => FALSE,
        ),
        ':input[name="ccl_type"]' => array(
          'value' => 'block',
        ),
      ),
    ),
  );

  // Add validation for blocks.
  $form['#validate'][] = "ccl_blocks_validation";
}

/**
 * Custom validation for the block options.
 */
function ccl_blocks_validation($form, &$form_state) {
  $values = $form_state['values'];

  // Check that the node id token is not used for blocks.
  if ($values['ccl_type'] == 'block' && strpos($values['ccl_link'], '[node:') !== FALSE) {
    form_set_error('ccl_link', t('Node tokens are not processed for links added to blocks.'));
  }
}

/**
 * Hook function to process the contextual links element.
 */
function ccl_blocks_ccl_add_link($element, $dest) {

  // Check if it is a block.
  if (isset($element['#element']['#block']->delta)) {
    $bid = $element['#element']['#block']->module . '|' . $element['#element']['#block']->delta;
    $block_cache = ccl_cache_get('ccl_blocks');

    // Global Blocks.
    foreach ($block_cache['global'] as $id => $link) {
      if ($processed_link = _ccl_prepare_link($link, $dest)) {
        $element['#links']['ccl-global-block-' . $id] = $processed_link;
      }
    }

    // Individual blocks.
    if (in_array($bid, array_keys($block_cache['ids']))) {
      foreach ($block_cache['ids'][$bid] as $id => $link) {
        if ($processed_link = _ccl_prepare_link($link, $dest)) {
          $element['#links']['ccl-block-' . $id] = $processed_link;
        }
      }
    }
  }
  return $element;
}

/**
 * Implements hook_ccl_cache_update().
 *
 * Hook function triggered by the chache update routine of the main module.
 */
function ccl_blocks_ccl_cache_update() {
  $blocks = db_query("SELECT * FROM {ccl} WHERE type = :type", array(
    ':type' => 'block',
  ));
  $block_cache = array(
    'global' => array(),
    'ids' => array(),
  );
  foreach ($blocks as $block) {
    $block->options = unserialize($block->options);
    $advanced = array();
    if (isset($block->options['advanced_css'])) {
      $advanced['class'] = $block->options['advanced_css'];
    }
    if (isset($block->options['advanced_query'])) {
      $advanced['query'] = $block->options['advanced_query'];
    }
    if (isset($block->options['advanced_anchor'])) {
      $advanced['anchor'] = $block->options['advanced_anchor'];
    }
    if (isset($block->options['advanced_target']) && $block->options['advanced_target'] != "default") {
      $advanced['target'] = $block->options['advanced_target'];
    }
    if (isset($block->options['advanced_destination'])) {
      $advanced['destination'] = $block->options['advanced_destination'];
    }
    if ($block->options['block_global']) {
      $block_cache['global'][] = array(
        'title' => $block->title,
        'href' => $block->link,
        'advanced' => $advanced,
      );
    }
    else {

      // Create an entry for each selected block.
      foreach ($block->options['block_select'] as $id) {
        $block_cache['ids'][$id][] = array(
          'title' => $block->title,
          'href' => $block->link,
          'advanced' => $advanced,
        );
      }
    }
  }
  cache_set('ccl_blocks', $block_cache);
}

/**
 * Helper function to retrieve all the information for all blocks in the system.
 */
function _ccl_blocks_get_info() {
  $block_info = cache_get('ccl_blocks_info');

  // If no data is found in the cache invoke all block hooks
  // and create the cache entry.
  if (empty($block_info)) {
    $block_info = array();
    foreach (module_implements('block_info') as $module) {
      $module_blocks = module_invoke($module, 'block_info');
      if (!empty($module_blocks)) {
        foreach ($module_blocks as $delta => $block) {
          $block = (object) $block;
          $block->module = $module;
          $block->delta = $delta;
          $block->bid = "{$block->module}|{$block->delta}";
          $block_info[$block->bid] = $block->info;
        }
      }
    }

    // Unset unsupported blocks.
    unset($block_info['system|main']);
    unset($block_info['system|help']);
    cache_set('ccl_blocks_info', $block_info);
  }
  if (isset($block_info->cid)) {
    return $block_info->data;
  }
  else {
    return $block_info;
  }
}

/**
 * Hook function to provide link option information for the link list page.
 */
function ccl_blocks_ccl_link_info($record) {
  if ($record->type == 'block') {
    $options_return = array(
      'desc' => '',
      'op' => l(t('Edit'), 'admin/config/user-interface/ccl/' . $record->clid . '/edit') . ' | ' . l(t('Delete'), 'admin/config/user-interface/ccl/' . $record->clid . '/delete'),
    );
    $options = unserialize($record->options);
    if ($options['block_global']) {
      $options_return['desc'] = t('Attached to all blocks.');
    }
    else {
      $blocks = _ccl_blocks_get_info();
      $options_return['desc'] = format_plural(count($options['block_select']), 'Attached to block: %block', 'Attached to blocks: %block', array(
        '%block' => implode(', ', array_intersect_key($blocks, $options['block_select'])),
      ));
    }
    return $options_return;
  }
  else {
    return "";
  }
}

Functions

Namesort descending Description
ccl_blocks_ccl_add_link Hook function to process the contextual links element.
ccl_blocks_ccl_cache_update Implements hook_ccl_cache_update().
ccl_blocks_ccl_link_info Hook function to provide link option information for the link list page.
ccl_blocks_form_ccl_add_form_alter Implements hook_form_FORM_ID_alter().
ccl_blocks_validation Custom validation for the block options.
_ccl_blocks_get_info Helper function to retrieve all the information for all blocks in the system.