getDirectoryPath();
return $directory_path . '/css/follow.css';
}
/**
* Save the Follow module generated CSS.
*/
function follow_save_css($reset = FALSE) {
// Destination where the file will be saved.
$destination = 'public://css/follow.css';
// Delete stale CSS file if necessary.
if (file_exists($destination)) {
drupal_delete_file_if_stale($destination);
}
// If reset is FALSE and the file exists, do nothing.
if (!$reset && file_exists($destination)) {
return TRUE;
}
// We have to prepare the directory, in case it doesn't exist.
$directory = 'public://css';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
// Clean out any existing aggregated CSS files.
file_scan_directory($directory, '/.*/', array('callback' => 'file_unmanaged_delete'));
// Generate a new CSS/JS token since we just wiped the CSS dir.
_drupal_flush_css_js();
// Load up the styles for each follow link type.
$site_style = variable_get('follow_site_icon_style', 'small');
$user_style = variable_get('follow_user_icon_style', 'small');
$contents = "/**
* This CSS file is generated by Follow module. DO NOT edit it directly.
* Instead, copy the file to your theme's CSS directory and edit it there.
*/\n\n";
$contents .= theme('follow_css', array('icon_style_name' => $site_style));
// If the user style is different, append it to our contents, with a selector
// prefix to override the previous styles.
if ($site_style != $user_style) {
$contents .= theme('follow_css', array('icon_style_name' => $user_style, 'selector_prefix' => '.follow-links.user'));
}
return file_unmanaged_save_data($contents, $destination, FILE_EXISTS_REPLACE);
}
/**
* 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 a follow links element.
*
* @param array $links
* An array of follow links.
* @param array $networks
* An array of networks.
* @param string $type
* The type of follow links, user or site.
* @param string $alignment
* The alignment, horizontal or vertical.
*/
function _follow_links_element(array $links, array $networks, $type, $alignment = NULL) {
// Let's be sure the CSS exists before printing this.
follow_save_css();
$element['follow-links']['#prefix'] = "
";
$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'] = '
';
return $element;
}
/**
* 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);
}
// If a query parameter value is NULL, only append its 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 '@^[^:]+$@';
}
/**
* 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) {
$networks = &drupal_static(__FUNCTION__, 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;
}
/**
* Load up all icon styles. You can add or alter these icon styles in a module
* or theme by implementing hook_follow_icon_styles_alter(). See follow.api.php
* for an example.
*/
function follow_icon_styles() {
$styles = &drupal_static(__FUNCTION__);
if (!isset($styles)) {
$styles = follow_default_icon_styles();
drupal_alter('follow_icon_styles', $styles);
}
return $styles;
}
/**
* Load up a single icon style. If no icon style is found with the given name,
* the small icon style will be returned.
*
* @param string $name
* The string machine name of the style.
*/
function follow_get_icon_style($name) {
$styles = follow_icon_styles();
return isset($styles[$name]) ? $styles[$name] : $styles['small'];
}
/**
* Default icon styles provided by follow module.
*/
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;
}
/**
* Return an array of icon style options, with the key being the machine name of
* the style, and the value being the label of the style.
*/
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;
}
/**
* Helper function to determine the icon path for a icon style.
*
* @param array $style
* The style to check.
*/
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;
}