PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/swift/classes/Swift/Transport/EsmtpTransport.php

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