diff --git a/interwiki.info b/interwiki.info index ee1570bf197b61d0f96c40b56b6f7ed2b7b67ef3..b91ad157ff16e922570d565896f17a1262792c10 100644 --- a/interwiki.info +++ b/interwiki.info @@ -1,3 +1,9 @@ -name = interwiki -description = Easily link to wikis and other websites. -core = 6.x +; $Id$ + +name = "Interwiki" +description = "Easily link to wikis and other websites." +package = "Input filters" +core = 7.x +files[] = interwiki.module +files[] = interwiki.install + diff --git a/interwiki.install b/interwiki.install index 8edfffc2e080d8e9e6ffaac300424ec18d538538..8f3c1b0324a7fd5ce7ef61ccf03e2dfaa65e97e5 100644 --- a/interwiki.install +++ b/interwiki.install @@ -1,34 +1,64 @@ t('Base table for interwiki module'), + 'fields' => array( + 'iw_prefix' => array( + 'description' => t('The interwiki prefix'), + 'type' => 'char', + 'length' => '32', + 'not null' => TRUE, + 'default' => '', + ), + 'iw_url' => array( + 'description' => t('The interwiki URL'), + 'type' => 'char', + 'length' => '127', + 'not null' => TRUE, + 'default' => '', + ), + 'iw_local' => array( + 'description' => t('Flag indicating whether this is a local or an external link'), + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + ), + 'iw_rel' => array( + 'description' => t('The interwiki rel field'), + 'type' => 'char', + 'length' => '32', + 'not null' => TRUE, + 'default' => '', + ), + ), + 'unique keys' => array( + 'iw_prefix' => array('iw_prefix') + ), + ); + return $schema; +} function interwiki_install() { - switch ($GLOBALS['db_type']) { - case 'mysqli': - case 'mysql': - $result = db_query(" - CREATE TABLE {interwiki} ( - iw_prefix char(32) NOT NULL default '', - iw_url char(127) NOT NULL default '', - iw_local tinyint(1) NOT NULL default '0', - iw_rel char(32) NOT NULL default '', - UNIQUE KEY iw_prefix (iw_prefix) - ) /*!40100 DEFAULT CHARACTER SET utf8 */;"); - $result = _interwiki_insert('kos', 'http://www.dkosopedia.com/index.php/$1', 0); - $result = _interwiki_insert('w', 'http://en.wikipedia.org/wiki/$1', 0); - $result = _interwiki_insert('dis', 'http://www.sourcewatch.org/index.php?title=$1', 0); - $result = _interwiki_insert('http', 'http:$1', 0); - $result = _interwiki_insert('', '$1', 1); - $result = _interwiki_insert('ebay', 'http://search.ebay.com/$4', 0); - $result = _interwiki_insert('googledef', 'http://www.google.com/search?&q=define%3A$2', 0); - $result = _interwiki_insert('google', 'http://www.google.com/search?q=%22$2%22', 0); - $result = _interwiki_insert('sw', 'http://www.sourcewatch.org/index.php?title=$1', 0); - $result = _interwiki_insert('th', 'http://thesaurus.reference.com/search?q=$3', 0); - $result = _interwiki_insert('archive', 'http://web.archive.org/web/*/http://$1', 0); - $result = _interwiki_insert('whois', 'http://reports.internic.net/cgi/whois?whois_nic=$1&type=domain', 0); - $result = _interwiki_insert('opendir', 'http://search.dmoz.org/cgi-bin/search?search=$2', 0); - $result = _interwiki_insert('technorati', 'http://technorati.com/tag/$2', 0, 'tag'); - break; - } + _interwiki_insert('kos', 'http://www.dkosopedia.com/index.php/$1', 0); + _interwiki_insert('w', 'http://en.wikipedia.org/wiki/$1', 0); + _interwiki_insert('dis', 'http://www.sourcewatch.org/index.php?title=$1', 0); + _interwiki_insert('http', 'http:$1', 0); + _interwiki_insert('', '$1', 1); + _interwiki_insert('ebay', 'http://search.ebay.com/$4', 0); + _interwiki_insert('googledef', 'http://www.google.com/search?&q=define%3A$2', 0); + _interwiki_insert('google', 'http://www.google.com/search?q=%22$2%22', 0); + _interwiki_insert('sw', 'http://www.sourcewatch.org/index.php?title=$1', 0); + _interwiki_insert('th', 'http://thesaurus.reference.com/search?q=$3', 0); + _interwiki_insert('archive', 'http://web.archive.org/web/*/http://$1', 0); + _interwiki_insert('whois', 'http://reports.internic.net/cgi/whois?whois_nic=$1&type=domain', 0); + _interwiki_insert('opendir', 'http://search.dmoz.org/cgi-bin/search?search=$2', 0); + _interwiki_insert('technorati', 'http://technorati.com/tag/$2', 0, 'tag'); } function _interwiki_insert($prefix,$url,$local,$rel='') { @@ -37,10 +67,14 @@ function _interwiki_insert($prefix,$url,$local,$rel='') { function interwiki_uninstall() { db_query('DROP TABLE {interwiki}'); + db_delete('filter') + ->condition('module', 'interwiki') + ->execute(); } function interwiki_update_1() { $ret = array(); $ret[] = update_sql("ALTER TABLE {interwiki} ADD iw_rel char(32) NOT NULL default ''"); return $ret; -} \ No newline at end of file +} +s \ No newline at end of file diff --git a/interwiki.module b/interwiki.module index ca3fc25b720ea67e345845593784d6f0005949ad..544adfc031f46d575df29f7a5bcf84c9f706811e 100644 --- a/interwiki.module +++ b/interwiki.module @@ -8,6 +8,8 @@ * * Upgraded to Drupal 4.7, 5/13/2006 * Updated to Drupal 5.0, 2/03/2007 + * Updated to Drupal 6.0, + * Updated to Drupal 7.0, 1/17/2011 * * This module, when configured, is responsible for translating user-inputted links of the form * '[prefix:some term]' into the form 'some term' @@ -16,141 +18,148 @@ */ /** - * Implementation of hook_help(). + * Implements hook_help(). */ -function interwiki_help($section) { - switch ($section) { - case 'admin/modules#description': - return t('Easily link to wikis and other websites.'); +function interwiki_help($path, $arg) { + switch ($path) { case 'admin/help#interwiki': return t("

This module makes it easy to link to wikis and other websites. Users avoid entering entire URLs, as they would for regular web pages, " . - "and instead use a shorthand similar to the syntax used by %Wikipedia and other %MediaWiki sites, in which \"[prefix:some term]\" creates a hyperlink to the ". + "and instead use a shorthand similar to the syntax used by !Wikipedia and other !MediaWiki sites, in which \"[prefix:some term]\" creates a hyperlink to the ". "\"some term\" article on the website specified by \"prefix.\" It is also possible to use the \"|\" character to create a \"piped link,\" with display text that is ". "different from the search term. For example, \"[w:public transport|public transportation]\" could be translated as a reference to the Wikipedia article on \"public ". "transport\" that displays as \"public transportation.\" In addition to the single bracket syntax, ". - "a double bracket syntax like the one used by %MediaWiki can be chosen from the interwiki configuration in %settings. The double-bracket syntax lets you specify a ". + "a double bracket syntax like the one used by !MediaWiki can be chosen from the interwiki configuration in !settings. The double-bracket syntax lets you specify a ". "\"default prefix\" that is used if no prefix is explicitly specified. For example, a default prefix of \"w\" means that [[some term]] is synonymous with [[w:some term]]. ". "This makes it easier to cut-and-paste text from MediaWiki sites directly into your Drupal site.

\n". - "

Configuration

To use this module, you have to take a few steps:

". - "\n", + "

Configuration

To use this module, you have to take a few steps:

". + "\n", array( - '%Wikipedia' => 'Wikipedia', - '%MediaWiki' => 'MediaWiki', - '%settings' => l(t("administer » filters"), "admin/filters", array(), NULL, NULL, FALSE, TRUE), - '%modules' => l(t("administer » modules"), "admin/modules", array(), NULL, NULL, FALSE, TRUE), - '%access' => l(t("administer » access control"), "admin/access", array(), NULL, NULL, FALSE, TRUE), - '%interwikis' => l(t("administer » interwiki"), "admin/settings/interwiki", array(), NULL, NULL, FALSE, TRUE) + '!Wikipedia' => 'Wikipedia', + '!MediaWiki' => 'MediaWiki', + '!settings' => l(t("administer » filters"), "admin/filters", array('html' => TRUE)), + '!modules' => l(t("administer » modules"), "admin/modules", array('html' => TRUE)), + '!access' => l(t("administer » access control"), "admin/access", array('html' => TRUE)), + '!interwikis' => l(t("administer » interwiki"), "admin/settings/interwiki", array('html' => TRUE)), )) . t("

Included search prefixes

". "

The \"interwiki\" table created via file interwiki.sql comes with a number of records already included that facilitate linking to articles or search results on the following websites:

\n". "\n". - "". - "". - "". - "". - "". - "". - "". - "". - "
PrefixSite
w%w, the online, open source encyclopedia
sw%sw, a wiki-based encyclopedia of lobbyists, PR firms, think tanks and other political advocacy groups
kos%kos, a wiki affiliated with the Daily Kos website
ebay%ebay
google%google, the online search engine
than online %th
archivethe %archive, also known as the Internet Archive, which stores and displays old versions of websites
whois%whois, Internic's search tool for information about who owns a domain name
opendirthe %opendir, a human-edited web search engine
\n". + "w!w, the online, open source encyclopedia". + "sw!sw, a wiki-based encyclopedia of lobbyists, PR firms, think tanks and other political advocacy groups". + "kos!kos, a wiki affiliated with the Daily Kos website". + "ebay!ebay". + "google!google, the online search engine". + "than online !th". + "archivethe !archive, also known as the Internet Archive, which stores and displays old versions of websites". + "whois!whois, Internic's search tool for information about who owns a domain name". + "opendirthe !opendir, a human-edited web search engine\n". "

In addition, it has entries that facilitate linking to URLs in general and to content on your own local site. For example, [http://www.somesite.org|Some Website] ". "produces Some Website, and [:node/5|my fifth posting] produces my fifth posting. If \"http:\" is used as ". - "the prefix, you can use %settings to specify the space character instead of the vertical bar character as the \"URL terminator\" which separates the URL from its display text. ". + "the prefix, you can use !settings to specify the space character instead of the vertical bar character as the \"URL terminator\" which separates the URL from its display text. ". "(This option emulates the syntax used to specify external URLs in Wikipedia articles. If emulating Wikipedia is not important on your site, you'll probably want to use the default vertical bar character.)

", array( - '%w' => l('Wikipedia', 'http://www.wikipedia.org'), - '%sw' => l('SourceWatch', 'http://www.sourcewatch.org'), - '%kos' => l('dKosopedia', 'http://www.dkosopedia.com'), - '%ebay' => l('eBay', 'http://www.ebay.com'), - '%google' => l('Google', 'http://www.google.com'), - '%th' => l('thesaurus', 'http://thesaurus.reference.com'), - '%archive' => l('Wayback Machine', 'http://web.archive.org'), - '%whois' => l('whois', 'http://www.internic.net/whois.html'), - '%opendir' => l('Open Directory project', 'http://search.dmoz.org'), - '%settings' => l(t("administer » filters"), "admin/filters", array(), NULL, NULL, FALSE, TRUE), + '!w' => l('Wikipedia', 'http://www.wikipedia.org'), + '!sw' => l('SourceWatch', 'http://www.sourcewatch.org'), + '!kos' => l('dKosopedia', 'http://www.dkosopedia.com'), + '!ebay' => l('eBay', 'http://www.ebay.com'), + '!google' => l('Google', 'http://www.google.com'), + '!th' => l('thesaurus', 'http://thesaurus.reference.com'), + '!archive' => l('Wayback Machine', 'http://web.archive.org'), + '!whois' => l('whois', 'http://www.internic.net/whois.html'), + '!opendir' => l('Open Directory project', 'http://search.dmoz.org'), + '!settings' => l(t("administer » filters"), "admin/filters", array('html' => TRUE)), )) . - t("

For more information

". - ""); + t("

For more information

". + "" + ); } } /** - * hook_perm: Define user permissions for module interwiki - * - * - access content: User can view the list of available filters - * - administer interwiki: User can edit or add to the list of filters - * - * @note See hook_perm() for a description of parameters and return values. + * Implements hook_permission(). */ -function interwiki_perm() { - return array('administer interwiki'); +function interwiki_permission() { + return array( + 'administer interwiki' => array( + 'title' => t('Administer interwiki'), + 'description' => t('Administration the interwiki table for easy linking to wikis and other external websites.'), + ), + ); } /** * Implementation of hook_menu(). */ - function interwiki_menu() { $items['interwiki'] = array( 'title' => 'Wiki filter prefixes', 'access arguments' => array(TRUE), 'page callback' => 'interwiki_list', - 'type' => MENU_CALLBACK); + 'type' => MENU_NORMAL_ITEM, + ); $items['admin/settings/interwiki'] = array( 'title' => 'Interwiki', 'description' => 'Manage interwiki filters.', 'access arguments' => array('administer interwiki'), - 'page callback' => 'interwiki_admin'); + 'page callback' => 'interwiki_admin', + ); $items['admin/settings/interwiki/list'] = array( 'title' => 'list', 'access arguments' => array('administer interwiki'), 'page callback' => 'interwiki_admin', 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10 ); + 'weight' => -10, + ); $items['admin/settings/interwiki/add'] = array( 'title' => 'add', 'access arguments' => array('administer interwiki'), 'page callback' => 'interwiki_admin', - 'type' => MENU_LOCAL_TASK); + 'type' => MENU_LOCAL_TASK, + ); return $items; } /** - * Return a prefix from the interwiki table. The prefix chosen - * should be something other than "http" or the empty string "". - * Preference is first given to the default prefix for the specified - * format. If no format is specified, preference is given to - * prefixes that have a value of 1 for iw_local, and then to - * the prefix "w" if it exists. (The "w" prefix for Wikipedia is included - * in the standard interwiki table that ships with this module.) + * List interwiki filter prefixes. + * + * @return + * A format id that uses the interwiki filter */ -function _interwiki_sample_prefix($format) { - if ($format) { - $default_prefix = variable_get("interwiki_default_$format", ''); - $prefix = db_result(db_query("SELECT iw_prefix FROM {interwiki} WHERE iw_prefix = '%s'", $default_prefix)); - } - if (!$prefix) { - $prefix = db_result(db_query("SELECT iw_prefix FROM {interwiki} WHERE iw_prefix != 'http' AND iw_prefix != '' AND iw_local = 1")); - } - if (!$prefix) { - $prefix = db_result(db_query("SELECT iw_prefix FROM {interwiki} WHERE iw_prefix = 'w'")); - } - if (!$prefix) { - $prefix = db_result(db_query("SELECT iw_prefix FROM {interwiki} WHERE iw_prefix != '' ORDER BY iw_local DESC")); - } - return $prefix; +function interwiki_fallback_format_id() { + $format_id = db_select('filter') + ->fields('filter') + ->condition('module', 'interwiki') + ->condition('status', 1) + ->execute() + ->fetchField(); + return $format_id; } /** * List interwiki filter prefixes. + * + * @return + * An HTML-formatted list of prefixes and the URLs to which they map. */ function interwiki_list() { - $format = arg(1); - $sample_prefix = _interwiki_sample_prefix($format); - $syntax = variable_get("interwiki_syntax_$format", array('single')); + $format_id = arg(1) ? arg(1) : interwiki_fallback_format_id(); + $sample_prefix = _interwiki_sample_prefix($format_id); + if ($format_id) { + $filters = filter_list_format($format_id); + if (isset($filters['interwiki'])) { + $filter = $filters['interwiki']; + } + } + if (!isset($filter)) { + $filter_info = filter_get_filters(); + $filter = new StdClass; + $filter->module = 'interwiki'; + $filter->settings = $filter_info['interwiki']['default settings']; + } + $syntax = $filter->settings['interwiki_syntax']; if ((array_search('double', $syntax) === FALSE) || !(array_search('single', $syntax) === FALSE)) { $unpiped = t('[prefix:some term]'); $piped = t("[$sample_prefix:public transport|public transportation]"); @@ -158,19 +167,19 @@ function interwiki_list() { $unpiped = t('[[prefix:some term]]'); $piped = t("[[$sample_prefix:public transport|public transportation]]"); } - $trans_result = interwiki_filter('process', 0, $format, $piped); + $trans_result = interwiki_filter($piped, $filter); $output = t("

You can easily link to terms in wikis and various other websites using a simplified markup syntax. For example, \"%unpiped\" creates a hyperlink to the ". - "\"some term\" article on the website specified by \"prefix.\" It is also possible to use the \"|\" character to create a \"piped link,\" with display text that is ". - "different from the search term. For example, \"%piped\" would be translated as a reference to an article about \"public ". - "transport\" that displays as \"%trans.\"

", - array( - '%unpiped' => $unpiped, - '%piped' => $piped, - '%trans' => $trans_result - )); + "\"some term\" article on the website specified by \"prefix.\" It is also possible to use the \"|\" character to create a \"piped link,\" with display text that is ". + "different from the search term. For example, \"%piped\" would be translated as a reference to an article about \"public ". + "transport\" that displays as \"!trans.\"

", + array( + '%unpiped' => $unpiped, + '%piped' => $piped, + '!trans' => $trans_result, + )); $result = db_query("SELECT iw_prefix, iw_url, iw_rel from {interwiki}"); $header = array(t('Prefix'), t('rel'), t('Translates to')); - while ($record = db_fetch_object($result)) { + foreach ($result as $record) { // Strip out $1, $2, $3 and $4 from interwiki tables ... $url = preg_replace(array('/\$1/', '/\$2/', '/\$3/', '/\$4/'), '', $record->iw_url); if ($url == '') { @@ -179,214 +188,130 @@ function interwiki_list() { $rows[] = array ($record->iw_prefix . ":", $record->iw_rel, $url); } $output .= t('Available prefixes are:') . '

'; - $output .= theme('table',$header,$rows); - print theme("page", $output); + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + return $output; } /** - * Implementation of hook_filter(). + * Return a prefix from the interwiki table. + * + * The prefix chosen should be something other than "http" or the empty string "". + * Preference is first given to the default prefix for the specified + * format. If no format is specified, preference is given to + * prefixes that have a value of 1 for iw_local, and then to + * the prefix "w" if it exists. (The "w" prefix for Wikipedia is included + * in the standard interwiki table that ships with this module.) + * + * @param $format_id + * A format ID from which to return the prefix. + * @return + * A valid prefix */ -function interwiki_filter($op, $delta = 0, $format = -1, $text = '') { - switch ($op) { - case 'list': - return array(0 => t('Interwiki filter')); - - case 'description': - return t('Easily link to wikis and other reference websites'); - - case 'process': - $result = db_query("SELECT iw_prefix, iw_url, iw_local, iw_rel from {interwiki}"); - $targets = array(); - while ($record = db_fetch_object($result)) { - $matcha[$record->iw_prefix] = $record->iw_url; - $targets[$record->iw_prefix] = $record->iw_local ? '_self' : '_blank'; - $rels[$record->iw_prefix] = $record->iw_rel; - } - $syntax = variable_get("interwiki_syntax_$format", array('single')); - if (!(array_search('double', $syntax) === FALSE)) { - $pregs[] = '/\[\[([^]:]+)?:([^]]+)?\]\]/i'; - } - if (!(array_search('single', $syntax) === FALSE) || (array_search('double', $syntax) === FALSE)) { - $pregs[] = '/\[([^]:]+)?:([^]]+)?\]/i'; - } - foreach ($pregs as $preg) { - if (preg_match_all($preg, $text, $match)) { - $index = 0; - foreach($match[0] as $pattern_matched) { - if (! ($matcha[$match[1][$index]] == "")) { - // a prefix of 'http' is a special case where the prefix ought to display if no separate display term is specified - if ($match[1][$index] == 'http') { - $display_prefix = $match[1][$index] . ':'; - $url_terminator = (variable_get("interwiki_terminator_$format", 'vert') == 'space') ? ' ' : '|'; - } else { - $display_prefix = ''; - $url_terminator = '|'; - } - $target = $targets[$match[1][$index]]; - $rel = $rels[$match[1][$index]]; - $term = trim($match[2][$index]); - $term_array = explode($url_terminator, $term, 2); - $display_term = $term_array[1] ? $term_array[1] : $display_prefix . $term; - $url_term = $term_array[0]; - // if the prefix is 'http', don't fix ampersands - if (!$display_prefix) { - $display_term = preg_replace('/\&/', '&', $display_term); - $url_term = preg_replace('/\&/', '%26', $url_term); - $url_term = preg_replace('/\&/', '%26', $url_term); - $url_term = preg_replace('/\&/', '%26', $url_term); - } - $display_term = preg_replace("/<[^>]*>/", "", $display_term); // strip out any HTML tags - $url_term1 = preg_replace('/\ /', '_', $url_term); - $url_term2 = preg_replace('/\ /', '+', $url_term); - $url_term3 = preg_replace('/\ /', '%20', $url_term); - $url_term4 = preg_replace('/\ /', '-', $url_term); - $url = preg_replace(array('/\$1/','/\$2/', '/\$3/', '/\$4/'), array($url_term1, $url_term2, $url_term3, $url_term4), $matcha[$match[1][$index]]); - // If it's an external path, don't use the l() function - if (preg_match("/^(http|https|mailto|ftp):/i", $url)) { - $html = ''. $display_term .''; - } else { - $html = l($display_term, $url, array('title' => "reference on $display_term", 'target' => $target)); - } - $text = str_replace($pattern_matched, $html, $text); - } - $index++; - } - } - } +function _interwiki_sample_prefix($format_id = NULL) { + if ($format_id) { + $filters = filter_list_format($format_id); + $filter = $filters['interwiki']; + $prefix = $filter->settings['interwiki_default']; + } + if (!isset($prefix)) { + $prefix = db_query("SELECT iw_prefix FROM {interwiki} WHERE iw_prefix != 'http' AND iw_prefix != '' AND iw_local = 1")->fetchField(); + } + if (!$prefix) { + $prefix = db_query("SELECT iw_prefix FROM {interwiki} WHERE iw_prefix = 'w'")->fetchField(); + } + if (!$prefix) { + $prefix = db_query("SELECT iw_prefix FROM {interwiki} WHERE iw_prefix != '' ORDER BY iw_local DESC")->fetchField(); + } + return $prefix; +} - // Handle the default prefix - if (!(array_search('double', $syntax) === FALSE)) { - $preg = '/\[\[([^]]+)?\]\]/i'; - $match_default = variable_get("interwiki_default_$format", _interwiki_sample_prefix($format)); - if (preg_match_all($preg, $text, $match)) { - $index = 0; - foreach($match[0] as $pattern_matched) { - if (! ($matcha[$match_default] == "")) { - // a prefix of 'http' is a special case where the prefix ought to display if no separate display term is specified - if ($match_default == 'http') { - $display_prefix = $match_default . ':'; - $url_terminator = (variable_get("interwiki_terminator_$format", 'vert') == 'space') ? ' ' : '|'; - } else { - $display_prefix = ''; - $url_terminator = '|'; - } - $target = $targets[$match_default]; - $rel = $rels[$match_default]; - $term = trim($match[1][$index]); - $term_array = explode($url_terminator, $term, 2); - $display_term = $term_array[1] ? $term_array[1] : $display_prefix . $term; - $url_term = $term_array[0]; - // if the prefix is 'http', don't fix ampersands - if (!$display_prefix) { - $display_term = preg_replace('/\&/', '&', $display_term); - $url_term = preg_replace('/\&/', '%26', $url_term); - $url_term = preg_replace('/\&/', '%26', $url_term); - $url_term = preg_replace('/\&/', '%26', $url_term); - } - $url_term1 = preg_replace('/\ /', '_', $url_term); - $url_term2 = preg_replace('/\ /', '+', $url_term); - $url_term3 = preg_replace('/\ /', '%20', $url_term); - $url_term4 = preg_replace('/\ /', '-', $url_term); - $url = preg_replace(array('/\$1/','/\$2/', '/\$3/', '/\$4/'), array($url_term1, $url_term2, $url_term3, $url_term4), $matcha[$match_default]); - // If it's an external path, don't use the l() function - if (preg_match("/^(http|https|mailto|ftp):/i", $url)) { - $html = ''. $display_term .''; - } else { - $html = l($display_term, $url, array('title' => "reference on $display_term", 'target' => $target)); - } - $text = str_replace($pattern_matched, $html, $text); - } - $index++; - } - } +/** + * Route all requests to administer the filters. + * + * @return + * An HTML-formatted page + */ +function interwiki_admin() { + $op = isset($_POST["op"]) ? $_POST["op"] : arg(3); + $edit = $_POST; + $output = ''; + switch ($op) { + case "add": + $output = drupal_get_form('interwiki_edit_form'); + break; + case "edit": + $output = drupal_get_form('interwiki_edit_form', interwiki_get(arg(4))); + break; + case "delete": // the lower-case "d" in "delete" indicates that this came from a URL, so there's no $_POST variable and therefore no $edit + $edit = interwiki_get(arg(4)); + // fall through: + case t("Delete"): // the upper-case "D" indicates that this came from the editing form, so there is a $_POST variable but no arg(3) + if (!isset($edit['confirm'])) { + $output = drupal_get_form('interwiki_delete_confirm_form', $edit); + break; } - - return $text; - - case 'settings': - $form['interwiki'] = array('#type' => 'fieldset', '#title' => t('Interwiki settings'), '#collapsible' => TRUE, '#collapsed' => TRUE); - $sample_prefix = _interwiki_sample_prefix($format); - $syntax = variable_get("interwiki_syntax_$format", array('single')); - if ((array_search('double', $syntax) === FALSE) || !(array_search('single', $syntax) === FALSE)) { - $unpiped = t('[prefix:term]'); - $piped = t("[$sample_prefix:public transport|public transportation]"); - } else { - $unpiped = t('[[prefix:term]]'); - $piped = t("[[$sample_prefix:public transport|public transportation]]"); + else { + $edit['action'] = 'delete'; + // fall through: } - $trans_result = interwiki_filter('process', 0, $format, $piped); - $output = t('The interwiki filter is enabled. You can easily link to terms in various wikis or other websites by typing %unpiped. ' . - 'Use the "|" character to create a "piped link," e.g., "%piped" '. - 'displays as "%trans." '. - 'For a full list of available prefixes and the websites to which they point, see %prefixes.', - array( - '%unpiped' => $unpiped, - '%piped' => $piped, - '%trans' => $trans_result, - '%prefixes' => l('interwiki', "interwiki/$format") - )); - $form[interwiki]['intro'] = array('#type' => 'markup', '#value' => "

$output

"); - - $syntax = array('single' => 'Single brackets, e.g., [prefix:some term]', 'double' => 'Double brackets, e.g., [[prefix:some term]]'); - $form['interwiki']["interwiki_syntax_$format"] = array( '#type' => 'checkboxes', '#title' => t('Syntax'), '#default_value' => variable_get("interwiki_syntax_$format", array('single')), '#options' => $syntax, '#description' => t('Check the boxes above to select the syntax(es) used to specify interwiki links. Single brackets are simpler, but double brackets are closer to the syntax used by MediaWiki, one of the most most popular wiki software packages. (If neither is checked, the filter defaults to single bracket syntax.)') ); - - $form['interwiki']["interwiki_default_$format"] = array( '#type' => 'textfield', '#title' => t('Default prefix'), '#default_value' => variable_get("interwiki_default_$format", _interwiki_sample_prefix($format)), '#size' => 10, '#maxlength' => 30, '#description' => t("The prefix used by default with the double bracket syntax. For example, a default prefix of \"$sample_prefix\" means that [[some term]] is synonymous with [[$sample_prefix:some term]]. (This may be useful if you want to be able to cut-and-paste text from an existing wiki into your site.)") ); - - $terminators = array('space' => t('Space character'), 'vert' => t('Vertical bar (|)')); - $form['interwiki']["interwiki_terminator_$format"] = array( '#type' => 'radios', '#title' => t('URL terminator'), '#default_value' => variable_get("interwiki_terminator_$format", 'vert'), '#options' => $terminators, '#description' => t('The terminator character used to mark the end of a URL. For maximum compatibility with Wikipedia\'s syntax, choose "space." Otherwise, choose the vertical bar character (|).') ); - return $form; + case t("Submit"): + $output = interwiki_save($edit); + // fall through: default: - return $text; + $output .= interwiki_display(); } + return $output; } /** - * Implementation of hook_filter_tips(). + * Display the list of filters for editing purposes. + * + * @return + * An HTML-formatted listing of interwiki prefixes */ -function interwiki_filter_tips($delta, $format, $long = false) { - $syntax = variable_get("interwiki_syntax_$format", array('single')); - $sample_prefix = _interwiki_sample_prefix($format); - if ((array_search('double', $syntax) === FALSE) || !(array_search('single', $syntax) === FALSE)) { - $unpiped = t('[prefix:term]'); - $piped = t("[$sample_prefix:public transport|public transportation]"); - } else { - $unpiped = t('[[prefix:term]]'); - $piped = t("[[$sample_prefix:public transport|public transportation]]"); - } - if ($long) { - return t('Easily link to terms in various wikis or other websites by typing %unpiped. ' . - 'Use the "|" character to create a "piped link," e.g., "%piped" '. - 'displays as "public transportation." '. - 'For a full list of available prefixes and the websites to which they point, see %prefixes.', - array( - '%unpiped' => $unpiped, - '%piped' => $piped, - '%prefixes' => l('interwiki', "interwiki/$format") - )); - } else { - return t('Easily link to terms in various wikis. For help, see %prefixes.', - array( - '%prefixes' => l('interwiki', "interwiki/$format") - )); +function interwiki_display() { + $output = '

' . t("The interwiki table lets website users easily link to terms in wikis and various other websites using a simplified markup syntax. For example, \"[prefix:some term]\" creates a hyperlink to the ". + "\"some term\" article on the website specified by \"prefix.\" Available prefixes and the paths to which they point are:") . '

'; + $result = db_query("SELECT iw_prefix, iw_url, iw_rel, iw_local from {interwiki}"); + $header = array(t('Prefix'), t('rel'), t('Translates to'), t('Local?'), array("data" => t("operations"), "colspan" => 2)); + foreach ($result as $record) { + $rows[] = array ($record->iw_prefix . ":", $record->iw_rel, $record->iw_url, ($record->iw_local ? 'Yes' : 'No'), l(t("edit"), "admin/settings/interwiki/edit/$record->iw_prefix"), l(t("delete"), "admin/settings/interwiki/delete/$record->iw_prefix")); } + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + $output .= '

' . t('The paths in the "translates to" row above use placeholder strings to specify how the space character should be ' . + 'escaped in the URL generated by an interwiki translation. The placeholder strings are $1, $2, $3 and $4. They have the following effect:') . '

'; + $output .= ''; + $output .= '

' . t('Therefore, [w:ad hominem] uses the string "ad_hominem" in building the URL to Wikipedia\'s article on ad hominem arguments, '. + 'while [th:ad hominem] uses the string "ad%20hominem" in building the URL to a thesaurus reference for the phrase ad hominem.') . '

