devel.mail.inc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. /**
  3. * @file
  4. * MailSystemInterface for logging mails to the filesystem.
  5. *
  6. * To enable, save a variable in settings.php (or otherwise) whose value
  7. * can be as simple as:
  8. *
  9. * $conf['mail_system'] = array(
  10. * 'default-system' => 'DevelMailLog',
  11. *);
  12. *
  13. * Saves to temporary://devel-mails dir by default. Can be changed using
  14. * 'devel_debug_mail_directory' variable. Filename pattern controlled by
  15. * 'devel_debug_mail_file_format' variable.
  16. *
  17. */
  18. /**
  19. * Logs mail messages to the filesystem.
  20. */
  21. class DevelMailLog extends DefaultMailSystem {
  22. /**
  23. * Converts a message array to a string.
  24. *
  25. * @param $message
  26. * The message array containing the body and headers.
  27. *
  28. * @return
  29. * The message as it will be printed in the file.
  30. */
  31. public function composeMessage($message) {
  32. $mimeheaders = array();
  33. $message['headers']['To'] = $message['to'];
  34. foreach ($message['headers'] as $name => $value) {
  35. $mimeheaders[] = $name . ': ' . mime_header_encode($value);
  36. }
  37. $line_endings = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
  38. $output = join($line_endings, $mimeheaders) . $line_endings;
  39. // 'Subject:' is a mail header and should not be translated.
  40. $output .= 'Subject: ' . $message['subject'] . $line_endings;
  41. // Blank line to separate headers from body.
  42. $output .= $line_endings;
  43. $output .= preg_replace('@\r?\n@', $line_endings, $message['body']);
  44. return $output;
  45. }
  46. /**
  47. * Gets a filename for a message using tokens.
  48. *
  49. * @param $message
  50. * The message that will supply values for token replacement.
  51. *
  52. * @return
  53. * The full path and filename after token replacement.
  54. */
  55. public function getFileName($message) {
  56. $output_directory = $this->getOutputDirectory();
  57. $this->makeOutputDirectory($output_directory);
  58. $output_file_format = variable_get('devel_debug_mail_file_format', '%to-%subject-%datetime.mail.txt');
  59. $tokens = array(
  60. '%to' => $message['to'],
  61. '%subject' => $message['subject'],
  62. '%datetime' => date('y-m-d_his'),
  63. );
  64. return $output_directory . '/' . $this->dirify(str_replace(array_keys($tokens), array_values($tokens), $output_file_format));
  65. }
  66. /**
  67. * Convert a string to a valid directory name.
  68. *
  69. * @return
  70. * The sanitized string, replacing any characters not whitelisted with "_".
  71. */
  72. private function dirify($string) {
  73. return preg_replace('/[^a-zA-Z0-9_\-\.@]/', '_', $string);
  74. }
  75. /**
  76. * Save a mail message to a file using Drupal variables and default settings.
  77. *
  78. * @param $message
  79. * A message array, as described in hook_mail_alter().
  80. * @return
  81. * TRUE if the mail was successfully accepted, otherwise FALSE.
  82. *
  83. * @see http://php.net/manual/en/function.mail.php
  84. * @see drupal_mail()
  85. */
  86. public function mail(array $message) {
  87. $output = $this->composeMessage($message);
  88. $output_file = $this->getFileName($message);
  89. return file_put_contents($output_file, $output);
  90. }
  91. /**
  92. * Creates the directory to contain the message file if necessary.
  93. *
  94. * @throws Exception
  95. * Exception thrown when unable to create the destination directory.
  96. */
  97. protected function makeOutputDirectory($output_directory) {
  98. if (!file_prepare_directory($output_directory, FILE_CREATE_DIRECTORY)) {
  99. throw new Exception("Unable to continue sending mail, $output_directory is not writable");
  100. }
  101. }
  102. /**
  103. * Retrieves the directory that contains message files.
  104. *
  105. * @return
  106. * The path to mail messages, possibly using a file URI scheme.
  107. */
  108. public function getOutputDirectory() {
  109. return variable_get('devel_debug_mail_directory', 'temporary://devel-mails');
  110. }
  111. }