You are here

pathfilter.module in Path Filter 5

This filter takes internal Drupal paths in double quotes, written as e.g. "internal:node/99", and replaces them with the appropriate absolute http URL using Drupal's url() function [1]. E.g. for a site located at http://example.com/mysite

"internal:node/99" becomes "http://example.com/mysite/node/99"

Note: Because it uses url(), if a path alias exists, it will be substituted.

[1] http://api.drupal.org/api/4.7/function/url

Credits: @author Ray Zimmerman (drupal.org user "RayZ") @author Tom Kirkpatrick (drupal.org user "mrfelton"), www.kirkdesigns.co.uk

File

pathfilter.module
View source
<?php

/**
 * @file
 * This filter takes internal Drupal paths in double quotes, written as
 * e.g. "internal:node/99", and replaces them with the appropriate absolute
 * http URL using Drupal's url() function [1]. E.g. for a site located at
 * http://example.com/mysite
 *
 *   "internal:node/99" becomes "http://example.com/mysite/node/99"
 *
 * Note: Because it uses url(), if a path alias exists, it will be substituted.
 *
 * [1] http://api.drupal.org/api/4.7/function/url
 *
 * Credits:   
 * @author Ray Zimmerman (drupal.org user "RayZ")
 * @author Tom Kirkpatrick (drupal.org user "mrfelton"), www.kirkdesigns.co.uk
 */

/**
 * Implementation of hook_filter_tips().
 */
function pathfilter_filter_tips($delta, $format, $long = FALSE) {
  switch ($delta) {
    case 0:
      if ($long) {
        $output = '<p>' . t('Internal paths in single or double quotes, written as "internal:node/99", for example, are replaced with the appropriate absolute URL or path. Given a site located at http://example.com/mysite, assuming clean URLs are enabled and "internal:admin/user" becomes "http://example.com/mysite/admin/user" and "internal:node/99" becomes "http://example.com/mysite/node/99". If \'node/99\' has a URL alias assigned, such as \'news/latest\' the alias will be substituted giving "http://example.com/mysite/news/latest".') . '</p>';
        $output .= '<p>' . t('Paths to files in single or double quotes, written as "files:somefile.ext", for example, are replaced with the appropriate URL that can be used to download the file.') . '</p>';
        return $output;
      }
      else {
        return t('Internal paths in single or double quotes, written as "internal:node/99", for example, are replaced with the appropriate absolute URL or path. Paths to files in single or double quotes, written as "files:somefile.ext", for example, are replaced with the appropriate URL that can be used to download the file.');
      }
      break;
  }
}

/**
 * Implementation of hook_filter().
 */
function pathfilter_filter($op, $delta = 0, $format = -1, $text = '') {

  // The "list" operation provides the module an opportunity to declare
  // both how many filters it defines and a human-readable name for each filter.
  // Note that the returned name should be passed through t() for translation.
  if ($op == 'list') {
    return array(
      0 => t('Internal path filter'),
    );
  }

  // All operations besides "list" provide a $delta argument so we know which
  // filter they refer to.
  switch ($delta) {
    case 0:
      switch ($op) {

        // This description is shown in the administrative interface, unlike
        // the filter tips which are shown in the content editing interface.
        case 'description':
          $output = t('Internal paths in single or double quotes, written as "internal:node/99", for example, are replaced with the appropriate absolute URL or path.');
          $output .= t(' Paths to files in single or double quotes, written as "files:somefile.ext", for example, are replaced with the appropriate URL that can be used to download the file.');
          return $output;

        // The actual filtering is performed here. The supplied text should be
        // returned, once any necessary substitutions have taken place.
        case 'process':
          $patterns = array();
          $replacement = array();
          $patterns[] = '/(["\'])(internal):([^"#\\?\']+)\\??([^"#\']+)?#?([^"\']+)?\\1/';
          $patterns[] = '/(["\'])(files):([^"\']+)\\1/';

          // use the 'currying' technique to allow us to pass the format into
          // the callback function.
          $callback = _pathfilter_curry(_pathfilter_process, 2);
          return preg_replace_callback($patterns, $callback($format), $text);

        // Filter settings for pathfilter.
        case 'settings':
          return _pathfilter_settings($format);
        default:
          return $text;
      }
      break;
  }
}

/*
 * A 'currying' function that allows paramaters to be passed into the
 * preg_replace_callback callback. Taken from
 * http://ie2.php.net/manual/en/function.preg-replace-callback.php#88013
 */
function _pathfilter_curry($func, $arity) {
  return create_function('', "\n    \$args = func_get_args();\n    if(count(\$args) >= {$arity})\n      return call_user_func_array('{$func}', \$args);\n    \$args = var_export(\$args, 1);\n    return create_function('','\n      \$a = func_get_args();\n      \$z = ' . \$args . ';\n      \$a = array_merge(\$z,\$a);\n      return call_user_func_array(\\'{$func}\\', \$a);\n    ');\n  ");
}
function _pathfilter_process($format, $matches) {
  switch ($matches[2]) {
    case 'internal':
      return _pathfilter_process_internal($format, $matches);
      break;
    case 'files':
      return _pathfilter_process_files($matches);
  }
}
function _pathfilter_process_internal($format, $matches) {
  $absolute = variable_get('pathfilter_link_absolute_' . $format, 1) ? TRUE : FALSE;
  if (module_exists('i18n')) {
    if (preg_match('/(node\\/([0-9]+))$/', $matches[3], $match)) {

      // if we have a drupal node url, ensure we get the translated url alias
      $language = i18n_node_get_lang($match[2]);
      $path = $language ? i18n_path($match[1], $language) : $match[1];
      $link = url($path, $matches[4], $matches[5], $absolute);
    }
  }
  $link = $link ? $link : url($matches[3], $matches[4], $matches[5], $absolute);
  return $matches[1] . $link . $matches[1];
}
function _pathfilter_process_files($matches) {
  return $matches[1] . file_create_url($matches[3]) . $matches[1];
}

/**
 * Helper settings function for hook_filter('settings').
 */
function _pathfilter_settings($format) {
  $form = array();
  $form['pathfilter'] = array(
    '#type' => 'fieldset',
    '#title' => t('Internal path filter'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
  $form['pathfilter']['pathfilter_link_absolute_' . $format] = array(
    '#type' => 'radios',
    '#title' => t('Convert internal paths to'),
    '#options' => array(
      1 => t('Absolute URL (including http://www.example.com)'),
      0 => t('Absolute path (relative to document root)'),
    ),
    '#default_value' => variable_get('pathfilter_link_absolute_' . $format, 1),
    '#description' => t('Should internal paths be transformed to absolute URLs, such as %absolute_url or absolute paths, like %absolute_path. Note that your changes may not appear until the cache has been cleared.', array(
      '%absolute_url' => 'http://www.example.com/my-page',
      '%absolute_path' => '/my-page',
    )),
  );
  return $form;
}