'; + return $output; } /** - * Return a single filter from the database. + * Return a single interwiki record from the database. + * + * @param $iw_prefix + * An interwiki prefix. + * @return + * An interwiki record */ function interwiki_get($iw_prefix) { - return db_fetch_array(db_query("SELECT * FROM {interwiki} WHERE iw_prefix = '%s'", $iw_prefix)); + return db_select('interwiki') + ->fields('interwiki') + ->condition('iw_prefix', $iw_prefix) + ->execute() + ->fetchAssoc(); } /** * Display an editing form for adding or changing an individual filter. * + * @return + * A form array */ -function interwiki_form($edit = array()) { - return drupal_get_form('interwiki_edit_form', $edit); -} - -function interwiki_edit_form($form_state, $edit) { +function interwiki_edit_form($form, &$form_state, $edit = array( 'iw_prefix' => '', 'iw_rel' => '', 'iw_url' => '', 'iw_local' => 1)) { $form["iw_prefix"] = array( '#type' => 'textfield', '#title' => t("Prefix"), @@ -415,7 +340,7 @@ function interwiki_edit_form($form_state, $edit) { '#type' => 'checkbox', '#title' => t("Local?"), '#return_value' => 1, - '#default_value' => $edit["iw_local"], + '#default_value' => (isset($edit["iw_local"]) && $edit["iw_local"]) ? 1 : 0, '#description' => t("Is this link local to your website? Non-local links will open in a new window."), ); $form[] = array( @@ -432,100 +357,275 @@ function interwiki_edit_form($form_state, $edit) { return $form; } - /** * Update, insert or delete a filter from the database. * + * @param $edit + * An array with results from a form submission. */ function interwiki_save($edit) { - db_query("DELETE FROM {interwiki} WHERE iw_prefix = '%s'", $edit["iw_prefix"]); - if ($edit["action"] != 'delete') { - db_query("INSERT INTO {interwiki} (iw_prefix, iw_url, iw_rel, iw_local) VALUES ('%s', '%s', '%s', '%d')", $edit["iw_prefix"], $edit["iw_url"], $edit["iw_rel"], $edit["iw_local"]); + db_delete('interwiki') + ->condition('iw_prefix', $edit["iw_prefix"]) + ->execute(); + if (!isset($edit["action"]) || $edit["action"] != 'delete') { + db_insert('interwiki') + ->fields(array( + 'iw_prefix' => $edit["iw_prefix"], + 'iw_url' => $edit["iw_url"], + 'iw_rel' => $edit["iw_rel"], + 'iw_local' => (isset($edit["iw_local"]) && $edit["iw_local"]) ? 1 : 0, + )) + ->execute(); } } -/**Confirm deletion of filter*/ -function _interwiki_confirm_del($edit) { - return drupal_get_form('interwiki_delete_confirm_form', $edit); -} - - -function interwiki_delete_confirm_form($form_state, $edit) { - +/** + * Confirm deletion of filter + * + * @param $form + * A form. + * @param &$form_state + * A form state. + * @param $edit + * Results of form submission. + * @return + * A confirmation form + */ +function interwiki_delete_confirm_form($form, &$form_state, $edit) { $form['confirm'] = array( '#type' => 'hidden', '#value' => 1, ); $form['iw_prefix'] = array( '#type' => 'hidden', - '#value' => $edit[iw_prefix], + '#value' => $edit['iw_prefix'], ); return confirm_form($form, - t('Are you sure you want to delete the interwiki prefix %name?', array('%name' => $iw_prefix)), + t('Are you sure you want to delete the interwiki prefix %name?', array('%name' => $edit['iw_prefix'])), 'admin/settings/interwiki', t('This action cannot be undone.'), t('Delete'), t('Cancel') ); } /** - * Display the list of filters for editing purposes. - * + * Implementation of hook_filter_info() */ -function interwiki_display() { - $output = '

