Skip to content

Commit

Permalink
11740: Sending emails from Admin in Multi-Store Environment defaults …
Browse files Browse the repository at this point in the history
…to Primary Store
  • Loading branch information
RomaKis committed Nov 13, 2017
1 parent ef03b52 commit f2bfdd9
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 38 deletions.
16 changes: 14 additions & 2 deletions app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
*/
namespace Magento\Sales\Model\Order\Email;

use Magento\Framework\App\ObjectManager;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Mail\Template\TransportBuilderByStore;
use Magento\Sales\Model\Order\Email\Container\IdentityInterface;
use Magento\Sales\Model\Order\Email\Container\Template;

Expand All @@ -26,19 +28,29 @@ class SenderBuilder
*/
protected $transportBuilder;

/**
* @var TransportBuilderByStore
*/
private $transportBuilderByStore;

/**
* @param Template $templateContainer
* @param IdentityInterface $identityContainer
* @param TransportBuilder $transportBuilder
* @param TransportBuilderByStore $transportBuilderByStore
*/
public function __construct(
Template $templateContainer,
IdentityInterface $identityContainer,
TransportBuilder $transportBuilder
TransportBuilder $transportBuilder,
TransportBuilderByStore $transportBuilderByStore = null
) {
$this->templateContainer = $templateContainer;
$this->identityContainer = $identityContainer;
$this->transportBuilder = $transportBuilder;
$this->transportBuilderByStore = $transportBuilderByStore ?: ObjectManager::getInstance()->get(
TransportBuilderByStore::class
);
}

/**
Expand Down Expand Up @@ -98,7 +110,7 @@ protected function configureEmailTemplate()
$this->transportBuilder->setTemplateIdentifier($this->templateContainer->getTemplateId());
$this->transportBuilder->setTemplateOptions($this->templateContainer->getTemplateOptions());
$this->transportBuilder->setTemplateVars($this->templateContainer->getTemplateVars());
$this->transportBuilder->setFromByStore(
$this->transportBuilderByStore->setFromByStore(
$this->identityContainer->getEmailIdentity(),
$this->identityContainer->getStore()->getId()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace Magento\Sales\Test\Unit\Model\Order\Email;

use Magento\Framework\Mail\Template\TransportBuilderByStore;
use Magento\Sales\Model\Order\Email\SenderBuilder;

class SenderBuilderTest extends \PHPUnit\Framework\TestCase
Expand Down Expand Up @@ -35,6 +36,11 @@ class SenderBuilderTest extends \PHPUnit\Framework\TestCase
*/
private $storeMock;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $transportBuilderByStore;

protected function setUp()
{
$templateId = 'test_template_id';
Expand Down Expand Up @@ -76,10 +82,11 @@ protected function setUp()
'setTemplateIdentifier',
'setTemplateOptions',
'setTemplateVars',
'setFromByStore',
]
);

$this->transportBuilderByStore = $this->createMock(TransportBuilderByStore::class);

$this->templateContainerMock->expects($this->once())
->method('getTemplateId')
->will($this->returnValue($templateId));
Expand All @@ -102,7 +109,7 @@ protected function setUp()
$this->identityContainerMock->expects($this->once())
->method('getEmailIdentity')
->will($this->returnValue($emailIdentity));
$this->transportBuilder->expects($this->once())
$this->transportBuilderByStore->expects($this->once())
->method('setFromByStore')
->with($this->equalTo($emailIdentity));

Expand All @@ -113,7 +120,8 @@ protected function setUp()
$this->senderBuilder = new SenderBuilder(
$this->templateContainerMock,
$this->identityContainerMock,
$this->transportBuilder
$this->transportBuilder,
$this->transportBuilderByStore
);
}

Expand Down
14 changes: 0 additions & 14 deletions lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,20 +171,6 @@ public function setFrom($from)
return $this;
}

/**
* Set mail from address by store.
*
* @param string|array $from
* @param string|int $store
* @return $this
*/
public function setFromByStore($from, $store)
{
$result = $this->_senderResolver->resolve($from, $store);
$this->message->setFrom($result['email'], $result['name']);
return $this;
}

/**
* Set template identifier
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Framework\Mail\Template;

use Magento\Framework\Mail\MessageInterface;

class TransportBuilderByStore
{
/**
* Message.
*
* @var \Magento\Framework\Mail\Message
*/
protected $message;

/**
* Sender resolver.
*
* @var \Magento\Framework\Mail\Template\SenderResolverInterface
*/
private $senderResolver;

/**
* @param MessageInterface $message
* @param SenderResolverInterface $senderResolver
*/
public function __construct(
MessageInterface $message,
SenderResolverInterface $senderResolver
) {
$this->message = $message;
$this->senderResolver = $senderResolver;
}

/**
* Set mail from address by store.
*
* @param string|array $from
* @param string|int $store
*
* @return $this
*/
public function setFromByStore($from, $store)
{
$result = $this->senderResolver->resolve($from, $store);
$this->message->setFrom($result['email'], $result['name']);

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Framework\Mail\Test\Unit\Template;

use Magento\Framework\Mail\Template\TransportBuilderByStore;

class TransportBuilderByStoreTest extends \PHPUnit\Framework\TestCase
{
/**
* @var \Magento\Framework\Mail\Template\TransportBuilderByStore
*/
protected $model;

/**
* @var \Magento\Framework\Mail\Message | \PHPUnit_Framework_MockObject_MockObject
*/
protected $messageMock;

/**
* @var \Magento\Framework\Mail\Template\SenderResolverInterface | \PHPUnit_Framework_MockObject_MockObject
*/
protected $senderResolverMock;

/**
* @return void
*/
protected function setUp()
{
$objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$this->messageMock = $this->createMock(\Magento\Framework\Mail\Message::class);
$this->senderResolverMock = $this->createMock(\Magento\Framework\Mail\Template\SenderResolverInterface::class);

$this->model = $objectManagerHelper->getObject(
TransportBuilderByStore::class,
[
'message' => $this->messageMock,
'senderResolver' => $this->senderResolverMock,
]
);
}

/**
* @return void
*/
public function setFromByStore()
{
$sender = ['email' => 'from@example.com', 'name' => 'name'];
$store = 1;
$this->senderResolverMock->expects($this->once())
->method('resolve')
->with($sender, $store)
->willReturn($sender);
$this->messageMock->expects($this->once())
->method('setFrom')
->with('from@example.com', 'name')
->willReturnSelf();

$this->model->setFromByStore($sender, $store);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,25 +168,6 @@ public function testSetFrom()
$this->builder->setFrom($sender);
}

/**
* @return void
*/
public function setFromByStore()
{
$sender = ['email' => 'from@example.com', 'name' => 'name'];
$store = 1;
$this->senderResolverMock->expects($this->once())
->method('resolve')
->with($sender, $store)
->willReturn($sender);
$this->messageMock->expects($this->once())
->method('setFrom')
->with('from@example.com', 'name')
->willReturnSelf();

$this->builder->setFromByStore($sender);
}

/**
* @return void
*/
Expand Down

1 comment on commit f2bfdd9

@0m3r
Copy link
Contributor

@0m3r 0m3r commented on f2bfdd9 Aug 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Houston we have a problem.

header 'from' is empty.

I looked at the log of my SMTP provider and it says the email is blocked because a "from" is missing.

Please check methods send and configureEmailTemplate in Magento/Sales/Model/Order/Email/SenderBuilder.php

public function send()
    {
        $this->configureEmailTemplate();
        ....
        $transport = $this->transportBuilder->getTransport();
        $transport->sendMessage();
}
...
protected function configureEmailTemplate()
{
     ...
     $this->transportBuilder->setTemplateVars($this->templateContainer->getTemplateVars());
     $this->transportBuilderByStore->setFromByStore(
         $this->identityContainer->getEmailIdentity(),
          $this->identityContainer->getStore()->getId()
      );
 }

Transport sub object message will be without 'from' because 'from' is set in another transportBuilderByStore.
f2bfdd9#diff-005142026772e36908ca304e67f21453L105

Please restore setFromByStore in lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php

/**
      * Set mail from address by store.
      *
      * @param string|array $from
      * @param string|int $store
      * @return $this
      */
     public function setFromByStore($from, $store)
     {
         $result = $this->_senderResolver->resolve($from, $store);
         $this->message->setFrom($result['email'], $result['name']);
         return $this;
     }

Debug for Zend_Mail_Transport_Smtp::_sendMail

\Zend_Debug::dump($this->_mail->getReturnPath(), 'From ');
$this->_connection->mail($this->_mail->getReturnPath());
\Zend_Debug::dump($this->_connection->getLog());
\Zend_Debug::dump($this->_connection->getRequest());
\Zend_Debug::dump($this->_connection->getResponse());

2018-08-20 14-16-09

p.s.

#16461

Please sign in to comment.