diff --git a/core/includes/mail.inc b/core/includes/mail.inc index 1f7897e..afc206c 100644 --- a/core/includes/mail.inc +++ b/core/includes/mail.inc @@ -8,7 +8,7 @@ /** * Auto-detect appropriate line endings for e-mails. * - * $conf['mail_line_endings'] will override this setting. + * $settings['mail_line_endings'] will override this setting. */ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE ? "\r\n" : "\n"); @@ -216,14 +216,14 @@ function drupal_mail($module, $key, $to, $langcode, $params = array(), $from = N * By default, all messages are sent via PHP's mail() function by the * 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 - * is the class whose name is the value of 'default-system' key. A more specific - * match first to key and then to module will be used in preference to the - * default. To specify a different class for all mail sent by one module, set - * the class name as the value for the key corresponding to the module name. To - * specify a class for a particular message sent by one module, set the class - * name as the value for the array key that is the message id, which is + * The selection of a particular implementation is controlled via the config + * 'system.mail.interface', which is a keyed array. The default implementation + * is the class whose name is the value of 'default' key. A more specific match + * first to key and then to module will be used in preference to the default. To + * specify a different class for all mail sent by one module, set the class + * name as the value for the key corresponding to the module name. To specify + * a class for a particular message sent by one module, set the class name as + * the value for the array key that is the message id, which is * "${module}_${key}". * * For example to debug all mail sent by the user module by logging it to a @@ -231,7 +231,7 @@ function drupal_mail($module, $key, $to, $langcode, $params = array(), $from = N * * @code * array( - * 'default-system' => 'Drupal\Core\Mail\PhpMail', + * 'default' => 'Drupal\Core\Mail\PhpMail', * 'user' => 'DevelMailLog', * ); * @endcode @@ -241,7 +241,7 @@ function drupal_mail($module, $key, $to, $langcode, $params = array(), $from = N * * @code * array( - * 'default-system' => 'Drupal\Core\Mail\PhpMail', + * 'default' => 'Drupal\Core\Mail\PhpMail', * 'user' => 'DevelMailLog', * 'contact_page_autoreply' => 'DrupalDevNullMailSend', * ); @@ -260,13 +260,15 @@ function drupal_mail($module, $key, $to, $langcode, $params = array(), $from = N * alter hook in drupal_mail() would have been {$module}_{$key}. * * @return Drupal\Core\Mail\MailInterface + * + * @throws \Exception */ function drupal_mail_system($module, $key) { $instances = &drupal_static(__FUNCTION__, array()); $id = $module . '_' . $key; - $configuration = variable_get('mail_system', array('default-system' => 'Drupal\Core\Mail\PhpMail')); + $configuration = config('system.mail')->get('interface'); // Look for overrides for the default class, starting from the most specific // id, and falling back to the module name. @@ -277,7 +279,7 @@ function drupal_mail_system($module, $key) { $class = $configuration[$module]; } else { - $class = $configuration['default-system']; + $class = $configuration['default']; } if (empty($instances[$class])) { @@ -506,8 +508,9 @@ function drupal_html_to_text($string, $allowed_tags = NULL) { if (isset($casing)) { $chunk = $casing($chunk); } + $line_endings = settings()->get('mail_line_endings', MAIL_LINE_ENDINGS); // Format it and apply the current indentation. - $output .= drupal_wrap_mail($chunk, implode('', $indent)) . MAIL_LINE_ENDINGS; + $output .= drupal_wrap_mail($chunk, implode('', $indent)) . $line_endings; // Remove non-quotation markers from indentation. $indent = array_map('_drupal_html_to_text_clean', $indent); } diff --git a/core/lib/Drupal/Core/Mail/PhpMail.php b/core/lib/Drupal/Core/Mail/PhpMail.php index f5ec995..580a824 100644 --- a/core/lib/Drupal/Core/Mail/PhpMail.php +++ b/core/lib/Drupal/Core/Mail/PhpMail.php @@ -59,13 +59,13 @@ public function mail(array $message) { foreach ($message['headers'] as $name => $value) { $mimeheaders[] = $name . ': ' . mime_header_encode($value); } - $line_endings = variable_get('mail_line_endings', MAIL_LINE_ENDINGS); + $line_endings = settings()->get('mail_line_endings', MAIL_LINE_ENDINGS); // Prepare mail commands. $mail_subject = mime_header_encode($message['subject']); // Note: e-mail uses CRLF for line-endings. PHP's API requires LF // on Unix and CRLF on Windows. Drupal automatically guesses the // line-ending format appropriate for your system. If you need to - // override this, adjust $conf['mail_line_endings'] in settings.php. + // override this, adjust $settings['mail_line_endings'] in settings.php. $mail_body = preg_replace('@\r?\n@', $line_endings, $message['body']); // For headers, PHP's API suggests that we use CRLF normally, // but some MTAs incorrectly replace LF with CRLF. See #234403. diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 4fb76a5..d19744a 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -837,7 +837,7 @@ protected function setUp() { $this->resetAll(); // Use the test mail class instead of the default mail handler class. - variable_set('mail_system', array('default-system' => 'Drupal\Core\Mail\VariableLog')); + config('system.mail')->set('interface.default', 'Drupal\Core\Mail\VariableLog')->save(); drupal_set_time_limit($this->timeLimit); // Temporary fix so that when running from run-tests.sh we don't get an diff --git a/core/modules/system/config/system.mail.yml b/core/modules/system/config/system.mail.yml new file mode 100644 index 0000000..e3eb768 --- /dev/null +++ b/core/modules/system/config/system.mail.yml @@ -0,0 +1,2 @@ +interface: + default: 'Drupal\Core\Mail\PhpMail' diff --git a/core/modules/system/lib/Drupal/system/Tests/Mail/HtmlToTextTest.php b/core/modules/system/lib/Drupal/system/Tests/Mail/HtmlToTextTest.php index 5302c8d..f93b40f 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Mail/HtmlToTextTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Mail/HtmlToTextTest.php @@ -348,11 +348,8 @@ public function testDrupalHtmlToTextParagraphs() { public function testVeryLongLineWrap() { $input = 'Drupal

' . str_repeat('x', 2100) . '
Drupal'; $output = drupal_html_to_text($input); - // This awkward construct comes from includes/mail.inc lines 8-13. - $eol = variable_get('mail_line_endings', MAIL_LINE_ENDINGS); - // We must use strlen() rather than drupal_strlen() in order to count - // octets rather than characters. - $line_length_limit = 1000 - drupal_strlen($eol); + $eol = settings()->get('mail_line_endings', MAIL_LINE_ENDINGS); + $maximum_line_length = 0; foreach (explode($eol, $output) as $line) { // We must use strlen() rather than drupal_strlen() in order to count diff --git a/core/modules/system/lib/Drupal/system/Tests/Mail/MailTest.php b/core/modules/system/lib/Drupal/system/Tests/Mail/MailTest.php index bb72d29..155fdb8 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Mail/MailTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Mail/MailTest.php @@ -42,7 +42,7 @@ function setUp() { parent::setUp(); // Set MailTestCase (i.e. this class) as the SMTP library - variable_set('mail_system', array('default-system' => 'Drupal\system\Tests\Mail\MailTest')); + config('system.mail')->set('interface.default', 'Drupal\system\Tests\Mail\MailTest')->save(); } /** @@ -119,4 +119,3 @@ public function mail(array $message) { self::$sent_message = $message; } } - diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/MailUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/MailUpgradePathTest.php new file mode 100644 index 0000000..68b9ab1 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/MailUpgradePathTest.php @@ -0,0 +1,52 @@ + 'Mail upgrade test', + 'description' => 'Tests upgrade of Mail backend configuration.', + 'group' => 'Upgrade path', + ); + } + + public function setUp() { + $this->databaseDumpFiles = array( + drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.standard_all.database.php.gz', + drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.system.database.php', + ); + parent::setUp(); + } + + /** + * Tests that mail backends are upgraded to their Drupal 8 equivalents. + */ + function testMailSystemUpgrade() { + // Perform the upgrade without redirecting to check for pending updates, + // so that we can test for user warnings. + $this->performUpgrade(TRUE, FALSE); + // Ensure the user is informed about mail backends that need updating. + $this->assertText('The following mail backends need to be re-configured: MaillogMailSystem', 'User notified about outdated mail backends.'); + $this->assertTrue($this->checkPendingUpdates(), 'The upgrade was completed successfully.'); + + // Get the new mailer definitions. + $mail_system = config('system.mail')->get('interface'); + + // Check that the default mailer has been changed to a PSR-0 definition. + $this->assertTrue($mail_system['default'] == 'Drupal\Core\Mail\PhpMail', 'Default mailer upgraded to Drupal 8 syntax.'); + + // Check that a custom mailer has been preserved through the upgrade. + $this->assertTrue($mail_system['maillog'] == 'MaillogMailSystem', 'Custom mail backend preserved during upgrade.'); + } + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php index c4dda65..bdfdcff 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php @@ -195,12 +195,17 @@ protected function refreshVariables() { /** * Perform the upgrade. * - * @param $register_errors + * @param bool $register_errors * Register the errors during the upgrade process as failures. - * @return + * @param bool $check_pending_updates + * Check to make sure no updates are outstanding after an upgrade. + * + * @return bool * TRUE if the upgrade succeeded, FALSE otherwise. + * + * @throws \Exception */ - protected function performUpgrade($register_errors = TRUE) { + protected function performUpgrade($register_errors = TRUE, $check_pending_updates = TRUE) { // Load the first update screen. $this->getUpdatePhp(); @@ -251,7 +256,22 @@ protected function performUpgrade($register_errors = TRUE) { // don't process. throw new Exception('Errors during update process.'); } + if ($check_pending_updates) { + return $this->checkPendingUpdates(); + } + + return TRUE; + } + /** + * Checks that no updates are pending at the end of an upgrade. + * + * @return bool + * TRUE if there are no pending updates, FALSE if not. + * + * @throws \Exception + */ + protected function checkPendingUpdates() { // Check if there still are pending updates. $this->getUpdatePhp(); $this->drupalPost(NULL, array(), t('Continue')); diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 5a0aade..788465b 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -2214,6 +2214,45 @@ function system_update_8046() { } /** + * Converts mail settings to config. + * + * @ingroup config_upgrade + */ +function system_update_8047() { + // Update any mail interfaces to their Drupal 8 equivalents. + $old_mail_system_settings = update_variable_get('mail_system'); + + if ($old_mail_system_settings) { + $new_mail_system_settings = array(); + + foreach ($old_mail_system_settings as $key => $mailer_class) { + // Update old class name to PSR-0. + if ($mailer_class == 'DefaultMailSystem') { + $mailer_class = 'Drupal\Core\Mail\PhpMail'; + } + // New default key. + if ($key == 'default-system') { + $new_mail_system_settings['default'] = $mailer_class; + unset($old_mail_system_settings[$key]); + } + } + if (count($old_mail_system_settings)) { + // Warn about non-core classes which may need to be updated. + drupal_set_message(t('The following mail backends need to be re-configured: @list', array('@list' => implode(', ', $old_mail_system_settings))), 'warning'); + } + + $new_mail_system_settings += $old_mail_system_settings; + // Save the updated variable, and let update_variables_to_config convert it. + if ($new_mail_system_settings) { + update_variable_set('mail_system', $new_mail_system_settings); + update_variables_to_config('system.mail', array( + 'mail_system' => 'interface', + )); + } + } +} + +/** * @} End of "defgroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */ diff --git a/core/modules/system/tests/upgrade/drupal-7.system.database.php b/core/modules/system/tests/upgrade/drupal-7.system.database.php index 061540b..b0c032f 100644 --- a/core/modules/system/tests/upgrade/drupal-7.system.database.php +++ b/core/modules/system/tests/upgrade/drupal-7.system.database.php @@ -119,6 +119,10 @@ 'name' => 'actions_max_stack', 'value' => 'i:42;', )) + ->values(array( + 'name' => 'mail_system', + 'value' => 'a:2:{s:14:"default-system";s:17:"DefaultMailSystem";s:7:"maillog";s:17:"MaillogMailSystem";}', +)) ->execute(); db_update('variable')