PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/app/protected/extensions/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php

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