PageRenderTime 44ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php

https://gitlab.com/judielsm/Handora
PHP | 386 lines | 216 code | 41 blank | 129 comment | 14 complexity | edf22b386937b4cd0d1cd8def7a47e4b MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of SwiftMailer.
  4. * (c) 2004-2009 Chris Corbyn
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * Sends Messages over SMTP with ESMTP support.
  11. *
  12. * @author Chris Corbyn
  13. */
  14. class Swift_Transport_EsmtpTransport extends Swift_Transport_AbstractSmtpTransport implements Swift_Transport_SmtpAgent
  15. {
  16. /**
  17. * ESMTP extension handlers.
  18. *
  19. * @var Swift_Transport_EsmtpHandler[]
  20. */
  21. private $_handlers = array();
  22. /**
  23. * ESMTP capabilities.
  24. *
  25. * @var string[]
  26. */
  27. private $_capabilities = array();
  28. /**
  29. * Connection buffer parameters.
  30. *
  31. * @var array
  32. */
  33. private $_params = array(
  34. 'protocol' => 'tcp',
  35. 'host' => 'localhost',
  36. 'port' => 25,
  37. 'timeout' => 30,
  38. 'blocking' => 1,
  39. 'tls' => false,
  40. 'type' => Swift_Transport_IoBuffer::TYPE_SOCKET,
  41. );
  42. /**
  43. * Creates a new EsmtpTransport using the given I/O buffer.
  44. *
  45. * @param Swift_Transport_IoBuffer $buf
  46. * @param Swift_Transport_EsmtpHandler[] $extensionHandlers
  47. * @param Swift_Events_EventDispatcher $dispatcher
  48. */
  49. public function __construct(Swift_Transport_IoBuffer $buf, array $extensionHandlers, Swift_Events_EventDispatcher $dispatcher)
  50. {
  51. parent::__construct($buf, $dispatcher);
  52. $this->setExtensionHandlers($extensionHandlers);
  53. }
  54. /**
  55. * Set the host to connect to.
  56. *
  57. * @param string $host
  58. *
  59. * @return Swift_Transport_EsmtpTransport
  60. */
  61. public function setHost($host)
  62. {
  63. $this->_params['host'] = $host;
  64. return $this;
  65. }
  66. /**
  67. * Get the host to connect to.
  68. *
  69. * @return string
  70. */
  71. public function getHost()
  72. {
  73. return $this->_params['host'];
  74. }
  75. /**
  76. * Set the port to connect to.
  77. *
  78. * @param int $port
  79. *
  80. * @return Swift_Transport_EsmtpTransport
  81. */
  82. public function setPort($port)
  83. {
  84. $this->_params['port'] = (int) $port;
  85. return $this;
  86. }
  87. /**
  88. * Get the port to connect to.
  89. *
  90. * @return int
  91. */
  92. public function getPort()
  93. {
  94. return $this->_params['port'];
  95. }
  96. /**
  97. * Set the connection timeout.
  98. *
  99. * @param int $timeout seconds
  100. *
  101. * @return Swift_Transport_EsmtpTransport
  102. */
  103. public function setTimeout($timeout)
  104. {
  105. $this->_params['timeout'] = (int) $timeout;
  106. $this->_buffer->setParam('timeout', (int) $timeout);
  107. return $this;
  108. }
  109. /**
  110. * Get the connection timeout.
  111. *
  112. * @return int
  113. */
  114. public function getTimeout()
  115. {
  116. return $this->_params['timeout'];
  117. }
  118. /**
  119. * Set the encryption type (tls or ssl).
  120. *
  121. * @param string $encryption
  122. *
  123. * @return Swift_Transport_EsmtpTransport
  124. */
  125. public function setEncryption($encryption)
  126. {
  127. if ('tls' == $encryption) {
  128. $this->_params['protocol'] = 'tcp';
  129. $this->_params['tls'] = true;
  130. } else {
  131. $this->_params['protocol'] = $encryption;
  132. $this->_params['tls'] = false;
  133. }
  134. return $this;
  135. }
  136. /**
  137. * Get the encryption type.
  138. *
  139. * @return string
  140. */
  141. public function getEncryption()
  142. {
  143. return $this->_params['tls'] ? 'tls' : $this->_params['protocol'];
  144. }
  145. /**
  146. * Sets the source IP.
  147. *
  148. * @param string $source
  149. *
  150. * @return Swift_Transport_EsmtpTransport
  151. */
  152. public function setSourceIp($source)
  153. {
  154. $this->_params['sourceIp'] = $source;
  155. return $this;
  156. }
  157. /**
  158. * Returns the IP used to connect to the destination.
  159. *
  160. * @return string
  161. */
  162. public function getSourceIp()
  163. {
  164. return isset($this->_params['sourceIp']) ? $this->_params['sourceIp'] : null;
  165. }
  166. /**
  167. * Set ESMTP extension handlers.
  168. *
  169. * @param Swift_Transport_EsmtpHandler[] $handlers
  170. *
  171. * @return Swift_Transport_EsmtpTransport
  172. */
  173. public function setExtensionHandlers(array $handlers)
  174. {
  175. $assoc = array();
  176. foreach ($handlers as $handler) {
  177. $assoc[$handler->getHandledKeyword()] = $handler;
  178. }
  179. uasort($assoc, array($this, '_sortHandlers'));
  180. $this->_handlers = $assoc;
  181. $this->_setHandlerParams();
  182. return $this;
  183. }
  184. /**
  185. * Get ESMTP extension handlers.
  186. *
  187. * @return Swift_Transport_EsmtpHandler[]
  188. */
  189. public function getExtensionHandlers()
  190. {
  191. return array_values($this->_handlers);
  192. }
  193. /**
  194. * Run a command against the buffer, expecting the given response codes.
  195. *
  196. * If no response codes are given, the response will not be validated.
  197. * If codes are given, an exception will be thrown on an invalid response.
  198. *
  199. * @param string $command
  200. * @param int[] $codes
  201. * @param string[] $failures An array of failures by-reference
  202. *
  203. * @return string
  204. */
  205. public function executeCommand($command, $codes = array(), &$failures = null)
  206. {
  207. $failures = (array) $failures;
  208. $stopSignal = false;
  209. $response = null;
  210. foreach ($this->_getActiveHandlers() as $handler) {
  211. $response = $handler->onCommand(
  212. $this, $command, $codes, $failures, $stopSignal
  213. );
  214. if ($stopSignal) {
  215. return $response;
  216. }
  217. }
  218. return parent::executeCommand($command, $codes, $failures);
  219. }
  220. // -- Mixin invocation code
  221. /** Mixin handling method for ESMTP handlers */
  222. public function __call($method, $args)
  223. {
  224. foreach ($this->_handlers as $handler) {
  225. if (in_array(strtolower($method),
  226. array_map('strtolower', (array) $handler->exposeMixinMethods())
  227. )) {
  228. $return = call_user_func_array(array($handler, $method), $args);
  229. // Allow fluid method calls
  230. if (is_null($return) && substr($method, 0, 3) == 'set') {
  231. return $this;
  232. } else {
  233. return $return;
  234. }
  235. }
  236. }
  237. trigger_error('Call to undefined method '.$method, E_USER_ERROR);
  238. }
  239. /** Get the params to initialize the buffer */
  240. protected function _getBufferParams()
  241. {
  242. return $this->_params;
  243. }
  244. /** Overridden to perform EHLO instead */
  245. protected function _doHeloCommand()
  246. {
  247. try {
  248. $response = $this->executeCommand(
  249. sprintf("EHLO %s\r\n", $this->_domain), array(250)
  250. );
  251. } catch (Swift_TransportException $e) {
  252. return parent::_doHeloCommand();
  253. }
  254. if ($this->_params['tls']) {
  255. try {
  256. $this->executeCommand("STARTTLS\r\n", array(220));
  257. if (!$this->_buffer->startTLS()) {
  258. throw new Swift_TransportException('Unable to connect with TLS encryption');
  259. }
  260. try {
  261. $response = $this->executeCommand(
  262. sprintf("EHLO %s\r\n", $this->_domain), array(250)
  263. );
  264. } catch (Swift_TransportException $e) {
  265. return parent::_doHeloCommand();
  266. }
  267. } catch (Swift_TransportException $e) {
  268. $this->_throwException($e);
  269. }
  270. }
  271. $this->_capabilities = $this->_getCapabilities($response);
  272. $this->_setHandlerParams();
  273. foreach ($this->_getActiveHandlers() as $handler) {
  274. $handler->afterEhlo($this);
  275. }
  276. }
  277. /** Overridden to add Extension support */
  278. protected function _doMailFromCommand($address)
  279. {
  280. $handlers = $this->_getActiveHandlers();
  281. $params = array();
  282. foreach ($handlers as $handler) {
  283. $params = array_merge($params, (array) $handler->getMailParams());
  284. }
  285. $paramStr = !empty($params) ? ' '.implode(' ', $params) : '';
  286. $this->executeCommand(
  287. sprintf("MAIL FROM:<%s>%s\r\n", $address, $paramStr), array(250)
  288. );
  289. }
  290. /** Overridden to add Extension support */
  291. protected function _doRcptToCommand($address)
  292. {
  293. $handlers = $this->_getActiveHandlers();
  294. $params = array();
  295. foreach ($handlers as $handler) {
  296. $params = array_merge($params, (array) $handler->getRcptParams());
  297. }
  298. $paramStr = !empty($params) ? ' '.implode(' ', $params) : '';
  299. $this->executeCommand(
  300. sprintf("RCPT TO:<%s>%s\r\n", $address, $paramStr), array(250, 251, 252)
  301. );
  302. }
  303. /** Determine ESMTP capabilities by function group */
  304. private function _getCapabilities($ehloResponse)
  305. {
  306. $capabilities = array();
  307. $ehloResponse = trim($ehloResponse);
  308. $lines = explode("\r\n", $ehloResponse);
  309. array_shift($lines);
  310. foreach ($lines as $line) {
  311. if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) {
  312. $keyword = strtoupper($matches[1]);
  313. $paramStr = strtoupper(ltrim($matches[2], ' ='));
  314. $params = !empty($paramStr) ? explode(' ', $paramStr) : array();
  315. $capabilities[$keyword] = $params;
  316. }
  317. }
  318. return $capabilities;
  319. }
  320. /** Set parameters which are used by each extension handler */
  321. private function _setHandlerParams()
  322. {
  323. foreach ($this->_handlers as $keyword => $handler) {
  324. if (array_key_exists($keyword, $this->_capabilities)) {
  325. $handler->setKeywordParams($this->_capabilities[$keyword]);
  326. }
  327. }
  328. }
  329. /** Get ESMTP handlers which are currently ok to use */
  330. private function _getActiveHandlers()
  331. {
  332. $handlers = array();
  333. foreach ($this->_handlers as $keyword => $handler) {
  334. if (array_key_exists($keyword, $this->_capabilities)) {
  335. $handlers[] = $handler;
  336. }
  337. }
  338. return $handlers;
  339. }
  340. /** Custom sort for extension handler ordering */
  341. private function _sortHandlers($a, $b)
  342. {
  343. return $a->getPriorityOver($b->getHandledKeyword());
  344. }
  345. }