PageRenderTime 37ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/dmCorePlugin/lib/mail/dmMail.php

http://github.com/diem-project/diem
PHP | 327 lines | 221 code | 50 blank | 56 comment | 15 complexity | 91fb90bbbfdbadcd5bef856096ccc1a3 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, ISC
  1. <?php
  2. class dmMail
  3. {
  4. protected
  5. $mailer,
  6. $dispatcher,
  7. $message,
  8. $template,
  9. $values,
  10. $isRendered;
  11. public function __construct(sfContext $context, sfEventDispatcher $dispatcher)
  12. {
  13. $this->mailer = $context->getMailer();
  14. $this->dispatcher = $dispatcher;
  15. $this->initialize();
  16. }
  17. protected function initialize()
  18. {
  19. dm::enableMailer();
  20. $this->values = array();
  21. $this->isRendered = false;
  22. $this->message = Swift_Message::newInstance();
  23. }
  24. /**
  25. * Set a template to the mail
  26. *
  27. * @param mixed $templateName the template name, or a DmMailTemplateInstance
  28. * @return dmMail $this
  29. */
  30. public function setTemplate($templateName)
  31. {
  32. if($templateName instanceof DmMailTemplate)
  33. {
  34. $this->template = $templateName;
  35. }
  36. elseif (!$this->template = dmDb::query('DmMailTemplate t')->where('t.name = ?', $templateName)->fetchRecord())
  37. {
  38. $this->template = dmDb::table('DmMailTemplate')->createDefault($templateName);
  39. }
  40. return $this;
  41. }
  42. /**
  43. * Get the template used to build the mail
  44. *
  45. * @return DmMailTemplate the template instance
  46. */
  47. public function getTemplate()
  48. {
  49. return $this->template;
  50. }
  51. /**
  52. * Set a message manually to the mail
  53. *
  54. * @param Swift_Message $message the Swift message
  55. * @return dmMail $this
  56. */
  57. public function setMessage(Swift_Message $message)
  58. {
  59. $this->message = $message;
  60. return $this;
  61. }
  62. /**
  63. * Get the Swift message that will be sent
  64. *
  65. * @return Swift_Message the message instance
  66. */
  67. public function getMessage()
  68. {
  69. return $this->message;
  70. }
  71. /**
  72. * Set a mailer manually
  73. *
  74. * @param sfMailer $mailer another mailer
  75. * @return dmMail $this
  76. */
  77. public function setMailer(sfMailer $mailer)
  78. {
  79. $this->mailer = $mailer;
  80. return $this;
  81. }
  82. /**
  83. * Get the mailer used
  84. *
  85. * @return sfMailer the mailer instance
  86. */
  87. public function getMailer()
  88. {
  89. return $this->mailer;
  90. }
  91. /**
  92. * Add values to the mail that will be available in the template
  93. *
  94. * @param mixed $data a record, a form or an array
  95. * @param string $prefix a prefix for this data
  96. * @return dmMail $this
  97. */
  98. public function addValues($values, $prefix = null)
  99. {
  100. if ($values instanceof dmDoctrineRecord)
  101. {
  102. $values = $values->toArray();
  103. }
  104. elseif($values instanceof dmFormDoctrine)
  105. {
  106. $values = $values->getObject()->toArray();
  107. }
  108. elseif($values instanceof dmForm)
  109. {
  110. $values = $values->getValues();
  111. }
  112. if(!is_array($values))
  113. {
  114. throw new dmException('dmMail->setValues supports records, forms and arrays');
  115. }
  116. foreach($values as $key => $value)
  117. {
  118. if(is_array($value))
  119. {
  120. unset($values[$key]);
  121. }
  122. elseif(is_object($value))
  123. {
  124. try
  125. {
  126. $values[$key] = (string)$value;
  127. }
  128. catch(Exception $e)
  129. {
  130. unset($values[$key]);
  131. }
  132. }
  133. elseif($prefix)
  134. {
  135. $values[$prefix.$key] = $value;
  136. unset($values[$key]);
  137. }
  138. }
  139. $this->values = array_merge($this->values, $values);
  140. return $this;
  141. }
  142. /**
  143. * Return values that will be available in the template
  144. *
  145. * @return array $values
  146. */
  147. public function getValues()
  148. {
  149. return $this->values;
  150. }
  151. /**
  152. * Binds the mail with available data
  153. * Uses Swift to send it.
  154. *
  155. * @return dmMail $this
  156. */
  157. public function send()
  158. {
  159. if(!$this->getTemplate()->get('is_active'))
  160. {
  161. return $this;
  162. }
  163. if(!$this->isRendered())
  164. {
  165. $this->render();
  166. }
  167. $eventParams = array(
  168. 'mailer' => $this->getMailer(),
  169. 'message' => $this->getMessage(),
  170. 'template' => $this->getTemplate()
  171. );
  172. $this->dispatcher->notify(new sfEvent($this, 'dm.mail.pre_send', $eventParams));
  173. $this->getMailer()->send($this->getMessage());
  174. $this->dispatcher->notify(new sfEvent($this, 'dm.mail.post_send', $eventParams));
  175. return $this;
  176. }
  177. public function isRendered()
  178. {
  179. return $this->isRendered;
  180. }
  181. /**
  182. * Builds the Swift message inserting vars in templates
  183. *
  184. * @return dmMail $this
  185. */
  186. public function render()
  187. {
  188. if (!$this->getTemplate())
  189. {
  190. throw new dmMailException('You must call setTemplate() to set a mail template');
  191. }
  192. $this->updateTemplate();
  193. $template = $this->getTemplate();
  194. $replacements = $this->getReplacements();
  195. $message = $this->getMessage();
  196. $message
  197. ->setContentType($template->isHtml ? "text/html" : "text/plain")
  198. ->setSubject(strtr($template->subject, $replacements))
  199. ->setBody(strtr($template->body, $replacements))
  200. ->setFrom($this->emailListToArray(strtr($template->from_email, $replacements)))
  201. ->setTo($this->emailListToArray(strtr($template->to_email, $replacements)));
  202. foreach(array('cc', 'bcc', 'reply_to', 'sender') as $field)
  203. {
  204. if($value = $template->get($field.'_email'))
  205. {
  206. $processedValue = $this->emailListToArray(strtr($value, $replacements));
  207. $message->{'set'.dmString::camelize($field)}($processedValue);
  208. }
  209. }
  210. $headers = $message->getHeaders();
  211. if($headers->has('List-Unsubscribe'))
  212. {
  213. $headers->remove('List-Unsubscribe');
  214. }
  215. if($template->list_unsubscribe)
  216. {
  217. $headers->addTextHeader('List-Unsubscribe', strtr($template->list_unsubscribe, $replacements));
  218. }
  219. $this->isRendered = true;
  220. return $this;
  221. }
  222. protected function getReplacements()
  223. {
  224. $replacements = array();
  225. foreach($this->getValues() as $key => $value)
  226. {
  227. $replacements[$this->wrap($key)] = $value;
  228. }
  229. return $replacements;
  230. }
  231. protected function emailListToArray($emails)
  232. {
  233. $entries = array_unique(array_filter(array_map('trim', explode(',', str_replace("\n", ',', $emails)))));
  234. $emails = array();
  235. foreach($entries as $entry)
  236. {
  237. if(preg_match('/^.+\s<.+>$/', $entry))
  238. {
  239. $email = preg_replace('/^.+\s<(.+)>$/', '$1', $entry);
  240. $name = preg_replace('/^(.+)\s<.+$/', '$1', $entry);
  241. $emails[$email] = $name;
  242. }
  243. else
  244. {
  245. $emails[$entry] = null;
  246. }
  247. }
  248. return $emails;
  249. }
  250. protected function updateTemplate()
  251. {
  252. $template = $this->getTemplate();
  253. $templateVars = array_keys($this->getValues());
  254. natsort($templateVars);
  255. if ($template->get('vars') != implode(', ', $templateVars))
  256. {
  257. $template->set('vars', implode(', ', $templateVars));
  258. }
  259. if (!$template->get('body'))
  260. {
  261. $body = array();
  262. foreach($this->getValues() as $key => $value)
  263. {
  264. $body[] = dmString::humanize($key).' : '.$this->wrap($key);
  265. }
  266. $template->set('body', implode("\n", $body));
  267. }
  268. if($template->isModified())
  269. {
  270. $template->save();
  271. }
  272. }
  273. protected function wrap($key)
  274. {
  275. return '%'.$key.'%';
  276. }
  277. }