Completed
Push — master ( 3793b4...3fda48 )
by Craig
03:13 queued 01:58
created

PostmarkTransport::getHtmlAndTextBody()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 9
cts 9
cp 1
rs 9.6666
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Coconuts\Mail;
4
5
use Swift_MimePart;
6
use Swift_Attachment;
7
use Swift_Mime_SimpleMessage;
8
use GuzzleHttp\ClientInterface;
9
use Illuminate\Mail\Transport\Transport;
10
11
class PostmarkTransport extends Transport
12
{
13
    /**
14
     * Guzzle client instance.
15
     *
16
     * @var \GuzzleHttp\ClientInterface
17
     */
18
    protected $client;
19
20
    /**
21
     * The Postmark API key.
22
     *
23
     * @var string
24
     */
25
    protected $key;
26
27
    /**
28
     * The Postmark API end-point.
29
     *
30
     * @var string
31
     */
32
    protected $url = 'https://api.postmarkapp.com/email';
33
34
    /**
35
     * Create a new Postmark transport instance.
36
     *
37
     * @param \GuzzleHttp\ClientInterface $client
38
     * @param string $key
39
     *
40
     * @return void
41
     */
42 29
    public function __construct(ClientInterface $client, $key)
43
    {
44 29
        $this->key = $key;
45 29
        $this->client = $client;
46 29
    }
47
48
    /**
49
     * {@inheritdoc}
50
     */
51 1
    public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
52
    {
53 1
        $this->beforeSendPerformed($message);
54
55 1
        $response = $this->client->post($this->url, $this->payload($message));
56
57 1
        $message->getHeaders()->addTextHeader(
58 1
            'X-PM-Message-Id',
59 1
            $this->getMessageId($response)
60
        );
61
62 1
        $this->sendPerformed($message);
63
64 1
        return $this->numberOfRecipients($message);
65
    }
66
67
    /**
68
     * Get all attachments for the given message.
69
     *
70
     * @param \Swift_Mime_SimpleMessage $message
71
     *
72
     * @return array
73
     */
74 19
    protected function getAttachments(Swift_Mime_SimpleMessage $message)
75
    {
76 19
        return collect($message->getChildren())
77
            ->filter(function ($child) {
78 16
                return $child instanceof Swift_Attachment;
79 19
            })
80
            ->map(function ($child) {
81
                return [
82 15
                    'Name' => $child->getHeaders()->get('content-type')->getParameter('name'),
83 15
                    'Content' => base64_encode($child->getBody()),
84 15
                    'ContentType' => $child->getContentType(),
85
                ];
86 19
            })
87 19
            ->values()
88 19
            ->toArray();
89
    }
90
91
    /**
92
     * Format the display name.
93
     *
94
     * @param  string
95
     * @return string
96
     */
97 7
    protected function getDisplayname($value)
98
    {
99 7
        if (strpos($value, ',') !== false) {
100 1
            return '"' . $value . '"';
101
        }
102
103 6
        return $value;
104
    }
105
106
    /**
107
     * Format the contacts for the API request.
108
     *
109
     * @param string|array $contacts
110
     *
111
     * @return string
112
     */
113 19
    protected function getContacts($contacts)
114
    {
115 19
        return collect($contacts)
116
            ->map(function ($display, $address) {
117 14
                return $display ? $this->getDisplayname($display) . " <{$address}>" : $address;
118 19
            })
119 19
            ->values()
120 19
            ->implode(',');
121
    }
122
123
    /**
124
     * Get the message ID from the response.
125
     *
126
     * @param \GuzzleHttp\Psr7\Response $response
127
     *
128
     * @return string
129
     */
130 1
    protected function getMessageId($response)
131
    {
132 1
        return object_get(
133 1
            json_decode($response->getBody()->getContents()),
134 1
            'MessageID'
135
        );
136
    }
137
138
    /**
139
     * Get the body for the given message.
140
     *
141
     * @param \Swift_Mime_SimpleMessage $message
142
     *
143
     * @return string
144
     */
145 20
    protected function getBody(Swift_Mime_SimpleMessage $message)
146
    {
147 20
        return $message->getBody() ?: '';
148
    }
149
150
    /**
151
     * Get the text and html fields for the given message.
152
     *
153
     * @param \Swift_Mime_SimpleMessage $message
154
     *
155
     * @return array
156
     */
157 18
    protected function getHtmlAndTextBody(Swift_Mime_SimpleMessage $message)
158
    {
159 18
        $key = collect([
160 18
            'text/html' => 'HtmlBody',
161
            'multipart/mixed' => 'HtmlBody',
162
            'multipart/related' => 'HtmlBody',
163
            'multipart/alternative' => 'HtmlBody',
164
        ])
165 18
        ->get($message->getContentType(), 'TextBody');
166
167 18
        return collect([
168 18
            $key => $this->getBody($message)
169
        ])->when($this->getMimePart($message, 'text/plain'), function ($collection, $value) {
0 ignored issues
show
Documentation introduced by
$this->getMimePart($message, 'text/plain') is of type object<Swift_MimePart>|null, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
170 1
            return $collection->put('TextBody', $value->getBody());
171
        })->when($this->getMimePart($message, 'text/html'), function ($collection, $value) {
172 13
            return $collection->put('HtmlBody', $value->getBody());
173 18
        })->all();
174
    }
175
176
    /**
177
     * Get a mime part from the given message.
178
     *
179
     * @param \Swift_Mime_SimpleMessage $message
180
     * @param string $mimeType
181
     *
182
     * @return \Swift_MimePart|null
183
     */
184 19
    protected function getMimePart(Swift_Mime_SimpleMessage $message, $mimeType)
185
    {
186 19
        return collect($message->getChildren())
187
            ->filter(function ($child) {
188 16
                return $child instanceof Swift_MimePart;
189 19
            })
190
            ->filter(function ($child) use ($mimeType) {
191 15
                return strpos($child->getContentType(), $mimeType) === 0;
192 19
            })
193 19
            ->first();
194
    }
195
196
    /**
197
     * Get the subject for the given message.
198
     *
199
     * @param \Swift_Mime_SimpleMessage $message
200
     *
201
     * @return string
202
     */
203 20
    protected function getSubject(Swift_Mime_SimpleMessage $message)
204
    {
205 20
        return $message->getSubject() ?: '';
206
    }
207
208
    /**
209
     * Get the tag for the given message.
210
     *
211
     * @param \Swift_Mime_SimpleMessage $message
212
     *
213
     * @return string
214
     */
215 21
    protected function getTag(Swift_Mime_SimpleMessage $message)
216
    {
217 21
        return optional(
218 21
            collect($message->getHeaders()->getAll('tag'))
219 21
            ->last()
220
        )
221 21
        ->getFieldBody() ?: '';
222
    }
223
224
    /**
225
     * Get the HTTP payload for sending the Postmark message.
226
     *
227
     * @param \Swift_Mime_SimpleMessage $message
228
     *
229
     * @return array
230
     */
231 18
    protected function payload(Swift_Mime_SimpleMessage $message)
232
    {
233 18
        return collect([
234
            'headers' => [
235 18
                'Accept' => 'application/json',
236 18
                'Content-Type' => 'application/json',
237 18
                'X-Postmark-Server-Token' => $this->key,
238
            ]
239
        ])
240 18
        ->merge([
241 18
            'json' => collect([
242 18
                'Cc' => $this->getContacts($message->getCc()),
243 18
                'Bcc' => $this->getContacts($message->getBcc()),
244 18
                'Tag' => $this->getTag($message),
245 18
                'Subject' => $this->getSubject($message),
246 18
                'ReplyTo' => $this->getContacts($message->getReplyTo()),
247 18
                'Attachments' => $this->getAttachments($message),
248
            ])
249
            ->reject(function ($item) {
250 18
                return empty($item);
251 18
            })
252 18
            ->put('From', $this->getContacts($message->getFrom()))
253 18
            ->put('To', $this->getContacts($message->getTo()))
254 18
            ->merge($this->getHtmlAndTextBody($message))
255
        ])
256 18
        ->toArray();
257
    }
258
}
259