Skip to content

Instantly share code, notes, and snippets.

@boombatower
Created April 13, 2011 15:34
Show Gist options
  • Save boombatower/917763 to your computer and use it in GitHub Desktop.
Save boombatower/917763 to your computer and use it in GitHub Desktop.
commit 52a710098090c132181164544b00b1ba4e02ab9d
Author: Jimmy Berry <[email protected]>
Date: Wed Apr 13 10:30:24 2011 -0500
#945512: Drupal 7 port.
diff --git pathfilter.info pathfilter.info
index 6961d5b..fa9fce6 100644
--- pathfilter.info
+++ pathfilter.info
@@ -1,3 +1,3 @@
name = Path Filter
description = "Input filter to convert internal paths, such as &quot;internal:node/99&quot;, to their corresponding absolute URL or relative path."
-core = 6.x
+core = 7.x
diff --git pathfilter.install pathfilter.install
index 7a26052..4f5ccdb 100644
--- pathfilter.install
+++ pathfilter.install
@@ -9,7 +9,7 @@
*/
/**
- * Implementation of hook_install()
+ * Implements hook_install().
*/
function pathfilter_install() {
$allowed_protocols = _pathfilter_allowed_protocol_helper();
@@ -17,55 +17,30 @@ function pathfilter_install() {
}
/**
- * Implementation of hook_uninstall()
+ * Implements hook_uninstall().
*/
function pathfilter_uninstall() {
// Delete all pathfilter variables
- db_query("DELETE FROM {variable} WHERE name like 'pathfilter_%%'");
-
+ db_delete('variable')
+ ->condition('name', 'pathfilter_%%', 'LIKE')
+ ->execute();
+
// Disable pathfilter from all formats
- db_query("DELETE FROM {filters} WHERE module = '%s'", 'pathfilter');
-
+ db_delete('filter')
+ ->condition('module', 'pathfilter')
+ ->execute();
+
// Remove internal and files from allowed protocols.
$allowed_protocols = array_flip(_pathfilter_allowed_protocol_helper());
unset($allowed_protocols['internal']);
unset($allowed_protocols['files']);
- variable_set('filter_allowed_protocols', array_flip($allowed_protocols));
+ variable_set('filter_allowed_protocols', array_flip($allowed_protocols));
cache_clear_all('variables', 'cache');
watchdog('pathfilter', 'Path filter module removed');
}
/**
- * Fix absolute/relative setting isn't input format-specific
- */
-function pathfilter_update_6101() {
- $ret = array();
- // If old variable is different to default
- // for each input format set new variable only if pathfilter is enabled
- if (variable_get('pathfilter_link_type', 'absolute') != 'absolute') {
- foreach (filter_formats() as $format) {
- $filters = filter_list_format($format->format);
- if (isset($filters['pathfilter/0'])) {
- variable_set('pathfilter_link_absolute_'. $format->format, 0);
- }
- }
- }
- variable_del('pathfilter_link_type');
- return $ret;
-}
-
-/**
- * Add internal and files to allowed protocol variable.
- */
-function pathfilter_update_6200() {
- $ret = array();
- $allowed_protocols = _pathfilter_allowed_protocol_helper();
- variable_set('filter_allowed_protocols', $allowed_protocols);
- return $ret;
-}
-
-/**
* Helper function returns allowed protocols with internal and files added.
*/
function _pathfilter_allowed_protocol_helper() {
diff --git pathfilter.module pathfilter.module
index d4dd79c..3a4e7af 100644
--- pathfilter.module
+++ pathfilter.module
@@ -18,6 +18,8 @@
* @author Tom Kirkpatrick (drupal.org user "mrfelton"), www.kirkdesigns.co.uk
* @author George Montana Harkin (drupal.org user "harking") Auto internalization
* @author Shayne Huddleston ([email protected]) Fix to auto internailze all node fields
+ * @author Brett Lischalk (drupal.org user "blischalk")
+ * @author Jimmy Berry ("boombatower", http://drupal.org/user/214218)
*/
global $_pathfilter_replacement_patterns;
@@ -26,63 +28,45 @@ $_pathfilter_replacement_patterns[] = '/(["\'])(internal):([^"#\?\']*)\??([^"#\'
$_pathfilter_replacement_patterns[] = '/(["\'])(files):([^"\']*)\1/';
/**
- * Implementation of hook_filter_tips().
+ * Implements hook_filter_info().
*/
-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;
- }
+function pathfilter_filter_info() {
+ return array(
+ 'pathfilter' => array(
+ 'title' => t('Converts internal Drupal paths to absolute URL\'s'),
+ 'description' => t('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.'),
+ 'settings callback' => '_pathfilter_settings',
+ 'default settings' => array(
+ 'link_absolute' => TRUE,
+ 'process_all' => TRUE,
+ ),
+ 'process callback' => '_pathfilter_process',
+ 'tips callback' => '_pathfilter_tips',
+ ),
+ );
+ return $filters;
+}
+
+function _pathfilter_process($text, $filter, $format, $langcode, $cache, $cache_id) {
+ $patterns = array();
+ $replacement = array();
+ $patterns[] = '/(["\'])(internal):([^"#\?\']+)\??([^"#\']+)?#?([^"\']+)?\1/';
+ $patterns[] = '/(["\'])(files):([^"\']+)\1/';
+ $func = "_pathfilter_process_handler";
+ // use the 'currying' technique to allow us to pass the format into
+ // the callback function.
+ $callback = _pathfilter_curry($func, 2);
+ return preg_replace_callback($patterns, $callback($filter->settings), $text);
}
/**
- * Implementation of hook_filter().
+ * Filter tips callback function for $filters[0] in hook_filter_info().
*/
-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':
- global $_pathfilter_replacement_patterns;
- // use the 'currying' technique to allow us to pass the format into
- // the callback function.
- $callback = _pathfilter_curry(_pathfilter_process, 3);
- return preg_replace_callback($_pathfilter_replacement_patterns, $callback($format, TRUE), $text);
-
- // Filter settings for pathfilter.
- case 'settings':
- return _pathfilter_settings($format);
-
- default:
- return $text;
- }
- break;
+function pathfilter_filter_tips_0($format, $long = FALSE) {
+ 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;
}
}
@@ -106,19 +90,25 @@ function _pathfilter_curry($func, $arity) {
");
}
-function _pathfilter_process($format, $convert_to_alias = TRUE, $matches) {
+function _pathfilter_process_handler($settings, $matches) {
switch ($matches[2]) {
case 'internal':
- return _pathfilter_process_internal($format, $convert_to_alias, $matches); //Converts to alias form.
+ return _pathfilter_process_internal($settings, $matches); //Converts to alias form.
break;
case 'files':
- return _pathfilter_process_files($format, $matches);
+ return _pathfilter_process_files($settings, $matches);
}
}
-function _pathfilter_process_internal($format, $convert_to_alias, $matches) {
- $absolute = variable_get('pathfilter_link_absolute_'. $format, 1) ? TRUE : FALSE;
+function _pathfilter_process_internal($settings, $matches) {
+ $absolute = $settings['link_absolute'];
+ // Initialize an array to store additional matches to pass into the url function
+ // we can't access array offsets that aren't defined.
+ $url_array = array();
+ if (isset($matches[4])) { $url_array['query'] = $matches[4];}
+ if (isset($matches[5])) { $url_array['fragment'] = $matches[5];}
+ if (isset($absolute)) { $url_array['absolute'] = $absolute;}
// If we are going to convert our output to the aliased version ($convert_to_alias is set to TRUE),
// We need to pass 'alias' => true into url to tell it to not pass our URL through
@@ -135,141 +125,71 @@ function _pathfilter_process_internal($format, $convert_to_alias, $matches) {
if (!empty($nid)) {
$languages = language_list('enabled');
$languages = $languages[1];
- $language = $languages[i18n_node_get_lang($nid)];
- $link = url($matches[3], array(
- 'query' => $matches[4],
- 'fragment' => $matches[5],
- 'absolute' => $absolute,
- 'alias' => !$convert_to_alias,
- 'language' => $language ));
+ if (isset($language)) { $url_array['language'] = $languages[i18n_node_get_lang($match[2])];}
+ $link = url($match[1], $url_array);
}
}
- $link = $link? $link :
- url($matches[3], array(
- 'query' => $matches[4],
- 'fragment' => $matches[5],
- 'absolute' => $absolute,
- 'alias' => !$convert_to_alias ));
+ $link = (isset($link)) ? $link : url($matches[3], $url_array);
return $matches[1] . $link . $matches[1];
}
-function _pathfilter_process_files($format, $matches) {
- $absolute = variable_get('pathfilter_link_absolute_'. $format, 1) ? TRUE : FALSE;
+function _pathfilter_process_files($settings, $matches) {
+ $absolute = $settings['link_absolute'];
$link = file_create_url($matches[3]);
$link = $absolute ? $link : substr($link, strlen($GLOBALS['base_url']));
return $matches[1] . $link . $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(
+function _pathfilter_tips($filter, $format, $long) {
+ 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.');
+ }
+}
+
+function _pathfilter_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
+ $filter->settings += $defaults;
+
+ $elements = array();
+ $elements['link_absolute'] = 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),
+ '#options' => array(
+ t('Absolute URL (including http://www.example.com)'),
+ t('Absolute path (relative to document root)')
+ ),
+ '#default_value' => $filter->settings['link_absolute'],
'#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')),
);
- $form['pathfilter']['pathfilter_process_all'] = array(
+ $elements['process_all'] = array(
'#type' => 'checkbox',
'#title' => t('Enable automatic url processing for attributes.'),
- '#default_value' => variable_get('pathfilter_process_all', 1),
+ '#default_value' => $filter->settings['process_all'],
'#description' => t('When this option is enabled, all %element_list elements will automatically have the servername and base path of their src, href, and action urls replaced with %internal. On editing of these elements, all instances of %internal will be replaced with the site\'s base path (%current_base_path).', array('%element_list' => '<img>, <a>, <script>, <object>, and <form>', '%internal' => '\'internal:\'', '%current_base_path' => base_path())),
);
- return $form;
+ return $elements;
}
/**
- * Modifies submitted node body values. Replaces base_path() in images, hrefs,
- * etc with 'internal:' on save. When editing a node, the body's 'internal:'
- * strings are replaced with 'base_path()'.
- */
-function pathfilter_nodeapi( &$node, $op ) {
- switch ($op) {
- case 'prepare':
- // Convert "internal:" and "files:" back into full URL of site for editing.
- // We convert back into 'node/#' if possible to keep from breaking URLs when an
- // alias changes
- _pathfilter_replace_links($node, '_pathfilter_replace_internal');
- break;
- case 'presave':
- /** We do more when we look for what to replace with 'internal:'
- * - Only want to replace items that are links, not text or data
- * - Check to see if they specified the hostname of the server */
- _pathfilter_replace_links($node, '_pathfilter_internalize');
- break;
- }
-}
-
-
-/**
- * Replaces the links in select node properties (body, teaser, and any
- * textfields that have formatting defined for them)
- *
- * $node : StdClass Object
- * $func_name : String Can be either _pathfilter_internalize or _pathfilter_replace_internal
- * both functions replace links, one is before saving and one is
- * before viewing
- */
-function _pathfilter_replace_links(&$node, $func_name) {
-
- // If we have our pathfilter variable defined let's replace otherwise bail out.
- if (variable_get('pathfilter_process_all', 1)) {
-
- // Let's get all the pathfilters we have defined and their corresponding formats.
- $defined_formats = array();
-
- $result = db_query("SELECT format FROM {filters} WHERE module = 'pathfilter'");
- while ($row = db_fetch_object($result)) {
- $defined_formats[] = $row->format;
- }
-
- // Iterate through our objects properties looking for body, teaser, and any fields that have
- // formatting defined for them.
- foreach ($node as $key => &$value) {
- //if this is the body or teaser lets run our replaces
- if ($key == "body" || $key == "teaser") {
- if (in_array($node->format, $defined_formats)) {
- $func_name($node->format, $value);
- }
- }
- elseif (is_array($value)) {
- // Look at the rest of the fields...if they have a format from our defined formats list
- // and we have a value that is a string run our replace...otherwise ignore them
- if (is_array($value[0]) && !empty($value[0]['format']) && in_array($value[0]['format'], $defined_formats) &&
- !empty($value[0]['value']) && is_string($value[0]['value'])) {
- $func_name($value[0]['format'], $value[0]['value']);
- }
- }
- }
- }
-}
-
-
-/**
* Replaces the internal: and files: in elements with the url for it
*/
-function _pathfilter_replace_internal( $format, &$text ) {
+function _pathfilter_replace_internal($settings, &$text) {
global $_pathfilter_replacement_patterns;
// use the 'currying' technique to allow us to pass the format into
// the callback function.
$callback = _pathfilter_curry(_pathfilter_process, 3);
- $text = preg_replace_callback($_pathfilter_replacement_patterns, $callback($format, FALSE), $text); //Converts to non-aliased form.
+ $text = preg_replace_callback($_pathfilter_replacement_patterns, $callback($settings, FALSE), $text); //Converts to non-aliased form.
}
/**
* Internalizes all urls in a string automatically, doing the user's job for them.
*/
-function _pathfilter_internalize( $format, &$item ) {
+function _pathfilter_internalize($settings, &$item) {
// First we find all of the items that look like they need to be replaced.
$pattern = '/(<img|<a|<script|<object|<form|<param)[^\>]*>/i';
preg_match_all( $pattern, $item, $matches );
@@ -300,14 +220,14 @@ function _pathfilter_internalize( $format, &$item ) {
preg_match('#^node/[0-9]*$#', $tmp_replaced_path, $matches);
if ($matches) {
// add the internal: prefix
- $replaced_path = 'internal:'. $tmp_replaced_path;
- }
+ $replaced_path = 'internal:' . $tmp_replaced_path;
+ }
}
// Update original string with changes, if needed.
if ($replaced_path != $url[3]) {
- $item = preg_replace( '/(src=|href=|action=|data=|value=)(\'|")('. preg_quote($url[3], '/') .')(\'|"|>)/',
- '$1$2'. $replaced_path .'$4',
+ $item = preg_replace( '/(src=|href=|action=|data=|value=)(\'|")(' . preg_quote($url[3], '/') . ')(\'|"|>)/',
+ '$1$2' . $replaced_path . '$4',
$item, 1);
}
}
@@ -327,15 +247,15 @@ function _pathfilter_base_url_re() {
$base_path = base_path();
if ($base_path != '/') {
- $tmp_base_url = str_replace($base_path, '', $base_url .'/');
+ $tmp_base_url = str_replace($base_path, '', $base_url . '/');
}
else {
$tmp_base_url = $base_url;
}
$base_url_re = array(
- 0 => '/^('.preg_quote($tmp_base_url, '/').')?'.preg_quote($base_path, '/').'/',
- 1 => '/^('.preg_quote($tmp_base_url, '/').')?'.preg_quote(drupal_urlencode($base_path), '/').'/',
+ 0 => '/^(' . preg_quote($tmp_base_url, '/') . ')?' . preg_quote($base_path, '/') . '/',
+ 1 => '/^(' . preg_quote($tmp_base_url, '/') . ')?' . preg_quote(drupal_encode_path($base_path), '/') . '/',
);
return $base_url_re;
@@ -354,7 +274,7 @@ function _pathfilter_base_files_url_re() {
//Taken from file_create_url() http://api.drupal.org/api/function/file_create_url
switch (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)) {
case FILE_DOWNLOADS_PUBLIC:
- $files_url = file_directory_path() .'/';
+ $files_url = file_directory_path() . '/';
break;
case FILE_DOWNLOADS_PRIVATE:
$files_url = 'system/files/';
@@ -365,16 +285,16 @@ function _pathfilter_base_files_url_re() {
$base_path = base_path();
if ($base_path != '/') {
- $tmp_base_url = str_replace($base_path, '', $base_url .'/');
+ $tmp_base_url = str_replace($base_path, '', $base_url . '/');
}
else {
$tmp_base_url = $base_url;
}
$base_files_url_re = array(
- 0 => '/^('.preg_quote($tmp_base_url, '/').')?'.preg_quote($base_path.$files_url, '/').'/',
- 1 => '/^('.preg_quote($tmp_base_url, '/').')?'.preg_quote(drupal_urlencode($base_path.$files_url), '/').'/',
+ 0 => '/^(' . preg_quote($tmp_base_url, '/') . ')?' . preg_quote($base_path . $files_url, '/') . '/',
+ 1 => '/^(' . preg_quote($tmp_base_url, '/') . ')?' . preg_quote(drupal_encode_path($base_path . $files_url), '/') . '/',
);
-
+
return $base_files_url_re;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment