Skip to content
Snippets Groups Projects
Commit 701862ed authored by Adam Shepherd's avatar Adam Shepherd
Browse files

Issue #3274899 by AdamPS: Set account/langcode from recipient

parent f4eb87d8
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,8 @@ class ContactEmailBuilderBase extends EmailProcessorBase {
$sender = $email->getParam('sender');
$contact_message = $email->getParam('contact_message');
// The contact entity cannot contain private information so we don't need
// to switch account for rendering it.
$email->appendBodyEntity($contact_message, 'mail')
->addLibrary('symfony_mailer_bc/contact')
->setVariable('subject', $contact_message->getSubject())
......
......@@ -39,6 +39,10 @@ class ContactPageEmailBuilder extends ContactEmailBuilderBase implements MailerP
$email->setVariable('form', $email->getEntity()->label())
->setVariable('form_url', Url::fromRoute('<current>')->toString());
if ($email->getSubType() == 'mail') {
// Set the account from the recipient to set langcode.
$email->setAccount();
}
if ($email->getSubType() == 'autoreply') {
$email->setBody($email->getParam('contact_form')->getReply());
}
......
......@@ -48,6 +48,7 @@ class SimplenewsNewsletterEmailBuilder extends EmailProcessorBase implements Mai
$subscriber = $email->getParam('simplenews_subscriber');
$email->setTo($subscriber->getMail())
->setLangcode($subscriber->getLangcode())
->setAccount($subscriber->getUser(), TRUE)
->appendBodyEntity($email->getParam('issue'), 'email_html')
->addTextHeader('Precedence', 'bulk')
->setVariable('opt_out_hidden', !$email->getEntity()->isAccessible())
......
......@@ -26,7 +26,9 @@ class UpdateEmailBuilder extends EmailProcessorBase {
}
$site_name = \Drupal::config('system.site')->get('name');
$email->setVariable('site_name', $site_name)
// Set the account from the recipient to set langcode.
$email->setAccount()
->setVariable('site_name', $site_name)
->setVariable('update_status', Url::fromRoute('update.status')->toString())
->setVariable('update_settings', Url::fromRoute('update.settings')->toString())
->setVariable('messages', $messages);
......
......@@ -25,7 +25,7 @@ use Drupal\symfony_mailer\Processor\TokenProcessorTrait;
* "status_blocked" = @Translation("Account blocked"),
* "status_canceled" = @Translation("Account cancelled"),
* },
* common_adjusters = {"email_subject", "email_body"},
* common_adjusters = {"email_subject", "email_body", "email_skip_sending"},
* import = @Translation("User email settings"),
* import_warning = @Translation("This overrides the default HTML messages with imported plain text versions."),
* )
......@@ -43,7 +43,11 @@ class UserEmailBuilder extends EmailProcessorBase implements MailerPolicyImportI
*/
public function build(EmailInterface $email) {
if ($email->getSubType() != 'register_pending_approval_admin') {
$email->setTo($email->getParam('user')->getEmail());
$email->setAccount($email->getParam('user'));
}
else {
// Set the account from the recipient to set langcode.
$email->setAccount();
}
$this->tokenOptions(['callback' => 'user_mail_tokens', 'clear' => TRUE]);
}
......
......@@ -123,9 +123,12 @@ function symfony_mailer_bc_mailer_bc_contact_alter(array &$message, ?ConfigEntit
// Set the associated config entity.
$entity = $message['params']['contact_form'];
if ($message['key'] == 'page_copy') {
if ($message['key'] == 'page_mail') {
// Remove the 'to' address as it will be set by Mailer Policy.
$message['to'] = '';
// Remove the langcode as we calculate it.
$message['langcode'] = '';
}
}
......@@ -188,11 +191,12 @@ function symfony_mailer_bc_mailer_bc_user_alter(array &$message, ?ConfigEntityIn
// @see \Drupal\symfony_mailer\EmailInterface::setParam()
$message['params'] = ['user' => $message['params']['account']];
// Remove the 'to' address as we calculate it.
// Remove the 'to' address and langcode as we calculate them.
$message['to'] = '';
$message['langcode'] = '';
// Remove the 'reply-to' address as it will be set by Mailer Policy.
$message['reply'] = '';
$message['reply-to'] = '';
}
/**
......@@ -201,3 +205,11 @@ function symfony_mailer_bc_mailer_bc_user_alter(array &$message, ?ConfigEntityIn
function symfony_mailer_bc_mailer_bc_user_registrationpassword_alter(array &$message, ?ConfigEntityInterface &$entity) {
symfony_mailer_bc_mailer_bc_user_alter($message, $entity);
}
/**
* Implements hook_mailer_bc_MODULE_alter() for update.
*/
function symfony_mailer_bc_mailer_bc_update_alter(array &$message, ?ConfigEntityInterface &$entity) {
// Remove the langcode as we calculate it.
$message['langcode'] = '';
}
......@@ -12,6 +12,7 @@ use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\Entity\User;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email as SymfonyEmail;
/**
......@@ -97,12 +98,19 @@ class Email implements InternalEmailInterface {
protected $variables = [];
/**
* The account to switch to for rendering.
* The account for the recipient (can be anonymous).
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* Whether to switch account for rendering.
*
* @var bool
*/
protected $switchAccount = FALSE;
/**
* @var string
*/
......@@ -249,17 +257,38 @@ class Email implements InternalEmailInterface {
/**
* {@inheritdoc}
*/
public function setAccount(AccountInterface $account) {
public function setAccount(AccountInterface $account = NULL, bool $switch = FALSE) {
$this->valid(self::PHASE_BUILD);
$to = $this->getTo();
if (empty($account)) {
if (count($to) == 1) {
$account = user_load_by_mail($to[0]);
}
if (empty($account)) {
$account = User::getAnonymousUser();
}
}
$this->account = $account;
$this->switchAccount = $switch;
if (!isset($this->langcode)) {
$this->setLangcode($account->getPreferredLangcode());
}
if (empty($to) && ($email = $account->getEmail())) {
$this->setTo(new Address($email, $account->getDisplayName()));
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getAccount() {
return $this->account;
public function getAccount(bool $switch = FALSE) {
return ($switch && !$this->switchAccount) ? NULL : $this->account;
}
/**
......@@ -289,11 +318,6 @@ class Email implements InternalEmailInterface {
$build = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId())
->view($entity, $view_mode);
$this->appendBody($build);
if (!$this->getAccount()) {
$this->setAccount($this->getUser());
}
return $this;
}
......@@ -519,22 +543,4 @@ class Email implements InternalEmailInterface {
return $this;
}
/**
* Gets a user account for the recipient of this email.
*
* If there is a single to address, searcch for a matching user account.
*
* @return
*/
protected function getUser() {
$to = $this->getTo();
if (count($to) == 1) {
$user = user_load_by_mail($to[0]);
}
if (empty($user)) {
$user = User::getAnonymousUser();
}
return $user;
}
}
......@@ -150,24 +150,33 @@ interface EmailInterface extends BaseEmailInterface {
public function send();
/**
* Sets the account to switch to for rendering.
* Sets the account associated with the recipient of this email.
*
* Also sets the to address and langcode if they are not already set.
*
* Valid: build.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The account.
* (Optional) The account, which can be anonymous. If not set, then the
* account will be calculated from the to address.
* @param bool $switch
* (Optional) Switch to this account for rendering.
*
* @return $this
*/
public function setAccount(AccountInterface $account);
public function setAccount(AccountInterface $account, bool $switch = FALSE);
/**
* Gets the account to switch to for rendering.
* Gets the account associated with the recipient of this email.
*
* @param bool $switch
* (Optional) Only return an account that needs switching to for rendering.
*
* @return \Drupal\Core\Session\AccountInterface
* The account.
*/
public function getAccount();
public function getAccount(bool $switch = FALSE);
/**
* Sets the unrendered email body.
*
......@@ -199,6 +208,9 @@ interface EmailInterface extends BaseEmailInterface {
/**
* Appends a rendered entity to the email body.
*
* WARNING: rendering as a trusted user can expose private information . Call
* ::setAccount() unless you are sure this cannot occur.
*
* Valid: before rendering.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
......
......@@ -184,7 +184,7 @@ class Mailer implements MailerInterface {
$this->changeTheme($theme_name);
}
$account = $email->getAccount();
$account = $email->getAccount(TRUE);
$must_switch_account = $account && $account->id() != $this->account->id();
if ($must_switch_account) {
......
......@@ -11,10 +11,20 @@ use Drupal\symfony_mailer\EmailInterface;
* id = "email_to",
* label = @Translation("To"),
* description = @Translation("Sets the email to header."),
* weight = 200,
* )
*/
class ToEmailAdjuster extends AddressAdjusterBase {
/**
* {@inheritdoc}
*/
public function initialize(EmailInterface $email) {
// The to address can be used to default the recipient account. Ensure that
// it is set early enough to do this.
$email->addProcessor($this->getPluginId(), EmailInterface::PHASE_BUILD, [$this, 'postRender'], $this->getWeight(EmailInterface::PHASE_BUILD));
}
/**
* {@inheritdoc}
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment