77
88namespace Magento \Email \Model ;
99
10+ use Laminas \Mail \Transport \Smtp ;
11+ use Laminas \Mail \Transport \SmtpOptions ;
1012use Magento \Framework \App \Config \ScopeConfigInterface ;
1113use Magento \Framework \App \ObjectManager ;
1214use Magento \Framework \Exception \MailException ;
1618use Magento \Store \Model \ScopeInterface ;
1719use Laminas \Mail \Message ;
1820use Laminas \Mail \Transport \Sendmail ;
21+ use Laminas \Mail \Transport \TransportInterface as LaminasTransportInterface ;
1922use Psr \Log \LoggerInterface ;
2023
2124/**
2225 * Class that responsible for filling some message data before transporting it.
2326 * @see \Laminas\Mail\Transport\Sendmail is used for transport
27+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2428 */
2529class Transport implements TransportInterface
2630{
2731 /**
2832 * Configuration path to source of Return-Path and whether it should be set at all
2933 * @see \Magento\Config\Model\Config\Source\Yesnocustom to possible values
3034 */
31- const XML_PATH_SENDING_SET_RETURN_PATH = 'system/smtp/set_return_path ' ;
35+ public const XML_PATH_SENDING_SET_RETURN_PATH = 'system/smtp/set_return_path ' ;
3236
3337 /**
3438 * Configuration path for custom Return-Path email
3539 */
36- const XML_PATH_SENDING_RETURN_PATH_EMAIL = 'system/smtp/return_path_email ' ;
40+ public const XML_PATH_SENDING_RETURN_PATH_EMAIL = 'system/smtp/return_path_email ' ;
41+
42+ /**
43+ * Configuration path for custom Transport
44+ */
45+ private const XML_PATH_TRANSPORT = 'system/smtp/transport ' ;
46+
47+ /**
48+ * Configuration path for SMTP Host
49+ */
50+ private const XML_PATH_HOST = 'system/smtp/host ' ;
51+
52+ /**
53+ * Configuration path for SMTP Port
54+ */
55+ private const XML_PATH_PORT = 'system/smtp/port ' ;
56+
57+ /**
58+ * Configuration path for SMTP Username
59+ */
60+ private const XML_PATH_USERNAME = 'system/smtp/username ' ;
61+
62+ /**
63+ * Configuration path for SMTP Password
64+ */
65+ private const XML_PATH_PASSWORD = 'system/smtp/password ' ;
66+
67+ /**
68+ * Configuration path for SMTP Auth type
69+ */
70+ private const XML_PATH_AUTH = 'system/smtp/auth ' ;
71+
72+ /**
73+ * Configuration path for SMTP SSL value
74+ */
75+ private const XML_PATH_SSL = 'system/smtp/ssl ' ;
3776
3877 /**
3978 * Whether return path should be set or no.
@@ -53,10 +92,20 @@ class Transport implements TransportInterface
5392 private $ returnPathValue ;
5493
5594 /**
56- * @var Sendmail
95+ * @var ScopeConfigInterface
96+ */
97+ private $ scopeConfig ;
98+
99+ /**
100+ * @var LaminasTransportInterface|null
57101 */
58102 private $ laminasTransport ;
59103
104+ /**
105+ * @var null|string|array|\Traversable
106+ */
107+ private $ parameters ;
108+
60109 /**
61110 * @var MessageInterface
62111 */
@@ -87,12 +136,35 @@ public function __construct(
87136 self ::XML_PATH_SENDING_RETURN_PATH_EMAIL ,
88137 ScopeInterface::SCOPE_STORE
89138 );
90-
91- $ this ->laminasTransport = new Sendmail ($ parameters );
92139 $ this ->message = $ message ;
140+ $ this ->scopeConfig = $ scopeConfig ;
141+ $ this ->parameters = $ parameters ;
93142 $ this ->logger = $ logger ?: ObjectManager::getInstance ()->get (LoggerInterface::class);
94143 }
95144
145+ /**
146+ * Get the LaminasTransport based on the configuration.
147+ *
148+ * @return LaminasTransportInterface
149+ */
150+ public function getTransport (): LaminasTransportInterface
151+ {
152+ if ($ this ->laminasTransport === null ) {
153+ $ transport = $ this ->scopeConfig ->getValue (
154+ self ::XML_PATH_TRANSPORT ,
155+ ScopeInterface::SCOPE_STORE
156+ );
157+
158+ if ($ transport === 'smtp ' ) {
159+ $ this ->laminasTransport = $ this ->createSmtpTransport ();
160+ } else {
161+ $ this ->laminasTransport = $ this ->createSendmailTransport ();
162+ }
163+ }
164+
165+ return $ this ->laminasTransport ;
166+ }
167+
96168 /**
97169 * @inheritdoc
98170 */
@@ -108,7 +180,7 @@ public function sendMessage()
108180 $ laminasMessage ->setSender ($ fromAddressList ->current ()->getEmail ());
109181 }
110182
111- $ this ->laminasTransport ->send ($ laminasMessage );
183+ $ this ->getTransport () ->send ($ laminasMessage );
112184 } catch (\Exception $ e ) {
113185 $ this ->logger ->error ($ e );
114186 throw new MailException (new Phrase ('Unable to send mail. Please try again later. ' ), $ e );
@@ -122,4 +194,75 @@ public function getMessage()
122194 {
123195 return $ this ->message ;
124196 }
197+
198+ /**
199+ * Create a Smtp LaminasTransport.
200+ *
201+ * @return Smtp
202+ */
203+ private function createSmtpTransport (): Smtp
204+ {
205+ $ host = $ this ->scopeConfig ->getValue (
206+ self ::XML_PATH_HOST ,
207+ ScopeInterface::SCOPE_STORE
208+ );
209+
210+ $ port = $ this ->scopeConfig ->getValue (
211+ self ::XML_PATH_PORT ,
212+ ScopeInterface::SCOPE_STORE
213+ );
214+
215+ $ username = $ this ->scopeConfig ->getValue (
216+ self ::XML_PATH_USERNAME ,
217+ ScopeInterface::SCOPE_STORE
218+ );
219+
220+ $ password = $ this ->scopeConfig ->getValue (
221+ self ::XML_PATH_PASSWORD ,
222+ ScopeInterface::SCOPE_STORE
223+ );
224+
225+ $ auth = $ this ->scopeConfig ->getValue (
226+ self ::XML_PATH_AUTH ,
227+ ScopeInterface::SCOPE_STORE
228+ );
229+
230+ $ ssl = $ this ->scopeConfig ->getValue (
231+ self ::XML_PATH_SSL ,
232+ ScopeInterface::SCOPE_STORE
233+ );
234+
235+ $ options = [
236+ 'name ' => 'localhost ' ,
237+ 'host ' => $ host ,
238+ 'port ' => $ port ,
239+ 'connection_config ' => [
240+ 'username ' => $ username ,
241+ 'password ' => $ password ,
242+ ]
243+ ];
244+
245+ if ($ auth && $ auth !== 'none ' ) {
246+ $ options ['connection_class ' ] = $ auth ;
247+ }
248+
249+ if ($ ssl && $ ssl !== 'none ' ) {
250+ $ options ['connection_config ' ]['ssl ' ] = $ ssl ;
251+ }
252+
253+ $ transport = new Smtp ();
254+ $ transport ->setOptions (new SmtpOptions ($ options ));
255+
256+ return $ transport ;
257+ }
258+
259+ /**
260+ * Create a Sendmail Laminas Transport
261+ *
262+ * @return Sendmail
263+ */
264+ private function createSendmailTransport (): Sendmail
265+ {
266+ return new Sendmail ($ this ->parameters );
267+ }
125268}
0 commit comments