You are here

block_titlelink.module in Block Title Link 7

module for adding a link to a block title

File

block_titlelink.module
View source
<?php

// $Id$

/**
 * @file module for adding a link to a block title
*/

// Variable Table Prefex
define('BLOCK_TITLELINK_VARIABLE_PREFIX', 'block_titlelink_');

/**
 * Implementation of hook_permission
*/
function block_titlelink_permission() {
  return array(
    'set block title links' => array(
      'title' => t('Set block title links'),
      'description' => t('Set optional links for block titles'),
    ),
  );
}

/**
 * Implementation of hook_form_alter
*/
function block_titlelink_form_alter(&$form, &$form_state, $form_id) {
  if (($form_id == 'block_admin_configure' || $form_id == 'block_add_block_form') && user_access('set block title links')) {
    $block = new stdClass();
    $block->module = $form['module']['#value'];
    $block->delta = $form['delta']['#value'];
    $titlelink_data = _block_titlelink_get_data($block);
    $url = isset($titlelink_data['url']) ? $titlelink_data['url'] : NULL;
    $title = isset($titlelink_data['title']) ? $titlelink_data['title'] : NULL;
    $targets = drupal_map_assoc(array(
      '_blank',
      '_self',
      '_parent',
      '_top',
    ));
    $target = isset($titlelink_data['target']) ? $titlelink_data['target'] : NULL;
    $display_link = isset($titlelink_data['display']) ? $titlelink_data['display'] : TRUE;

    //Define Titlelink form elements
    $form['settings']['block_titlelink'] = array(
      '#type' => 'fieldset',
      '#title' => t('Block Title Link Settings'),
      '#collapsible' => TRUE,
      '#collapsed' => !empty($url) ? FALSE : TRUE,
      '#weight' => 0,
      '#tree' => TRUE,
    );
    $form['settings']['block_titlelink']['title_link'] = array(
      '#type' => 'textfield',
      '#title' => t('Title Path'),
      '#default_value' => $url,
      '#description' => t('URL path of Block Title. Tokens are supported. If this field is left blank, the block title link information will be removed and set back to defaults for this block.'),
      '#maxlength' => '255',
    );
    $form['settings']['block_titlelink']['title_link_title'] = array(
      '#type' => 'textfield',
      '#title' => t('title attribute'),
      '#description' => t('value for the &lt;a&gt; title attribute.'),
      '#default_value' => $title,
    );
    $form['settings']['block_titlelink']['title_link_target'] = array(
      '#type' => 'select',
      '#title' => t('link target'),
      '#options' => $targets,
      '#empty_value' => '',
      '#description' => t('Add a target to open the link in a new tab/window'),
      '#default_value' => $target,
    );
    $form['settings']['block_titlelink']['display_link'] = array(
      '#type' => 'checkbox',
      '#title' => t('Display Link'),
      '#description' => t('Select this option if title should render as a link. If deselected, the title path value is stored within the block object as $block->title_link but is not rendered. This is useful if you wish to use the link elsewhere in the block template (ex: as an icon).'),
      '#default_value' => $display_link,
    );

    //Provide Token Help
    $form['settings']['block_titlelink']['token_help'] = array(
      '#theme' => 'token_tree',
      '#token_types' => array(
        'user',
      ),
    );

    //Assign weight to block title so it appears above link
    if (!isset($form['block_settings']['#weight'])) {
      $form['block_settings']['#weight'] = -1;
    }
    $form['#validate'][] = 'block_titlelink_form_validate';
    $form['#submit'][] = 'block_titlelink_form_submit';
  }
}

/**
 * Implementation of hook_validate()
*/
function block_titlelink_form_validate(&$elements, &$form_state, $form_id = NULL) {
  $title_link = trim($form_state['values']['block_titlelink']['title_link']);
  $valid = _block_titlelink_validate_url($title_link);
  if (!empty($title_link) && !$valid) {
    form_error($elements['settings']['block_titlelink']['title_link'], t('The title path appears to contain an invalid URL.'));
  }
}

/**
 * Implementation of hook_submit()
*/
function block_titlelink_form_submit($form, &$form_state) {
  $block = new stdClass();
  $block->module = $form['module']['#value'];
  $block->delta = $form_state['values']['delta'];
  $url = trim($form_state['values']['block_titlelink']['title_link']);
  $data = array(
    'url' => $url,
    'display' => $form_state['values']['block_titlelink']['display_link'],
    'title' => $form_state['values']['block_titlelink']['title_link_title'],
    'target' => $form_state['values']['block_titlelink']['title_link_target'],
  );
  if (empty($url)) {
    _block_titlelink_delete_data($block);
  }
  else {
    _block_titlelink_save_data($block, $data);
  }
}

/**
 * Implements hook_preprocess_block().
 */
