PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/core/model/modx/mail/modmail.class.php

http://github.com/modxcms/revolution
PHP | 430 lines | 154 code | 18 blank | 258 comment | 16 complexity | 301a45cf22bcca05b3b8d736d6e0b326 MD5 | raw file
Possible License(s): GPL-2.0, Apache-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /*
  3. * This file is part of MODX Revolution.
  4. *
  5. * Copyright (c) MODX, LLC. All Rights Reserved.
  6. *
  7. * For complete copyright and license information, see the COPYRIGHT and LICENSE
  8. * files found in the top-level directory of this distribution.
  9. */
  10. /**
  11. * Defines the interface for the modX email service.
  12. *
  13. * @abstract Implement a derivative of this class to define an actual email service implementation.
  14. * @package modx
  15. * @subpackage mail
  16. */
  17. abstract class modMail {
  18. /**
  19. * @const An option for setting the mail body
  20. */
  21. const MAIL_BODY = 'mail_body';
  22. /**
  23. * @const An option for setting the mail body text
  24. */
  25. const MAIL_BODY_TEXT = 'mail_body_text';
  26. /**
  27. * @const An option for setting the mail charset
  28. */
  29. const MAIL_CHARSET = 'mail_charset';
  30. /**
  31. * @const An option for setting the mail content type
  32. */
  33. const MAIL_CONTENT_TYPE = 'mail_content_type';
  34. /**
  35. * @const An option for setting the mail encoding
  36. */
  37. const MAIL_ENCODING = 'mail_encoding';
  38. /**
  39. * @const An option for setting the mail engine
  40. */
  41. const MAIL_ENGINE = 'mail_engine';
  42. /**
  43. * @const An option for setting the mail engine path
  44. */
  45. const MAIL_ENGINE_PATH = 'mail_engine_path';
  46. /**
  47. * @const An option for setting the mail error information
  48. */
  49. const MAIL_ERROR_INFO = 'mail_error_info';
  50. /**
  51. * @const An option for setting the mail From address
  52. */
  53. const MAIL_FROM = 'mail_from';
  54. /**
  55. * @const An option for setting the mail From name
  56. */
  57. const MAIL_FROM_NAME = 'mail_from_name';
  58. /**
  59. * @const An option for setting the mail hostname
  60. */
  61. const MAIL_HOSTNAME = 'mail_hostname';
  62. /**
  63. * @const An option for setting the mail language
  64. */
  65. const MAIL_LANGUAGE = 'mail_language';
  66. /**
  67. * @const An option for setting the mail priority header
  68. */
  69. const MAIL_PRIORITY = 'mail_priority';
  70. /**
  71. * @const An option for setting the mail read to header
  72. */
  73. const MAIL_READ_TO = 'mail_read_to';
  74. /**
  75. * @const An option for setting the mail sender
  76. */
  77. const MAIL_SENDER = 'mail_sender';
  78. /**
  79. * @const An option for setting the mail service
  80. */
  81. const MAIL_SERVICE = 'mail_service';
  82. /**
  83. * @const An option for setting the mail SMTP auth type
  84. */
  85. const MAIL_SMTP_AUTH = 'mail_smtp_auth';
  86. /**
  87. * @const An option for setting the mail SMTP HELO boolean
  88. */
  89. const MAIL_SMTP_HELO = 'mail_smtp_helo';
  90. /**
  91. * @const An option for setting the mail SMTP hosts
  92. */
  93. const MAIL_SMTP_HOSTS = 'mail_smtp_hosts';
  94. /**
  95. * @const An option for setting the mail SMTP Keep-Alive boolean
  96. */
  97. const MAIL_SMTP_KEEPALIVE = 'mail_smtp_keepalive';
  98. /**
  99. * @const An option for setting the mail SMTP password
  100. */
  101. const MAIL_SMTP_PASS = 'mail_smtp_pass';
  102. /**
  103. * @const An option for setting the mail SMTP port
  104. */
  105. const MAIL_SMTP_PORT = 'mail_smtp_port';
  106. /**
  107. * @const An option for setting the mail SMTP prefix
  108. */
  109. const MAIL_SMTP_PREFIX = 'mail_smtp_prefix';
  110. /**
  111. * @const An option for setting the mail SMTP Single-To option
  112. */
  113. const MAIL_SMTP_SINGLE_TO = 'mail_smtp_single_to';
  114. /**
  115. * @const An option for setting the mail SMTP timeout
  116. */
  117. const MAIL_SMTP_TIMEOUT = 'mail_smtp_timeout';
  118. /**
  119. * @const An option for setting the mail SMTP username
  120. */
  121. const MAIL_SMTP_USER = 'mail_smtp_user';
  122. /**
  123. * @const An option for setting the mail subject
  124. */
  125. const MAIL_SUBJECT = 'mail_subject';
  126. /**
  127. * @const An option for setting the mail DKIM selector
  128. */
  129. const MAIL_DKIM_SELECTOR = 'mail_dkim_selector';
  130. /**
  131. * @const An option for setting the DKIM identity you're signing as - usually your From address
  132. */
  133. const MAIL_DKIM_IDENTITY = 'mail_dkim_identity';
  134. /**
  135. * @const An option for setting DKIM domain name
  136. */
  137. const MAIL_DKIM_DOMAIN = 'mail_dkim_domain';
  138. /**
  139. * @const An option for setting DKIM private key file path
  140. */
  141. const MAIL_DKIM_PRIVATEKEYFILE = 'mail_dkim_privatekeyfile';
  142. /**
  143. * @const An option for setting DKIM private key string - takes precedence over MAIL_DKIM_PRIVATEKEYFILE
  144. */
  145. const MAIL_DKIM_PRIVATEKEYSTRING = 'mail_dkim_privatekeystring';
  146. /**
  147. * @const An option for setting DKIM passphrase - used if your private key has a passphrase
  148. */
  149. const MAIL_DKIM_PASSPHRASE = 'mail_dkim_passphrase';
  150. /**
  151. * A reference to the modX instance communicating with this service instance.
  152. * @var modX
  153. */
  154. public $modx= null;
  155. /**
  156. * A collection of attributes defining all of the details of email communication.
  157. * @var array
  158. */
  159. public $attributes= array();
  160. /**
  161. * The mailer object responsible for implementing the modMail methods.
  162. * @var object
  163. */
  164. public $mailer= null;
  165. /**
  166. * A collection of all the current headers for the object.
  167. * @var array
  168. */
  169. public $headers= array();
  170. /**
  171. * An array of address types: to, cc, bcc, reply-to
  172. * @var array
  173. */
  174. public $addresses= array(
  175. 'to' => array(),
  176. 'cc' => array(),
  177. 'bcc' => array(),
  178. 'reply-to' => array(),
  179. );
  180. /**
  181. * An array of attached files
  182. * @var array
  183. */
  184. public $files= array();
  185. /**
  186. * An array of embedded images
  187. * @var array
  188. */
  189. public $images= array();
  190. /**
  191. * Error
  192. * @access protected
  193. * @var modError
  194. */
  195. protected $error = null;
  196. /**
  197. * Constructs a new instance of the modMail class.
  198. *
  199. * @param modX &$modx A reference to the modX instance
  200. * @param array $attributes An array of attributes to assign to the new mail instance
  201. */
  202. function __construct(modX &$modx, array $attributes= array()) {
  203. $this->modx= & $modx;
  204. if (!$this->modx->lexicon) {
  205. $this->modx->getService('lexicon','modLexicon');
  206. }
  207. $this->modx->lexicon->load('mail');
  208. $this->defaultAttributes = is_array($attributes) ? $attributes : array();
  209. $this->attributes= $this->getDefaultAttributes($attributes);
  210. }
  211. /**
  212. * Gets the default attributes for modMail based on system settings
  213. *
  214. * @param array $attributes An optional array of default attributes to override with
  215. * @return array An array of default attributes
  216. */
  217. public function getDefaultAttributes(array $attributes = array()) {
  218. $default = array();
  219. if ($this->modx->getOption('mail_use_smtp',false)) {
  220. $default[modMail::MAIL_ENGINE] = 'smtp';
  221. $default[modMail::MAIL_SMTP_AUTH] = $this->modx->getOption('mail_smtp_auth',null,false);
  222. $helo = $this->modx->getOption('mail_smtp_helo','');
  223. if (!empty($helo)) { $default[modMail::MAIL_SMTP_HELO] = $helo; }
  224. $default[modMail::MAIL_SMTP_HOSTS] = $this->modx->getOption('mail_smtp_hosts',null,'localhost');
  225. $default[modMail::MAIL_SMTP_KEEPALIVE] = $this->modx->getOption('mail_smtp_keepalive',null,false);
  226. $default[modMail::MAIL_SMTP_PASS] = $this->modx->getOption('mail_smtp_pass',null,'');
  227. $default[modMail::MAIL_SMTP_PORT] = $this->modx->getOption('mail_smtp_port',null,25);
  228. $default[modMail::MAIL_SMTP_PREFIX] = $this->modx->getOption('mail_smtp_prefix',null,'');
  229. $default[modMail::MAIL_SMTP_SINGLE_TO] = $this->modx->getOption('mail_smtp_single_to',null,false);
  230. $default[modMail::MAIL_SMTP_TIMEOUT] = $this->modx->getOption('mail_smtp_timeout',null,10);
  231. $default[modMail::MAIL_SMTP_USER] = $this->modx->getOption('mail_smtp_user',null,'');
  232. }
  233. $default[modMail::MAIL_CHARSET] = $this->modx->getOption('mail_charset',null,'UTF-8');
  234. $default[modMail::MAIL_ENCODING] = $this->modx->getOption('mail_encoding',null,'8bit');
  235. /* first start with this method default, then constructor passed-in default, then method passed-in attributes */
  236. return array_merge($default,$this->defaultAttributes,$attributes);
  237. }
  238. /**
  239. * Gets a reference to an attribute of the mail object.
  240. *
  241. * @access public
  242. * @param string $key The attribute key.
  243. * @return mixed A reference to the attribute, or null if no attribute value is set for the key.
  244. */
  245. public function & get($key) {
  246. $value= null;
  247. if (isset($this->attributes[$key])) {
  248. $value = & $this->attributes[$key];
  249. }
  250. return $value;
  251. }
  252. /**
  253. * Sets the value of an attribute of the mail object.
  254. *
  255. * {@internal Override this method in a derivative to set the appropriate attributes of the
  256. * actual mailer implementation being used. Make sure to call this parent implementation first
  257. * and then set the value of the corresponding mailer attribute as a reference to the attribute
  258. * set in $this->attributes}
  259. *
  260. * @abstract
  261. * @access public
  262. * @param string $key The key of the attribute to set.
  263. * @param mixed $value The value of the attribute.
  264. */
  265. public function set($key, $value) {
  266. $this->attributes[$key]= $value;
  267. }
  268. /**
  269. * Add a new recipient email address to one of the valid address type buckets.
  270. *
  271. * @access public
  272. * @param string $type The address type to add; to, cc, bcc, or reply-to.
  273. * @param string $email The email address.
  274. * @param string $name An optional name for the addressee.
  275. * @return boolean Indicates if the address was set/unset successfully.
  276. */
  277. public function address($type, $email, $name= '') {
  278. $set= false;
  279. $type = strtolower($type);
  280. if (isset($this->addresses[$type])) {
  281. if ($email === null && isset($this->addresses[$type][$email])) {
  282. $this->addresses[$type][$email]= null;
  283. $set= true;
  284. } else {
  285. $this->addresses[$type][$email]= array($email, $name);
  286. $set= true;
  287. }
  288. }
  289. return $set;
  290. }
  291. /**
  292. * Adds a header to the mailer
  293. *
  294. * @access public
  295. * @param string $header The HTTP header to send.
  296. * @return boolean True if the header is valid and is set.
  297. */
  298. public function header($header) {
  299. $set= false;
  300. $parsed= explode(':', $header, 2);
  301. if ($parsed && count($parsed) == 2) {
  302. $this->headers[]= $parsed;
  303. $set= true;
  304. }
  305. return $set;
  306. }
  307. /**
  308. * Send an email setting any supplied attributes before sending.
  309. *
  310. * {@internal You should implement the rest of this method in a derivative class.}
  311. *
  312. * @abstract
  313. * @access public
  314. * @param array $attributes Attributes to override any existing attributes before sending.
  315. * @return boolean Indicates if the email was sent successfully.
  316. */
  317. public function send(array $attributes= array()) {
  318. if (is_array($attributes)) {
  319. foreach ($attributes as $attrKey => $attrVal) {
  320. $this->set($attrKey, $attrVal);
  321. }
  322. }
  323. return false;
  324. }
  325. /**
  326. * Reset the mail service, clearing addresses and attributes.
  327. *
  328. * @access public
  329. * @param array $attributes An optional array of attributes to apply after reset.
  330. */
  331. public function reset(array $attributes = array()) {
  332. $this->addresses= array(
  333. 'to' => array(),
  334. 'cc' => array(),
  335. 'bcc' => array(),
  336. 'reply-to' => array(),
  337. );
  338. $attributes = $this->getDefaultAttributes($attributes);
  339. foreach ($this->attributes as $attrKey => $attrVal) {
  340. if (array_key_exists($attrKey, $attributes)) {
  341. $this->set($attrKey, $attributes[$attrKey]);
  342. } else {
  343. $this->set($attrKey, null);
  344. }
  345. }
  346. }
  347. /**
  348. * Get an instance of the email class responsible for sending emails from the modEmail service.
  349. *
  350. * {@internal Implement this function in derivatives and call it in the constructor after all
  351. * other dependencies have been satisfied.}
  352. *
  353. * @abstract
  354. * @access protected
  355. * @return boolean Indicates if the mailer class was instantiated successfully.
  356. */
  357. abstract protected function _getMailer();
  358. /**
  359. * Attach a file to the attachments queue.
  360. *
  361. * @access public
  362. * @param string $file The absolute path to the file
  363. */
  364. public function attach($file) {
  365. array_push($this->files,$file);
  366. }
  367. /**
  368. * Add an embedded image.
  369. *
  370. * @access public
  371. * @param string $image The absolute path to the file
  372. * @param string $cid Id of the image by wich it will be available in html.
  373. * Example: <img src="cid:<$cid>" />
  374. */
  375. public function embedImage($image, $cid) {
  376. array_push($this->images,array('image' => $image, 'cid' => $cid));
  377. }
  378. /**
  379. * Clear all embedded images.
  380. *
  381. * @access public
  382. */
  383. public function clearEmbeddedImages() {
  384. $this->images = array();
  385. }
  386. /**
  387. * Clear all existing attachments.
  388. *
  389. * @access public
  390. */
  391. public function clearAttachments() {
  392. $this->files = array();
  393. }
  394. /**
  395. * Check if there is any error.
  396. *
  397. * @access public
  398. * @return boolean Indicates if there is error.
  399. */
  400. public function hasError() {
  401. return $this->error !== null && $this->error instanceof modError && $this->error->hasError();
  402. }
  403. /**
  404. * Get error object
  405. *
  406. * @access public
  407. * @return null|modError
  408. */
  409. public function getError() {
  410. return $this->error;
  411. }
  412. }