View source
<?php
define('BLOCK_TITLELINK_VARIABLE_PREFIX', 'block_titlelink_');
function block_titlelink_help($path, $arg) {
switch ($path) {
case 'admin/help#block_titlelink':
$output = '<p>' . t('Blocks titles are by plain text by default. This module aims to allow users with adequate permissions to add links to block titles.') . '</p>';
$output .= '<p>' . t('The configuration settings for Block Title Link are available in each of the blocks within the Block Title Link Settings fieldset. Each block may have its own link from the title with associated options. These may be set on each block, accessed from the <a href="@blocks">blocks administration page</a>.', array(
'@blocks' => url('admin/build/block'),
)) . '</p>';
$output .= '<p>' . t('The display link checkbox may be unticked to not render the block title as a link. The data from the Block Title Link module may be used elsewhere in the block template (ex: as an icon)') . '</p>';
return $output;
}
}
function block_titlelink_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'block_admin_configure' || $form_id == 'block_add_block_form') {
$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;
$form['block_titlelink'] = array(
'#type' => 'fieldset',
'#title' => t('Block Title Link Settings'),
'#collapsible' => TRUE,
'#weight' => 0,
'#tree' => TRUE,
);
$form['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 the <a href="@token-module" target="_blank">token module</a> is enabled.', array(
'@token-module' => url("http://drupal.org/project/token"),
)),
'#maxlength' => '255',
);
$form['block_titlelink']['title_link_title'] = array(
'#type' => 'textfield',
'#title' => t('Title Attribute'),
'#description' => t('value for the <a> title attribute.'),
'#default_value' => $title,
);
$form['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['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,
);
$value = function_exists('token_replace') ? theme('token_tree', array(
'user',
), TRUE, TRUE) : t('Tokens are supported if the <a href="@token-module">token module</a> is enabled.', array(
'@token-module' => url("http://drupal.org/project/token"),
));
$form['block_titlelink']['token_help'] = array(
'#type' => 'item',
'#value' => $value,
);
if (!isset($form['block_settings']['#weight'])) {
$form['block_settings']['#weight'] = -1;
}
$form['#validate'][] = 'block_titlelink_form_validate';
$form['#submit'][] = 'block_titlelink_form_submit';
}
}
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['block_titlelink']['title_link'], t('The title path appears to contain an invalid URL.'));
}
}
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);
}
}
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;
if (function_exists('token_replace')) {
$vars['block']->title_link = token_replace($vars['block']->title_link, 'user', $user);
$vars['block']->title_link_title = token_replace($vars['block']->title_link_title, 'user', $user);
}
if (module_exists('php')) {
$vars['block']->title_link = drupal_eval($vars['block']->title_link);
}
$display = isset($data['display']) ? $data['display'] : TRUE;
if (!empty($vars['block']->title_link) && $display) {
$options = array(
'attributes' => array(
'class' => 'block-title-link',
),
'html' => TRUE,
);
if (!empty($vars['block']->title_link_title)) {
$options['attributes']['title'] = $vars['block']->title_link_title;
}
if (!empty($vars['block']->title_link_target)) {
$options['attributes']['target'] = $vars['block']->title_link_target;
}
$vars['block']->subject = l(t($vars['block']->subject), $vars['block']->title_link, $options);
}
}
}
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);
if (is_string($result)) {
return array(
'url' => $result,
'display' => TRUE,
);
}
elseif (is_array($result)) {
return $result;
}
else {
return FALSE;
}
}
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 _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);
}
function _block_titlelink_validate_url($url) {
$text = $url;
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(
"æ",
"Æ",
"ø",
"Ø",
"å",
"Å",
"ä",
"Ä",
"ö",
"Ö",
"ü",
"Ü",
"Ñ",
"ñ",
)), ENT_QUOTES, 'UTF-8');
$LINK_ICHARS = $LINK_ICHARS_DOMAIN . (string) html_entity_decode(implode("", array(
"ß",
)), 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}))';
$external_pattern = '/^' . $protocol . '?' . $authentication . '?(' . $domain . '|' . $ipv4 . '|' . $ipv6 . ' |localhost)' . $port . '?';
$internal_pattern = "/^([a-z0-9" . $LINK_ICHARS . "_\\-+\\[\\]]+)";
$internal_pattern_file = "/^([a-z0-9" . $LINK_ICHARS . "_\\-+\\[\\]\\.]+)\$/i";
$directories = "(\\/[a-z0-9" . $LINK_ICHARS . "_\\-\\.~+%=&,\$'!():;*@\\[\\]]*)*";
$query = "(\\/?\\?([?a-z0-9" . $LINK_ICHARS . "+_|\\-\\.\\/\\\\%=&,\$'():;*@\\[\\]{} ]*))";
$anchor = "(#[a-z0-9" . $LINK_ICHARS . "_\\-\\.~+%=&,\$'():;*@\\[\\]\\/\\?]*)";
$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;
}