Completed
Push — master ( 3e59f6...649b2a )
by Craig
10s
created

PostmarkTransport::getMessageId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Coconuts\Mail;
4
5
use Swift_Attachment;
6
use Swift_Mime_Message;
7
use GuzzleHttp\ClientInterface;
8
use Illuminate\Mail\Transport\Transport;
9
10
class PostmarkTransport extends Transport
11
{
12
    /**
13
     * Guzzle client instance.
14
     *
15
     * @var \GuzzleHttp\ClientInterface
16
     */
17
    protected $client;
18
19
    /**
20
     * The Postmark API key.
21
     *
22
     * @var string
23
     */
24
    protected $key;
25
26
    /**
27
     * The Postmark API end-point.
28
     *
29
     * @var string
30
     */
31
    protected $url = 'https://api.postmarkapp.com/email';
32
33
    /**
34
     * Create a new Postmark transport instance.
35
     *
36
     * @param \GuzzleHttp\ClientInterface $client
37
     * @param string $key
38
     *
39
     * @return void
40
     */
41 5
    public function __construct(ClientInterface $client, $key)
42
    {
43 5
        $this->key = $key;
44 5
        $this->client = $client;
45 5
    }
46
47
    /**
48
     * Send the given Message.
49
     *
50
     * Recipient/sender data will be retrieved from the Message API.
51
     * The return value is the number of recipients who were accepted for delivery.
52
     *
53
     * @param Swift_Mime_Message $message
54
     * @param string[] $failedRecipients An array of failures by-reference
55
     *
56
     * @return int
57
     */
58 1
    public function send(Swift_Mime_Message $message, &$failedRecipients = null)
59
    {
60 1
        $this->beforeSendPerformed($message);
61
62 1
        $response = $this->client->post($this->url, $this->payload($message));
63
64 1
        $message->getHeaders()->addTextHeader(
65 1
            'X-PM-Message-Id',
66 1
            $this->getMessageId($response)
67
        );
68
69 1
        $this->sendPerformed($message);
70
71 1
        return $this->numberOfRecipients($message);
72
    }
73
74
    /**
75
     * Get all attachments for the given message.
76
     *
77
     * @param \Swift_Mime_Message $message
78
     *
79
     * @return array
80
     */
81 2
    protected function getAttachments(Swift_Mime_Message $message)
82
    {
83 2
        $attachments = [];
84
85 2
        $children = $message->getChildren();
86
87 2
        foreach ($children as $child) {
88 2
            if ($child instanceof Swift_Attachment) {
89 2
                $header = $child->getHeaders()->get('content-type');
90
91 2
                $attachments[] = [
92 2
                    'Name' => $header->getParameter('name'),
93 2
                    'Content' => base64_encode($child->getBody()),
94 2
                    'ContentType' => $child->getContentType(),
95
                ];
96
            }
97
        }
98
99 2
        return $attachments;
100
    }
101
102
    /**
103
     * Format the contacts for the API request
104
     *
105
     * @param array $contacts
106
     *
107
     * @return string
108
     */
109 3
    protected function getContacts($contacts)
110
    {
111 3
        return collect($contacts)
112
            ->map(function ($display, $address) {
113 3
                return $display ? $display . " <{$address}>" : $address;
114 3
            })
115 3
            ->values()
116 3
            ->implode(',');
117
    }
118
119
    /**
120
     * Get the "From" payload field for the API request.
121
     *
122
     * @param \Swift_Mime_Message $message
123
     *
124
     * @return string
125
     */
126 3
    protected function getFrom(Swift_Mime_Message $message)
127
    {
128 3
        return collect($message->getFrom())
129 3
            ->map(function ($display, $address) {
130 3
                return $display ? $display . " <$address>" : $address;
131 3
            })
132 3
            ->values()
133 3
            ->implode(',');
134
    }
135
136
    /**
137
     * Get the message ID from the response.
138
     *
139
     * @param \GuzzleHttp\Psr7\Response $response
140
     * @return string
141
     */
142 1
    protected function getMessageId($response)
143
    {
144 1
        return object_get(
145 1
            json_decode($response->getBody()->getContents()),
146 1
            'MessageID'
147
        );
148
    }
149
150
    /**
151
     * Get the HTTP payload for sending the Postmark message.
152
     *
153
     * @param \Swift_Mime_Message $message
154
     *
155
     * @return array
156
     */
157 2
    protected function payload(Swift_Mime_Message $message)
158
    {
159 2
        $headers = $message->getHeaders();
160
161 2
        $to = $this->getContacts($message->getTo());
162 2
        $cc = $this->getContacts($message->getCc());
163 2
        $bcc = $this->getContacts($message->getBcc());
164 2
        $replyTo = $this->getContacts($message->getReplyTo());
165 2
        $attachments = $this->getAttachments($message);
166
167
        return [
168
            'headers' => [
169 2
                'Accept' => 'application/json',
170 2
                'X-Postmark-Server-Token' => $this->key,
171
            ],
172
            'json' => [
173 2
                'From' => $this->getFrom($message),
174 2
                'To' => $to,
175 2
                'Cc' => $cc,
176 2
                'Bcc' => $bcc,
177 2
                'Tag' => $headers->has('tag') ? $headers->get('tag')->getFieldBody() : '',
178 2
                'Subject' => $message->getSubject(),
179 2
                'HtmlBody' => $message->getBody(),
180 2
                'ReplyTo' => $replyTo,
181 2
                'Attachments' => $attachments,
182
            ],
183
        ];
184
    }
185
}
186