You are here

noreferrer.module in No Referrer 7

Same filename and directory in other branches
  1. 8 noreferrer.module

No Referrer module.

File

noreferrer.module
View source
<?php

/**
 * @file
 * No Referrer module.
 */

/**
 * Implements hook_menu().
 */
function noreferrer_menu() {
  $items['admin/config/content/noreferrer'] = array(
    'title' => 'Link types',
    'description' => 'Configure <code>rel="noopener"</code> and <code>rel="noreferrer"</code> link types.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'noreferrer_admin',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'noreferrer.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_cron().
 */
function noreferrer_cron() {
  if ($url = variable_get('noreferrer_subscribe_url', '')) {
    module_load_include('admin.inc', 'noreferrer');
    noreferrer_subscribe($url);
  }
}

/**
 * As an optimization for the l() function, only define if enabled.
 */
if (variable_get('noreferrer_link', TRUE)) {

  /**
   * Implements hook_preprocess_link().
   */
  function noreferrer_preprocess_link(&$variables) {
    if (variable_get('noreferrer_noopener', TRUE) && isset($variables['options']['attributes']['target']) && $variables['options']['attributes']['target'] !== '') {
      if (!isset($variables['options']['attributes']['rel']) || is_array($variables['options']['attributes']['rel'])) {
        $variables['options']['attributes']['rel'][] = 'noopener';
      }
      else {
        $variables['options']['attributes']['rel'] = array(
          $variables['options']['attributes']['rel'],
          'noopener',
        );
      }
    }
    if (!variable_get('noreferrer_noreferrer', TRUE) || !url_is_external($variables['path']) || noreferrer_is_whitelisted($variables['path'])) {
      return;
    }
    if (!isset($variables['options']['attributes']['rel']) || is_array($variables['options']['attributes']['rel'])) {
      $variables['options']['attributes']['rel'][] = 'noreferrer';
    }
    else {
      $variables['options']['attributes']['rel'] = array(
        $variables['options']['attributes']['rel'],
        'noreferrer',
      );
    }
  }
}

/**
 * Helper function to determine if a host is in the domain whitelist.
 */
function noreferrer_is_whitelisted($url) {
  if ($whitelist = variable_get('noreferrer_whitelisted_domains', '')) {
    $whitelist = explode(' ', $whitelist);
    $host = parse_url($url, PHP_URL_HOST);
    foreach ($whitelist as $domain) {
      if (!strcasecmp($domain, $host) || strripos($host, '.' . $domain) === strlen($host) - strlen($domain) - 1) {
        return TRUE;
      }
    }
  }
  return FALSE;
}

/**
 * Implements hook_filter_info().
 */
function noreferrer_filter_info() {
  $filters['noreferrer'] = array(
    'title' => t('Add <code>rel="noopener"</code> and/or <code>rel="noreferrer"</code> to links'),
    'process callback' => 'noreferrer_filter_process',
    'weight' => 10,
  );
  return $filters;
}

/**
 * Filter process callback.
 */
function noreferrer_filter_process($text, $filter) {
  $modified = FALSE;
  $html_dom = filter_dom_load($text);
  $links = $html_dom
    ->getElementsByTagName('a');
  $noopener = variable_get('noreferrer_noopener', TRUE);
  $noreferrer = variable_get('noreferrer_noreferrer', TRUE);
  foreach ($links as $link) {
    $types = [];
    if ($noopener && $link
      ->getAttribute('target') !== '') {
      $types[] = 'noopener';
    }
    if ($noreferrer && ($href = $link
      ->getAttribute('href')) && url_is_external($href) && !noreferrer_is_whitelisted($href)) {
      $types[] = 'noreferrer';
    }
    if ($types) {
      $rel = $link
        ->getAttribute('rel');
      foreach ($types as $type) {
        $rel .= $rel ? " {$type}" : $type;
      }
      $link
        ->setAttribute('rel', $rel);
      $modified = TRUE;
    }
  }
  return $modified ? filter_dom_serialize($html_dom) : $text;
}

Functions

Namesort descending Description
noreferrer_cron Implements hook_cron().
noreferrer_filter_info Implements hook_filter_info().
noreferrer_filter_process Filter process callback.
noreferrer_is_whitelisted Helper function to determine if a host is in the domain whitelist.
noreferrer_menu Implements hook_menu().