Completed
Push — master ( d8ae00...12ed8a )
by Tobias
02:18
created

Message::sendMime()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3.0026

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 14
cts 15
cp 0.9333
rs 9.52
c 0
b 0
f 0
cc 3
nc 2
nop 4
crap 3.0026
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright (C) 2013 Mailgun
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license. See the LICENSE file for details.
10
 */
11
12
namespace Mailgun\Api;
13
14
use Mailgun\Assert;
15
use Mailgun\Exception\InvalidArgumentException;
16
use Mailgun\Message\BatchMessage;
17
use Mailgun\Model\Message\SendResponse;
18
use Mailgun\Model\Message\ShowResponse;
19
use Psr\Http\Message\ResponseInterface;
20
21
/**
22
 * @see https://documentation.mailgun.com/en/latest/api-sending.html
23
 *
24
 * @author Tobias Nyholm <[email protected]>
25
 */
26
class Message extends HttpApi
27
{
28 14
    public function getBatchMessage(string $domain, bool $autoSend = true): BatchMessage
29
    {
30 14
        return new BatchMessage($this, $domain, $autoSend);
31
    }
32
33
    /**
34
     * @see https://documentation.mailgun.com/en/latest/api-sending.html#sending
35
     *
36
     * @return SendResponse|ResponseInterface
37
     */
38 1
    public function send(string $domain, array $params)
39
    {
40 1
        Assert::string($domain);
41 1
        Assert::notEmpty($domain);
42 1
        Assert::notEmpty($params);
43
44 1
        $postDataMultipart = [];
45 1
        $fields = ['attachment', 'inline'];
46 1
        foreach ($fields as $fieldName) {
47 1
            if (!isset($params[$fieldName])) {
48 1
                continue;
49
            }
50
51 1
            Assert::isArray($params[$fieldName]);
52 1
            foreach ($params[$fieldName] as $file) {
53 1
                $postDataMultipart[] = $this->prepareFile($fieldName, $file);
54
            }
55
56 1
            unset($params[$fieldName]);
57
        }
58
59 1
        $postDataMultipart = array_merge($this->prepareMultipartParameters($params), $postDataMultipart);
60 1
        $response = $this->httpPostRaw(sprintf('/v3/%s/messages', $domain), $postDataMultipart);
61 1
        $this->closeResources($postDataMultipart);
62
63
        return $this->hydrateResponse($response, SendResponse::class);
64
    }
65
66
    /**
67
     * @see https://documentation.mailgun.com/en/latest/api-sending.html#sending
68
     *
69
     * @param array  $recipients with all you send emails to. Including bcc and cc
70
     * @param string $message    Message filepath or content
71
     *
72
     * @return SendResponse|ResponseInterface
73
     */
74 2
    public function sendMime(string $domain, array $recipients, string $message, array $params)
75
    {
76 2
        Assert::string($domain);
77 2
        Assert::notEmpty($domain);
78 2
        Assert::notEmpty($recipients);
79 2
        Assert::notEmpty($message);
80 2
        Assert::nullOrIsArray($params);
0 ignored issues
show
Bug introduced by
The method nullOrIsArray() does not exist on Mailgun\Assert. Did you maybe mean isArray()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
81
82 2
        $params['to'] = $recipients;
83 2
        $postDataMultipart = $this->prepareMultipartParameters($params);
84
85 2
        if (strlen($message) < PHP_MAXPATHLEN && is_file($message)) {
86
            $fileData = ['filePath' => $message];
87
        } else {
88
            $fileData = [
89 2
                'fileContent' => $message,
90 2
                'filename' => 'message',
91
            ];
92
        }
93 2
        $postDataMultipart[] = $this->prepareFile('message', $fileData);
94 2
        $response = $this->httpPostRaw(sprintf('/v3/%s/messages.mime', $domain), $postDataMultipart);
95 2
        $this->closeResources($postDataMultipart);
96
97
        return $this->hydrateResponse($response, SendResponse::class);
98
    }
99
100
    /**
101
     * Get stored message.
102
     *
103
     * @see https://documentation.mailgun.com/en/latest/api-sending.html#retrieving-stored-messages
104
     *
105
     * @param bool $rawMessage if true we will use "Accept: message/rfc2822" header
106
     *
107
     * @return ShowResponse|ResponseInterface
108
     */
109 2
    public function show(string $url, bool $rawMessage = false)
110
    {
111 2
        Assert::notEmpty($url);
112
113 2
        $headers = [];
114 2
        if ($rawMessage) {
115 1
            $headers['Accept'] = 'message/rfc2822';
116
        }
117
118 2
        $response = $this->httpGet($url, [], $headers);
119
120
        return $this->hydrateResponse($response, ShowResponse::class);
121
    }
122
123
    /**
124
     * @param array $filePath array('fileContent' => 'content') or array('filePath' => '/foo/bar')
125
     *
126
     * @throws InvalidArgumentException
127
     */
128 3
    private function prepareFile(string $fieldName, array $filePath): array
129
    {
130 3
        $filename = isset($filePath['filename']) ? $filePath['filename'] : null;
131
132 3
        if (isset($filePath['fileContent'])) {
133
            // File from memory
134 2
            $resource = fopen('php://temp', 'r+');
135 2
            fwrite($resource, $filePath['fileContent']);
136 2
            rewind($resource);
137 1
        } elseif (isset($filePath['filePath'])) {
138
            // File form path
139 1
            $path = $filePath['filePath'];
140
141
            // Remove leading @ symbol
142 1
            if (0 === strpos($path, '@')) {
143
                $path = substr($path, 1);
144
            }
145
146 1
            $resource = fopen($path, 'r');
147
        } else {
148
            throw new InvalidArgumentException('When using a file you need to specify parameter "fileContent" or "filePath"');
149
        }
150
151
        return [
152 3
            'name' => $fieldName,
153 3
            'content' => $resource,
154 3
            'filename' => $filename,
155
        ];
156
    }
157
158
    /**
159
     * Prepare multipart parameters. Make sure each POST parameter is split into an array with 'name' and 'content' keys.
160
     */
161 3
    private function prepareMultipartParameters(array $params): array
162
    {
163 3
        $postDataMultipart = [];
164 3
        foreach ($params as $key => $value) {
165
            // If $value is not an array we cast it to an array
166 3
            foreach ((array) $value as $subValue) {
167 3
                $postDataMultipart[] = [
168 3
                    'name' => $key,
169 3
                    'content' => $subValue,
170
                ];
171
            }
172
        }
173
174 3
        return $postDataMultipart;
175
    }
176
177
    /**
178
     * Close open resources.
179
     */
180 3
    private function closeResources(array $params): void
181
    {
182 3
        foreach ($params as $param) {
183 3
            if (is_array($param) && array_key_exists('content', $param) && is_resource($param['content'])) {
184 3
                fclose($param['content']);
185
            }
186
        }
187 3
    }
188
}
189