You are here

service_links.module in Service links 7.2

Same filename and directory in other branches
  1. 5 service_links.module
  2. 6.2 service_links.module
  3. 6 service_links.module

Adds social network links to the content.

This module is the enhanced version of Service Links 1.x developed by Fredrik Jonsson, rewritten and improved to fit the new purposes: extend easily the number of services supported and provide APIs to print links everywhere within any content. At the home page a web interface helps to create a module including the services not availables in the standard package.

@author: Fabio Mucciante (TheCrow)

File

service_links.module
View source
<?php

/**
 * @file
 * Adds social network links to the content.
 *
 * This module is the enhanced version of Service Links 1.x developed
 * by Fredrik Jonsson, rewritten and improved to fit the new purposes:
 * extend easily the number of services supported and provide APIs to
 * print links everywhere within any content.
 * At the @link http://servicelinks.altervista.org/?q=service home page
 * @endlink a web interface helps to create a module including the
 * services not availables in the standard package.
 *
 * @author: Fabio Mucciante (TheCrow)
 */
define('SERVICE_LINKS_STYLE_NONE', 0);
define('SERVICE_LINKS_STYLE_TEXT', 1);
define('SERVICE_LINKS_STYLE_IMAGE', 2);
define('SERVICE_LINKS_STYLE_IMAGE_AND_TEXT', 3);
define('SERVICE_LINKS_STYLE_EMPTY', 4);
define('SERVICE_LINKS_STYLE_FISHEYE', 5);
define('SERVICE_LINKS_SHORT_URL_USE_NEVER', 0);
define('SERVICE_LINKS_SHORT_URL_USE_WHEN_REQUESTED', 1);
define('SERVICE_LINKS_SHORT_URL_USE_ALWAYS', 2);
define('SERVICE_LINKS_SHORT_URL_TYPE_NODE', 1);
define('SERVICE_LINKS_SHORT_URL_TYPE_SERVICE', 2);
define('SERVICE_LINKS_SHORT_URL_TYPE_REDIRECT_DOMAIN', 3);
define('SERVICE_LINKS_SHORT_URL_TYPE_REDIRECT_ALL', 4);
define('SERVICE_LINKS_TAG_TITLE_NODE', 0);
define('SERVICE_LINKS_TAG_TITLE_OVERRIDE', 1);
define('SERVICE_LINKS_TAG_TITLE_TOKEN', 2);
define('SERVICE_LINKS_VISIBILITY_NOT_LISTED', 0);
define('SERVICE_LINKS_VISIBILITY_ONLY_LISTED', 1);
define('SERVICE_LINKS_VISIBILITY_PHP', 2);

/**
 * Implements hook_help().
 */
function service_links_help($path, $arg) {
  switch ($path) {
    case 'admin/help#service_links':
      return '<p>' . t('Display links to social sharing websites like Digg, del.icio.us, reddit, Technorati etc.') . '</p>';
      break;
  }
}

/**
 * Implements hook_hook_info().
 */
function service_links_hook_info() {
  $hooks = array(
    'service_links' => array(
      'group' => 'service_links',
    ),
    'service_links_alter' => array(
      'group' => 'service_links',
    ),
    'service_links_node_settings_alter' => array(
      'group' => 'service_links',
    ),
  );
  return $hooks;
}

/**
 * Implements hook_permission().
 */
