PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Foundry 1.8.1/mail/lib/classes/Swift/Transport/EsmtpTransport.php

https://gitlab.com/shivkumarsah/shivkumarsah.com
PHP | 387 lines | 217 code | 41 blank | 129 comment | 14 complexity | 6d5535fe2982778066dbc37f504568b4 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 $this->_params['sourceIp'];
  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. {
  229. $return = call_user_func_array(array($handler, $method), $args);
  230. // Allow fluid method calls
  231. if (is_null($return) && substr($method, 0, 3) == 'set') {
  232. return $this;
  233. } else {
  234. return $return;
  235. }
  236. }
  237. }
  238. trigger_error('Call to undefined method ' . $method, E_USER_ERROR);
  239. }
  240. /** Get the params to initialize the buffer */
  241. protected function _getBufferParams()
  242. {
  243. return $this->_params;
  244. }
  245. /** Overridden to perform EHLO instead */
  246. protected function _doHeloCommand()
  247. {
  248. try {
  249. $response = $this->executeCommand(
  250. sprintf("EHLO %s\r\n", $this->_domain), array(250)
  251. );
  252. } catch (Swift_TransportException $e) {
  253. return parent::_doHeloCommand();
  254. }
  255. if ($this->_params['tls']) {
  256. try {
  257. $this->executeCommand("STARTTLS\r\n", array(220));
  258. if (!$this->_buffer->startTLS()) {
  259. throw new Swift_TransportException('Unable to connect with TLS encryption');
  260. }
  261. try {
  262. $response = $this->executeCommand(
  263. sprintf("EHLO %s\r\n", $this->_domain), array(250)
  264. );
  265. } catch (Swift_TransportException $e) {
  266. return parent::_doHeloCommand();
  267. }
  268. } catch (Swift_TransportException $e) {
  269. $this->_throwException($e);
  270. }
  271. }
  272. $this->_capabilities = $this->_getCapabilities($response);
  273. $this->_setHandlerParams();
  274. foreach ($this->_getActiveHandlers() as $handler) {
  275. $handler->afterEhlo($this);
  276. }
  277. }
  278. /** Overridden to add Extension support */
  279. protected function _doMailFromCommand($address)
  280. {
  281. $handlers = $this->_getActiveHandlers();
  282. $params = array();
  283. foreach ($handlers as $handler) {
  284. $params = array_merge($params, (array) $handler->getMailParams());
  285. }
  286. $paramStr = !empty($params) ? ' ' . implode(' ', $params) : '';
  287. $this->executeCommand(
  288. sprintf("MAIL FROM: <%s>%s\r\n", $address, $paramStr), array(250)
  289. );
  290. }
  291. /** Overridden to add Extension support */
  292. protected function _doRcptToCommand($address)
  293. {
  294. $handlers = $this->_getActiveHandlers();
  295. $params = array();
  296. foreach ($handlers as $handler) {
  297. $params = array_merge($params, (array) $handler->getRcptParams());
  298. }
  299. $paramStr = !empty($params) ? ' ' . implode(' ', $params) : '';
  300. $this->executeCommand(
  301. sprintf("RCPT TO: <%s>%s\r\n", $address, $paramStr), array(250, 251, 252)
  302. );
  303. }
  304. /** Determine ESMTP capabilities by function group */
  305. private function _getCapabilities($ehloResponse)
  306. {
  307. $capabilities = array();
  308. $ehloResponse = trim($ehloResponse);
  309. $lines = explode("\r\n", $ehloResponse);
  310. array_shift($lines);
  311. foreach ($lines as $line) {
  312. if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) {
  313. $keyword = strtoupper($matches[1]);
  314. $paramStr = strtoupper(ltrim($matches[2], ' ='));
  315. $params = !empty($paramStr) ? explode(' ', $paramStr) : array();
  316. $capabilities[$keyword] = $params;
  317. }
  318. }
  319. return $capabilities;
  320. }
  321. /** Set parameters which are used by each extension handler */
  322. private function _setHandlerParams()
  323. {
  324. foreach ($this->_handlers as $keyword => $handler) {
  325. if (array_key_exists($keyword, $this->_capabilities)) {
  326. $handler->setKeywordParams($this->_capabilities[$keyword]);
  327. }
  328. }
  329. }
  330. /** Get ESMTP handlers which are currently ok to use */
  331. private function _getActiveHandlers()
  332. {
  333. $handlers = array();
  334. foreach ($this->_handlers as $keyword => $handler) {
  335. if (array_key_exists($keyword, $this->_capabilities)) {
  336. $handlers[] = $handler;
  337. }
  338. }
  339. return $handlers;
  340. }
  341. /** Custom sort for extension handler ordering */
  342. private function _sortHandlers($a, $b)
  343. {
  344. return $a->getPriorityOver($b->getHandledKeyword());
  345. }
  346. }