View source
<?php
define('FOLLOW_NAME', 0);
define('FOLLOW_ME', 1);
define('FOLLOW_US', 2);
function follow_help($path, $arg) {
switch ($path) {
case 'follow':
case 'user/%/follow':
case 'admin/config/services/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 title 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/config/services/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_permission() {
return array(
'edit own follow links' => array(
'title' => t('Edit own follow links'),
'description' => t(''),
),
'edit site follow links' => array(
'title' => t('Edit the site-wide follow links'),
'description' => t(''),
),
'edit any user follow links' => array(
'title' => t("Edit any user's follow links"),
'description' => t(''),
),
'administer follow' => array(
'title' => t('Administer follow'),
'description' => t(''),
),
'change follow link titles' => array(
'title' => t('Change link titles'),
'description' => t('Allows changing the text that appears in the follow links.'),
),
);
}
function follow_theme() {
$items = array();
$items['follow_links_form'] = array(
'render element' => 'form',
);
$items['follow_links'] = array(
'variables' => array(
'links' => array(),
'networks' => array(),
'alignment' => array(),
),
);
$items['follow_link'] = array(
'variables' => array(
'link' => NULL,
'title' => NULL,
),
);
return $items;
}
function follow_preprocess_page(&$variables) {
if ($links = follow_links_load()) {
$args = array(
'links' => $links,
'networks' => follow_networks_load(),
'alignment' => variable_get('follow_alignment', 'vertical'),
);
$variables['follow_site'] = theme('follow_links', $args);
}
}
function follow_block_info() {
$blocks['site'] = array(
'info' => t('Follow Site'),
'cache' => DRUPAL_CACHE_PER_ROLE,
);
$blocks['user'] = array(
'info' => t('Follow User'),
'cache' => DRUPAL_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', array(
'account' => $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_block_content($uid = 0) {
$output = '';
if ($links = follow_links_load($uid)) {
$output = theme('follow_links', array(
'links' => $links,
'networks' => follow_networks_load($uid),
'alignment' => variable_get('follow_alignment', 'vertical'),
));
}
return $output;
}
function theme_follow_links($variables) {
$links = $variables['links'];
$networks = $variables['networks'];
$wrapper = $variables['alignment'] == 'horizontal' ? 'span' : 'div';
$output = '<div class="follow-links clearfix">';
foreach ($links as $link) {
$title = !empty($link->title) ? $link->title : $networks[$link->name]['title'];
$output .= '<' . $wrapper . ' class="follow-link-wrapper follow-link-wrapper-' . $link->name . '">';
$output .= theme('follow_link', array(
'link' => $link,
'title' => $title,
));
$output .= '</' . $wrapper . '>';
}
$output .= '</div>';
return $output;
}
function theme_follow_link($variables) {
$link = $variables['link'];
$title = $variables['title'];
$classes = array();
$classes[] = 'follow-link';
$classes[] = "follow-link-{$link->name}";
$classes[] = $link->uid ? 'follow-link-user' : 'follow-link-site';
$attributes = array(
'class' => $classes,
'title' => follow_link_title($link->uid) . ' ' . $title,
);
if ($title == '<none>') {
$title = '';
}
$link->options['attributes'] = $attributes;
return l($title, $link->path, $link->options) . "\n";
}
function follow_contextual_links_view_alter(&$element, $items) {
$block = isset($element['#element']['#block']) ? $element['#element']['#block'] : NULL;
if (is_object($block) && $block->module == 'follow') {
$uid = arg(1);
if ($block->delta == 'site' && user_access('edit site follow links')) {
$element['#links']['follow-edit'] = array(
'title' => t('Edit Follow links'),
'href' => 'admin/config/services/follow',
'query' => drupal_get_destination(),
'attributes' => array(
'title' => t('Configure the site-wide web service follow links.'),
),
);
}
elseif ($block->delta == 'user' && follow_links_user_access($uid)) {
$element['#links']['follow-edit'] = array(
'title' => t('Edit Follow links'),
'href' => 'user/' . $uid . '/follow',
'query' => drupal_get_destination(),
'attributes' => array(
'title' => t('Update the associated web service follow links.'),
),
);
}
}
}
function follow_links_form($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'),
'wpzoom26' => t('WPZOOM 26x'),
'wpzoom38' => t('WPZOOM 38x'),
'paulrobertlloyd32' => t('Paul Robert Lloyd 32x32'),
),
'#description' => t('How the Follow icons should appear.'),
'#default_value' => variable_get('follow_icon_style', 'small'),
'#access' => $uid < 1,
);
$form['follow_alignment'] = array(
'#type' => 'select',
'#title' => t('Alignment'),
'#options' => array(
'vertical' => t('Vertical'),
'horizontal' => t('Horizontal'),
),
'#description' => t('Whether the icons are to appear horizontally beside each other, or one after another in a list.'),
'#default_value' => variable_get('follow_alignment', 'vertical'),
'#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(
'#markup' => $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 = follow_build_url_regex($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. Please enter a path on this site (e.g. rss.xml or taxonomy/term/1/feed).');
}
form_error($form, $message);
}
}
function follow_build_url_regex($network_info) {
if (!empty($network_info['domain'])) {
return '@^https?://([a-z0-9\\-_.]+\\.|)' . str_replace('.', '\\.', $network_info['domain']) . '/@i';
}
return '@^[^:]+$@';
}
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',
'wpzoom26',
'wpzoom38',
'paulrobertlloyd32',
))) {
variable_set('follow_icon_style', $icon_style);
}
$alignment = $values['follow_alignment'];
if (in_array($alignment, array(
'vertical',
'horizontal',
))) {
variable_set('follow_alignment', $alignment);
}
}
function theme_follow_links_form($variables) {
$form = $variables['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' => array(
'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', array(
'header' => $header,
'rows' => $rows,
'attributes' => array(
'id' => 'follow-links-weighted-form',
),
));
}
if (count($disabled_rows)) {
$output .= theme('table', array(
'header' => $disabled_header,
'rows' => $disabled_rows,
));
}
$output .= drupal_render_children($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 = :uid ORDER BY weight ASC";
$result = db_query($sql, array(
':uid' => $uid,
));
foreach ($result as $link) {
$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) {
db_delete('follow_links')
->condition('lid', $lid)
->execute();
}
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' => '',
);
$networks['newsletter'] = array(
'title' => t('Newsletter'),
'domain' => '',
);
}
return $networks;
}
function follow_admin_paths() {
$paths = array(
'user/*/follow' => TRUE,
);
return $paths;
}