Passed
Push — master ( ea065f...d241b8 )
by Chris
02:02
created

MailjetCourier   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Test Coverage

Coverage 84.85%

Importance

Changes 0
Metric Value
eloc 71
dl 0
loc 163
ccs 56
cts 66
cp 0.8485
rs 10
c 0
b 0
f 0
wmc 22

10 Methods

Rating   Name   Duplication   Size   Complexity  
A supportedContent() 0 5 1
A buildAttachments() 0 15 2
A prepareEmail() 0 29 4
A deliver() 0 17 3
A buildHeaders() 0 13 3
A buildAddresses() 0 5 1
A supportsContent() 0 9 3
A buildContent() 0 19 3
A __construct() 0 3 1
A buildAddress() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Camuthig\Courier\Mailjet;
6
7
use Courier\ConfirmingCourier;
8
use Courier\Exceptions\TransmissionException;
9
use Courier\Exceptions\UnsupportedContentException;
10
use Courier\SavesReceipts;
11
use Mailjet\Client;
12
use Mailjet\Resources;
13
use PhpEmail\Address;
14
use PhpEmail\Attachment;
15
use PhpEmail\Content;
16
use PhpEmail\Content\Contracts\SimpleContent;
17
use PhpEmail\Content\Contracts\TemplatedContent;
18
use PhpEmail\Email;
19
use PhpEmail\Header;
20
use Ramsey\Uuid\Uuid;
21
22
class MailjetCourier implements ConfirmingCourier
23
{
24
    use SavesReceipts;
25
26
    /**
27
     * @var Client
28
     */
29
    protected $client;
30
31 1
    public function __construct(Client $client)
32
    {
33 1
        $this->client = $client;
34
    }
35
36
    /**
37
     * @param Email $email
38
     *
39
     * @throws TransmissionException
40
     * @throws UnsupportedContentException
41
     *
42
     * @return void
43
     */
44 1
    public function deliver(Email $email): void
45
    {
46 1
        if (!$this->supportsContent($email->getContent())) {
47
            throw new UnsupportedContentException($email->getContent());
48
        }
49
50 1
        $preparedEmail = $this->prepareEmail($email);
51
52 1
        $response = $this->client->post(Resources::$Email, ['body' => $preparedEmail], ['version' => 'v3.1']);
53
54 1
        if (!$response->success()) {
55
            throw new TransmissionException($response->getStatus(), new \Exception($response->getReasonPhrase()));
56
        }
57
58 1
        $customId = $response->getBody()['Messages'][0]['CustomID'];
59
60 1
        $this->saveReceipt($email, $customId);
61
    }
62
63 1
    protected function supportedContent(): array
64
    {
65
        return [
66 1
            SimpleContent::class,
67
            TemplatedContent::class,
68
        ];
69
    }
70
71 1
    protected function supportsContent(Content $content): bool
72
    {
73 1
        foreach ($this->supportedContent() as $contentType) {
74 1
            if ($content instanceof $contentType) {
75 1
                return true;
76
            }
77
        }
78
79
        return false;
80
    }
81
82 1
    protected function prepareEmail(Email $email): array
83
    {
84
        $preparedEmail = [
85
            'Messages' => [
86 1
                array_merge([
87 1
                    'CustomID' => Uuid::uuid4()->toString(),
88 1
                    'From' => $this->buildAddress($email->getFrom()),
89 1
                    'To' => $this->buildAddresses($email->getToRecipients()),
90 1
                    'Cc' => $this->buildAddresses($email->getCcRecipients()),
91 1
                    'Bcc' => $this->buildAddresses($email->getBccRecipients()),
92 1
                    'Subject' => $email->getSubject() !== null ? substr($email->getSubject(), 0, 255) : '',
93 1
                    'Attachments' => $this->buildAttachments($email->getAttachments(), false),
94 1
                    'InlinedAttachments' => $this->buildAttachments($email->getEmbedded(), true),
95 1
                ], $this->buildContent($email)),
96
            ],
97
        ];
98
99 1
        if (!empty($email->getReplyTos())) {
100
            $replyTos = $email->getReplyTos();
101
            $replyTo = $this->buildAddress(reset($replyTos));
102
103
            $preparedEmail['Messages'][0]['ReplyTo'] = $replyTo;
104
        }
105
106 1
        if (!empty($email->getHeaders())) {
107 1
            $preparedEmail['Messages'][0]['Headers'] = $this->buildHeaders($email->getHeaders());
108
        }
109
110 1
        return $preparedEmail;
111
    }
112
113 1
    protected function buildContent(Email $email): array
114
    {
115 1
        $content = $email->getContent();
116
117 1
        if ($content instanceof TemplatedContent) {
118
            return [
119
                'TemplateID' => (int) $content->getTemplateId(),
120
                'Variables' => $content->getTemplateData(),
121
            ];
122 1
        } elseif ($content instanceof SimpleContent) {
123
            return [
124 1
                'TextPart' => $content->getText()->getBody(),
125 1
                'HTMLPart' => $content->getHtml()->getBody(),
126
            ];
127
        }
128
129
        return [
130
            'TextPart' => '',
131
            'HTMLPart' => '',
132
        ];
133
    }
134
135 1
    protected function buildAddresses(array $addresses): array
136
    {
137
        return array_map(function (Address $address) {
138 1
            return $this->buildAddress($address);
139 1
        }, $addresses);
140
    }
141
142 1
    protected function buildAddress(Address $address): array
143
    {
144
        return [
145 1
            'Email' => $address->getEmail(),
146 1
            'Name' => $address->getName() ?? 'null',
147
        ];
148
    }
149
150 1
    protected function buildAttachments(array $attachments, bool $embedded): array
151
    {
152
        return array_map(function (Attachment $attachment) use ($embedded) {
153
            $arr = [
154 1
                'ContentType' => $attachment->getContentType(),
155 1
                'Filename' => $attachment->getName(),
156 1
                'Base64Content' => $attachment->getBase64Content(),
157
            ];
158
159 1
            if ($embedded) {
160 1
                $arr['ContentID'] = $attachment->getContentId();
161
            }
162
163 1
            return $arr;
164 1
        }, $attachments);
165
    }
166
167
    /**
168
     * @param Header[] $headers
169
     *
170
     * @return array|null
171
     */
172 1
    protected function buildHeaders(array $headers): ?array
173
    {
174 1
        $headersArray = [];
175
176 1
        foreach ($headers as $header) {
177 1
            $headersArray[$header->getField()] = $header->getValue();
178
        }
179
180 1
        if (empty($headersArray)) {
181
            return null;
182
        }
183
184 1
        return $headersArray;
185
    }
186
}
187