/classes/email/driver/mandrill.php

https://github.com/fuel/email · PHP · 350 lines · 199 code · 51 blank · 100 comment · 11 complexity · a420147a60ee7b5e2b06e2cd1f423362 MD5 · raw file

  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP 5.4+ framework.
  4. *
  5. * @package Fuel
  6. * @version 1.9-dev
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2019 Fuel Development Team
  10. * @link https://fuelphp.com
  11. */
  12. namespace Email;
  13. use Mandrill;
  14. use Mandrill_Messages;
  15. class Email_Driver_Mandrill extends \Email_Driver
  16. {
  17. /**
  18. * Global merge vars
  19. *
  20. * @var array
  21. */
  22. protected $merge_vars = array();
  23. /**
  24. * Recipient merge vars
  25. *
  26. * @var array
  27. */
  28. protected $rcpt_merge_vars = array();
  29. /**
  30. * Global metadata
  31. *
  32. * @var array
  33. */
  34. protected $metadata = array();
  35. /**
  36. * Recipient metadata
  37. *
  38. * @var array
  39. */
  40. protected $rcpt_metadata = array();
  41. /**
  42. * {@inheritdoc}
  43. */
  44. public function __construct(array $config)
  45. {
  46. // Mandrill wants header encoding to be switched off
  47. $config['encode_headers'] = false;
  48. parent::__construct($config);
  49. }
  50. /**
  51. * {@inheritdoc}
  52. */
  53. protected function _send()
  54. {
  55. $mandrill = new \Mandrill($this->config['mandrill']['key']);
  56. $message = new Mandrill_Messages($mandrill);
  57. $headers = $this->extra_headers;
  58. // Get recipients
  59. $to = $this->build_rcpt();
  60. $cc = $this->build_rcpt('cc');
  61. $bcc = $this->build_rcpt('bcc');
  62. $to = array_merge($bcc, $cc, $to);
  63. // Get recipient merge vars
  64. $merge_vars = array();
  65. foreach ($this->rcpt_merge_vars as $rcpt => $_merge_vars)
  66. {
  67. $merge_vars[] = array(
  68. 'rcpt' => $rcpt,
  69. 'vars' => \Arr::keyval_to_assoc($_merge_vars, 'name', 'content'),
  70. );
  71. }
  72. // Get recipient meta data
  73. $metadata = array();
  74. foreach ($this->rcpt_metadata as $rcpt => $_metadata)
  75. {
  76. $metadata[] = array(
  77. 'rcpt' => $rcpt,
  78. 'values' => $_metadata,
  79. );
  80. }
  81. // Get attachments
  82. $attachments = array();
  83. foreach ($this->attachments['attachment'] as $cid => $attachment)
  84. {
  85. $attachments[] = array(
  86. 'type' => $attachment['mime'],
  87. 'name' => $attachment['file'][1],
  88. 'content' => $attachment['contents'],
  89. );
  90. }
  91. // Get inline images
  92. $images = array();
  93. foreach ($this->attachments['inline'] as $cid => $attachment)
  94. {
  95. if (\Str::starts_with($attachment['mime'], 'image/'))
  96. {
  97. $name = substr($cid, 4); // remove cid:
  98. $images[] = array(
  99. 'type' => $attachment['mime'],
  100. 'name' => $name,
  101. 'content' => $attachment['contents'],
  102. );
  103. }
  104. }
  105. // Get reply-to addresses
  106. if ( ! empty($this->reply_to))
  107. {
  108. $headers['Reply-To'] = static::format_addresses($this->reply_to);
  109. }
  110. $important = false;
  111. if (in_array($this->config['priority'], array(\Email::P_HIGH, \Email::P_HIGHEST)))
  112. {
  113. $important = true;
  114. }
  115. $message_data = array(
  116. 'html' => $this->body,
  117. 'text' => isset($this->alt_body) ? $this->alt_body : '',
  118. 'subject' => $this->subject,
  119. 'from_email' => $this->config['from']['email'],
  120. 'from_name' => $this->config['from']['name'],
  121. 'to' => $to,
  122. 'headers' => $headers,
  123. 'global_merge_vars' => \Arr::keyval_to_assoc($this->merge_vars, 'name', 'content'),
  124. 'merge_vars' => $merge_vars,
  125. 'metadata' => $this->metadata,
  126. 'recipient_metadata' => $metadata,
  127. 'attachments' => $attachments,
  128. 'images' => $images,
  129. 'important' => $important,
  130. );
  131. $message_options = \Arr::filter_keys($this->get_config('mandrill.message_options', array()), array_keys($message_data), true);
  132. $message_data = \Arr::merge($message_data, $message_options);
  133. $send_options = extract($this->config['mandrill']['send_options'], EXTR_SKIP);
  134. $message->send($message_data, $async, $ip_pool, $send_at);
  135. return true;
  136. }
  137. /**
  138. * {@inheritdoc}
  139. */
  140. public function attach($file, $inline = false, $cid = null, $mime = null, $name = null)
  141. {
  142. parent::attach($file, $inline, $cid, $mime, $name);
  143. if ($inline === true)
  144. {
  145. // Check the last attachment
  146. $attachment = end($this->attachments['inline']);
  147. if ( ! \Str::starts_with($attachment['mime'], 'image/'))
  148. {
  149. throw new \InvalidAttachmentsException('Non-image inline attachments are not supported by this driver.');
  150. }
  151. }
  152. }
  153. /**
  154. * Add type to recipient list
  155. *
  156. * @param string $list to, cc, bcc
  157. * @return array
  158. */
  159. protected function build_rcpt($list = 'to')
  160. {
  161. return array_map(function ($item) use ($list)
  162. {
  163. $item['type'] = $list;
  164. return $item;
  165. }, $this->{$list});
  166. }
  167. /**
  168. * {@inheritdoc}
  169. */
  170. protected function clear_list($list)
  171. {
  172. is_array($list) or $list = array($list);
  173. foreach ($list as $_list)
  174. {
  175. $rcpt = array_keys($this->{$_list});
  176. \Arr::delete($this->rcpt_merge_vars, $rcpt);
  177. \Arr::delete($this->rcpt_metadata, $rcpt);
  178. }
  179. return parent::clear_list($list);
  180. }
  181. /**
  182. * Get merge vars
  183. *
  184. * @param mixed $key Null for all, string for specific
  185. * @param mixed $rcpt Null for global, string for recipient
  186. * @return array
  187. */
  188. public function get_merge_vars($key = null, $rcpt = null)
  189. {
  190. if (is_null($rcpt))
  191. {
  192. return \Arr::get($this->merge_vars, $key);
  193. }
  194. elseif (isset($this->rcpt_merge_vars[$rcpt]))
  195. {
  196. return \Arr::get($this->rcpt_merge_vars[$rcpt], $key);
  197. }
  198. }
  199. /**
  200. * Add merge vars
  201. *
  202. * @param array $merge_vars Key-value pairs
  203. * @param mixed $rcpt Null for global, string for recipient
  204. * @return array
  205. */
  206. public function add_merge_vars(array $merge_vars, $rcpt = null)
  207. {
  208. if (is_null($rcpt))
  209. {
  210. $this->merge_vars = $merge_vars;
  211. }
  212. else
  213. {
  214. $this->rcpt_merge_vars[$rcpt] = $merge_vars;
  215. }
  216. return $this;
  217. }
  218. /**
  219. * Set one or several merge vars
  220. *
  221. * @param mixed $key Array for many vars, string for one
  222. * @param mixed $value In case of many vars it is ommited
  223. * @param mixed $rcpt Null for global, string for recipient
  224. * @return object $this
  225. */
  226. public function set_merge_var($key, $value = null, $rcpt = null)
  227. {
  228. is_array($key) or $key = array($key => $value);
  229. if (is_null($rcpt))
  230. {
  231. $this->merge_vars = \Arr::merge($this->merge_vars, $key);
  232. }
  233. else
  234. {
  235. $merge_vars = \Arr::get($this->rcpt_merge_vars, $rcpt, array());
  236. $this->rcpt_merge_vars[$rcpt] = \Arr::merge($merge_vars, $key);
  237. }
  238. return $this;
  239. }
  240. /**
  241. * Get metadata
  242. *
  243. * @param mixed $key Null for all, string for specific
  244. * @param mixed $rcpt Null for global, string for recipient
  245. * @return array
  246. */
  247. public function get_metadata($key = null, $rcpt = null)
  248. {
  249. if (is_null($rcpt))
  250. {
  251. return \Arr::get($this->metadata, $key);
  252. }
  253. elseif (isset($this->rcpt_metadata[$rcpt]))
  254. {
  255. return \Arr::get($this->rcpt_metadata[$rcpt], $key);
  256. }
  257. }
  258. /**
  259. * Add metadata
  260. *
  261. * @param array $metadata Key-value pairs
  262. * @param mixed $rcpt Null for global, string for recipient
  263. * @return array
  264. */
  265. public function add_metadata(array $metadata, $rcpt = null)
  266. {
  267. if (is_null($rcpt))
  268. {
  269. $this->metadata = $metadata;
  270. }
  271. else
  272. {
  273. $this->rcpt_metadata[$rcpt] = $metadata;
  274. }
  275. return $this;
  276. }
  277. /**
  278. * Set one or several metadata
  279. *
  280. * @param mixed $key Array for many, string for one
  281. * @param mixed $value In case of many it is ommited
  282. * @param mixed $rcpt Null for global, string for recipient
  283. * @return object $this
  284. */
  285. public function set_metadata($key, $value = null, $rcpt = null)
  286. {
  287. is_array($key) or $key = array($key => $value);
  288. if (is_null($rcpt))
  289. {
  290. $this->metadata = \Arr::merge($this->metadata, $key);
  291. }
  292. else
  293. {
  294. $metadata = \Arr::get($this->rcpt_metadata, $rcpt, array());
  295. $this->rcpt_metadata[$rcpt] = \Arr::merge($metadata, $key);
  296. }
  297. return $this;
  298. }
  299. }