You are here

follow.module in Follow 7

Same filename and directory in other branches
  1. 8.2 follow.module
  2. 5 follow.module
  3. 6 follow.module
  4. 7.2 follow.module

Allows users to add links to their social network profiles.

File

follow.module
View source
<?php

/**
 * @file
 *   Allows users to add links to their social network profiles.
 */
define('FOLLOW_NAME', 0);
define('FOLLOW_ME', 1);
define('FOLLOW_US', 2);

/**
 * Implementation of hook_help().
 */
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 "&lt;none&gt;" 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'),
      ));
  }
}

/**
 * Implementation of hook_init().
 */
function follow_init() {

  // Switch the Follow icon style.
  $style = variable_get('follow_icon_style', 'small');
  $path = drupal_get_path('module', 'follow') . '/icons/';
  drupal_add_css($path . $style . '.css');
}

/**
 * Implementation of hook_menu().
 */
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,
  );

  // No settings!

  /* $items['admin/settings/follow'] = array(
      'title' => 'Follow',
      'description' => 'Administer the follow module',
      'page callback' => 'drupal_get_form',
      'page arguments' => array('follow_settings_form'),
      'access arguments' => array('administer follow'),
    ); */
  return $items;
}

/**
 * Access callback for user follow links editing.
 */
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;
}

/**
 * Implementation of hook_permission().
 */
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.'),
    ),
  );
}

/**
 * Implementation of hook_theme().
 */
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;
}

/**
 * Implementation of hook_preprocess_page().
 */
function follow_preprocess_page(&$variables) {

  // Expose the site follow links as a variable to the page template.
  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);
  }
}

/**
 * Implementation of hook_block_info().
 */
function follow_block_info() {
  $blocks['site'] = array(
    'info' => t('Follow Site'),
    // We need to cache per role so the edit/configure links display only if user
    // has access.
    'cache' => DRUPAL_CACHE_PER_ROLE,
  );
  $blocks['user'] = array(
    'info' => t('Follow User'),
    // Here we need to cache per user so the edit link only shows for the associated
    // account.
    'cache' => DRUPAL_CACHE_PER_USER,
  );
  return $blocks;
}

/**
 * Implementation of hook_block_configure().
 */
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;
  }
}

/**
 * Implementation of hook_block_save().
 */
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']);
  }
}

/**
 * Implementation of hook_block_view().
 */
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;
  }
}

/**
 * Helper function to build the block title.
 *
 * @param $uid
 *   The uid of the user account.  Defaults to the site form, $uid = 0.
 */
function _follow_block_subject($uid = 0) {
  return follow_link_title($uid) . ':';
}

/**
 * Helper function to create a link or block title.
 *
 * @param $uid
 *   The uid of the user account.  Defaults to the site form, $uid = 0.
 */
function follow_link_title($uid = 0) {

  // Check to see if we have a valid username.
  if ($uid) {
    $setting = variable_get('follow_user_block_title', FOLLOW_NAME);

    // Special handling for usernames.
    if ($setting == FOLLOW_NAME) {
      $account = user_load($uid);

      // Set plain to TRUE for realname module support.
      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');
  }
}

/**
 * Helper function to build the block content display.
 *
 * @param $uid
 *   The uid of the user account.  Defaults to the site form, $uid = 0.
 */
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;
}

/**
 * Theme function to output a list of links.
 *
 * @param $links
 *   An array of follow link objects.
 * @param $networks
 *   An array of network names, keys are machine names, values are visible titles.
 * @param $alignment
 *   A string depicting whether the icons should be displayed in a "horizontal"
 *   or "vertical" list.
 *
 * @ingroup themeable
 */
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;
}

/**
 * Theme function to print an individual link.
 *
 * @param $link
 *   A follow link object.
 * @param $title
 *   The translated title of the social network.
 *
 * @ingroup themable
 */
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,
  );

  // Clean up the blank titles.
  if ($title == '<none>') {
    $title = '';
  }
  $link->options['attributes'] = $attributes;
  return l($title, $link->path, $link->options) . "\n";
}

/**
 * Implements hook_contextual_links_view_alter().
 *
 * @param $element
 *   A renderable array representing the contextual links.
 * @param $items
 *   An associative array containing the original contextual link items, as
 *   generated by menu_contextual_links(), which were used to build
 *   $element['#links'].
 */
