advanced_mail_reroute.module 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. <?php
  2. /**
  3. * @file
  4. * Reroute E-mails based on specific rules.
  5. */
  6. //=============================================================================
  7. // Constant Initalization
  8. //=============================================================================
  9. define('ADVANCED_MAIL_REROUTE_ALLOW', 0);
  10. define('ADVANCED_MAIL_REROUTE_BLOCK', 1);
  11. define('ADVANCED_MAIL_REROUTE_REROUTE', 2);
  12. define('ADVANCED_MAIL_REROUTE_OVERRIDE_DISABLED', 3);
  13. define('ADVANCED_MAIL_REROUTE_DEFAULT_RULE', 'Allow');
  14. //=============================================================================
  15. // Hook Implementations
  16. //=============================================================================
  17. /**
  18. * Implementation of hook_menu()
  19. */
  20. function advanced_mail_reroute_menu() {
  21. $items = array();
  22. $items['admin/config/advanced_mail_reroute_rules'] = array(
  23. 'title' => 'Advanced mail reroute rules',
  24. 'description' => t('Configure which mail will be allowed through, blocked or rerouted'),
  25. 'page callback' => 'drupal_get_form',
  26. 'page arguments' => array('advanced_mail_reroute_settings_form'),
  27. 'access arguments' => array('administer advanced mail reroute')
  28. );
  29. $items['admin/reports/advanced_mail_reroute_log'] = array(
  30. 'title' => 'Advanced mail reroute log',
  31. 'description' => t('View which mail was allowed through, blocked or rerouted'),
  32. 'page callback' => 'advanced_mail_reroute_log',
  33. 'access arguments' => array('administer site configuration'),
  34. );
  35. return $items;
  36. }
  37. /**
  38. * Implementation of hook_help()
  39. */
  40. function advanced_mail_reroute_help($section='') {
  41. $output = '';
  42. switch ($section) {
  43. case "admin/help#advanced_mail_reroute":
  44. $output = '<p>'. t("Used to reroute all mail or specific mail based on their mail id.") .'</p>';
  45. break;
  46. }
  47. return $output;
  48. }
  49. /**
  50. * Implementation of hook_theme
  51. */
  52. function advanced_mail_reroute_theme($existing, $type, $theme, $path) {
  53. return array(
  54. 'advanced_mail_reroute_table' => array(
  55. 'arguments' => array('element' => NULL),
  56. )
  57. );
  58. }
  59. /**
  60. * Implementation of hook_perm()
  61. */
  62. function advanced_mail_reroute_perm() {
  63. return array('administer advanced mail reroute');
  64. }
  65. /**
  66. * Implementation of hook_elements()
  67. */
  68. function advanced_mail_reroute_elements() {
  69. return array(
  70. 'advanced_mail_reroute_table' => array(
  71. '#input' => TRUE,
  72. '#process' => array('advanced_mail_reroute_table_process'),
  73. '#element_validate' => array('advanced_mail_reroute_table_validate')
  74. )
  75. );
  76. }
  77. /**
  78. * Implementation of hook_mail_alter()
  79. */
  80. function advanced_mail_reroute_mail_alter(&$message) {
  81. $num_rows = db_result(db_query("SELECT COUNT(*) FROM {advanced_mail_reroute_rules} WHERE mailkey='%s'", $message['id']));
  82. // fetch or create new rule
  83. if ($num_rows > 0) {
  84. $result = db_query("SELECT reroute_rule, email FROM {advanced_mail_reroute_rules} WHERE mailkey='%s'", $message['id']);
  85. $rule = db_fetch_array($result);
  86. }
  87. else {
  88. $rule = array(
  89. 'reroute_rule' => variable_get('advanced_mail_reroute_default_rule', ADVANCED_MAIL_REROUTE_ALLOW),
  90. 'email' => ''
  91. );
  92. db_query("INSERT INTO {advanced_mail_reroute_rules} (mailkey, reroute_rule, email) VALUES ('%s', %d, '')", $message['id'], $rule['reroute_rule']);
  93. }
  94. // apply override rule
  95. $reroute_override_rule = variable_get('advanced_mail_reroute_override', ADVANCED_MAIL_REROUTE_OVERRIDE_DISABLED);
  96. if ($reroute_override_rule != ADVANCED_MAIL_REROUTE_OVERRIDE_DISABLED) {
  97. $rule['reroute_rule'] = $reroute_override_rule;
  98. if ($rule['reroute_rule'] == ADVANCED_MAIL_REROUTE_REROUTE) {
  99. $rule['email'] = variable_get('advanced_mail_reroute_primary_email', variable_get('site_mail', NULL));
  100. }
  101. }
  102. else if ($rule['reroute_rule'] == ADVANCED_MAIL_REROUTE_REROUTE && empty($rule['email'])) {
  103. $rule['email'] = variable_get('advanced_mail_reroute_primary_email', variable_get('site_mail', NULL));
  104. }
  105. // log message
  106. if (variable_get('advanced_mail_reroute_log_enabled', TRUE)) {
  107. _advanced_mail_reroute_log($message['id'], $message['from'], $message['to'], $rule['reroute_rule'], $rule['email']);
  108. }
  109. // perform action
  110. switch ($rule['reroute_rule']) {
  111. case ADVANCED_MAIL_REROUTE_ALLOW:
  112. break;
  113. case ADVANCED_MAIL_REROUTE_BLOCK:
  114. $message['to'] = NULL;
  115. // Remove warning about Drupal being unable to send email.
  116. $warnings = drupal_get_messages('warning');
  117. foreach($warnings['warning'] as $warning) {
  118. if($error != 'Unable to send e-mail') {
  119. drupal_set_message($warning, 'warning');
  120. }
  121. }
  122. break;
  123. case ADVANCED_MAIL_REROUTE_REROUTE:
  124. _advanced_mail_reroute_reroute($message, $rule['email']);
  125. break;
  126. }
  127. }
  128. //=============================================================================
  129. // Callback Functions
  130. //=============================================================================
  131. function advanced_mail_reroute_settings_form() {
  132. drupal_add_js(drupal_get_path('module', 'advanced_mail_reroute') .'/advanced_mail_reroute.js');
  133. $override_value_to_index = array(
  134. ADVANCED_MAIL_REROUTE_OVERRIDE_DISABLED => 0,
  135. ADVANCED_MAIL_REROUTE_ALLOW => 1,
  136. ADVANCED_MAIL_REROUTE_BLOCK => 2,
  137. ADVANCED_MAIL_REROUTE_REROUTE => 3
  138. );
  139. $override_value = variable_get('advanced_mail_reroute_override', ADVANCED_MAIL_REROUTE_OVERRIDE_DISABLED);
  140. $form['#tree'] = TRUE;
  141. $form['main_settings'] = array(
  142. '#type' => 'fieldset',
  143. '#title' => t('Main settings'),
  144. '#collapsible' => TRUE
  145. );
  146. $form['main_settings']['override'] = array(
  147. '#type' => 'select',
  148. '#title' => t('Override rule'),
  149. '#options' => array(t('- Disabled -'), t('Allow all emails through'), t('Block all emails'), t('Redirect all emails to primary email address')),
  150. '#default_value' => $override_value_to_index[$override_value],
  151. '#description' => t('This will override any settings in the Mailkey rules table')
  152. );
  153. $form['main_settings']['primary_email'] = array(
  154. '#type' => 'textfield',
  155. '#title' => t('Primary E-mail'),
  156. '#default_value' => variable_get('advanced_mail_reroute_primary_email', variable_get('site_mail', '')),
  157. '#description' => t('By default all E-mails will be sent to this address'),
  158. );
  159. $form['main_settings']['enable_logging'] = array(
  160. '#type' => 'checkbox',
  161. '#title' => t('Enable logging'),
  162. '#default_value' => variable_get('advanced_mail_reroute_enable_logging', TRUE),
  163. );
  164. $mailkey_rules_description = t('This table is automatically updated as new mailkeys are discovered.');
  165. if (variable_get('advanced_mail_reroute_override', ADVANCED_MAIL_REROUTE_OVERRIDE_DISABLED) != ADVANCED_MAIL_REROUTE_OVERRIDE_DISABLED) {
  166. $mailkey_rules_description .= ' <div style="color: red; display: block;">'. t('Override is currently enabled. All rules below will be ignored.') .'</div>';
  167. }
  168. $form['mailkey_rules'] = array(
  169. '#type' => 'fieldset',
  170. '#title' => t('Reroute rules'),
  171. '#collapsible' => TRUE,
  172. '#description' => $mailkey_rules_description,
  173. );
  174. $form['mailkey_rules']['default_rule'] = array(
  175. '#type' => 'select',
  176. '#title' => t('Default rule for new mailkeys'),
  177. '#options' => array('Allow', 'Block', 'Reroute'),
  178. '#default_value' => variable_get('advanced_mail_reroute_default_rule', ADVANCED_MAIL_REROUTE_DEFAULT_RULE),
  179. );
  180. $form['mailkey_rules']['table'] = array(
  181. '#type' => 'advanced_mail_reroute_table'
  182. );
  183. $form['new_rule'] = array(
  184. '#type' => 'fieldset',
  185. '#title' => t('New rule'),
  186. '#collapsible' => TRUE,
  187. '#collapsed' => TRUE
  188. );
  189. $form['new_rule']['mailkey'] = array(
  190. '#type' => 'textfield',
  191. '#title' => t('Mailkey')
  192. );
  193. $form['new_rule']['rule'] = array(
  194. '#type' => 'select',
  195. '#title' => t('Rule'),
  196. '#options' => array('Allow', 'Block', 'Reroute'),
  197. '#default_value' => variable_get('advanced_mail_reroute_default_rule', ADVANCED_MAIL_REROUTE_DEFAULT_RULE),
  198. '#attributes' => array('class' => 'advanced-mail-reroute-rule')
  199. );
  200. $form['new_rule']['email'] = array(
  201. '#type' => 'textfield',
  202. '#title' => t('E-mail'),
  203. '#description' => t("When reroute is selected you may enter an optional email if"),
  204. '#attributes' => array('class' => 'advanced-mail-reroute-email')
  205. );
  206. $form['submit'] = array(
  207. '#type' => 'submit',
  208. '#value' => t('Save'),
  209. );
  210. return $form;
  211. }
  212. function advanced_mail_reroute_settings_form_validate($form_id, $form_values) {
  213. if (!valid_email_address($form_values['values']['main_settings']['primary_email'])) {
  214. form_set_error('main_settings][primary_email', t('Invalid email entered for primary email'));
  215. }
  216. $new_rule = $form_values['values']['new_rule'];
  217. if (!empty($new_rule['mailkey']) && $new_rule['rule'] == ADVANCED_MAIL_REROUTE_REROUTE &&
  218. !empty($new_rule['email']) && !valid_email_address($new_rule['email'])) {
  219. form_set_error('new_rule][email', t('Invalid email entered for new mailkey rule'));
  220. }
  221. }
  222. function advanced_mail_reroute_settings_form_submit($form_id, $form_state) {
  223. $override_index_to_value = array(
  224. 0 => ADVANCED_MAIL_REROUTE_OVERRIDE_DISABLED,
  225. 1 => ADVANCED_MAIL_REROUTE_ALLOW,
  226. 2 => ADVANCED_MAIL_REROUTE_BLOCK,
  227. 3 => ADVANCED_MAIL_REROUTE_REROUTE
  228. );
  229. $override_index = $form_state['values']['main_settings']['override'];
  230. variable_set('advanced_mail_reroute_override', $override_index_to_value[$override_index]);
  231. variable_set('advanced_mail_reroute_primary_email', $form_state['values']['main_settings']['primary_email']);
  232. variable_set('advanced_mail_reroute_enable_logging', $form_state['values']['main_settings']['enable_logging']);
  233. variable_set('advanced_mail_reroute_default_rule', $form_state['values']['mailkey_rules']['default_rule']);
  234. $new_rule = $form_state['values']['new_rule'];
  235. if (!empty($new_rule['mailkey'])) {
  236. $email = ($new_rule['rule'] == ADVANCED_MAIL_REROUTE_REROUTE ? $new_rule['email'] : '');
  237. db_query("INSERT INTO {advanced_mail_reroute_rules} (mailkey, reroute_rule, email) VALUES ('%s', %d, '%s')",
  238. $new_rule['mailkey'], $new_rule['rule'], $new_rule['email']);
  239. }
  240. $table = $form_state['values']['mailkey_rules']['table']['mailkeys'];
  241. if (!empty($table)) {
  242. foreach ($table as $key => $value) {
  243. if ($value['remove']) {
  244. db_query("DELETE FROM {advanced_mail_reroute_rules} WHERE mailkey ='%s'", $value['mailkey']);
  245. }
  246. else {
  247. $email = ($value['rule'] == ADVANCED_MAIL_REROUTE_REROUTE ? $value['email'] : '');
  248. db_query("UPDATE {advanced_mail_reroute_rules} SET reroute_rule = %d, email = '%s' WHERE mailkey = '%s'", $value['rule'], $email, $value['mailkey']);
  249. }
  250. }
  251. }
  252. }
  253. function advanced_mail_reroute_table_process($element, $form_state) {
  254. $result = db_query('SELECT mailkey, reroute_rule, email FROM {advanced_mail_reroute_rules}');
  255. while ($row = db_fetch_object($result)) {
  256. $element['mailkeys']['M'. $row->mailkey] = array( // prefix with 'M' so mailkeys which begin with a '#' won't get discarded in the theme function
  257. 'mailkey' => array(
  258. '#type' => 'hidden',
  259. '#value' => $row->mailkey,
  260. ),
  261. 'rule' => array(
  262. '#type' => 'select',
  263. '#options' => array('Allow', 'Block', 'Reroute'),
  264. '#default_value' => $row->reroute_rule,
  265. '#attributes' => array('class' => 'advanced-mail-reroute-rule')
  266. ),
  267. 'email' => array(
  268. '#type' => 'textfield',
  269. '#default_value' => $row->email,
  270. '#size' => 25,
  271. '#attributes' => array('class' => 'advanced-mail-reroute-email')
  272. ),
  273. 'remove' => array(
  274. '#type' => 'checkbox',
  275. '#default_value' => 0
  276. )
  277. );
  278. }
  279. return $element;
  280. }
  281. function advanced_mail_reroute_table_validate($element, $form_state) {
  282. if (!empty($form_state['values']['new_rule']['mailkey'])) {
  283. $num_rows = db_result(db_query("SELECT COUNT(*) FROM {advanced_mail_reroute_rules} WHERE mailkey='%s'", $form_state['values']['new_rule']['mailkey']));
  284. if ($num_rows > 0) {
  285. form_set_error('new_rule][mailkey', t('Mailkey for new rule already exists'));
  286. }
  287. }
  288. if (!empty($form_state['values']['mailkey_rules']['table']['mailkeys'])) {
  289. foreach ($form_state['values']['mailkey_rules']['table']['mailkeys'] as $key => $value) {
  290. if ($value['rule'] == ADVANCED_MAIL_REROUTE_REROUTE &&
  291. !empty($value['email']) &&
  292. !$value['remove'] &&
  293. !valid_email_address($value['email'])) {
  294. form_set_error($key, t("Invalid email entered for mailkey rule '". substr($key, 1) ."'"));
  295. }
  296. }
  297. }
  298. }
  299. function theme_advanced_mail_reroute_table($element) {
  300. if (isset($element['mailkeys'])) {
  301. foreach ($element['mailkeys'] as $mailkey => $row) {
  302. if ($mailkey[0] == 'M') { // drupal inserts a lot of other stuff beginning with '#' so we want to skip past that.
  303. $rows[] = array(
  304. $row['mailkey']['#value'],
  305. theme('select', $row['rule']),
  306. theme('textfield', $row['email']),
  307. theme('checkbox', $row['remove'])
  308. );
  309. }
  310. }
  311. }
  312. if (!isset($rows)) {
  313. $rows[] = array(array('data' => t('No rules available.'), 'colspan' => 5));
  314. }
  315. $header = array(t('Mailkey'), t('Rule'), t('E-mail'), t('Remove'));
  316. $output = theme('table', $header, $rows);
  317. return $output;
  318. }
  319. /*
  320. function advanced_mail_reroute_log() {
  321. $actions = array('Allowed', 'Blocked', 'Rerouted');
  322. $header = array(
  323. array('data' => t('Time'), 'field' => 'timestamp', 'sort' => 'desc'),
  324. array('data' => t('Mailkey'), 'field' => 'mailkey'),
  325. array('data' => t('From'), 'field' => 'from_email'),
  326. array('data' => t('To'), 'field' => 'to_email'),
  327. array('data' => t('Action'), 'field' => 'reroute_rule')
  328. );
  329. $result = pager_query("SELECT timestamp, mailkey, from_email, to_email, reroute_rule, reroute_email FROM {advanced_mail_reroute_log}"
  330. . tablesort_sql($header), 30, 0, "SELECT COUNT(id) FROM {advanced_mail_reroute_log}");
  331. while ($row = db_fetch_object($result)) {
  332. $action_taken = $actions[$row->reroute_rule];
  333. if ($row->reroute_rule == ADVANCED_MAIL_REROUTE_REROUTE) {
  334. $action_taken .= ' to '. $row->reroute_email;
  335. }
  336. $rows[] = array(date('Y-m-d H:i:s', $row->timestamp), $row->mailkey, $row->from_email, $row->to_email, $action_taken);
  337. }
  338. if (!$rows) {
  339. $rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 5));
  340. }
  341. $content = theme('table', $header, $rows);
  342. $content .= theme('pager', NULL, 30, 0);
  343. return $content;
  344. }*/
  345. function advanced_mail_reroute_log() {
  346. //if ($node = node_load(arg(1))) {
  347. $header = array(
  348. array('data' => t('Time'), 'field' => 'timestamp', 'sort' => 'desc'),
  349. array('data' => t('Mailkey'), 'field' => 'mailkey'),
  350. array('data' => t('From'), 'field' => 'from_email'),
  351. array('data' => t('To'), 'field' => 'to_email'),
  352. array('data' => t('Action'), 'field' => 'reroute_rule')
  353. );
  354. $query = db_select('advanced_mail_reroute_log', 'amr', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
  355. $query
  356. ->fields('amr', array('timestamp', 'mailkey', 'from_email', 'to_email', 'reroute_rule', 'reroute_email'))
  357. ->limit(30)
  358. ->orderByHeader($header);
  359. $result = $query->execute();
  360. $rows = array();
  361. foreach ($result as $log) {
  362. $rows[] = array(
  363. array('data' => format_date($log->timestamp, 'short'), 'class' => array('nowrap')),
  364. );
  365. }
  366. //drupal_set_title($node->title);
  367. $build['advanced_mail_reroute_table'] = array(
  368. '#theme' => 'table',
  369. '#header' => $header,
  370. '#rows' => $rows,
  371. '#empty' => t('No logs available.'),
  372. );
  373. $build['advanced_mail_reroute_pager'] = array('#theme' => 'pager');
  374. return $build;
  375. //}
  376. //else {
  377. // drupal_not_found();
  378. //}
  379. }
  380. //=============================================================================
  381. // Private Functions
  382. //=============================================================================
  383. function _advanced_mail_reroute_log($mailkey, $from, $to, $reroute_rule, $reroute_email = '') {
  384. db_query("INSERT INTO {advanced_mail_reroute_log} (timestamp, mailkey, from_email, to_email, reroute_rule, reroute_email)
  385. VALUES (%d, '%s', '%s', '%s', %d, '%s')", time(), $mailkey, $from, $to, $reroute_rule, $reroute_email);
  386. }
  387. function _advanced_mail_reroute_reroute(&$message, $reroute_to) {
  388. $message['body'] = is_array($message['body']) ? implode("\n\n", $message['body']) : $message['body'];
  389. global $base_url;
  390. $message['subject'] = 'Rerouted email: '. $message['subject'];
  391. // Format copied from reroute_email module: http://drupal.org/project/reroute_email
  392. $body_header = "This email was rerouted.\n";
  393. $body_header .= "Web site: @site\n";
  394. $body_header .= "Mail key: @key\n";
  395. $body_header .= "Originally to: <@to>\n";
  396. $body_header .= "-----------------------\n";
  397. $body_header = t($body_header, array('@site' => $base_url, '@to' => $message['to'], '@key' => $message['id']));
  398. $message['body'] = $body_header . (is_array($message['body']) ? implode("\n\n", $message['body']) : $message['body']);
  399. $message['to'] = $reroute_to;
  400. }