View source  
  <?php
define('FOLLOW_NAME', 0);
define('FOLLOW_ME', 1);
define('FOLLOW_US', 2);
function _follow_css_get_path() {
  $directory_path = file_stream_wrapper_get_instance_by_scheme('public')
    ->getDirectoryPath();
  return $directory_path . '/css/follow.css';
}
function follow_save_css($reset = FALSE) {
  
  $destination = 'public://css/follow.css';
  
  if (file_exists($destination)) {
    drupal_delete_file_if_stale($destination);
  }
  
  if (!$reset && file_exists($destination)) {
    return TRUE;
  }
  
  $directory = 'public://css';
  file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
  
  file_scan_directory($directory, '/.*/', array(
    'callback' => 'file_unmanaged_delete',
  ));
  
  _drupal_flush_css_js();
  
  $site_style = variable_get('follow_site_icon_style', 'small');
  $user_style = variable_get('follow_user_icon_style', 'small');
  $site_hide_text = variable_get('follow_site_hide_text', FALSE);
  $user_hide_text = variable_get('follow_user_hide_text', FALSE);
  $contents = "/**\n * This CSS file is generated by Follow module. DO NOT edit it directly.\n * Instead, copy the file to your theme's CSS directory and edit it there.\n */\n\n";
  $variables = array(
    'icon_style_name' => $site_style,
    'hide_text' => $site_hide_text,
  );
  $contents .= theme('follow_css', $variables);
  
  if ($site_style != $user_style || $site_hide_text != $user_hide_text) {
    $variables = array(
      'icon_style_name' => $user_style,
      'hide_text' => $user_hide_text,
      'selector_prefix' => '.follow-links.user',
    );
    $contents .= theme('follow_css', $variables);
  }
  return file_unmanaged_save_data($contents, $destination, FILE_EXISTS_REPLACE);
}
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_links_element(array $links, array $networks, $type, $alignment = NULL) {
  
  follow_save_css();
  $element['follow-links']['#prefix'] = "<div class='follow-links clearfix {$type}'>";
  $element['follow-links']['#attached']['css'][] = _follow_css_get_path();
  if (!isset($alignment)) {
    $alignment = variable_get("follow_{$type}_alignment", 'vertical');
  }
  $wrapper = $alignment == 'horizontal' ? 'span' : 'div';
  foreach ($links as $link) {
    $title = !empty($link->title) ? $link->title : $networks[$link->name]['title'];
    $element['follow-links'][$link->name] = array(
      '#prefix' => "<{$wrapper} class='follow-link-wrapper follow-link-wrapper-{$link->name}'>",
      '#theme' => 'follow_link',
      '#link' => $link,
      '#title' => $title,
      '#suffix' => "</{$wrapper}>",
    );
  }
  $element['follow-links']['#suffix'] = '</div>';
  return $element;
}
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_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) {
  $networks =& drupal_static(__FUNCTION__, 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',
    ),
    'instagram' => array(
      'title' => t('Instagram'),
      'domain' => 'instagram.com',
    ),
    'pinterest' => array(
      'title' => t('Pinterest'),
      'domain' => 'pinterest.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_icon_styles() {
  $styles =& drupal_static(__FUNCTION__);
  if (!isset($styles)) {
    $styles = follow_default_icon_styles();
    drupal_alter('follow_icon_styles', $styles);
  }
  return $styles;
}
function follow_get_icon_style($name) {
  $styles = follow_icon_styles();
  return isset($styles[$name]) ? $styles[$name] : $styles['small'];
}
function follow_default_icon_styles() {
  $styles['small'] = array(
    'name' => 'small',
    'label' => t('Small'),
  );
  $styles['large'] = array(
    'name' => 'large',
    'label' => t('Large'),
    'css-overrides' => array(
      'height: 42px;',
      'line-height: 38px;',
      'padding-left: 39px;',
      'padding-right: 5px;',
    ),
  );
  $styles['wpzoom26'] = array(
    'name' => 'wpzoom26',
    'label' => t('WPZOOM 26x'),
    'css-overrides' => array(
      'height: 32px;',
      'line-height: 28px;',
      'padding-left: 30px;',
      'padding-right: 3px;',
    ),
  );
  $styles['wpzoom38'] = array(
    'name' => 'wpzoom38',
    'label' => t('WPZOOM 38x'),
    'css-overrides' => array(
      'height: 44px;',
      'line-height: 40px;',
      'padding-left: 41px;',
      'padding-right: 5px;',
    ),
  );
  $styles['paulrobertlloyd32'] = array(
    'name' => 'paulrobertlloyd32',
    'label' => t('Paul Robert Lloyd 32x32'),
    'css-overrides' => array(
      'height: 38px;',
      'line-height: 34px;',
      'padding-left: 38px;',
      'padding-right: 5px;',
    ),
  );
  return $styles;
}
function follow_icon_style_options() {
  $options = array();
  foreach (follow_icon_styles() as $style) {
    if (!isset($style['name']) || !isset($style['label'])) {
      continue;
    }
    $options[$style['name']] = $style['label'];
  }
  return $options;
}
function _follow_style_icon_path(array $style) {
  $default_icon_path = drupal_get_path('module', 'follow') . '/icons/' . $style['name'];
  $path = !empty($style['icon-path']) ? $style['icon-path'] : $default_icon_path;
  return base_path() . $path;
}