View source
<?php
define('FOLLOW_NAME', 0);
define('FOLLOW_ME', 1);
define('FOLLOW_US', 2);
function follow_help($path, $arg) {
switch ($path) {
case 'admin/build/follow':
case 'user/%/follow':
return t('Please copy and paste the url for your public profile or page for each service you would like to display in the block. Links need to match the domain of the service in question. If you want to hide the text of the links, enter "<none>" in the customized name.');
case 'admin/settings/follow':
return t('Here you can set what the default titles are for the "follow" blocks. If you would like a custom title, edit the individual blocks <a href="!href">here</a>.', array(
'!href' => url('admin/build/block'),
));
}
}
function follow_init() {
$style = variable_get('follow_icon_style', 'small');
$path = drupal_get_path('module', 'follow') . '/icons/';
drupal_add_css($path . $style . '.css');
}
function follow_menu() {
$items = array();
$items['admin/build/follow'] = array(
'title' => 'Follow',
'description' => 'Configure the site-wide web service follow links.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'follow_links_form',
),
'access arguments' => array(
'edit site follow links',
),
);
$items['user/%/follow'] = array(
'title' => 'Follow',
'description' => 'Update the associated web service follow links.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'follow_links_form',
1,
),
'access callback' => 'follow_links_user_access',
'access arguments' => array(
1,
),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
function follow_links_user_access($uid) {
return ($GLOBALS['user']->uid == $uid && user_access('edit own follow links') || user_access('edit any user follow links')) && $uid > 0;
}
function follow_perm() {
return array(
'edit own follow links',
'edit site follow links',
'edit any user follow links',
'administer follow',
'change follow link titles',
);
}
function follow_theme() {
$items = array();
$items['follow_links_form'] = array(
'arguments' => array(
'form' => array(),
),
);
$items['follow_links'] = array(
'arguments' => array(
'variables' => array(),
),
);
$items['follow_link'] = array(
'arguments' => array(
'variables' => array(),
),
);
return $items;
}
function follow_preprocess_page(&$variables) {
if ($links = follow_links_load()) {
$args = array(
'links' => $links,
'networks' => follow_networks_load(),
);
$variables['follow_site'] = theme('follow_links', $args);
}
}
function follow_block($op = 'list', $delta = 'site', $edit = array()) {
switch ($op) {
case 'list':
return follow_block_info();
default:
$fnc = 'follow_block_' . $op;
if (function_exists($fnc)) {
return $fnc($delta, $edit);
}
}
}
function follow_block_info() {
$blocks['site'] = array(
'info' => t('Follow Site'),
'cache' => BLOCK_CACHE_PER_ROLE,
);
$blocks['user'] = array(
'info' => t('Follow User'),
'cache' => BLOCK_CACHE_PER_USER,
);
return $blocks;
}
function follow_block_configure($delta = '') {
switch ($delta) {
case 'site':
$form['follow_title'] = array(
'#type' => 'radios',
'#title' => t('Default block title'),
'#default_value' => variable_get('follow_site_block_title', FOLLOW_NAME),
'#options' => array(
FOLLOW_NAME => t('Follow @name on', array(
'@name' => variable_get('site_name', 'Drupal'),
)),
FOLLOW_ME => t('Follow me on'),
FOLLOW_US => t('Follow us on'),
),
);
$form['follow_user'] = array(
'#type' => 'checkbox',
'#title' => t('User pages'),
'#description' => t('Should this block display on user profile pages?'),
'#default_value' => variable_get('follow_site_block_user', TRUE),
);
return $form;
case 'user':
$form['follow_title'] = array(
'#type' => 'radios',
'#title' => t('Default block title'),
'#default_value' => variable_get('follow_user_block_title', FOLLOW_NAME),
'#options' => array(
FOLLOW_NAME => t('Follow [username] on'),
FOLLOW_ME => t('Follow me on'),
),
);
return $form;
}
}
function follow_block_save($delta = '', $edit = array()) {
variable_set('follow_' . $delta . '_block_title', $edit['follow_title']);
if ($delta == 'site') {
variable_set('follow_site_block_user', $edit['follow_user']);
}
}
function follow_block_view($delta = '') {
switch ($delta) {
case 'site':
if (($content = _follow_block_content()) && (variable_get('follow_site_block_user', TRUE) || !(arg(0) == 'user' && is_numeric(arg(1))))) {
return array(
'subject' => _follow_block_subject(),
'content' => $content,
);
}
break;
case 'user':
$uid = arg(1);
if (arg(0) == 'user' && is_numeric($uid) && ($content = _follow_block_content($uid))) {
return array(
'subject' => _follow_block_subject($uid),
'content' => $content,
);
}
break;
}
}
function _follow_block_subject($uid = 0) {
return follow_link_title($uid) . ':';
}
function follow_link_title($uid = 0) {
if ($uid) {
$setting = variable_get('follow_user_block_title', FOLLOW_NAME);
if ($setting == FOLLOW_NAME) {
$account = user_load($uid);
return t('Follow !name on', array(
'!name' => theme('username', $account),
));
}
return t('Follow me on');
}
switch (variable_get('follow_site_block_title', FOLLOW_NAME)) {
case FOLLOW_NAME:
return t('Follow @name on', array(
'@name' => variable_get('site_name', 'Drupal'),
));
case FOLLOW_ME:
return t('Follow me on');
case FOLLOW_US:
return t('Follow us on');
}
}
function follow_link_tooltip($title, $variables) {
$link = $variables['link'];
return strip_tags(follow_link_title($link->uid) . ' ' . $title);
}
function follow_link_tooltip_rss($title, $variables) {
return t('Subscribe to feed: @title', array(
'@title' => $title,
));
}
function follow_link_tooltip_newsletter($title, $variables) {
$string = $title == t('Newsletter') ? 'Subscribe to @title' : 'Subscribe to newsletter: @title';
return t($string, array(
'@title' => $title,
));
}
function _follow_block_content($uid = 0) {
$output = '';
if ($links = follow_links_load($uid)) {
$output = theme('follow_links', array(
'links' => $links,
'networks' => follow_networks_load($uid),
));
$output .= _follow_block_config_links($uid);
}
return $output;
}
function theme_follow_links($variables) {
$links = $variables['links'];
$networks = $variables['networks'];
$output = '<div class="follow-links clearfix">';
foreach ($links as $link) {
$output .= theme('follow_link', array(
'link' => $link,
'network' => $networks[$link->name],
));
}
$output .= '</div>';
return $output;
}
function theme_follow_link($variables) {
$link = $variables['link'];
$network = $variables['network'];
$title = !empty($link->title) ? $link->title : $network['title'];
$tooltip_callback = isset($network['tooltip callback']) && function_exists($network['tooltip callback']) ? $network['tooltip callback'] : 'follow_link_tooltip';
$tooltip = $tooltip_callback($title, $variables);
$classes = array();
$classes[] = 'follow-link';
$classes[] = "follow-link-{$link->name}";
$classes[] = $link->uid ? 'follow-link-user' : 'follow-link-site';
$attributes = array(
'class' => implode(' ', $classes),
'title' => $tooltip,
);
if ($title == '<none>') {
$title = '';
}
$link->options['attributes'] = $attributes;
return l($title, $link->path, $link->options) . "\n";
}
function _follow_block_config_links($uid) {
$links = array();
if ($uid == 0 && user_access('edit site follow links')) {
$links['follow_edit'] = array(
'title' => t('Edit'),
'href' => 'admin/build/follow',
'query' => drupal_get_destination(),
);
}
elseif (follow_links_user_access($uid)) {
$links['follow_edit'] = array(
'title' => t('Edit'),
'href' => 'user/' . $uid . '/follow',
'query' => drupal_get_destination(),
);
}
if (user_access('administer blocks')) {
$links['follow_configure'] = array(
'title' => t('Configure'),
'href' => $uid ? 'admin/build/block/configure/follow/user' : 'admin/build/block/configure/follow/site',
'query' => drupal_get_destination(),
);
}
return theme('links', $links, array(
'class' => 'links inline',
));
}
function follow_links_form(&$form_state, $uid = 0) {
$form = array();
$form['uid'] = array(
'#type' => 'hidden',
'#value' => $uid,
);
$form['follow_links']['#tree'] = TRUE;
$form['follow_icon_style'] = array(
'#type' => 'select',
'#title' => t('Icon Style'),
'#options' => array(
'small' => t('Small'),
'large' => t('Large'),
),
'#default_value' => variable_get('follow_icon_style', 'small'),
'#access' => $uid < 1,
);
$links = follow_links_load($uid);
$networks = follow_networks_load($uid, TRUE);
if (is_array($links)) {
foreach ($links as $name => $link) {
$title = $networks[$name]['title'];
$form['follow_links'][$name] = _follow_links_form_link($link, $title, $uid);
unset($networks[$name]);
}
}
foreach ($networks as $name => $info) {
$link = new stdClass();
$link->name = $name;
$form['follow_links'][$name] = _follow_links_form_link($link, $info['title'], $uid);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
function _follow_links_form_link($link, $title, $uid) {
$elements = array();
$elements['name'] = array(
'#type' => 'markup',
'#value' => $title,
);
if (isset($link->lid)) {
$elements['lid'] = array(
'#type' => 'hidden',
'#value' => $link->lid,
);
$elements['weight'] = array(
'#type' => 'weight',
'#default_value' => $link->weight,
);
}
$elements['url'] = array(
'#type' => 'textfield',
'#follow_network' => $link->name,
'#follow_uid' => $uid,
'#default_value' => isset($link->url) ? $link->url : '',
'#element_validate' => array(
'follow_url_validate',
),
'#maxlength' => 255,
);
$elements['title'] = array(
'#type' => 'textfield',
'#default_value' => isset($link->title) ? $link->title : '',
'#size' => 15,
'#access' => user_access('change follow link titles') && !empty($link->url),
);
return $elements;
}
function follow_build_query(array $query, $parent = '') {
$params = array();
foreach ($query as $key => $value) {
$key = $parent ? $parent . '[' . $key . ']' : $key;
if (is_array($value)) {
$params[] = follow_build_query($value, $key);
}
elseif (!isset($value)) {
$params[] = $key;
}
else {
$params[] = $key . '=' . $value;
}
}
return implode('&', $params);
}
function follow_build_url($path, $options) {
$url = $path;
if (!empty($options['query'])) {
$url .= (strpos($path, '?') !== FALSE ? '&' : '?') . follow_build_query($options['query']);
}
if (!empty($options['fragment'])) {
$url .= '#' . $options['fragment'];
}
return $url;
}
function follow_parse_url($url) {
$parsed_url = parse_url($url);
$defaults = array(
'scheme' => '',
'host' => '',
'port' => '',
'path' => '/',
'query' => '',
'fragment' => '',
);
$parsed_url += $defaults;
$options = array(
'query' => array(),
'fragment' => $parsed_url['fragment'],
);
parse_str($parsed_url['query'], $options['query']);
if ($parsed_url['scheme']) {
$parsed_url['scheme'] .= '://';
}
$path = $parsed_url['scheme'] . $parsed_url['host'] . $parsed_url['path'];
return array(
'path' => $path,
'options' => $options,
);
}
function follow_url_validate($form) {
$url = trim($form['#value']);
$networks = follow_networks_load($form['#follow_uid']);
$info = $networks[$form['#follow_network']];
$regex_callback = isset($info['regex callback']) && function_exists($info['regex callback']) ? $info['regex callback'] : 'follow_network_regex';
$regex = $regex_callback($info);
$parsed = follow_parse_url($url);
if ($url && !preg_match($regex, $parsed['path'])) {
if (!empty($info['domain'])) {
$message = t('The specified url is invalid for the domain %domain. Make sure you use http://.', array(
'%domain' => $info['domain'],
));
}
else {
$message = t('The specified path is invalid.');
}
form_error($form, $message);
}
}
function follow_network_regex($network_info) {
return '@^https?://([a-z0-9\\-_.]+\\.|)' . str_replace('.', '\\.', $network_info['domain']) . '/@i';
}
function follow_network_regex_internal() {
return '@^[^:]+$@';
}
function follow_network_regex_external() {
return '
/^(https?|ftp):\\/\\/(?# protocol
)(([a-z0-9$_\\.\\+!\\*\'\\(\\),;\\?&=-]|%[0-9a-f]{2})+(?# username
)(:([a-z0-9$_\\.\\+!\\*\'\\(\\),;\\?&=-]|%[0-9a-f]{2})+)?(?# password
)@)?(?# auth requires @
)((([a-z0-9][a-z0-9-]*[a-z0-9]\\.)*(?# domain segments AND
)[a-z]{2}[a-z0-9-]*[a-z0-9](?# top level domain OR
)|(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5]\\.){3}(?#
)(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])(?# IP address
))(:\\d+)?(?# port
))(((\\/+([a-z0-9$_\\.\\+!\\*\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)*(?# path
)(\\?([a-z0-9$_\\.\\+!\\*\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)(?# query string
)?)?)?(?# path and query string optional
)(#([a-z0-9$_\\.\\+!\\*\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)?(?# fragment
)$/i';
}
function follow_links_form_submit($form, &$form_state) {
$values = $form_state['values'];
$links = $values['follow_links'];
foreach ($links as $name => $link) {
$link = (object) $link;
$link->url = trim($link->url);
if (empty($link->url)) {
if (isset($link->lid)) {
follow_link_delete($link->lid);
}
continue;
}
else {
$link->uid = $values['uid'];
$link->name = $name;
follow_link_save($link);
}
}
$icon_style = $values['follow_icon_style'];
if (in_array($icon_style, array(
'small',
'large',
))) {
variable_set('follow_icon_style', $icon_style);
}
}
function theme_follow_links_form($form) {
$rows = array();
$disabled_rows = array();
foreach (element_children($form['follow_links']) as $key) {
$row = array();
if (isset($form['follow_links'][$key]['weight'])) {
$row[] = drupal_render($form['follow_links'][$key]['lid']) . drupal_render($form['follow_links'][$key]['name']);
$row[] = drupal_render($form['follow_links'][$key]['url']);
if (user_access('change follow link titles')) {
$row[] = drupal_render($form['follow_links'][$key]['title']);
}
$form['follow_links'][$key]['weight']['#attributes']['class'] = 'follow-links-weight';
$row[] = drupal_render($form['follow_links'][$key]['weight']);
$rows[] = array(
'data' => $row,
'class' => 'draggable',
);
}
else {
$disabled_rows[] = array(
drupal_render($form['follow_links'][$key]['name']),
drupal_render($form['follow_links'][$key]['url']),
);
}
}
$header = array(
t('Name'),
t('URL'),
);
if (user_access('change follow link titles')) {
$header[] = t('Customized Name');
}
$header[] = t('Weight');
$disabled_header = array(
t('Name'),
t('URL'),
);
$output = '';
if (count($rows)) {
$output .= theme('table', $header, $rows, array(
'id' => 'follow-links-weighted-form',
));
}
if (count($disabled_rows)) {
$output .= theme('table', $disabled_header, $disabled_rows);
}
$output .= drupal_render($form);
drupal_add_tabledrag('follow-links-weighted-form', 'order', 'self', 'follow-links-weight');
return $output;
}
function follow_settings_form() {
$form = array();
return system_settings_form($form);
}
function follow_links_load($uid = 0) {
$links = array();
$sql = "SELECT * FROM {follow_links} WHERE uid = %d ORDER BY weight ASC";
$result = db_query($sql, $uid);
while ($link = db_fetch_object($result)) {
$link->options = unserialize($link->options);
$link->url = follow_build_url($link->path, $link->options);
$links[$link->name] = $link;
}
return $links;
}
function follow_link_save($link) {
$parsed = follow_parse_url($link->url);
$link->path = $parsed['path'];
$link->options = $parsed['options'];
if (isset($link->lid)) {
drupal_write_record('follow_links', $link, 'lid');
}
else {
drupal_write_record('follow_links', $link);
}
return $link;
}
function follow_link_delete($lid) {
$sql = 'DELETE FROM {follow_links} WHERE lid = %d';
db_query($sql, $lid);
}
function follow_networks_load($uid = 0, $reset = FALSE) {
static $networks = array();
if ($reset) {
$networks = array();
}
if (empty($networks[$uid])) {
$networks[$uid] = follow_default_networks($uid);
drupal_alter('follow_networks', $networks, $uid);
}
return $networks[$uid];
}
function follow_default_networks($uid) {
$networks = array(
'facebook' => array(
'title' => t('Facebook'),
'domain' => 'facebook.com',
),
'googleplus' => array(
'title' => t('Google+'),
'domain' => 'plus.google.com',
),
'virb' => array(
'title' => t('Virb'),
'domain' => 'virb.com',
),
'myspace' => array(
'title' => t('MySpace'),
'domain' => 'myspace.com',
),
'twitter' => array(
'title' => t('Twitter'),
'domain' => 'twitter.com',
),
'picasa' => array(
'title' => t('Picasa'),
'domain' => 'picasaweb.google.com',
),
'flickr' => array(
'title' => t('Flickr'),
'domain' => 'flickr.com',
),
'youtube' => array(
'title' => t('YouTube'),
'domain' => 'youtube.com',
),
'vimeo' => array(
'title' => t('Vimeo'),
'domain' => 'vimeo.com',
),
'bliptv' => array(
'title' => t('blip.tv'),
'domain' => 'blip.tv',
),
'lastfm' => array(
'title' => t('last.fm'),
'domain' => 'last.fm',
),
'linkedin' => array(
'title' => t('LinkedIn'),
'domain' => 'linkedin.com',
),
'delicious' => array(
'title' => t('Delicious'),
'domain' => 'delicious.com',
),
'tumblr' => array(
'title' => t('Tumblr'),
'domain' => 'tumblr.com',
),
'viadeo' => array(
'title' => t('Viadeo'),
'domain' => 'viadeo.com',
),
'xing' => array(
'title' => t('Xing'),
'domain' => 'xing.com',
),
'spiceworks' => array(
'title' => t('Spiceworks'),
'domain' => 'spiceworks.com',
),
);
if ($uid == 0) {
$networks['this-site'] = array(
'title' => t('This site (RSS)'),
'domain' => '',
'regex callback' => 'follow_network_regex_internal',
'tooltip callback' => 'follow_link_tooltip_rss',
);
$networks['newsletter'] = array(
'title' => t('Newsletter'),
'domain' => '',
'regex callback' => 'follow_network_regex_external',
'tooltip callback' => 'follow_link_tooltip_newsletter',
);
}
return $networks;
}