1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (https://nette.org)
5: * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6: */
7:
8: namespace Nette\Mail;
9:
10: use Nette;
11:
12:
13: class FallbackMailer implements IMailer
14: {
15: use Nette\SmartObject;
16:
17: /** @var callable[] function (FallbackMailer $sender, SendException $e, IMailer $mailer, Message $mail) */
18: public $onFailure;
19:
20: /** @var IMailer[] */
21: private $mailers;
22:
23: /** @var int */
24: private $retryCount;
25:
26: /** @var int in miliseconds */
27: private $retryWaitTime;
28:
29:
30: /**
31: * @param IMailer[]
32: * @param int
33: * @param int in miliseconds
34: */
35: public function __construct(array $mailers, $retryCount = 3, $retryWaitTime = 1000)
36: {
37: $this->mailers = $mailers;
38: $this->retryCount = $retryCount;
39: $this->retryWaitTime = $retryWaitTime;
40: }
41:
42:
43: /**
44: * Sends email.
45: * @return void
46: * @throws FallbackMailerException
47: */
48: public function send(Message $mail)
49: {
50: if (!$this->mailers) {
51: throw new Nette\InvalidArgumentException('At least one mailer must be provided.');
52: }
53:
54: for ($i = 0; $i < $this->retryCount; $i++) {
55: if ($i > 0) {
56: usleep($this->retryWaitTime * 1000);
57: }
58:
59: foreach ($this->mailers as $mailer) {
60: try {
61: $mailer->send($mail);
62: return;
63:
64: } catch (SendException $e) {
65: $failures[] = $e;
66: $this->onFailure($this, $e, $mailer, $mail);
67: }
68: }
69: }
70:
71: $e = new FallbackMailerException('All mailers failed to send the message.');
72: $e->failures = $failures;
73: throw $e;
74: }
75:
76:
77: /**
78: * @return static
79: */
80: public function addMailer(IMailer $mailer)
81: {
82: $this->mailers[] = $mailer;
83: return $this;
84: }
85: }
86: