PageRenderTime 54ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/email/vendor/swift/classes/Swift/Transport/EsmtpTransport.php

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