*/}}

DSNConfigurator.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. /**
  3. * PHPMailer - PHP email creation and transport class.
  4. * PHP Version 5.5.
  5. *
  6. * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
  7. *
  8. * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
  9. * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
  10. * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
  11. * @author Brent R. Matzelle (original founder)
  12. * @copyright 2012 - 2023 Marcus Bointon
  13. * @copyright 2010 - 2012 Jim Jagielski
  14. * @copyright 2004 - 2009 Andy Prevost
  15. * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
  16. * @note This program is distributed in the hope that it will be useful - WITHOUT
  17. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  18. * FITNESS FOR A PARTICULAR PURPOSE.
  19. */
  20. namespace PHPMailer\PHPMailer;
  21. /**
  22. * Configure PHPMailer with DSN string.
  23. *
  24. * @see https://en.wikipedia.org/wiki/Data_source_name
  25. *
  26. * @author Oleg Voronkovich <oleg-voronkovich@yandex.ru>
  27. */
  28. class DSNConfigurator
  29. {
  30. /**
  31. * Create new PHPMailer instance configured by DSN.
  32. *
  33. * @param string $dsn DSN
  34. * @param bool $exceptions Should we throw external exceptions?
  35. *
  36. * @return PHPMailer
  37. */
  38. public static function mailer($dsn, $exceptions = null)
  39. {
  40. static $configurator = null;
  41. if (null === $configurator) {
  42. $configurator = new DSNConfigurator();
  43. }
  44. return $configurator->configure(new PHPMailer($exceptions), $dsn);
  45. }
  46. /**
  47. * Configure PHPMailer instance with DSN string.
  48. *
  49. * @param PHPMailer $mailer PHPMailer instance
  50. * @param string $dsn DSN
  51. *
  52. * @return PHPMailer
  53. */
  54. public function configure(PHPMailer $mailer, $dsn)
  55. {
  56. $config = $this->parseDSN($dsn);
  57. $this->applyConfig($mailer, $config);
  58. return $mailer;
  59. }
  60. /**
  61. * Parse DSN string.
  62. *
  63. * @param string $dsn DSN
  64. *
  65. * @throws Exception If DSN is malformed
  66. *
  67. * @return array Configuration
  68. */
  69. private function parseDSN($dsn)
  70. {
  71. $config = $this->parseUrl($dsn);
  72. if (false === $config || !isset($config['scheme']) || !isset($config['host'])) {
  73. throw new Exception('Malformed DSN');
  74. }
  75. if (isset($config['query'])) {
  76. parse_str($config['query'], $config['query']);
  77. }
  78. return $config;
  79. }
  80. /**
  81. * Apply configuration to mailer.
  82. *
  83. * @param PHPMailer $mailer PHPMailer instance
  84. * @param array $config Configuration
  85. *
  86. * @throws Exception If scheme is invalid
  87. */
  88. private function applyConfig(PHPMailer $mailer, $config)
  89. {
  90. switch ($config['scheme']) {
  91. case 'mail':
  92. $mailer->isMail();
  93. break;
  94. case 'sendmail':
  95. $mailer->isSendmail();
  96. break;
  97. case 'qmail':
  98. $mailer->isQmail();
  99. break;
  100. case 'smtp':
  101. case 'smtps':
  102. $mailer->isSMTP();
  103. $this->configureSMTP($mailer, $config);
  104. break;
  105. default:
  106. throw new Exception(
  107. sprintf(
  108. 'Invalid scheme: "%s". Allowed values: "mail", "sendmail", "qmail", "smtp", "smtps".',
  109. $config['scheme']
  110. )
  111. );
  112. }
  113. if (isset($config['query'])) {
  114. $this->configureOptions($mailer, $config['query']);
  115. }
  116. }
  117. /**
  118. * Configure SMTP.
  119. *
  120. * @param PHPMailer $mailer PHPMailer instance
  121. * @param array $config Configuration
  122. */
  123. private function configureSMTP($mailer, $config)
  124. {
  125. $isSMTPS = 'smtps' === $config['scheme'];
  126. if ($isSMTPS) {
  127. $mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
  128. }
  129. $mailer->Host = $config['host'];
  130. if (isset($config['port'])) {
  131. $mailer->Port = $config['port'];
  132. } elseif ($isSMTPS) {
  133. $mailer->Port = SMTP::DEFAULT_SECURE_PORT;
  134. }
  135. $mailer->SMTPAuth = isset($config['user']) || isset($config['pass']);
  136. if (isset($config['user'])) {
  137. $mailer->Username = $config['user'];
  138. }
  139. if (isset($config['pass'])) {
  140. $mailer->Password = $config['pass'];
  141. }
  142. }
  143. /**
  144. * Configure options.
  145. *
  146. * @param PHPMailer $mailer PHPMailer instance
  147. * @param array $options Options
  148. *
  149. * @throws Exception If option is unknown
  150. */
  151. private function configureOptions(PHPMailer $mailer, $options)
  152. {
  153. $allowedOptions = get_object_vars($mailer);
  154. unset($allowedOptions['Mailer']);
  155. unset($allowedOptions['SMTPAuth']);
  156. unset($allowedOptions['Username']);
  157. unset($allowedOptions['Password']);
  158. unset($allowedOptions['Hostname']);
  159. unset($allowedOptions['Port']);
  160. unset($allowedOptions['ErrorInfo']);
  161. $allowedOptions = \array_keys($allowedOptions);
  162. foreach ($options as $key => $value) {
  163. if (!in_array($key, $allowedOptions)) {
  164. throw new Exception(
  165. sprintf(
  166. 'Unknown option: "%s". Allowed values: "%s"',
  167. $key,
  168. implode('", "', $allowedOptions)
  169. )
  170. );
  171. }
  172. switch ($key) {
  173. case 'AllowEmpty':
  174. case 'SMTPAutoTLS':
  175. case 'SMTPKeepAlive':
  176. case 'SingleTo':
  177. case 'UseSendmailOptions':
  178. case 'do_verp':
  179. case 'DKIM_copyHeaderFields':
  180. $mailer->$key = (bool) $value;
  181. break;
  182. case 'Priority':
  183. case 'SMTPDebug':
  184. case 'WordWrap':
  185. $mailer->$key = (int) $value;
  186. break;
  187. default:
  188. $mailer->$key = $value;
  189. break;
  190. }
  191. }
  192. }
  193. /**
  194. * Parse a URL.
  195. * Wrapper for the built-in parse_url function to work around a bug in PHP 5.5.
  196. *
  197. * @param string $url URL
  198. *
  199. * @return array|false
  200. */
  201. protected function parseUrl($url)
  202. {
  203. if (\PHP_VERSION_ID >= 50600 || false === strpos($url, '?')) {
  204. return parse_url($url);
  205. }
  206. $chunks = explode('?', $url);
  207. if (is_array($chunks)) {
  208. $result = parse_url($chunks[0]);
  209. if (is_array($result)) {
  210. $result['query'] = $chunks[1];
  211. }
  212. return $result;
  213. }
  214. return false;
  215. }
  216. }