PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php

https://gitlab.com/PragmaticLinux/Laravel
PHP | 527 lines | 203 code | 63 blank | 261 comment | 12 complexity | 343b1cef2a157fa59ba32c9754e7fc96 MD5 | raw file
  1. <?php namespace Illuminate\Mail;
  2. use Closure;
  3. use Swift_Mailer;
  4. use Swift_Message;
  5. use SuperClosure\Serializer;
  6. use Psr\Log\LoggerInterface;
  7. use InvalidArgumentException;
  8. use Illuminate\Contracts\View\Factory;
  9. use Illuminate\Contracts\Events\Dispatcher;
  10. use Illuminate\Contracts\Container\Container;
  11. use Illuminate\Contracts\Queue\Queue as QueueContract;
  12. use Illuminate\Contracts\Mail\Mailer as MailerContract;
  13. use Illuminate\Contracts\Mail\MailQueue as MailQueueContract;
  14. class Mailer implements MailerContract, MailQueueContract {
  15. /**
  16. * The view factory instance.
  17. *
  18. * @var \Illuminate\Contracts\View\Factory
  19. */
  20. protected $views;
  21. /**
  22. * The Swift Mailer instance.
  23. *
  24. * @var \Swift_Mailer
  25. */
  26. protected $swift;
  27. /**
  28. * The event dispatcher instance.
  29. *
  30. * @var \Illuminate\Contracts\Events\Dispatcher
  31. */
  32. protected $events;
  33. /**
  34. * The global from address and name.
  35. *
  36. * @var array
  37. */
  38. protected $from;
  39. /**
  40. * The log writer instance.
  41. *
  42. * @var \Psr\Log\LoggerInterface
  43. */
  44. protected $logger;
  45. /**
  46. * The IoC container instance.
  47. *
  48. * @var \Illuminate\Contracts\Container\Container
  49. */
  50. protected $container;
  51. /**
  52. * The queue implementation.
  53. *
  54. * @var \Illuminate\Contracts\Queue\Queue
  55. */
  56. protected $queue;
  57. /**
  58. * Indicates if the actual sending is disabled.
  59. *
  60. * @var bool
  61. */
  62. protected $pretending = false;
  63. /**
  64. * Array of failed recipients.
  65. *
  66. * @var array
  67. */
  68. protected $failedRecipients = array();
  69. /**
  70. * Array of parsed views containing html and text view name.
  71. *
  72. * @var array
  73. */
  74. protected $parsedViews = array();
  75. /**
  76. * Create a new Mailer instance.
  77. *
  78. * @param \Illuminate\Contracts\View\Factory $views
  79. * @param \Swift_Mailer $swift
  80. * @param \Illuminate\Contracts\Events\Dispatcher $events
  81. * @return void
  82. */
  83. public function __construct(Factory $views, Swift_Mailer $swift, Dispatcher $events = null)
  84. {
  85. $this->views = $views;
  86. $this->swift = $swift;
  87. $this->events = $events;
  88. }
  89. /**
  90. * Set the global from address and name.
  91. *
  92. * @param string $address
  93. * @param string $name
  94. * @return void
  95. */
  96. public function alwaysFrom($address, $name = null)
  97. {
  98. $this->from = compact('address', 'name');
  99. }
  100. /**
  101. * Send a new message when only a raw text part.
  102. *
  103. * @param string $text
  104. * @param mixed $callback
  105. * @return int
  106. */
  107. public function raw($text, $callback)
  108. {
  109. return $this->send(array('raw' => $text), [], $callback);
  110. }
  111. /**
  112. * Send a new message when only a plain part.
  113. *
  114. * @param string $view
  115. * @param array $data
  116. * @param mixed $callback
  117. * @return int
  118. */
  119. public function plain($view, array $data, $callback)
  120. {
  121. return $this->send(array('text' => $view), $data, $callback);
  122. }
  123. /**
  124. * Send a new message using a view.
  125. *
  126. * @param string|array $view
  127. * @param array $data
  128. * @param \Closure|string $callback
  129. * @return mixed
  130. */
  131. public function send($view, array $data, $callback)
  132. {
  133. // First we need to parse the view, which could either be a string or an array
  134. // containing both an HTML and plain text versions of the view which should
  135. // be used when sending an e-mail. We will extract both of them out here.
  136. list($view, $plain, $raw) = $this->parseView($view);
  137. $data['message'] = $message = $this->createMessage();
  138. $this->callMessageBuilder($callback, $message);
  139. // Once we have retrieved the view content for the e-mail we will set the body
  140. // of this message using the HTML type, which will provide a simple wrapper
  141. // to creating view based emails that are able to receive arrays of data.
  142. $this->addContent($message, $view, $plain, $raw, $data);
  143. $message = $message->getSwiftMessage();
  144. return $this->sendSwiftMessage($message);
  145. }
  146. /**
  147. * Queue a new e-mail message for sending.
  148. *
  149. * @param string|array $view
  150. * @param array $data
  151. * @param \Closure|string $callback
  152. * @param string $queue
  153. * @return mixed
  154. */
  155. public function queue($view, array $data, $callback, $queue = null)
  156. {
  157. $callback = $this->buildQueueCallable($callback);
  158. return $this->queue->push('mailer@handleQueuedMessage', compact('view', 'data', 'callback'), $queue);
  159. }
  160. /**
  161. * Queue a new e-mail message for sending on the given queue.
  162. *
  163. * @param string $queue
  164. * @param string|array $view
  165. * @param array $data
  166. * @param \Closure|string $callback
  167. * @return mixed
  168. */
  169. public function queueOn($queue, $view, array $data, $callback)
  170. {
  171. return $this->queue($view, $data, $callback, $queue);
  172. }
  173. /**
  174. * Queue a new e-mail message for sending after (n) seconds.
  175. *
  176. * @param int $delay
  177. * @param string|array $view
  178. * @param array $data
  179. * @param \Closure|string $callback
  180. * @param string $queue
  181. * @return mixed
  182. */
  183. public function later($delay, $view, array $data, $callback, $queue = null)
  184. {
  185. $callback = $this->buildQueueCallable($callback);
  186. return $this->queue->later($delay, 'mailer@handleQueuedMessage', compact('view', 'data', 'callback'), $queue);
  187. }
  188. /**
  189. * Queue a new e-mail message for sending after (n) seconds on the given queue.
  190. *
  191. * @param string $queue
  192. * @param int $delay
  193. * @param string|array $view
  194. * @param array $data
  195. * @param \Closure|string $callback
  196. * @return mixed
  197. */
  198. public function laterOn($queue, $delay, $view, array $data, $callback)
  199. {
  200. return $this->later($delay, $view, $data, $callback, $queue);
  201. }
  202. /**
  203. * Build the callable for a queued e-mail job.
  204. *
  205. * @param mixed $callback
  206. * @return mixed
  207. */
  208. protected function buildQueueCallable($callback)
  209. {
  210. if ( ! $callback instanceof Closure) return $callback;
  211. return (new Serializer)->serialize($callback);
  212. }
  213. /**
  214. * Handle a queued e-mail message job.
  215. *
  216. * @param \Illuminate\Contracts\Queue\Job $job
  217. * @param array $data
  218. * @return void
  219. */
  220. public function handleQueuedMessage($job, $data)
  221. {
  222. $this->send($data['view'], $data['data'], $this->getQueuedCallable($data));
  223. $job->delete();
  224. }
  225. /**
  226. * Get the true callable for a queued e-mail message.
  227. *
  228. * @param array $data
  229. * @return mixed
  230. */
  231. protected function getQueuedCallable(array $data)
  232. {
  233. if (str_contains($data['callback'], 'SerializableClosure'))
  234. {
  235. return unserialize($data['callback'])->getClosure();
  236. }
  237. return $data['callback'];
  238. }
  239. /**
  240. * Add the content to a given message.
  241. *
  242. * @param \Illuminate\Mail\Message $message
  243. * @param string $view
  244. * @param string $plain
  245. * @param string $raw
  246. * @param array $data
  247. * @return void
  248. */
  249. protected function addContent($message, $view, $plain, $raw, $data)
  250. {
  251. if (isset($view))
  252. {
  253. $message->setBody($this->getView($view, $data), 'text/html');
  254. }
  255. if (isset($plain))
  256. {
  257. $message->addPart($this->getView($plain, $data), 'text/plain');
  258. }
  259. if (isset($raw))
  260. {
  261. $message->addPart($raw, 'text/plain');
  262. }
  263. }
  264. /**
  265. * Parse the given view name or array.
  266. *
  267. * @param string|array $view
  268. * @return array
  269. *
  270. * @throws \InvalidArgumentException
  271. */
  272. protected function parseView($view)
  273. {
  274. if (is_string($view)) return [$view, null, null];
  275. // If the given view is an array with numeric keys, we will just assume that
  276. // both a "pretty" and "plain" view were provided, so we will return this
  277. // array as is, since must should contain both views with numeric keys.
  278. if (is_array($view) && isset($view[0]))
  279. {
  280. return [$view[0], $view[1], null];
  281. }
  282. // If the view is an array, but doesn't contain numeric keys, we will assume
  283. // the the views are being explicitly specified and will extract them via
  284. // named keys instead, allowing the developers to use one or the other.
  285. elseif (is_array($view))
  286. {
  287. return [
  288. array_get($view, 'html'),
  289. array_get($view, 'text'),
  290. array_get($view, 'raw'),
  291. ];
  292. }
  293. throw new InvalidArgumentException("Invalid view.");
  294. }
  295. /**
  296. * Send a Swift Message instance.
  297. *
  298. * @param \Swift_Message $message
  299. * @return void
  300. */
  301. protected function sendSwiftMessage($message)
  302. {
  303. if ($this->events)
  304. {
  305. $this->events->fire('mailer.sending', array($message));
  306. }
  307. if ( ! $this->pretending)
  308. {
  309. return $this->swift->send($message, $this->failedRecipients);
  310. }
  311. elseif (isset($this->logger))
  312. {
  313. $this->logMessage($message);
  314. }
  315. }
  316. /**
  317. * Log that a message was sent.
  318. *
  319. * @param \Swift_Message $message
  320. * @return void
  321. */
  322. protected function logMessage($message)
  323. {
  324. $emails = implode(', ', array_keys((array) $message->getTo()));
  325. $this->logger->info("Pretending to mail message to: {$emails}");
  326. }
  327. /**
  328. * Call the provided message builder.
  329. *
  330. * @param \Closure|string $callback
  331. * @param \Illuminate\Mail\Message $message
  332. * @return mixed
  333. *
  334. * @throws \InvalidArgumentException
  335. */
  336. protected function callMessageBuilder($callback, $message)
  337. {
  338. if ($callback instanceof Closure)
  339. {
  340. return call_user_func($callback, $message);
  341. }
  342. elseif (is_string($callback))
  343. {
  344. return $this->container->make($callback)->mail($message);
  345. }
  346. throw new InvalidArgumentException("Callback is not valid.");
  347. }
  348. /**
  349. * Create a new message instance.
  350. *
  351. * @return \Illuminate\Mail\Message
  352. */
  353. protected function createMessage()
  354. {
  355. $message = new Message(new Swift_Message);
  356. // If a global from address has been specified we will set it on every message
  357. // instances so the developer does not have to repeat themselves every time
  358. // they create a new message. We will just go ahead and push the address.
  359. if (isset($this->from['address']))
  360. {
  361. $message->from($this->from['address'], $this->from['name']);
  362. }
  363. return $message;
  364. }
  365. /**
  366. * Render the given view.
  367. *
  368. * @param string $view
  369. * @param array $data
  370. * @return \Illuminate\View\View
  371. */
  372. protected function getView($view, $data)
  373. {
  374. return $this->views->make($view, $data)->render();
  375. }
  376. /**
  377. * Tell the mailer to not really send messages.
  378. *
  379. * @param bool $value
  380. * @return void
  381. */
  382. public function pretend($value = true)
  383. {
  384. $this->pretending = $value;
  385. }
  386. /**
  387. * Check if the mailer is pretending to send messages.
  388. *
  389. * @return bool
  390. */
  391. public function isPretending()
  392. {
  393. return $this->pretending;
  394. }
  395. /**
  396. * Get the view factory instance.
  397. *
  398. * @return \Illuminate\Contracts\View\Factory
  399. */
  400. public function getViewFactory()
  401. {
  402. return $this->views;
  403. }
  404. /**
  405. * Get the Swift Mailer instance.
  406. *
  407. * @return \Swift_Mailer
  408. */
  409. public function getSwiftMailer()
  410. {
  411. return $this->swift;
  412. }
  413. /**
  414. * Get the array of failed recipients.
  415. *
  416. * @return array
  417. */
  418. public function failures()
  419. {
  420. return $this->failedRecipients;
  421. }
  422. /**
  423. * Set the Swift Mailer instance.
  424. *
  425. * @param \Swift_Mailer $swift
  426. * @return void
  427. */
  428. public function setSwiftMailer($swift)
  429. {
  430. $this->swift = $swift;
  431. }
  432. /**
  433. * Set the log writer instance.
  434. *
  435. * @param \Psr\Log\LoggerInterface $logger
  436. * @return $this
  437. */
  438. public function setLogger(LoggerInterface $logger)
  439. {
  440. $this->logger = $logger;
  441. return $this;
  442. }
  443. /**
  444. * Set the queue manager instance.
  445. *
  446. * @param \Illuminate\Contracts\Queue\Queue $queue
  447. * @return $this
  448. */
  449. public function setQueue(QueueContract $queue)
  450. {
  451. $this->queue = $queue;
  452. return $this;
  453. }
  454. /**
  455. * Set the IoC container instance.
  456. *
  457. * @param \Illuminate\Contracts\Container\Container $container
  458. * @return void
  459. */
  460. public function setContainer(Container $container)
  461. {
  462. $this->container = $container;
  463. }
  464. }