Completed
Push — master ( 0f5433...3fbd33 )
by David
01:51
created

Message::send()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 17
cts 17
cp 1
rs 9.488
c 0
b 0
f 0
cc 4
nc 4
nop 2
crap 4
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
 * @author Tobias Nyholm <[email protected]>
23
 */
24
class Message extends HttpApi
25
{
26 14
    public function getBatchMessage(string $domain, bool $autoSend = true): BatchMessage
27
    {
28 14
        return new BatchMessage($this, $domain, $autoSend);
29
    }
30
31
    /**
32
     * @return SendResponse|ResponseInterface
33
     */
34 1
    public function send(string $domain, array $params)
35
    {
36 1
        Assert::string($domain);
37 1
        Assert::notEmpty($domain);
38 1
        Assert::notEmpty($params);
39
40 1
        $postDataMultipart = [];
41 1
        $fields = ['attachment', 'inline'];
42 1
        foreach ($fields as $fieldName) {
43 1
            if (!isset($params[$fieldName])) {
44 1
                continue;
45
            }
46
47 1
            Assert::isArray($params[$fieldName]);
48 1
            foreach ($params[$fieldName] as $file) {
49 1
                $postDataMultipart[] = $this->prepareFile($fieldName, $file);
50
            }
51
52 1
            unset($params[$fieldName]);
53
        }
54
55 1
        $postDataMultipart = array_merge($this->prepareMultipartParameters($params), $postDataMultipart);
56 1
        $response = $this->httpPostRaw(sprintf('/v3/%s/messages', $domain), $postDataMultipart);
57 1
        $this->closeResources($postDataMultipart);
58
59 1
        return $this->hydrateResponse($response, SendResponse::class);
60
    }
61
62
    /**
63
     * @param array  $recipients with all you send emails to. Including bcc and cc
64
     * @param string $message    Message filepath or content
65
     *
66
     * @return SendResponse|ResponseInterface
67
     */
68 2
    public function sendMime(string $domain, array $recipients, string  $message, array $params)
69
    {
70 2
        Assert::string($domain);
71 2
        Assert::notEmpty($domain);
72 2
        Assert::notEmpty($recipients);
73 2
        Assert::notEmpty($message);
74 2
        Assert::nullOrIsArray($params);
75
76 2
        $params['to'] = $recipients;
77 2
        $postDataMultipart = $this->prepareMultipartParameters($params);
78
79 2
        if (strlen($message) < PHP_MAXPATHLEN && is_file($message)) {
80
            $fileData = ['filePath' => $message];
81
        } else {
82
            $fileData = [
83 2
                'fileContent' => $message,
84 2
                'filename' => 'message',
85
            ];
86
        }
87 2
        $postDataMultipart[] = $this->prepareFile('message', $fileData);
88 2
        $response = $this->httpPostRaw(sprintf('/v3/%s/messages.mime', $domain), $postDataMultipart);
89 2
        $this->closeResources($postDataMultipart);
90
91 2
        return $this->hydrateResponse($response, SendResponse::class);
92
    }
93
94
    /**
95
     * Get stored message.
96
     *
97
     * @param bool $rawMessage if true we will use "Accept: message/rfc2822" header
98
     *
99
     * @return ShowResponse|ResponseInterface
100
     */
101 2
    public function show(string $url, bool $rawMessage = false)
102
    {
103 2
        Assert::notEmpty($url);
104
105 2
        $headers = [];
106 2
        if ($rawMessage) {
107 1
            $headers['Accept'] = 'message/rfc2822';
108
        }
109
110 2
        $response = $this->httpGet($url, [], $headers);
111
112 2
        return $this->hydrateResponse($response, ShowResponse::class);
113
    }
114
115
    /**
116
     * @param array $filePath array('fileContent' => 'content') or array('filePath' => '/foo/bar')
117
     *
118
     * @throws InvalidArgumentException
119
     */
120 3
    private function prepareFile(string $fieldName, array $filePath): array
121
    {
122 3
        $filename = isset($filePath['filename']) ? $filePath['filename'] : null;
123
124 3
        if (isset($filePath['fileContent'])) {
125
            // File from memory
126 2
            $resource = fopen('php://temp', 'r+');
127 2
            fwrite($resource, $filePath['fileContent']);
128 2
            rewind($resource);
129 1
        } elseif (isset($filePath['filePath'])) {
130
            // File form path
131 1
            $path = $filePath['filePath'];
132
133
            // Remove leading @ symbol
134 1
            if (0 === strpos($path, '@')) {
135
                $path = substr($path, 1);
136
            }
137
138 1
            $resource = fopen($path, 'r');
139
        } else {
140
            throw new InvalidArgumentException('When using a file you need to specify parameter "fileContent" or "filePath"');
141
        }
142
143
        return [
144 3
            'name' => $fieldName,
145 3
            'content' => $resource,
146 3
            'filename' => $filename,
147
        ];
148
    }
149
150
    /**
151
     * Prepare multipart parameters. Make sure each POST parameter is split into an array with 'name' and 'content' keys.
152
     */
153 3
    private function prepareMultipartParameters(array $params): array
154
    {
155 3
        $postDataMultipart = [];
156 3
        foreach ($params as $key => $value) {
157
            // If $value is not an array we cast it to an array
158 3
            foreach ((array) $value as $subValue) {
159 3
                $postDataMultipart[] = [
160 3
                    'name' => $key,
161 3
                    'content' => $subValue,
162
                ];
163
            }
164
        }
165
166 3
        return $postDataMultipart;
167
    }
168
169
    /**
170
     * Close open resources.
171
     */
172 3
    private function closeResources(array $params): void
173
    {
174 3
        foreach ($params as $param) {
175 3
            if (is_array($param) && array_key_exists('content', $param) && is_resource($param['content'])) {
176 3
                fclose($param['content']);
177
            }
178
        }
179 3
    }
180
}
181