' . t("The interwiki table lets website users easily link to terms in wikis and various other websites using a simplified markup syntax. For example, \"[prefix:some term]\" creates a hyperlink to the ". - "\"some term\" article on the website specified by \"prefix.\" Available prefixes and the paths to which they point are:") . '

'; - $result = db_query("SELECT iw_prefix, iw_url, iw_rel, iw_local from {interwiki}"); - $header = array(t('Prefix'), t('rel'), t('Translates to'), t('Local?'), array("data" => t("operations"), "colspan" => 2)); - while ($record = db_fetch_object($result)) { - $rows[] = array ($record->iw_prefix . ":", $record->iw_rel, $record->iw_url, ($record->iw_local ? 'Yes' : 'No'), l(t("edit"), "admin/settings/interwiki/edit/$record->iw_prefix"), l(t("delete"), "admin/settings/interwiki/delete/$record->iw_prefix")); - } - $output .= theme('table',$header,$rows); - $output .= '

' . t('The paths in the "translates to" row above use placeholder strings to specify how the space character should be ' . - 'escaped in the URL generated by an interwiki translation. The placeholder strings are $1, $2, $3 and $4. They have the following effect:') . '

'; - $output .= ''; - $output .= '

' . t('Therefore, [w:ad hominem] uses the string "ad_hominem" in building the URL to Wikipedia\'s article on ad hominem arguments, '. - 'while [th:ad hominem] uses the string "ad%20hominem" in building the URL to a thesaurus reference for the phrase ad hominem.') . '

