You are here

nofollowlist.module in Nofollow List 7

Same filename and directory in other branches
  1. 8 nofollowlist.module
  2. 5 nofollowlist.module
  3. 6 nofollowlist.module

Provides a nofollowlist filter.

File

nofollowlist.module
View source
<?php

/**
 * @file
 * Provides a nofollowlist filter.
 */

/**
 * Implements hook_menu().
 */
function nofollowlist_menu() {
  $items = array(
    'admin/config/search/nofollowlist' => array(
      'title' => 'Nofollow List settings',
      'page callback' => 'drupal_get_form',
      'page arguments' => array(
        'nofollowlist_admin_settings_form',
      ),
      'access arguments' => array(
        'administer nofollowlist',
      ),
      'type' => MENU_NORMAL_ITEM,
      'file' => 'nofollowlist.admin.inc',
    ),
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function nofollowlist_permission() {
  return array(
    'administer nofollowlist' => array(
      'title' => t('Administer Nofollow List'),
    ),
  );
}

/**
 * Implements hook_preprocess_link().
 */
function nofollowlist_preprocess_link(&$vars, $hook) {
  $url = parse_url($vars['path']);
  $option = variable_get('nofollowlist_option', 'black');
  $hosts = variable_get('nofollowlist_hosts', '');
  $host_list = preg_split('/\\s+/', $hosts);
  if (isset($url['host'])) {
    if (_nofollowlist_is_nofollow($url['host'], $host_list, $option)) {
      $vars['options']['attributes']['rel'] = 'nofollow';
    }
  }
}

/**
 * Implements hook_theme_registry_alter().
 */
function nofollowlist_theme_registry_alter(&$theme_registry) {

  /**
   * Preliminary benchmarks indicate that invoking theme() can slow down the l() function
   * by 20% or more, and that some of the link-heavy Drupal pages spend more
   * than 10% of the total page request time in the l() function.
   *
   * So if 'nofollowlist_everywhere' is disabled
   * - delete 'nofollowlist_preprocess_link' from registry
   */
  if (!variable_get('nofollowlist_everywhere', FALSE)) {
    $functions = $theme_registry['link']['preprocess functions'];
    $key = array_search('nofollowlist_preprocess_link', $functions);
    unset($theme_registry['link']['preprocess functions'][$key]);
  }
}

/**
 * Implements hook_help().
 */
function nofollowlist_help($path, $arg) {
  switch ($path) {
    case 'admin/help#nofollowlist':
      $output = '<p>' . t('This module implements a simple filter to add the nofollow tag to sites that are on your blacklist or to all sites except those on your whitelist.') . '</p>';
      return $output;
  }
}

/**
 * Implements hook_filter_tips()
 *
 * @param int $delta
 *   Used when a module defines more than one filter
 * @param unknown_type $format
 * @param boolean $long
 *   Determines whether the long or the short tip version is displayed
 * @return string
 *   The tip to be displayed
 */
function nofollowlist_filter_tips($delta, $format, $long = FALSE) {
  $output = t('Links to specified hosts will have a rel="nofollow" added to them.');
  return $output;
}

/**
 * Implements hook_filter_info().
 */
function nofollowlist_filter_info() {
  $filters['filter_nofollow'] = array(
    'title' => t('Nofollow list filter'),
    'description' => t('Links to specified hosts will have a rel="nofollow" added to them.'),
    'process callback' => '_nofollowlist_filter_filter_nofollow_process',
    'settings callback' => '_nofollowlist_filter_filter_nofollow_settings',
    'default settings' => array(
      'nofollowlist_use_global_settings' => TRUE,
      'nofollowlist_option' => 'black',
      'nofollowlist_hosts' => '',
    ),
    'tips callback' => 'nofollowlist_filter_tips',
  );
  return $filters;
}

/**
 * Implements hook_filter_FILTER_process().
 */
function _nofollowlist_filter_filter_nofollow_process($text, $filter, $format, $langcode, $cache, $cache_id) {

  // Check global
  if ($filter->settings['nofollowlist_use_global_settings']) {
    $option = variable_get('nofollowlist_option', 'black');
    $hosts = variable_get('nofollowlist_hosts', '');
  }
  else {
    $option = $filter->settings['nofollowlist_option'];
    $hosts = $filter->settings['nofollowlist_hosts'];
  }
  $host_list = preg_split('/\\s+/', $hosts);
  $html_dom = filter_dom_load($text);
  $links = $html_dom
    ->getElementsByTagName('a');
  foreach ($links as $link) {
    $url = parse_url($link
      ->getAttribute('href'));

    // Handle whitelist option.
    if (isset($url['host'])) {
      if (_nofollowlist_is_nofollow($url['host'], $host_list, $option)) {
        $link
          ->setAttribute('rel', 'nofollow');
      }
    }
  }
  $text = filter_dom_serialize($html_dom);
  return $text;
}

/**
 * Implements hook_filter_FILTER_settings().
 */
function _nofollowlist_filter_filter_nofollow_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
  $filter->settings += $defaults;
  $elements = _nofollowlist_settings_form();
  $elements['nofollowlist_option']['#default_value'] = $filter->settings['nofollowlist_option'];
  $elements['nofollowlist_hosts']['#default_value'] = $filter->settings['nofollowlist_hosts'];
  $use_global_settings_id = 'nofollowlist-use-global-settings';
  $states = array(
    'invisible' => array(
      "#{$use_global_settings_id}" => array(
        'checked' => TRUE,
      ),
    ),
  );
  $elements['nofollowlist_option']['#states'] = $states;
  $elements['nofollowlist_hosts']['#states'] = $states;
  $elements['nofollowlist_use_global_settings'] = array(
    '#type' => 'checkbox',
    '#title' => t('Use global settings'),
    '#description' => t('You can change settings !here.', array(
      '!here' => l('here', 'admin/config/search/nofollowlist'),
    )),
    '#default_value' => $filter->settings['nofollowlist_use_global_settings'],
    '#weight' => -99,
    '#attributes' => array(
      'id' => $use_global_settings_id,
    ),
  );
  return $elements;
}
function _nofollowlist_settings_form() {
  $form = array();
  $form['nofollowlist_option'] = array(
    '#type' => 'radios',
    '#title' => t('Hosts list option'),
    '#description' => t('If you choose the whitelist option, be sure to add your own site to the list!'),
    '#options' => array(
      'black' => t('Blacklist: Add rel="nofollow" to links leading to the listed hosts.'),
      'white' => t('Whitelist: Add rel="nofollow" to all links <b>except</b> the listed hosts.'),
    ),
  );
  $form['nofollowlist_hosts'] = array(
    '#type' => 'textarea',
    '#title' => t('Nofollowlist hosts'),
    '#description' => t('Add one host per line. Ex: en.wikipedia.org'),
  );
  return $form;
}
function _nofollowlist_is_nofollow($host, $host_list = array(), $option = 'black') {
  $is_black = $option == 'black' && in_array($host, $host_list);
  $is_white = $option == 'white' && !in_array($host, $host_list);
  return $host && ($is_black || $is_white) ? TRUE : FALSE;
}

Functions