You are here

noreferrer.module in No Referrer 8

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

No Referrer module.

File

noreferrer.module
View source
<?php

/**
 * @file
 * No Referrer module.
 */
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;

/**
 * Implements hook_link_alter().
 */
function noreferrer_link_alter(&$variables) {
  $config = \Drupal::config('noreferrer.settings');
  if ($config
    ->get('noopener') && 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'] = [
        $variables['options']['attributes']['rel'],
        'noopener',
      ];
    }
  }
  if (!$config
    ->get('noreferrer') || !$variables['url']
    ->isExternal() || noreferrer_is_whitelisted($variables['url']
    ->toString())) {
    return;
  }
  if (!isset($variables['options']['attributes']['rel']) || is_array($variables['options']['attributes']['rel'])) {
    $variables['options']['attributes']['rel'][] = 'noreferrer';
  }
  else {
    $variables['options']['attributes']['rel'] = [
      $variables['options']['attributes']['rel'],
      'noreferrer',
    ];
  }
}

/**
 * Helper function to determine if a host is in the domain whitelist.
 */
function noreferrer_is_whitelisted($url) {
  if ($whitelist = \Drupal::config('noreferrer.settings')
    ->get('whitelisted_domains')) {
    $domains = explode(' ', $whitelist);
    $host = parse_url($url, PHP_URL_HOST);
    foreach ($domains as $domain) {
      if (!strcasecmp($domain, $host) || strripos($host, '.' . $domain) === strlen($host) - strlen($domain) - 1) {
        return TRUE;
      }
    }
  }
  return FALSE;
}

/**
 * Implements hook_cron().
 */
function noreferrer_cron() {
  if ($url = \Drupal::config('noreferrer.settings')
    ->get('subscribe_url')) {
    noreferrer_subscribe($url);
  }
}

/**
 * Retrieves whitelist from external URL.
 */
function noreferrer_subscribe($url) {
  try {
    $response = \Drupal::httpClient()
      ->get($url);
  } catch (Exception $e) {
    \Drupal::logger('noreferrer')
      ->error('Error received at %url while retrieving domain whitelist: %message.', [
      '%url' => $url,
      '%message' => $e
        ->getMessage(),
    ]);
    return;
  }
  $whitelist = json_decode((string) $response
    ->getBody());
  if (is_array($whitelist)) {
    \Drupal::configFactory()
      ->getEditable('noreferrer.settings')
      ->set('whitelisted_domains', implode(' ', $whitelist))
      ->save();
  }
  else {
    \Drupal::logger('noreferrer')
      ->error('Unable to extract valid data from %url while retrieving domain whitelist.', [
      '%url' => $url,
    ]);
  }
}

/**
 * Implements hook_help().
 */
function noreferrer_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.noreferrer':
      $output[] = [
        '#type' => 'html_tag',
        '#tag' => 'p',
        '#value' => t('No Referrer module allows you to add the <code>rel="noopener"</code> and <code>rel="noreferrer"</code> link types to both links in user-generated content and links generated by code.'),
      ];
      $output[] = [
        '#type' => 'html_tag',
        '#tag' => 'p',
        '#value' => t('To apply the configured link types to user-generated content, simply enable the <em>Add rel="noopener" and/or rel="noreferrer" to links</em> filter on your text formats.'),
      ];
      $output[] = [
        '#type' => 'html_tag',
        '#tag' => 'p',
        0 => Link::fromTextAndUrl(t('Read more about link types.'), Url::fromUri('https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types', [
          'attributes' => [
            'target' => '_blank',
          ],
        ]))
          ->toRenderable(),
      ];
      return $output;
    case 'noreferrer.settings':
      return t('Link types enabled below will be added to links generated by code, such as link fields and menu items, as well as links in user-generated content using the <em>Add rel="noopener" and/or rel="noreferrer" to links</em> filter.');
  }
}

Functions

Namesort descending Description
noreferrer_cron Implements hook_cron().
noreferrer_help Implements hook_help().
noreferrer_is_whitelisted Helper function to determine if a host is in the domain whitelist.
noreferrer_link_alter Implements hook_link_alter().
noreferrer_subscribe Retrieves whitelist from external URL.