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

/framework/lib/swift/classes/Swift/Transport/EsmtpTransport.php

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