Issue #1471364 by amateescu: Move mail system classes from system.mail.inc to PSR-0 classes in Drupal\Core.

8.0.x
catch 2012-03-14 17:54:05 +09:00
parent fe263c8f19
commit 1de01b0025
7 changed files with 136 additions and 105 deletions

View File

@ -191,7 +191,8 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
}
/**
* Returns an object that implements the MailSystemInterface.
* Returns an object that implements the Drupal\Core\Mail\MailInterface
* interface.
*
* Allows for one or more custom mail backends to format and send mail messages
* composed using drupal_mail().
@ -199,14 +200,15 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
* An implementation needs to implement the following methods:
* - format: Allows to preprocess, format, and postprocess a mail
* message before it is passed to the sending system. By default, all messages
* may contain HTML and are converted to plain-text by the DefaultMailSystem
* implementation. For example, an alternative implementation could override
* the default implementation and additionally sanitize the HTML for usage in
* a MIME-encoded e-mail, but still invoking the DefaultMailSystem
* implementation to generate an alternate plain-text version for sending.
* may contain HTML and are converted to plain-text by the
* Drupal\Core\Mail\PhpMail implementation. For example, an alternative
* implementation could override the default implementation and additionally
* sanitize the HTML for usage in a MIME-encoded e-mail, but still invoking
* the Drupal\Core\Mail\PhpMail implementation to generate an alternate
* plain-text version for sending.
* - mail: Sends a message through a custom mail sending engine.
* By default, all messages are sent via PHP's mail() function by the
* DefaultMailSystem implementation.
* Drupal\Core\Mail\PhpMail implementation.
*
* The selection of a particular implementation is controlled via the variable
* 'mail_system', which is a keyed array. The default implementation
@ -223,7 +225,7 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
*
* @code
* array(
* 'default-system' => 'DefaultMailSystem',
* 'default-system' => 'Drupal\Core\Mail\PhpMail',
* 'user' => 'DevelMailLog',
* );
* @endcode
@ -233,7 +235,7 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
*
* @code
* array(
* 'default-system' => 'DefaultMailSystem',
* 'default-system' => 'Drupal\Core\Mail\PhpMail',
* 'user' => 'DevelMailLog',
* 'contact_page_autoreply' => 'DrupalDevNullMailSend',
* );
@ -251,14 +253,14 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
* A key to identify the e-mail sent. The final e-mail ID for the e-mail
* alter hook in drupal_mail() would have been {$module}_{$key}.
*
* @return MailSystemInterface
* @return Drupal\Core\Mail\MailInterface
*/
function drupal_mail_system($module, $key) {
$instances = &drupal_static(__FUNCTION__, array());
$id = $module . '_' . $key;
$configuration = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
$configuration = variable_get('mail_system', array('default-system' => 'Drupal\Core\Mail\PhpMail'));
// Look for overrides for the default class, starting from the most specific
// id, and falling back to the module name.
@ -274,59 +276,16 @@ function drupal_mail_system($module, $key) {
if (empty($instances[$class])) {
$interfaces = class_implements($class);
if (isset($interfaces['MailSystemInterface'])) {
if (isset($interfaces['Drupal\Core\Mail\MailInterface'])) {
$instances[$class] = new $class();
}
else {
throw new Exception(t('Class %class does not implement interface %interface', array('%class' => $class, '%interface' => 'MailSystemInterface')));
throw new Exception(t('Class %class does not implement interface %interface', array('%class' => $class, '%interface' => 'Drupal\Core\Mail\MailInterface')));
}
}
return $instances[$class];
}
/**
* An interface for pluggable mail back-ends.
*/
interface MailSystemInterface {
/**
* Format a message composed by drupal_mail() prior sending.
*
* @param $message
* A message array, as described in hook_mail_alter().
*
* @return
* The formatted $message.
*/
public function format(array $message);
/**
* Send a message composed by drupal_mail().
*
* @param $message
* Message array with at least the following elements:
* - id: A unique identifier of the e-mail type. Examples: 'contact_user_copy',
* 'user_password_reset'.
* - to: The mail address or addresses where the message will be sent to.
* The formatting of this string must comply with RFC 2822. Some examples:
* - user@example.com
* - user@example.com, anotheruser@example.com
* - User <user@example.com>
* - User <user@example.com>, Another User <anotheruser@example.com>
* - subject: Subject of the e-mail to be sent. This must not contain any
* newline characters, or the mail may not be sent properly.
* - body: Message to be sent. Accepts both CRLF and LF line-endings.
* E-mail bodies must be wrapped. You can use drupal_wrap_mail() for
* smart plain text wrapping.
* - headers: Associative array containing all additional mail headers not
* defined by one of the other parameters. PHP's mail() looks for Cc
* and Bcc headers and sends the mail to addresses in these headers too.
*
* @return
* TRUE if the mail was successfully accepted for delivery, otherwise FALSE.
*/
public function mail(array $message);
}
/**
* Perform format=flowed soft wrapping for mail (RFC 3676).
*

View File

@ -0,0 +1,52 @@
<?php
/**
* @file
* Definition of Drupal\Core\Mail\MailInterface.
*/
namespace Drupal\Core\Mail;
/**
* Defines an interface for pluggable mail back-ends.
*/
interface MailInterface {
/**
* Formats a message composed by drupal_mail() prior sending.
*
* @param array $message
* A message array, as described in hook_mail_alter().
*
* @return array
* The formatted $message.
*/
public function format(array $message);
/**
* Sends a message composed by drupal_mail().
*
* @param array $message
* Message array with at least the following elements:
* - id: A unique identifier of the e-mail type. Examples: 'contact_user_copy',
* 'user_password_reset'.
* - to: The mail address or addresses where the message will be sent to.
* The formatting of this string must comply with RFC 2822. Some examples:
* - user@example.com
* - user@example.com, anotheruser@example.com
* - User <user@example.com>
* - User <user@example.com>, Another User <anotheruser@example.com>
* - subject: Subject of the e-mail to be sent. This must not contain any
* newline characters, or the mail may not be sent properly.
* - body: Message to be sent. Accepts both CRLF and LF line-endings.
* E-mail bodies must be wrapped. You can use drupal_wrap_mail() for
* smart plain text wrapping.
* - headers: Associative array containing all additional mail headers not
* defined by one of the other parameters. PHP's mail() looks for Cc
* and Bcc headers and sends the mail to addresses in these headers too.
*
* @return bool
* TRUE if the mail was successfully accepted for delivery, otherwise FALSE.
*/
public function mail(array $message);
}

View File

@ -2,20 +2,23 @@
/**
* @file
* Drupal core implementations of MailSystemInterface.
* Definition of Drupal\Core\Mail\PhpMail.
*/
namespace Drupal\Core\Mail;
/**
* The default Drupal mail backend using PHP's mail function.
*/
class DefaultMailSystem implements MailSystemInterface {
class PhpMail implements MailInterface {
/**
* Concatenate and wrap the e-mail body for plain-text mails.
* Concatenates and wrap the e-mail body for plain-text mails.
*
* @param $message
* @param array $message
* A message array, as described in hook_mail_alter().
*
* @return
* @return array
* The formatted $message.
*/
public function format(array $message) {
@ -25,19 +28,21 @@ class DefaultMailSystem implements MailSystemInterface {
$message['body'] = drupal_html_to_text($message['body']);
// Wrap the mail body for sending.
$message['body'] = drupal_wrap_mail($message['body']);
return $message;
}
/**
* Send an e-mail message, using Drupal variables and default settings.
* Sends an e-mail message, using Drupal variables and default settings.
*
* @param array $message
* A message array, as described in hook_mail_alter().
*
* @return bool
* TRUE if the mail was successfully accepted, otherwise FALSE.
*
* @see http://php.net/manual/en/function.mail.php
* @see drupal_mail()
*
* @param $message
* A message array, as described in hook_mail_alter().
* @return
* TRUE if the mail was successfully accepted, otherwise FALSE.
*/
public function mail(array $message) {
// If 'Return-Path' isn't already set in php.ini, we pass it separately
@ -107,27 +112,7 @@ class DefaultMailSystem implements MailSystemInterface {
);
ini_set('sendmail_from', $old_from);
}
return $mail_result;
}
}
/**
* A mail sending implementation that captures sent messages to a variable.
*
* This class is for running tests or for development.
*/
class TestingMailSystem extends DefaultMailSystem implements MailSystemInterface {
/**
* Accept an e-mail message and store it in a variable.
*
* @param $message
* An e-mail message.
*/
public function mail(array $message) {
$captured_emails = variable_get('drupal_test_email_collector', array());
$captured_emails[] = $message;
variable_set('drupal_test_email_collector', $captured_emails);
return TRUE;
}
}

View File

@ -0,0 +1,30 @@
<?php
/**
* @file
* Definition of Drupal\Core\Mail\VariableLog.
*/
namespace Drupal\Core\Mail;
/**
* Defines a mail sending implementation that captures sent messages to a
* variable.
*
* This class is for running tests or for development.
*/
class VariableLog extends PhpMail implements MailInterface {
/**
* Overrides Drupal\Core\Mail\PhpMail::mail().
*
* Accepts an e-mail message and store it in a variable.
*/
public function mail(array $message) {
$captured_emails = variable_get('drupal_test_email_collector', array());
$captured_emails[] = $message;
variable_set('drupal_test_email_collector', $captured_emails);
return TRUE;
}
}

View File

@ -1441,7 +1441,7 @@ class DrupalWebTestCase extends DrupalTestCase {
$language_interface = language_default();
// Use the test mail class instead of the default mail handler class.
variable_set('mail_system', array('default-system' => 'TestingMailSystem'));
variable_set('mail_system', array('default-system' => 'Drupal\Core\Mail\VariableLog'));
drupal_set_time_limit($this->timeLimit);
$this->setup = TRUE;

View File

@ -4,7 +4,13 @@
* @file
* Test the Drupal mailing system.
*/
class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
use Drupal\Core\Mail\MailInterface;
/**
* Defines a mail class used for testing.
*/
class MailTestCase extends DrupalWebTestCase implements MailInterface {
/**
* The most recent message that was sent through the test case.
*
@ -17,7 +23,7 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
return array(
'name' => 'Mail system',
'description' => 'Performs tests on the pluggable mailing framework.',
'group' => 'System',
'group' => 'Mail',
);
}
@ -31,7 +37,7 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
/**
* Assert that the pluggable mail system is functional.
*/
function testPluggableFramework() {
public function testPluggableFramework() {
global $language_interface;
// Use MailTestCase for sending a message.
@ -46,7 +52,7 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
*
* @see simpletest_mail_alter()
*/
function testCancelMessage() {
public function testCancelMessage() {
global $language;
// Reset the class variable holding a copy of the last sent message.
@ -62,7 +68,7 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
/**
* Concatenate and wrap the e-mail body for plain-text mails.
*
* @see DefaultMailSystem
* @see Drupal\Core\Mail\PhpMail
*/
public function format(array $message) {
// Join the body array into one string.
@ -104,7 +110,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
* An HTML representation of the text string that, when displayed in a
* browser, represents the PHP source code equivalent of $text.
*/
function stringToHtml($text) {
protected function stringToHtml($text) {
return '"' .
str_replace(
array("\n", ' '),
@ -126,7 +132,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
* (optional) An array of allowed tags, or NULL to default to the full
* set of tags supported by drupal_html_to_text().
*/
function assertHtmlToText($html, $text, $message, $allowed_tags = NULL) {
protected function assertHtmlToText($html, $text, $message, $allowed_tags = NULL) {
preg_match_all('/<([a-z0-6]+)/', drupal_strtolower($html), $matches);
$tested_tags = implode(', ', array_unique($matches[1]));
$message .= ' (' . $tested_tags . ')';
@ -145,7 +151,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
/**
* Test all supported tags of drupal_html_to_text().
*/
function testTags() {
public function testTags() {
global $base_path, $base_url;
$tests = array(
// @todo Trailing linefeeds should be trimmed.
@ -240,7 +246,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
/**
* Test $allowed_tags argument of drupal_html_to_text().
*/
function testDrupalHtmlToTextArgs() {
public function testDrupalHtmlToTextArgs() {
// The second parameter of drupal_html_to_text() overrules the allowed tags.
$this->assertHtmlToText(
'Drupal <b>Drupal</b> Drupal',
@ -273,7 +279,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
/**
* Test that whitespace is collapsed.
*/
function testDrupalHtmltoTextCollapsesWhitespace() {
public function testDrupalHtmltoTextCollapsesWhitespace() {
$input = "<p>Drupal Drupal\n\nDrupal<pre>Drupal Drupal\n\nDrupal</pre>Drupal Drupal\n\nDrupal</p>";
// @todo The whitespace should be collapsed.
$collapsed = "Drupal Drupal\n\nDrupalDrupal Drupal\n\nDrupalDrupal Drupal\n\nDrupal\n\n";
@ -289,7 +295,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
* Test that text separated by block-level tags in HTML get separated by
* (at least) a newline in the plaintext version.
*/
function testDrupalHtmlToTextBlockTagToNewline() {
public function testDrupalHtmlToTextBlockTagToNewline() {
$input = '[text]'
. '<blockquote>[blockquote]</blockquote>'
. '<br />[br]'
@ -339,7 +345,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
/**
* Test that headers are properly separated from surrounding text.
*/
function testHeaderSeparation() {
public function testHeaderSeparation() {
$html = 'Drupal<h1>Drupal</h1>Drupal';
// @todo There should be more space above the header than below it.
$text = "Drupal\n======== DRUPAL ==============================================================\n\nDrupal\n";
@ -364,7 +370,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
/**
* Test that footnote references are properly generated.
*/
function testFootnoteReferences() {
public function testFootnoteReferences() {
global $base_path, $base_url;
$source = '<a href="http://www.example.com/node/1">Host and path</a>'
. '<br /><a href="http://www.example.com">Host, no path</a>'
@ -389,7 +395,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
* Test that combinations of paragraph breaks, line breaks, linefeeds,
* and spaces are properly handled.
*/
function testDrupalHtmlToTextParagraphs() {
public function testDrupalHtmlToTextParagraphs() {
$tests = array();
$tests[] = array(
'html' => "<p>line 1<br />\nline 2<br />line 3\n<br />line 4</p><p>paragraph</p>",
@ -418,7 +424,7 @@ class DrupalHtmlToTextTestCase extends DrupalWebTestCase {
* RFC 821 says, "The maximum total length of a text line including the
* <CRLF> is 1000 characters."
*/
function testVeryLongLineWrap() {
public function testVeryLongLineWrap() {
$input = 'Drupal<br /><p>' . str_repeat('x', 2100) . '</><br />Drupal';
$output = drupal_html_to_text($input);
// This awkward construct comes from includes/mail.inc lines 8-13.

View File

@ -4,7 +4,6 @@ package = Core
version = VERSION
core = 8.x
files[] = system.archiver.inc
files[] = system.mail.inc
files[] = system.tar.inc
files[] = system.test
required = TRUE