extlink.module 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. /**
  3. * @file
  4. * External Link module.
  5. */
  6. /**
  7. * Implements hook_help().
  8. */
  9. function extlink_help($path, $arg) {
  10. switch ($path) {
  11. case 'admin/help#extlink':
  12. $output = '';
  13. $output .= '<p>' . t('External Links is used to differentiate between internal and external links. Using jQuery, it will find all external links on a page and add an external icon indicating it will take you offsite or a mail icon for mailto links.') . '</p>';
  14. return $output;
  15. }
  16. }
  17. /**
  18. * Implements hook_menu().
  19. */
  20. function extlink_menu() {
  21. $items = array();
  22. $items['admin/config/user-interface/extlink'] = array(
  23. 'title' => 'External links',
  24. 'description' => 'Alter the display of external links on the site.',
  25. 'page callback' => 'drupal_get_form',
  26. 'page arguments' => array('extlink_admin_settings'),
  27. 'access callback' => 'user_access',
  28. 'access arguments' => array('administer site configuration'),
  29. );
  30. return $items;
  31. }
  32. /**
  33. * Implements hook_page_build().
  34. */
  35. function extlink_page_build() {
  36. $path = drupal_get_path('module', 'extlink');
  37. drupal_add_js($path . '/extlink.js', array('every_page' => TRUE));
  38. drupal_add_js(array(
  39. 'extlink' => array(
  40. 'extTarget' => variable_get('extlink_target', 0),
  41. 'extClass' => variable_get('extlink_class', 'ext'),
  42. 'extLabel' => check_plain(variable_get('extlink_label', t('(link is external)'))),
  43. 'extImgClass' => variable_get('extlink_img_class', 0),
  44. 'extIconPlacement' => variable_get('extlink_icon_placement', 'append'),
  45. 'extSubdomains' => variable_get('extlink_subdomains', 1),
  46. 'extExclude' => variable_get('extlink_exclude', ''),
  47. 'extInclude' => variable_get('extlink_include', ''),
  48. 'extCssExclude' => variable_get('extlink_css_exclude', ''),
  49. 'extCssExplicit' => variable_get('extlink_css_explicit', ''),
  50. 'extAlert' => variable_get('extlink_alert', 0),
  51. 'extAlertText' => variable_get('extlink_alert_text', 'This link will take you to an external web site. We are not responsible for their content.'),
  52. 'mailtoClass' => variable_get('extlink_mailto_class', 'mailto'),
  53. 'mailtoLabel' => check_plain(variable_get('extlink_mailto_label', t('(link sends e-mail)'))),
  54. ),
  55. ), 'setting');
  56. }
  57. /**
  58. * Administrative settings.
  59. */
  60. function extlink_admin_settings() {
  61. $form = array();
  62. $form['extlink_class'] = array(
  63. '#type' => 'checkbox',
  64. '#title' => t('Place an icon next to external links.'),
  65. '#return_value' => 'ext',
  66. '#default_value' => variable_get('extlink_class', 'ext'),
  67. '#description' => t('Places an !icon icon next to external links.',
  68. array(
  69. '!icon' => theme('image',
  70. array(
  71. 'path' => drupal_get_path('module', 'extlink') . '/extlink.png',
  72. 'alt' => t('External Links icon'),
  73. )
  74. ),
  75. )),
  76. );
  77. $form['extlink_mailto_class'] = array(
  78. '#type' => 'checkbox',
  79. '#title' => t('Place an icon next to mailto links.'),
  80. '#return_value' => 'mailto',
  81. '#default_value' => variable_get('extlink_mailto_class', 'mailto'),
  82. '#description' => t('Places an !icon icon next to mailto links.',
  83. array(
  84. '!icon' => theme('image',
  85. array(
  86. 'path' => drupal_get_path('module', 'extlink') . '/mailto.png',
  87. 'alt' => t('Email links icon'),
  88. )
  89. ),
  90. )),
  91. );
  92. $form['extlink_img_class'] = array(
  93. '#type' => 'checkbox',
  94. '#title' => t('Place an icon next to image links.'),
  95. '#return_value' => TRUE,
  96. '#default_value' => variable_get('extlink_img_class', FALSE),
  97. '#description' => t('If checked, images wrapped in an anchor tag will be treated as external links.'),
  98. );
  99. $form['extlink_icon_placement'] = array(
  100. '#type' => 'checkbox',
  101. '#title' => t('Add icon in front of any processed link'),
  102. '#return_value' => 'prepend',
  103. '#default_value' => variable_get('extlink_icon_placement', 'append'),
  104. '#description' => t('If checked, the icon will be placed in front of any external link, otherwise it will be placed behind it.'),
  105. );
  106. $form['extlink_subdomains'] = array(
  107. '#type' => 'checkbox',
  108. '#title' => t('Exclude links with the same primary domain.'),
  109. '#default_value' => variable_get('extlink_subdomains', 1),
  110. '#description' => t("For example, a link from 'www.example.com' to the subdomain of 'my.example.com' would be excluded."),
  111. );
  112. $form['extlink_target'] = array(
  113. '#type' => 'checkbox',
  114. '#title' => t('Open external links in a new window.'),
  115. '#return_value' => '_blank',
  116. '#default_value' => variable_get('extlink_target', 0),
  117. );
  118. $form['extlink_alert'] = array(
  119. '#type' => 'checkbox',
  120. '#title' => t('Display a pop-up warning when any external link is clicked.'),
  121. '#return_value' => '_blank',
  122. '#default_value' => variable_get('extlink_alert', 0),
  123. );
  124. $form['extlink_alert_text'] = array(
  125. '#type' => 'textarea',
  126. '#title' => t('Text to display in the pop-up warning box.'),
  127. '#rows' => 3,
  128. '#default_value' => variable_get('extlink_alert_text', 'This link will take you to an external web site.'),
  129. '#wysiwyg' => FALSE,
  130. '#states' => array(
  131. // Only show this field when user opts to display a pop-up warning.
  132. 'visible' => array(
  133. ':input[name="extlink_alert"]' => array('checked' => TRUE),
  134. ),
  135. ),
  136. );
  137. $patterns = array(
  138. '<code>(example\.com)</code> ' . t('Matches example.com.'),
  139. '<code>(example\.com)|(example\.net)</code> ' . t('Multiple patterns can be strung together by using a pipe. Matches example.com OR example.net.'),
  140. '<code>(links/goto/[0-9]+/[0-9]+)</code> ' . t('Matches links that go through the <a href="http://drupal.org/project/links">Links module</a> redirect.'),
  141. );
  142. $wildcards = array(
  143. '<code>.</code> ' . t('Matches any character.'),
  144. '<code>?</code> ' . t('The previous character or set is optional.'),
  145. '<code>\d</code> ' . t('Matches any digit (0-9).'),
  146. '<code>[a-z]</code> ' . t('Brackets may be used to match a custom set of characters. This matches any alphabetic letter.'),
  147. );
  148. $form['patterns'] = array(
  149. '#tree' => FALSE,
  150. '#type' => 'fieldset',
  151. '#title' => t('Pattern matching'),
  152. '#collapsible' => TRUE,
  153. '#collapsed' => TRUE,
  154. '#description' =>
  155. '<p>' . t('External links uses patterns (regular expressions) to match the "href" property of links.') . '</p>' . t('Here are some common patterns.') .
  156. theme('item_list', array('items' => $patterns)) . t('Common special characters:') .
  157. theme('item_list', array('items' => $wildcards)) . '<p>' . t('All special characters (!characters) must also be escaped with backslashes. Patterns are not case-sensitive. Any <a href="http://www.javascriptkit.com/javatutors/redev2.shtml">pattern supported by JavaScript</a> may be used.', array('!characters' => '<code>^ $ . ? ( ) | * +</code>')) . '</p>',
  158. );
  159. $form['patterns']['extlink_exclude'] = array(
  160. '#type' => 'textfield',
  161. '#title' => t('Exclude links matching the pattern'),
  162. '#maxlength' => NULL,
  163. '#default_value' => variable_get('extlink_exclude', ''),
  164. '#description' => t('Enter a regular expression for links that you wish to exclude from being considered external.'),
  165. );
  166. $form['patterns']['extlink_include'] = array(
  167. '#type' => 'textfield',
  168. '#title' => t('Include links matching the pattern'),
  169. '#maxlength' => NULL,
  170. '#default_value' => variable_get('extlink_include', ''),
  171. '#description' => t('Enter a regular expression for internal links that you wish to be considered external.'),
  172. );
  173. $form['css_matching'] = array(
  174. '#tree' => FALSE,
  175. '#type' => 'fieldset',
  176. '#title' => t('CSS Matching'),
  177. '#collapsible' => TRUE,
  178. '#collapsed' => TRUE,
  179. '#description' =>
  180. '<p>' . t('Use CSS selectors to exclude entirely or only look inside explicitly specified classes and IDs for external links. These will be passed straight to jQuery for matching.') . '</p>',
  181. );
  182. $form['css_matching']['extlink_css_exclude'] = array(
  183. '#type' => 'textarea',
  184. '#title' => t('Exclude links inside these CSS selectors'),
  185. '#maxlength' => NULL,
  186. '#default_value' => variable_get('extlink_css_exclude', ''),
  187. '#description' => t('Enter a comma-separated list of CSS selectors (ie "#block-block-2 .content, ul.menu")'),
  188. );
  189. $form['css_matching']['extlink_css_explicit'] = array(
  190. '#type' => 'textarea',
  191. '#title' => t('Only look for links inside these CSS selectors'),
  192. '#maxlength' => NULL,
  193. '#default_value' => variable_get('extlink_css_explicit', ''),
  194. '#description' => t('Enter a comma-separated list of CSS selectors (ie "#block-block-2 .content, ul.menu")'),
  195. );
  196. return system_settings_form($form);
  197. }
  198. /**
  199. * Validation handler for admin settings form.
  200. */
  201. function extlink_admin_settings_validate($form, &$form_state) {
  202. // Check if the exclude pattern is a valid regular expression.
  203. if ($exclude = $form_state['values']['extlink_exclude']) {
  204. // Testing the regex via replace.
  205. $regexeval = @preg_replace('/' . $exclude . '/', '', 'Lorem ipsum');
  206. // If the regex returns NULL, then throw an error and reset the variable.
  207. if ($regexeval === NULL) {
  208. form_set_error('extlink_exclude', t('Invalid regular expression.'));
  209. variable_set('extlink_exclude', '');
  210. }
  211. }
  212. // Check if the include pattern is a valid regular expression.
  213. if ($include = $form_state['values']['extlink_include']) {
  214. // Testing the regex via replace.
  215. $regexeval = @preg_replace('/' . $include . '/', '', 'Lorem ipsum');
  216. // If the regex returns NULL, then throw an error and reset the variable.
  217. if ($regexeval === NULL) {
  218. form_set_error('extlink_include', t('Invalid regular expression.'));
  219. variable_set('extlink_include', '');
  220. }
  221. }
  222. }