function follow_contextual_links_view_alter(&$element, $items) {

  // Add the Follow configuration links to both of the Follow blocks.
  $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.'),
        ),
      );
    }
  }
}

/**
 * The form for editing follow links.
 *
 * @param $form_state
 *   A keyed array containing the current state of the form.
 * @param $uid
 *   The uid of the user account.  Defaults to the site form, $uid = 0.
 *
 * @ingroup forms
 */
function follow_links_form($form, &$form_state, $uid = 0) {
  $form = array();
  $form['uid'] = array(
    '#type' => 'hidden',
    '#value' => $uid,
  );
  $form['follow_links']['#tree'] = TRUE;

  // Allow changing which icon style to use on the global service links.
  $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,
  );

  // Allow changing which icon style to use on the global service links.
  $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,
  );

  // List all the available links.
  $links = follow_links_load($uid);
  $networks = follow_networks_load($uid, TRUE);

  // Put all our existing links at the top, sorted by weight.
  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 this specific network so we don't add the same one again below.
      unset($networks[$name]);
    }
  }

  // Now add all the empty ones.
  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;
}

/**
 * Helper function to create an individual link form element.
 */
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,
  );

  // Provide the title of the link only if the link URL is there and the user
  // has the appropriate access.
  $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;
}

/**
 * Like drupal_http_build_query() but without urlencodings.
 */
function follow_build_query(array $query, $parent = '') {
  $params = array();
  foreach ($query as $key => $value) {
    $key = $parent ? $parent . '[' . $key . ']' : $key;

    // Recurse into children.
    if (is_array($value)) {
      $params[] = follow_build_query($value, $key);
    }
    elseif (!isset($value)) {
      $params[] = $key;
    }
    else {
      $params[] = $key . '=' . $value;
    }
  }
  return implode('&', $params);
}

/**
 * Build a url for use in the form.
 */
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;
}

/**
 * Split a Drupal path or external link into path and options like a menu link.
 */
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 the query string into an array.
  parse_str($parsed_url['query'], $options['query']);
  if ($parsed_url['scheme']) {
    $parsed_url['scheme'] .= '://';
  }

  // Throw away port for now.
  $path = $parsed_url['scheme'] . $parsed_url['host'] . $parsed_url['path'];
  return array(
    'path' => $path,
    'options' => $options,
  );
}

/**
 * Validates the url field to verify it's actually a url.
 */
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);
  }
}

/**
 * Build a regex to validate the url based on a known service url.
 */
function follow_build_url_regex($network_info) {
  if (!empty($network_info['domain'])) {

    // An external link.
    return '@^https?://([a-z0-9\\-_.]+\\.|)' . str_replace('.', '\\.', $network_info['domain']) . '/@i';
  }

  // An internal link should not have ':'.
  return '@^[^:]+$@';
}

/**
 * Submit handler for the follow_links_form.
 */
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);

    // Check to see if there's actually a link
    if (empty($link->url)) {

      // If there's an lid, delete the link.
      if (isset($link->lid)) {
        follow_link_delete($link->lid);
      }

      // Continue to the next link.
      continue;
    }
    else {
      $link->uid = $values['uid'];
      $link->name = $name;
      follow_link_save($link);
    }
  }

  // Save the Follow icon style.
  $icon_style = $values['follow_icon_style'];
  if (in_array($icon_style, array(
    'small',
    'large',
    'wpzoom26',
    'wpzoom38',
    'paulrobertlloyd32',
  ))) {
    variable_set('follow_icon_style', $icon_style);
  }

  // Save the Follow alignment.
  $alignment = $values['follow_alignment'];
  if (in_array($alignment, array(
    'vertical',
    'horizontal',
  ))) {
    variable_set('follow_alignment', $alignment);
  }
}

/**
 * Theme the drag-and-drop form.
 *
 * Arranges records in a table, and adds the css and js for draggable sorting.
 *
 * @ingroup themeable
 * @ingroup forms
 */
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']);
      }

      // Now, render the weight row.
      $form['follow_links'][$key]['weight']['#attributes']['class'][] = 'follow-links-weight';
      $row[] = drupal_render($form['follow_links'][$key]['weight']);

      // Add the new row to our collection of rows, and give it the 'draggable' class.
      $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']),
      );
    }
  }

  // Render a list of header titles, and our array of rows, into a table.
  $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;
}

