Completed
Push — master ( f867ee...b2d0fe )
by Adrien
09:16 queued 04:47
created

Mailer::queueBalance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 10
rs 10
c 0
b 0
f 0
ccs 5
cts 5
cp 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Service;
6
7
use Application\Model\Message;
8
use Cake\Chronos\Chronos;
9
use Doctrine\ORM\EntityManager;
10
use Zend\Mail;
11
use Zend\Mail\Transport\TransportInterface;
12
use Zend\Mime\Message as MimeMessage;
13
use Zend\Mime\Mime;
14
use Zend\Mime\Part as MimePart;
15
16
/**
17
 * Service to send a message as an email
18
 */
19
class Mailer
20
{
21
    /**
22
     * @var EntityManager
23
     */
24
    private $entityManager;
25
26
    /**
27
     * @var TransportInterface
28
     */
29
    private $transport;
30
31
    /**
32
     * @var null|string
33
     */
34
    private $emailOverride;
35
36
    /**
37
     * @var string
38
     */
39
    private $fromEmail;
40
41
    /**
42
     * @var string
43
     */
44
    private $phpPath;
45
46 2
    public function __construct(EntityManager $entityManager, TransportInterface $transport, ?string $emailOverride, string $fromEmail, string $phpPath)
47
    {
48 2
        $this->entityManager = $entityManager;
49 2
        $this->transport = $transport;
50 2
        $this->emailOverride = $emailOverride;
51 2
        $this->fromEmail = $fromEmail;
52 2
        $this->phpPath = $phpPath;
53 2
    }
54
55
    /**
56
     * Send a message asynchronously in a separate process.
57
     *
58
     * This should be the preferred way to send a message, unless if we are the cron.
59
     *
60
     * @param Message $message
61
     */
62 4
    public function sendMessageAsync(Message $message): void
63
    {
64
        // Be sure we have an ID before "forking" process
65 4
        if ($message->getId() === null) {
0 ignored issues
show
introduced by
The condition $message->getId() === null is always false.
Loading history...
66 4
            $this->entityManager->flush();
67
        }
68
69
        $args = [
70 4
            realpath('bin/send-message.php'),
71 4
            $message->getId(),
72
        ];
73
74 4
        $escapedArgs = array_map('escapeshellarg', $args);
75
76 4
        $cmd = escapeshellcmd($this->phpPath) . ' ' . implode(' ', $escapedArgs) . ' > /dev/null 2>&1 &';
77 4
        exec($cmd);
78 4
    }
79
80
    /**
81
     * Send a message
82
     *
83
     * @param Message $message
84
     */
85 1
    public function sendMessage(Message $message): void
86
    {
87 1
        $mailMessage = $this->modelMessageToMailMessage($message);
88
89 1
        $email = $message->getEmail();
90 1
        $overriddenBy = '';
91 1
        if ($this->emailOverride) {
92
            $email = $this->emailOverride;
93
            $overriddenBy = ' overridden by ' . $email;
94
        }
95
96 1
        $recipientName = $message->getRecipient() ? $message->getRecipient()->getName() : null;
97 1
        if ($email) {
98 1
            $mailMessage->addTo($email, $recipientName);
99 1
            $this->transport->send($mailMessage);
100
        }
101
102 1
        $message->setDateSent(new Chronos());
103 1
        $this->entityManager->flush();
104
105 1
        echo 'email sent to: ' . $message->getEmail() . "\t" . $overriddenBy . "\t" . $message->getSubject() . PHP_EOL;
106 1
    }
107
108
    /**
109
     * Convert our model message to a mail message
110
     *
111
     * @param Message $modelMessage
112
     *
113
     * @return Mail\Message
114
     */
115 1
    private function modelMessageToMailMessage(Message $modelMessage): Mail\Message
116
    {
117
        // set Mime type html
118 1
        $htmlPart = new MimePart($modelMessage->getBody());
119 1
        $htmlPart->type = Mime::TYPE_HTML;
120 1
        $body = new MimeMessage();
121 1
        $body->setParts([$htmlPart]);
122
123 1
        $mailMessage = new Mail\Message();
124 1
        $mailMessage->setSubject($modelMessage->getSubject());
125 1
        $mailMessage->setBody($body);
126 1
        $mailMessage->setFrom($this->fromEmail, 'Ichtus');
127
128 1
        return $mailMessage;
129
    }
130
131
    /**
132
     * Send all messages that are not sent yet
133
     */
134
    public function sendAllMessages(): void
135
    {
136
        $messages = $this->entityManager->getRepository(Message::class)->getAllMessageToSend();
137
        foreach ($messages as $message) {
138
            $this->sendMessage($message);
139
        }
140
    }
141
}
142