function block_titlelink_preprocess_block(&$vars) {
  global $user;
  $data = _block_titlelink_get_data($vars['block']);
  if ($data) {
    $vars['block']->title_link = isset($data['url']) ? trim($data['url']) : NULL;
    $vars['block']->title_link_title = isset($data['title']) ? check_plain($data['title']) : NULL;
    $vars['block']->title_link_target = isset($data['target']) ? $data['target'] : NULL;

    // Add Tokens
    if (function_exists('token_replace')) {
      $token_params = array(
        'user' => $user,
      );
      $vars['block']->title_link = token_replace($vars['block']->title_link, $token_params);
      $vars['block']->title_link_title = token_replace($vars['block']->title_link_title, $token_params);
    }

    // PHP Eval
    if (module_exists('php')) {
      $vars['block']->title_link = php_eval($vars['block']->title_link);
    }
    $display = isset($data['display']) ? $data['display'] : TRUE;
    if (!empty($vars['block']->title_link) && $display) {
      $attributes = array(
        'attributes' => array(
          'class' => array(
            'block-title-link',
          ),
        ),
        'html' => TRUE,
      );
      if (!empty($vars['block']->title_link_title)) {
        $attributes['attributes']['title'] = $vars['block']->title_link_title;
      }
      if (!empty($vars['block']->title_link_target)) {
        $attributes['attributes']['target'] = $vars['block']->title_link_target;
      }

      // Allow Drupal to parse the URL and provide us with a keyed array
      // that we can hand off to l()
      $parsed_url = drupal_parse_url($vars['block']->title_link);

      // Add in the query string if one exists.
      if (!empty($parsed_url['query'])) {
        $attributes['query'] = $parsed_url['query'];
      }

      // Build the fragment onto the end if it is present.
      if (!empty($parsed_url['fragment'])) {
        $attributes['fragment'] = $parsed_url['fragment'];
      }
      $vars['block']->subject = l(t($vars['block']->subject), $parsed_url['path'], $attributes);
    }
  }
}

/**
 * Function to return a title link of a block
 * @param object $block - Block to search by
 * @return string Title Link
*/
function _block_titlelink_get_link($block) {
  if (!isset($block->module) && !isset($block->delta)) {
    return FALSE;
  }
  $varname = BLOCK_TITLELINK_VARIABLE_PREFIX . $block->module . '_' . $block->delta;
  $data = variable_get($varname, NULL);
  if (!empty($data['url'])) {
    return $data['url'];
  }
  else {
    return FALSE;
  }
}

/**
 * Function to return the data associated with a block_titlelink
 * @param object $block - Block to search by
 * @return array containing display_link and title_link variable.
 *
*/
function _block_titlelink_get_data($block) {
  if (!isset($block->module) && !isset($block->delta)) {
    return FALSE;
  }
  $varname = BLOCK_TITLELINK_VARIABLE_PREFIX . $block->module . '_' . $block->delta;
  $result = variable_get($varname, NULL);

  //Older versions of this module stored variable as string, return as array
  if (is_string($result)) {
    return array(
      'url' => $result,
      'display' => TRUE,
    );
  }
  elseif (is_array($result)) {
    return $result;
  }
  else {
    return FALSE;
  }
}

/**
 * Function to save titlelink data
 * @param object - Block object
 * @param array - Array containing data
 * $data['url'] - String, link to save
 * $data['display'] - Boolean, display title as link
*/
function _block_titlelink_save_data($block, $data) {
  if (!isset($block->module) || !isset($block->delta)) {
    return FALSE;
  }
  $varname = BLOCK_TITLELINK_VARIABLE_PREFIX . $block->module . '_' . $block->delta;
  variable_set($varname, $data);
}

/**
 * Function to delete block data
 * @param object - Block object
*/
function _block_titlelink_delete_data($block) {
  if (!isset($block->module) && !isset($block->delta)) {
    return FALSE;
  }
  $varname = BLOCK_TITLELINK_VARIABLE_PREFIX . $block->module . '_' . $block->delta;
  variable_del($varname);
}

/**
 * Heisted the url validation from the link field module.
*/
function _block_titlelink_validate_url($url) {
  $text = $url;

  // These constants were heisted from the field_module.
  // Check if they exist
  if (!defined('LINK_EXTERNAL')) {
    define('LINK_EXTERNAL', 'external');
  }
  if (!defined('LINK_INTERNAL')) {
    define('LINK_INTERNAL', 'internal');
  }
  if (!defined('LINK_FRONT')) {
    define('LINK_FRONT', 'front');
  }
  if (!defined('LINK_EMAIL')) {
    define('LINK_EMAIL', 'email');
  }
  if (!defined('LINK_NEWS')) {
    define('LINK_NEWS', 'news');
  }
  if (!defined('LINK_DOMAINS')) {
    define('LINK_DOMAINS', 'aero|arpa|asia|biz|com|cat|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|mobi|local');
  }
  $LINK_ICHARS_DOMAIN = (string) html_entity_decode(implode("", array(
    "&#x00E6;",
    // æ
    "&#x00C6;",
    // Æ
    "&#x00F8;",
    // ø
    "&#x00D8;",
    // Ø
    "&#x00E5;",
    // å
    "&#x00C5;",
    // Å
    "&#x00E4;",
    // ä
    "&#x00C4;",
    // Ä
    "&#x00F6;",
    // ö
    "&#x00D6;",
    // Ö
    "&#x00FC;",
    // ü
    "&#x00DC;",
    // Ü
    "&#x00D1;",
    // Ñ
    "&#x00F1;",
  )), ENT_QUOTES, 'UTF-8');
  $LINK_ICHARS = $LINK_ICHARS_DOMAIN . (string) html_entity_decode(implode("", array(
    "&#x00DF;",
  )), ENT_QUOTES, 'UTF-8');
  $allowed_protocols = variable_get('filter_allowed_protocols', array(
    'http',
    'https',
    'ftp',
    'news',
    'nntp',
    'telnet',
    'mailto',
    'irc',
    'ssh',
    'sftp',
    'webcal',
  ));
  $protocol = '((' . implode("|", $allowed_protocols) . '):\\/\\/)';
  $authentication = '(([a-z0-9%' . $LINK_ICHARS . ']+(:[a-z0-9%' . $LINK_ICHARS . '!]*)?)?@)';
  $domain = '(([a-z0-9' . $LINK_ICHARS_DOMAIN . ']([a-z0-9' . $LINK_ICHARS_DOMAIN . '\\-_\\[\\]])*)(\\.(([a-z0-9' . $LINK_ICHARS_DOMAIN . '\\-_\\[\\]])+\\.)*(' . LINK_DOMAINS . '|[a-z]{2}))?)';
  $ipv4 = '([0-9]{1,3}(\\.[0-9]{1,3}){3})';
  $ipv6 = '([0-9a-fA-F]{1,4}(\\:[0-9a-fA-F]{1,4}){7})';
  $port = '(:([0-9]{1,5}))';

  // Pattern specific to external links.
  $external_pattern = '/^' . $protocol . '?' . $authentication . '?(' . $domain . '|' . $ipv4 . '|' . $ipv6 . ' |localhost)' . $port . '?';

  // Pattern specific to internal links.
  $internal_pattern = "/^([a-z0-9" . $LINK_ICHARS . "_\\-+\\[\\]]+)";
  $internal_pattern_file = "/^([a-z0-9" . $LINK_ICHARS . "_\\-+\\[\\]\\.]+)\$/i";
  $directories = "(\\/[a-z0-9" . $LINK_ICHARS . "_\\-\\.~+%=& ,\$'!():;*@\\[\\]]*)*";

  // Yes, four backslashes == a single backslash.
  $query = "(\\/?\\?([?a-z0-9" . $LINK_ICHARS . "+_|\\-\\.\\/\\\\%=&,\$'():;*@\\[\\]{} ]*))";
  $anchor = "(#[a-z0-9" . $LINK_ICHARS . "_\\-\\.~+%=& ,\$'():;*@\\[\\]\\/\\?]*)";

  // The rest of the path for a standard URL.
  $end = $directories . '?' . $query . '?' . $anchor . '?' . '$/i';
  $message_id = '[^@].*@' . $domain;
  $newsgroup_name = '([0-9a-z+-]*\\.)*[0-9a-z+-]*';
  $news_pattern = '/^news:(' . $newsgroup_name . '|' . $message_id . ')$/i';
  $user = '[a-zA-Z0-9' . $LINK_ICHARS . '_\\-\\.\\+\\^!#\\$%&*+\\/\\=\\?\\`\\|\\{\\}~\'\\[\\]]+';
  $email_pattern = '/^mailto:' . $user . '@' . '(' . $domain . '|' . $ipv4 . '|' . $ipv6 . '|localhost)' . $query . '?$/';
  if (strpos($text, '<front>') === 0) {
    return LINK_FRONT;
  }
  if (in_array('mailto', $allowed_protocols) && preg_match($email_pattern, $text)) {
    return LINK_EMAIL;
  }
  if (in_array('news', $allowed_protocols) && preg_match($news_pattern, $text)) {
    return LINK_NEWS;
  }
  if (preg_match($internal_pattern . $end, $text)) {
    return LINK_INTERNAL;
  }
  if (preg_match($external_pattern . $end, $text)) {
    return LINK_EXTERNAL;
  }
  if (preg_match($internal_pattern_file, $text)) {
    return LINK_INTERNAL;
  }
  return FALSE;
}

Functions

Namesort descending Description
block_titlelink_form_alter Implementation of hook_form_alter
block_titlelink_form_submit Implementation of hook_submit()
block_titlelink_form_validate Implementation of hook_validate()
block_titlelink_permission Implementation of hook_permission
block_titlelink_preprocess_block Implements hook_preprocess_block().
_block_titlelink_delete_data Function to delete block data
_block_titlelink_get_data Function to return the data associated with a block_titlelink
_block_titlelink_get_link Function to return a title link of a block
_block_titlelink_save_data Function to save titlelink data
_block_titlelink_validate_url Heisted the url validation from the link field module.

Constants