/**
 * Follow settings form.
 *
 * @ingroup forms
 */
function follow_settings_form() {
  $form = array();
  return system_settings_form($form);
}

/**
 * Loader function for individual links.
 *
 * @param $uid
 *   An int containing the uid of the user. uid 0 pulls the site follow links.
 * @return
 *   A single link in array format, or FALSE if none matched the incoming ID.
 */
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;
}

/**
 * Inserts a new link, or updates an existing one.
 *
 * @param $link
 *   A link object to be saved.
 */
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;
}

/**
 * Deletes a link, given its unique ID.
 *
 * @param $lid
 *   An int containing the ID of a link.
 */
function follow_link_delete($lid) {
  db_delete('follow_links')
    ->condition('lid', $lid)
    ->execute();
}

/**
 * Loads all follow networks
 *
 * @param $uid
 *   The uid of the user. uid 0 pulls the site follow links.
 * @param $reset
 *   Boolean.  If TRUE, flushes the follow networks cache.
 *
 * @return
 *   An array of network names, keys are machine names, values are visible titles.
 */
function follow_networks_load($uid = 0, $reset = FALSE) {
  static $networks = array();

  // Clear cache if $reset is TRUE;
  if ($reset) {
    $networks = array();
  }

  // Return presets if the array is populated.
  if (empty($networks[$uid])) {

    // We call hook_follow_networks_alter() to allow other modules to create
    // or alter networks.
    $networks[$uid] = follow_default_networks($uid);
    drupal_alter('follow_networks', $networks, $uid);
  }
  return $networks[$uid];
}

/**
 * Retrieves the default networks available.
 *
 * @return
 *   An associative array, keyed by the machine name. The values are an array
 *   including title of the network, along with the domain to be used for
 *   input validation of the network.
 */
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;
}

/**
 * Implements hook_admin_paths().
 *
 * Have the Follow links for the user pop up in the Overlay.
 */
function follow_admin_paths() {
  $paths = array(
    'user/*/follow' => TRUE,
  );
  return $paths;
}

Functions

Namesort descending Description
follow_admin_paths Implements hook_admin_paths().
follow_block_configure Implementation of hook_block_configure().
follow_block_info Implementation of hook_block_info().
follow_block_save Implementation of hook_block_save().
follow_block_view Implementation of hook_block_view().
follow_build_query Like drupal_http_build_query() but without urlencodings.
follow_build_url Build a url for use in the form.
follow_build_url_regex Build a regex to validate the url based on a known service url.
follow_contextual_links_view_alter Implements hook_contextual_links_view_alter().
follow_default_networks Retrieves the default networks available.
follow_help Implementation of hook_help().
follow_init Implementation of hook_init().
follow_links_form The form for editing follow links.
follow_links_form_submit Submit handler for the follow_links_form.
follow_links_load Loader function for individual links.
follow_links_user_access Access callback for user follow links editing.
follow_link_delete Deletes a link, given its unique ID.
follow_link_save Inserts a new link, or updates an existing one.
follow_link_title Helper function to create a link or block title.
follow_menu Implementation of hook_menu().
follow_networks_load Loads all follow networks
follow_parse_url Split a Drupal path or external link into path and options like a menu link.
follow_permission Implementation of hook_permission().
follow_preprocess_page Implementation of hook_preprocess_page().
follow_settings_form Follow settings form.
follow_theme Implementation of hook_theme().
follow_url_validate Validates the url field to verify it's actually a url.
theme_follow_link Theme function to print an individual link.
theme_follow_links Theme function to output a list of links.
theme_follow_links_form Theme the drag-and-drop form.
_follow_block_content Helper function to build the block content display.
_follow_block_subject Helper function to build the block title.
_follow_links_form_link Helper function to create an individual link form element.

Constants

Namesort descending Description
FOLLOW_ME
FOLLOW_NAME @file Allows users to add links to their social network profiles.
FOLLOW_US