'; - return $output; +function interwiki_filter_info(){ + $filters['interwiki'] = array( + 'title' => t('Interwiki filter'), + 'description' => t('Easily link to wikis and other reference websites.'), + 'process callback' => 'interwiki_filter', + 'settings callback' => 'interwiki_settings', + 'default settings' => array( + 'interwiki_syntax' => array('single'), + 'interwiki_default' => _interwiki_sample_prefix(), + 'interwiki_terminator' => 'vert', + ), + 'tips callback' => 'interwiki_filter_tips', + ); + return $filters; } - + /** - * Route all requests to administer the filters. - * + * Implementation of hook_filter_FILTER_process() + * + * Or, more precisely, the filter's process callback. */ -function interwiki_admin() { - $op = $_POST["op"]; - $edit = $_POST; - if (empty($op)) { - $op = arg(3); +function interwiki_filter($text, $filter) { + $result = db_query("SELECT iw_prefix, iw_url, iw_local, iw_rel from {interwiki}"); + $targets = array(); + foreach ($result as $record) { + $matcha[$record->iw_prefix] = $record->iw_url; + $targets[$record->iw_prefix] = $record->iw_local ? '_self' : '_blank'; + $rels[$record->iw_prefix] = $record->iw_rel; + } + $syntax = $filter->settings['interwiki_syntax']; + if (!(array_search('double', $syntax) === FALSE)) { + $pregs[] = '/\[\[([^]:]+)?:([^]]+)?\]\]/i'; + } + if (!(array_search('single', $syntax) === FALSE) || (array_search('double', $syntax) === FALSE)) { + $pregs[] = '/\[([^]:]+)?:([^]]+)?\]/i'; + } + foreach ($pregs as $preg) { + if (preg_match_all($preg, $text, $match)) { + $index = 0; + foreach($match[0] as $pattern_matched) { + if (! ($matcha[$match[1][$index]] == "")) { + // a prefix of 'http' is a special case where the prefix ought to display if no separate display term is specified + if ($match[1][$index] == 'http') { + $display_prefix = $match[1][$index] . ':'; + $url_terminator = ($filter->settings['interwiki_terminator'] == 'space') ? ' ' : '|'; + } else { + $display_prefix = ''; + $url_terminator = '|'; + } + $target = $targets[$match[1][$index]]; + $rel = $rels[$match[1][$index]]; + $term = trim($match[2][$index]); + $term_array = explode($url_terminator, $term, 2); + $display_term = isset($term_array[1]) ? $term_array[1] : $display_prefix . $term; + $url_term = $term_array[0]; + // if the prefix is 'http', don't fix ampersands + if (!$display_prefix) { + $display_term = preg_replace('/\&/', '&', $display_term); + $url_term = preg_replace('/\&/', '%26', $url_term); + $url_term = preg_replace('/\&/', '%26', $url_term); + $url_term = preg_replace('/\&/', '%26', $url_term); + } + $display_term = preg_replace("/<[^>]*>/", "", $display_term); // strip out any HTML tags + $url_term1 = preg_replace('/\ /', '_', $url_term); + $url_term2 = preg_replace('/\ /', '+', $url_term); + $url_term3 = preg_replace('/\ /', '%20', $url_term); + $url_term4 = preg_replace('/\ /', '-', $url_term); + $url = preg_replace(array('/\$1/','/\$2/', '/\$3/', '/\$4/'), array($url_term1, $url_term2, $url_term3, $url_term4), $matcha[$match[1][$index]]); + // If it's an external path, don't use the l() function + if (preg_match("/^(http|https|mailto|ftp):/i", $url)) { + $html = ''. $display_term .''; + } else { + $html = l($display_term, $url, array('attributes' => array('title' => "reference on $display_term", 'target' => $target))); + } + $text = str_replace($pattern_matched, $html, $text); + } + $index++; + } + } } - switch ($op) { - case "add": - $output = interwiki_form(); - break; - case "edit": - $output = interwiki_form(interwiki_get(arg(4))); - break; - case "delete": // the lower-case "d" in "delete" indicates that this came from a URL, so there's no $_POST variable and therefore no $edit - $edit = interwiki_get(arg(4)); - // fall through: - case t("Delete"): // the upper-case "D" indicates that this came from the editing form, so there is a $_POST variable but no arg(3) - if (!$edit['confirm']) { - $output = _interwiki_confirm_del($edit); - break; - } - else { - $edit['action'] = 'delete'; - // fall through: + // Handle the default prefix + if (!(array_search('double', $syntax) === FALSE)) { + $preg = '/\[\[([^]]+)?\]\]/i'; + $match_default = $filter->settings['interwiki_default']; + if (preg_match_all($preg, $text, $match)) { + $index = 0; + foreach($match[0] as $pattern_matched) { + if (! ($matcha[$match_default] == "")) { + // a prefix of 'http' is a special case where the prefix ought to display if no separate display term is specified + if ($match_default == 'http') { + $display_prefix = $match_default . ':'; + $url_terminator = ($filter->settings['interwiki_terminator'] == 'space') ? ' ' : '|'; + } else { + $display_prefix = ''; + $url_terminator = '|'; + } + $target = $targets[$match_default]; + $rel = $rels[$match_default]; + $term = trim($match[1][$index]); + $term_array = explode($url_terminator, $term, 2); + $display_term = isset($term_array[1]) ? $term_array[1] : $display_prefix . $term; + $url_term = $term_array[0]; + // if the prefix is 'http', don't fix ampersands + if (!$display_prefix) { + $display_term = preg_replace('/\&/', '&', $display_term); + $url_term = preg_replace('/\&/', '%26', $url_term); + $url_term = preg_replace('/\&/', '%26', $url_term); + $url_term = preg_replace('/\&/', '%26', $url_term); + } + $url_term1 = preg_replace('/\ /', '_', $url_term); + $url_term2 = preg_replace('/\ /', '+', $url_term); + $url_term3 = preg_replace('/\ /', '%20', $url_term); + $url_term4 = preg_replace('/\ /', '-', $url_term); + $url = preg_replace(array('/\$1/','/\$2/', '/\$3/', '/\$4/'), array($url_term1, $url_term2, $url_term3, $url_term4), $matcha[$match_default]); + // If it's an external path, don't use the l() function + if (preg_match("/^(http|https|mailto|ftp):/i", $url)) { + $html = ''. $display_term .''; + } else { + $html = l($display_term, $url, array('attributes' => array('title' => "reference on $display_term", 'target' => $target))); + } + $text = str_replace($pattern_matched, $html, $text); + } + $index++; } - case t("Submit"): - $output = interwiki_save($edit); - // fall through: - default: - $output .= interwiki_display(); + } + } + return $text; +} + +/** + * Implementation of hook_filter_SETTINGS_process() + * + * Or, more precisely, the filter's settings callback. + */ +function interwiki_settings($form, &$form_state, $filter, $format, $defaults, $filters) { //$op, $delta = 0, $format = -1, $text = '') { + $filter->settings += $defaults; + $sample_prefix = _interwiki_sample_prefix($format->format); + $syntax = $filter->settings['interwiki_syntax']; + if ((array_search('double', $syntax) === FALSE) || !(array_search('single', $syntax) === FALSE)) { + $unpiped = t('[prefix:term]'); + $piped = t("[$sample_prefix:public transport|public transportation]"); + } else { + $unpiped = t('[[prefix:term]]'); + $piped = t("[[$sample_prefix:public transport|public transportation]]"); } + $trans_result = interwiki_filter($piped, $filter); - print theme('page', $output); + $output = t('The interwiki filter is enabled. You can easily link to terms in various wikis or other websites by typing %unpiped. ' . + 'Use the "|" character to create a "piped link," e.g., "%piped" displays as "%trans." '. + 'For a full list of available prefixes and the websites to which they point, see %prefixes.', + array( + '%unpiped' => $unpiped, + '%piped' => $piped, + '%trans' => $trans_result, + '%prefixes' => l('interwiki', "interwiki/" . $format->format) + ) + ); + $settings['intro'] = array( + '#type' => 'markup', + '#value' => "

$output

", + ); + $syntax = array('single' => 'Single brackets, e.g., [prefix:some term]', 'double' => 'Double brackets, e.g., [[prefix:some term]]'); + $settings["interwiki_syntax"] = array( + '#type' => 'checkboxes', + '#title' => t('Syntax'), + '#default_value' => $filter->settings['interwiki_syntax'], + '#options' => $syntax, + '#description' => t('Check the boxes above to select the syntax(es) used to specify interwiki links. Single brackets are simpler, but double brackets are closer to the syntax used by MediaWiki, one of the most most popular wiki software packages. (If neither is checked, the filter defaults to single bracket syntax.)'), + ); + $settings["interwiki_default"] = array( + '#type' => 'textfield', + '#title' => t('Default prefix'), + '#default_value' => $filter->settings['interwiki_default'], + '#size' => 10, + '#maxlength' => 30, + '#description' => t("The prefix used by default with the double bracket syntax. For example, a default prefix of \"$sample_prefix\" means that [[some term]] is synonymous with [[$sample_prefix:some term]]. (This may be useful if you want to be able to cut-and-paste text from an existing wiki into your site.)"), + ); + $terminators = array('space' => t('Space character'), 'vert' => t('Vertical bar (|)')); + $settings["interwiki_terminator"] = array( + '#type' => 'radios', + '#title' => t('URL terminator'), + '#default_value' => $filter->settings['interwiki_terminator'], + '#options' => $terminators, + '#description' => t('The terminator character used to mark the end of a URL. For maximum compatibility with Wikipedia\'s syntax, choose "space." Otherwise, choose the vertical bar character (|).'), + ); + return $settings; +} + +/** + * Implementation of hook_filter_tips(). + */ +function interwiki_filter_tips($filter, $format, $long) { + $syntax = $filter->settings['interwiki_syntax']; + $sample_prefix = _interwiki_sample_prefix($format->format); + if ((array_search('double', $syntax) === FALSE) || !(array_search('single', $syntax) === FALSE)) { + $unpiped = t('[prefix:term]'); + $piped = t("[$sample_prefix:public transport|public transportation]"); + } else { + $unpiped = t('[[prefix:term]]'); + $piped = t("[[$sample_prefix:public transport|public transportation]]"); + } + if ($long) { + return t('Easily link to terms in various wikis or other websites by typing %unpiped. ' . + 'Use the "|" character to create a "piped link," e.g., "%piped" '. + 'displays as "public transportation." '. + 'For a full list of available prefixes and the websites to which they point, see !prefixes.', + array( + '%unpiped' => $unpiped, + '%piped' => $piped, + '!prefixes' => l('interwiki', "interwiki/" . $format->format) + )); + } else { + return t('Easily link to terms in various wikis. For help, see !prefixes.', + array( + '!prefixes' => l('interwiki', "interwiki/" . $format->format) + )); + } } +