function service_links_permission() {
  return array(
    'access service links' => array(
      'title' => t('Access to Service Links'),
    ),
    'use PHP for service visibility' => array(
      'title' => t('Use PHP for Service visibility'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function service_links_menu() {
  $items = array();
  $items['admin/config/services/service-links'] = array(
    'title' => 'Service Links',
    'description' => 'Control which and where service links should be active.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'service_links_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'service_links.admin.inc',
  );
  $items['admin/config/services/service-links/general'] = array(
    'title' => 'General Settings',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/config/services/service-links/services'] = array(
    'title' => 'Services',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'service_links_admin_services',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'service_links.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_node_view().
 */
function service_links_node_view($node, $view_mode) {
  static $view_modes_allowed;
  if (!isset($view_modes_allowed)) {
    $view_modes_allowed = array_filter(variable_get('service_links_node_view_modes', array()));
  }
  if (arg(2) != 'edit' && service_links_show($node) && user_access('access service links')) {
    $node->service_links = service_links_render($node, TRUE);
    if (!empty($view_modes_allowed) && in_array($view_mode, $view_modes_allowed)) {
      $node->service_links_rendered = theme('service_links_node_format', array(
        'links' => $node->service_links,
        'label' => variable_get('service_links_label_in_node', t('Bookmark/Search this post with')),
        'view_mode' => $view_mode,
        'node_type' => $node->type,
      ));
      $node->content['service_links'] = array(
        '#markup' => $node->service_links_rendered,
        '#weight' => variable_get('service_links_weight_in_node', 10),
      );
    }
    _service_links_link($node, $view_mode);
  }
}

/**
 * Create an array of links for the link section.
 */
function _service_links_link($node, $view_mode) {
  static $view_modes_allowed;
  if (!isset($view_modes_allowed)) {
    $view_modes_allowed = array_filter(variable_get('service_links_link_view_modes', array()));
  }
  if (in_array($view_mode, $view_modes_allowed)) {
    $links = $node->service_links;
    foreach ($links as $key => $value) {
      $node->content['links']['node']['#links'][$key] = $value;
    }
  }
}

/**
 * Implements hook_block_info().
 */
function service_links_block_info() {
  $blocks['service_links'] = array(
    'info' => t('Service links'),
    'cache' => DRUPAL_NO_CACHE,
  );
  $blocks['service_links_fisheye'] = array(
    'info' => t('Service links with FishEye effect'),
    'cache' => DRUPAL_NO_CACHE,
  );
  $blocks['service_links_not_node'] = array(
    'info' => t('Service links for not-node pages'),
    'cache' => DRUPAL_NO_CACHE,
  );
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function service_links_block_view($delta = '') {
  $node = menu_get_object('node');
  $block = array();
  if (user_access('access service links') && isset($node)) {
    if (service_links_show($node)) {
      switch ($delta) {
        case 'service_links':
          $block['subject'] = t('Bookmark/Search this post');
          $style = variable_get('service_links_block_style', SERVICE_LINKS_STYLE_IMAGE_AND_TEXT);
          $block['content'] = theme('service_links_block_format', array(
            'items' => service_links_render($node, FALSE, $style),
            'style' => $style,
          ));
          break;
        case 'service_links_fisheye':
          $block['subject'] = t('Bookmark/Search this post');
          $block['content'] = theme('service_links_fisheye_format', array(
            'items' => service_links_render($node, FALSE, SERVICE_LINKS_STYLE_FISHEYE),
          ));
          break;
      }
    }
    return $block;
  }
  elseif (user_access('access service links') && !isset($node)) {
    switch ($delta) {
      case 'service_links_not_node':
        $block['subject'] = t('Bookmark/Search this post');
        $options = array(
          'style' => variable_get('service_links_block_not_node_style', SERVICE_LINKS_STYLE_IMAGE_AND_TEXT),
          'link_to_front' => variable_get('service_links_block_not_node_front', FALSE),
        );
        $block['content'] = theme('service_links_block_format', array(
          'items' => service_links_render(NULL, FALSE, $options),
          'style' => $options['style'],
        ));
        break;
    }
    return $block;
  }
}

/**
 * Implements hook_block_configure().
 */
function service_links_block_configure($delta = '') {
  $form = array();
  switch ($delta) {
    case 'service_links':
      $form['service_links_block_style'] = array(
        '#type' => 'select',
        '#title' => t('Style'),
        '#description' => t('How the service links will appear in the block.'),
        '#default_value' => variable_get('service_links_block_style', SERVICE_LINKS_STYLE_IMAGE_AND_TEXT),
        '#options' => array(
          SERVICE_LINKS_STYLE_TEXT => t('Text'),
          SERVICE_LINKS_STYLE_IMAGE => t('Image'),
          SERVICE_LINKS_STYLE_IMAGE_AND_TEXT => t('Image and Text'),
        ),
      );
      break;
    case 'service_links_fisheye':
      $form['service_links_path_fisheye'] = array(
        '#type' => 'textfield',
        '#title' => t('Alternative icon folder'),
        '#size' => 60,
        '#description' => t('If you have alternative icons write here the path without trailing slash'),
        '#default_value' => service_links_expand_path(NULL, 'fisheye'),
      );
      break;
    case 'service_links_not_node':
      $form['service_links_block_not_node_style'] = array(
        '#type' => 'select',
        '#title' => t('Style'),
        '#description' => t('How the service links will appear in the block.'),
        '#default_value' => variable_get('service_links_block_not_node_style', SERVICE_LINKS_STYLE_IMAGE_AND_TEXT),
        '#options' => array(
          SERVICE_LINKS_STYLE_TEXT => t('Text'),
          SERVICE_LINKS_STYLE_IMAGE => t('Image'),
          SERVICE_LINKS_STYLE_IMAGE_AND_TEXT => t('Image and Text'),
        ),
      );
      $form['service_links_block_not_node_front'] = array(
        '#type' => 'checkbox',
        '#title' => t('Link always to the front page'),
        '#description' => t('If selected the services will link always to the front page %front.', array(
          '%front' => url('<front>', array(
            'absolute' => TRUE,
          )),
        )),
        '#default_value' => variable_get('service_links_block_not_node_front', FALSE),
      );
      break;
  }
  return $form;
}

/**
 * Implements hook_block_save().
 */
function service_links_block_save($delta = '', $edit = array()) {
  switch ($delta) {
    case 'service_links':
      variable_set('service_links_block_style', $edit['service_links_block_style']);
      break;
    case 'service_links_fisheye':
      variable_set('service_links_path_fisheye', $edit['service_links_path_fisheye']);
      break;
    case 'service_links_not_node':
      variable_set('service_links_block_not_node_style', $edit['service_links_block_not_node_style']);
      variable_set('service_links_block_not_node_front', $edit['service_links_block_not_node_front']);
      break;
  }
}

/**
 * Implements hook_theme().
 */
function service_links_theme() {
  return array(
    'service_links_build_link' => array(
      'variables' => array(
        'text' => NULL,
        'url' => array(),
        'image' => NULL,
        'nodelink' => FALSE,
        'style' => NULL,
        'attributes' => array(),
      ),
      'file' => 'service_links.theme.inc',
    ),
    'service_links_node_format' => array(
      'variables' => array(
        'links' => NULL,
        'label' => NULL,
        'view_mode' => NULL,
        'node_type' => NULL,
      ),
      'file' => 'service_links.theme.inc',
    ),
    'service_links_block_format' => array(
      'variables' => array(
        'items' => NULL,
        'style' => SERVICE_LINKS_STYLE_IMAGE_AND_TEXT,
      ),
      'file' => 'service_links.theme.inc',
    ),
    'service_links_fisheye_format' => array(
      'variables' => array(
        'items' => NULL,
      ),
      'file' => 'service_links.theme.inc',
    ),
    'service_links_drag_table' => array(
      'render element' => 'form',
    ),
  );
}

/**
 * Remove a service from the list if the related module is disabled
 * and can't provide the correct values.
 */
function service_links_array_filter($services) {
  $result = array();
  foreach ($services as $service_id => $service) {
    if ($service === 1) {
      drupal_set_message(t('The service having id "@id" is missing, reactivate its module or save again the list of services.', array(
        '@id' => $service_id,
      )), 'warning', FALSE);
    }
    else {
      $result[$service_id] = $service;
    }
  }
  return $result;
}

/**
 * Discover all available service links by invoking hook_service_links().
 *
 * @param $services
 *   If NULL, will retrieve all service link information. If an array is passed,
 *   will only obtain information for the given keyed links.
 * @param $reset
 *   Resets the Service Links cache.
 *
 * @return
 *   An array containing information for all the requested services.
 */
function service_links_get_links($services = NULL, $reset = FALSE) {
  $links =& drupal_static(__FUNCTION__, NULL);
  if (!isset($links) || $reset) {

    // Retrieve the links from the cache.
    if (!$reset && ($cache = cache_get('service_links_get_links')) && !empty($cache->data)) {
      $links = $cache->data;
    }
    else {

      // Create the repository of links.
      $links = array();
      foreach (module_implements('service_links') as $module) {
        $module_links = module_invoke($module, 'service_links');
        foreach ($module_links as $name => $link) {
          $link['module'] = $module;
          $links[$name] = $link;
        }
      }

      // Allow alteration of the links.
      drupal_alter('service_links', $links);

      // Save the links in the cache.
      cache_set('service_links_get_links', $links);
    }
  }

  // If desired, return only the wanted services.
  if (isset($services)) {

    // Detect a manual request and populate the array correctly.
    if (is_numeric(key($services))) {
      $services = array_combine($services, array_fill(0, count($services), 1));
    }

    // Provide only the services requested.
    $services = array_merge($services, array_intersect_key($links, $services));

    // Remove the unknown services.
    $services = service_links_array_filter($services);
  }
  return isset($services) ? $services : $links;
}

/**
 * Create short links using predefined settings.
 */
function service_links_short_url($url, $nid = NULL) {
  switch (variable_get('service_links_short_links_type', SERVICE_LINKS_SHORT_URL_TYPE_NODE)) {
    case SERVICE_LINKS_SHORT_URL_TYPE_NODE:
      if (empty($nid)) {
        return $url;
      }
      else {

        // With alias = true doesn't change the path.
        return url("node/{$nid}", array(
          'absolute' => TRUE,
          'alias' => TRUE,
        ));
      }
    case SERVICE_LINKS_SHORT_URL_TYPE_SERVICE:
      if (module_exists('shorten')) {
        $turl = shorten_url($url);
      }
      else {
        $turl = drupal_http_request('http://tinyurl.com/api-create.php?url=' . urlencode($url));
        $turl = isset($turl->data) && $turl->code == 200 ? $turl->data : $url;
      }
      return $turl;
    case SERVICE_LINKS_SHORT_URL_TYPE_REDIRECT_DOMAIN:
      $burl = variable_get('service_links_domain_redirect', NULL);
      return url($url, array(
        'absolute' => TRUE,
        'base_url' => $burl,
      ));
    case SERVICE_LINKS_SHORT_URL_TYPE_REDIRECT_ALL:
      $burl = variable_get('service_links_domain_redirect', NULL);
      if (empty($nid)) {
        return url($url, array(
          'absolute' => TRUE,
          'base_url' => $burl,
        ));
      }
      else {
        return url("node/{$nid}", array(
          'absolute' => TRUE,
          'alias' => TRUE,
          'base_url' => $burl,
        ));
      }
  }
}

/**
 * Function that render all the selected services.
 *
 * @param $node
 *   Contains the content structured as a node object.
 *   Use the node_load() function to build one or set
 *   NULL this variable to consider the current page.
 * @param $nodelink
 *   (optional) It determines the kind of render.
 *   If TRUE the function return an array of items 
 *   compatible with the standard Drupal link section.
 *   If FALSE return an array of HTML links.
 *   Default is FALSE.
 * @param $options
 *   (optional) Can assume the value of a valid service
 *   style either an array containing the settings 
 *   to override (look at _service_links_load_settings()
 *   for more details).
 *
 * @return
 *   An array of HTML links if $nodelink = FALSE, an array
 *   of structured links to be themed with theme_links() 
 *   if $nodelink = TRUE.
 */
function service_links_render($node, $nodelink = FALSE, $options = NULL) {
  $links = array(
    'weight' => array(),
    'link' => array(),
  );
  $settings = _service_links_load_settings();
  if (empty($settings['link_show'])) {
    return array();
  }
  if (isset($options)) {
    if (!is_array($options)) {
      $options = array(
        'style' => $options,
      );
    }
    $settings = array_merge($settings, $options);
  }
  _service_links_get_tags($node, $settings);

  // Services are filtered in _service_links_load_settings().
  $services = service_links_get_links($settings['link_show']);
  foreach ($services as $service_id => $service) {

    // Load the position.
    $links['weight'][] = isset($settings['link_weight'][$service_id]) ? $settings['link_weight'][$service_id] : 0;

    // Render the Service.
    $links['link'] += _service_links_render($service_id, $service, $settings, $nodelink, $node);
  }
  if (!empty($links['link'])) {
    array_multisort($links['weight'], $links['link']);
  }
  return !empty($links['link']) ? $links['link'] : array();
}

/**
 * This function render only the services requested
 * by their id.
 *
 * @param $service_ids
 *   The list of requested services, can be just a
 *   string, for a single services, or an array of
 *   id, don't need enable them on the admin page.
 * @param $node
 *   Contains the content structured as a node object.
 *   Use the node_load() function to build one or set
 *   NULL this variable to consider the current page.
 * @param $nodelink
 *   (optional) It determines the kind of render.
 *   If TRUE the function return an array of items 
 *   compatible with the standard Drupal link section.
 *   If FALSE return an array of HTML links.
 *   Default is FALSE.
 * @param $options
 *   (optional) Can assume the value of a valid service
 *   style either an array containing the settings 
 *   to override (look at _service_links_load_settings()
 *   for more details).
 *
 * @return
 *   An array of HTML links if $nodelink = FALSE, an array
 *   of structured links to be themed with theme_links() 
 *   if $nodelink = TRUE.
 */
function service_links_render_some($service_ids, $node = NULL, $nodelink = FALSE, $options = NULL) {
  if (is_array($service_ids)) {
    $services = service_links_get_links($service_ids);
  }
  else {
    $services = service_links_get_links(array(
      $service_ids,
    ));
  }
  if (empty($services)) {
    return array();
  }
  $settings = _service_links_load_settings();
  if (isset($options)) {
    if (!is_array($options)) {
      $options = array(
        'style' => $options,
      );
    }
    $settings = array_merge($settings, $options);
  }
  _service_links_get_tags($node, $settings);
  $links = array();
  foreach ($services as $service_id => $service) {
    $links += _service_links_render($service_id, $service, $settings, $nodelink, $node);
  }
  return $links;
}

/**
 * The common render function used privately.
 */
function _service_links_render($service_id, $service, $settings, $nodelink, $node = NULL) {
  if (isset($service['preset'])) {
    if (function_exists($function = $service['preset'])) {
      $function($service, $settings, $node);
    }
  }

  // On Drupal 7 this tag should be filled before the split otherwise will be lost.
  $service['link'] = str_replace('<front-page>', $settings['subst']['front-page'], $service['link']);
  if (strpos($service['link'], '=') === FALSE) {
    $service['url'] = array(
      $service['link'],
    );
  }
  else {
    $service['url'] = preg_split('/\\?/', $service['link']);
  }
  if (count($service['url']) > 1) {
    $service['url'][1] = service_links_get_query($service['url'][1]);
    $service['url'][1] = str_replace($settings['tag'], $settings['subst'], $service['url'][1]);
  }
  else {
    $service['url'][0] = str_replace($settings['tag'], $settings['subst'], $service['url'][0]);
  }
  $service['attributes']['title'] = t($service['description']);
  $class = str_replace(array(
    '][',
    '_',
    ' ',
  ), '-', 'service_links-' . $service_id);
  $service['attributes']['class'] = isset($service['attributes']['class']) ? array_merge($service['attributes']['class'], array(
    $class,
  )) : array(
    $class,
  );
  $service['attributes'] += $settings['attributes'];
  $service['icon'] = isset($service['icon']) ? $service['icon'] : "{$service_id}.png";
  $service_id = str_replace('_', '-', 'service_links_' . $service_id);

  // Check if a predefined style should be imposed.
  if (empty($service['style'])) {
    $service['style'] = $settings['style'];
  }

  // Add the related JavaScript and CSS.
  if (isset($service['javascript'])) {
    _service_links_add_js($service['javascript']);
  }
  if (isset($service['css'])) {
    drupal_add_css(service_links_expand_path($service['css'], 'css'));
  }

  // Invoke callback function.
  if (isset($service['callback'])) {
    if (function_exists($function = $service['callback'])) {
      $function($service, $settings['subst']);
    }
  }

  // Create the HTML.
  $link = theme('service_links_build_link', array(
    'text' => t($service['name']),
    'url' => $service['url'],
    'image' => $service['icon'],
    'nodelink' => $nodelink,
    'style' => $service['style'],
    'attributes' => $service['attributes'],
  ));
  return array(
    $service_id => $link,
  );
}

/**
 * Load correctly the needed javascripts.
 */
function _service_links_add_js($javascript) {
  global $is_https;
  static $external_js;
  if (!is_array($javascript)) {
    $javascript = array(
      $javascript,
    );
  }
  if (!isset($external_js)) {
    $external_js = array();
  }
  foreach ($javascript as $js) {
    if (strpos($js, '://') !== FALSE) {
      if ($is_https) {

        // Ensure that we embed the https js library.
        $js = str_replace('http://', 'https://', $js);
      }
      if (!in_array($js, $external_js)) {
        drupal_add_js($js, array(
          'type' => 'external',
        ));
        $external_js[] = $js;
      }
    }
    else {
      drupal_add_js(service_links_expand_path($js, 'javascript'));
    }
  }
}

/**
 * Fill an array with tags and the content to substitute.
 */
function _service_links_get_tags($node, &$settings) {
  if (!empty($node)) {
    $title = _service_links_get_node_title($node, $settings);
    $path = _service_links_get_node_path($node);
    $url = url("{$path}", array(
      'absolute' => TRUE,
      'query' => service_links_get_query($settings['text_to_append']),
    ));
    $query = drupal_get_path_alias("node/{$node->nid}");
    $body = field_get_items('node', $node, 'body');
    $teaser = $body ? strip_tags(text_summary($body[0]['value'])) : '';
    $nid = $node->nid;
  }
  elseif (isset($settings['data'])) {
    $title = isset($settings['data']['title']) ? $settings['data']['title'] : '';
    $url = isset($settings['data']['url']) ? $settings['data']['url'] : '';
    $query = isset($settings['data']['query']) ? $settings['data']['query'] : '';
    $teaser = isset($settings['data']['teaser']) ? $settings['data']['teaser'] : '';
    $nid = isset($settings['data']['node_id']) ? $settings['data']['node_id'] : NULL;
  }
  else {
    $title = drupal_get_title();
    $url = _service_links_get_page_url(NULL, $settings);

    // The query shouldn't follow the front_page alias but point the original page.
    $query = drupal_get_normal_path($_GET['q']);
    $teaser = '';
    $nid = NULL;
  }
  $source = variable_get('site_name', 'Drupal');
  $long_url = $url;
  $front_page = url('<front>', array(
    'absolute' => TRUE,
  ));
  if (variable_get('clean_url', 0) == 0 && strpos($front_page, '?q=') === FALSE) {
    $front_page .= '?q=';
  }
  else {

    // Ensure a trailing slash on multilingual sites with clean url on.
    $front_page = preg_replace('/([0-9a-z-_]+)$/i', '\\1/', $front_page);
  }
  switch ($settings['short_links_use']) {
    case SERVICE_LINKS_SHORT_URL_USE_NEVER:
      $short_url = $url;
      break;
    case SERVICE_LINKS_SHORT_URL_USE_WHEN_REQUESTED:
      $short_url = service_links_short_url($url, $nid);
      break;
    case SERVICE_LINKS_SHORT_URL_USE_ALWAYS:
      $short_url = service_links_short_url($url, $nid);
      $url = $short_url;
      break;
  }
  $settings['tag'] = array(
    'raw-encoded-title' => '<raw-encoded-title>',
    'raw-encoded-url' => '<raw-encoded-url>',
    'raw-encoded-teaser' => '<raw-encoded-teaser>',
    'raw-encoded-short-url' => '<raw-encoded-short-url>',
    'raw-encoded-long-url' => '<raw-encoded-long-url>',
    'raw-encoded-query' => '<raw-encoded-query>',
    'raw-encoded-source' => '<raw-encoded-source>',
    'encoded-title' => '<encoded-title>',
    'encoded-url' => '<encoded-url>',
    'encoded-teaser' => '<encoded-teaser>',
    'encoded-short-url' => '<encoded-short-url>',
    'encoded-long-url' => '<encoded-long-url>',
    'encoded-query' => '<encoded-query>',
    'encoded-source' => '<encoded-source>',
    'teaser' => '<teaser>',
    'short-url' => '<short-url>',
    'long-url' => '<long-url>',
    'source' => '<source>',
    'node-id' => '<node-id>',
    'query' => '<query>',
    'url' => '<url>',
    'title' => '<title>',
    'front-page' => '<front-page>',
  );
  $settings['subst'] = array(
    //'raw-encoded-title' => rawurlencode($title),
    'raw-encoded-title' => $title,
    //'raw-encoded-url' => rawurlencode($url),
    'raw-encoded-url' => $url,
    //'raw-encoded-teaser' => rawurlencode($teaser),
    'raw-encoded-teaser' => $teaser,
    //'raw-encoded-short-url' => rawurlencode($short_url),
    'raw-encoded-short-url' => $short_url,
    //'raw-encoded-long-url' => rawurlencode($long_url),
    'raw-encoded-long-url' => $long_url,
    //'raw-encoded-query' => rawurlencode($query),
    'raw-encoded-query' => $query,
    //'raw-encoded-source' => rawurlencode($source),
    'raw-encoded-source' => $source,
    //'encoded-title' => urlencode($title),
    'encoded-title' => $title,
    //'encoded-url' => urlencode($url),
    'encoded-url' => $url,
    //'encoded-teaser' => urlencode($teaser),
    'encoded-teaser' => $teaser,
    //'encoded-short-url' => urlencode($short_url),
    'encoded-short-url' => $short_url,
    //'encoded-long-url' => urlencode($long_url),
    'encoded-long-url' => $long_url,
    //'encoded-query' => urlencode($query),
    'encoded-query' => $query,
    //'encoded-source' => urlencode($source),
    'encoded-source' => $source,
    //Not needed
    'teaser' => $teaser,
    'short-url' => $short_url,
    'long-url' => $long_url,
    'source' => $source,
    'node-id' => $nid,
    'query' => $query,
    'url' => $url,
    'title' => $title,
    'front-page' => $front_page,
  );

  // Invoke an alter hook to let other modules modify these values if needed.
  drupal_alter('service_links_node_settings', $settings, $node);
}

/**
 * Return the url for not-node pages.
 */
function _service_links_get_page_url($node, $settings) {
  if ($settings['link_to_front'] || drupal_is_front_page()) {
    $url = url('<front>', array(
      'absolute' => TRUE,
      'query' => service_links_get_query($settings['text_to_append']),
    ));
  }
  else {
    $url = url($_GET['q'], array(
      'absolute' => TRUE,
      'query' => service_links_get_query($settings['text_to_append']),
    ));
  }
  return $url;
}

/**
 * Return the properly title.
 */
function _service_links_get_node_title($node, $settings) {
  $title = isset($node->title) ? $node->title : '';
  switch ($settings['title_override']) {
    case SERVICE_LINKS_TAG_TITLE_NODE:
      break;
    case SERVICE_LINKS_TAG_TITLE_OVERRIDE:
      $title = str_replace('<title>', $title, $settings['title_text']);
      break;
    case SERVICE_LINKS_TAG_TITLE_TOKEN:
      $title = token_replace($settings['title_text'], array(
        'node' => $node,
      ));
      break;
  }
  return $title;
}

/**
 * Detect if the node is used as front page and provide
 * the path to use.
 */
function _service_links_get_node_path($node) {
  static $front_page;
  if (!isset($front_page)) {
    $front_page = variable_get('site_frontpage', 'node');
  }
  $path = "node/{$node->nid}";
  if ($path == $front_page || isset($node->uri) && (object) $node->uri['path'] == $front_page) {
    $path = '<front>';
  }
  return $path;
}

/**
 * Check if the service links should be displayed for the content type,
 * for category or one of the other selected options.
 */
function service_links_show($node) {
  $links_show = FALSE;
  $category_type = FALSE;
  global $user;
  if (!_service_links_match_path()) {
    return FALSE;
  }
  if (in_array(strtolower(arg(0)), array(
    'print',
    'printpdf',
    'printmail',
  ))) {
    return FALSE;
  }
  if (variable_get('service_links_hide_for_author', FALSE) && $user->uid == $node->uid) {
    return FALSE;
  }
  if (variable_get('service_links_hide_if_unpublished', FALSE) && $node->status == '0') {
    return FALSE;
  }
  $node_type = in_array($node->type, variable_get('service_links_node_types', array()), TRUE);
  if (module_exists('taxonomy') && !empty($node->field_tags)) {
    $categories_allowed = variable_get('service_links_category_types', array());
    $language = isset($node->field_tags[$node->language]) ? $node->language : 'und';
    foreach ($node->field_tags[$language] as $term) {
      $tid = FALSE;
      if (isset($term['tid'])) {
        $tid = $term['tid'];
      }
      else {
        if (isset($term['target_id'])) {
          $tid = $term['target_id'];
        }
      }
      if ($tid) {
        $category_type |= in_array($tid, $categories_allowed, FALSE);
      }
    }
  }
  if ($node_type || $category_type) {
    $links_show = TRUE;
  }
  return $links_show;
}

/**
 * Match the current path with the list or the code
 * inserted in the configuration page.
 */
function _service_links_match_path() {
  static $page_match;
  if (isset($page_match)) {
    return $page_match;
  }
  $pages = variable_get('service_links_page_match_for_node', '');
  $visibility = variable_get('service_links_visibility_for_node', SERVICE_LINKS_VISIBILITY_NOT_LISTED);
  if (!empty($pages)) {

    // Convert path to lowercase. This allows comparison of the same path
    // with different case. Ex: /Page, /page, /PAGE.
    $pages = drupal_strtolower($pages);
    if ($visibility < SERVICE_LINKS_VISIBILITY_PHP) {
      $path = drupal_strtolower(drupal_get_path_alias($_GET['q']));

      // Compare with the internal and path alias (if any).
      $page_match = drupal_match_path($path, $pages);
      if ($path != $_GET['q']) {
        $page_match = $page_match || drupal_match_path($_GET['q'], $pages);
      }

      // When $visibility has a value of 0, the links are displayed on
      // all pages except those listed in $pages. When set to 1, it
      // is displayed only on those pages listed in $pages.
      $page_match = !($visibility xor $page_match);
    }
    elseif (module_exists('php')) {
      $page_match = php_eval($pages);
    }
    else {
      $page_match = FALSE;
    }
  }
  else {
    $page_match = TRUE;
  }
  return $page_match;
}

/**
 * Load the static settings and keep clear the render function.
 */
function _service_links_load_settings() {
  static $settings = NULL;
  if (!isset($settings)) {
    $settings['short_links_use'] = variable_get('service_links_short_links_use', SERVICE_LINKS_SHORT_URL_USE_NEVER);
    $settings['attributes'] = array(
      'rel' => 'nofollow',
    );
    if (variable_get('service_links_new_window', 0)) {
      $settings['attributes'] += array(
        'target' => '_blank',
      );
    }
    $settings['style'] = variable_get('service_links_style', SERVICE_LINKS_STYLE_TEXT);
    $settings['link_weight'] = variable_get('service_links_weight', array());
    $settings['link_show'] = array_filter(variable_get('service_links_show', array()));
    $settings['text_to_append'] = strip_tags(variable_get('service_links_append_to_url', ''));
    $settings['title_override'] = variable_get('service_links_override_title', SERVICE_LINKS_TAG_TITLE_NODE);
    $settings['title_text'] = variable_get('service_links_override_title_text', '<title>');
    $settings['link_to_front'] = FALSE;
  }
  return $settings;
}

/**
 * Expand the path around a filename depending from the context.
 *
 * @param $filename
 *   If NULL the function return only the path with trailing slash.
 * @param $context
 *   Define what path should consider this function.
 * @param $default
 *   Concerning the image path is useful define a default path if
 *   the alternative is not set up.
 *
 * @return
 *   A string with the full filename or the path.
 */
function service_links_expand_path($filename = NULL, $context = 'icons', $default = 'preset') {
  static $sl_paths;
  static $sl_checkpath;
  if (strpos($filename, '/') !== FALSE) {
    return $filename;
  }
  if (!isset($sl_paths)) {
    $sl_paths['base'] = drupal_get_path('module', 'service_links');
    $sl_paths += array(
      'preset' => $sl_paths['base'] . '/images',
      'javascript' => $sl_paths['base'] . '/js',
      'css' => $sl_paths['base'] . '/css',
    );
    $sl_checkpath = array(
      'preset' => FALSE,
      'javascript' => FALSE,
      'css' => FALSE,
    );
  }
  if (!isset($sl_paths[$context])) {
    $sl_paths[$context] = variable_get("service_links_path_{$context}", '');
    if (empty($sl_paths[$context])) {
      $sl_paths[$context] = $sl_paths[$default];
    }
    $sl_checkpath[$context] = variable_get("service_links_check_{$context}", FALSE);
  }
  if (isset($filename)) {
    if ($sl_checkpath[$context]) {
      if (file_exists($sl_paths[$context] . '/' . $filename)) {
        return $sl_paths[$context] . '/' . $filename;
      }
      else {
        return $sl_paths[$default] . '/' . $filename;
      }
    }
    else {
      return $sl_paths[$context] . '/' . $filename;
    }
  }
  else {
    return $sl_paths[$context];
  }
}

/**
 * Split a query string in the properly array.
 */
function service_links_get_query($query_str) {
  if (empty($query_str)) {
    return NULL;
  }
  $result = array();

  // parse_str() replaces dots and squares with underscores.
  $query_str = explode('&', $query_str);
  foreach ($query_str as $q) {
    $key_value = explode('=', $q);
    $result[$key_value[0]] = isset($key_value[1]) ? $key_value[1] : '';
  }
  return $result;
}

/**
 * Implements hook_views_api().
 */
function service_links_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'service_links'),
  );
}

/**
 * Implements hook_ctools_plugin_directory().
 */
function service_links_ctools_plugin_directory($module, $plugin) {

  // Also Prevent PHP warnings for undefined constants.
  if (defined('PANELS_REQUIRED_CTOOLS_API')) {

    // Safety: go away if CTools is not at an appropriate version.
    if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) {
      return;
    }
    return 'plugins/' . $plugin;
  }
}

Functions

Namesort descending Description
service_links_array_filter Remove a service from the list if the related module is disabled and can't provide the correct values.
service_links_block_configure Implements hook_block_configure().
service_links_block_info Implements hook_block_info().
service_links_block_save Implements hook_block_save().
service_links_block_view Implements hook_block_view().
service_links_ctools_plugin_directory Implements hook_ctools_plugin_directory().
service_links_expand_path Expand the path around a filename depending from the context.
service_links_get_links Discover all available service links by invoking hook_service_links().
service_links_get_query Split a query string in the properly array.
service_links_help Implements hook_help().
service_links_hook_info Implements hook_hook_info().
service_links_menu Implements hook_menu().
service_links_node_view Implements hook_node_view().
service_links_permission Implements hook_permission().
service_links_render Function that render all the selected services.
service_links_render_some This function render only the services requested by their id.
service_links_short_url Create short links using predefined settings.
service_links_show Check if the service links should be displayed for the content type, for category or one of the other selected options.
service_links_theme Implements hook_theme().
service_links_views_api Implements hook_views_api().
_service_links_add_js Load correctly the needed javascripts.
_service_links_get_node_path Detect if the node is used as front page and provide the path to use.
_service_links_get_node_title Return the properly title.
_service_links_get_page_url Return the url for not-node pages.
_service_links_get_tags Fill an array with tags and the content to substitute.
_service_links_link Create an array of links for the link section.
_service_links_load_settings Load the static settings and keep clear the render function.
_service_links_match_path Match the current path with the list or the code inserted in the configuration page.
_service_links_render The common render function used privately.

Constants