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'] = "'; 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; }