Completed
Push — master ( 4a903b...b725ab )
by Tobias
03:23 queued 53s
created

Message::prepareFile()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6.6

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 9
cts 15
cp 0.6
rs 9.1448
c 0
b 0
f 0
cc 5
nc 8
nop 2
crap 6.6
1
<?php
2
3
/*
4
 * Copyright (C) 2013 Mailgun
5
 *
6
 * This software may be modified and distributed under the terms
7
 * of the MIT license. See the LICENSE file for details.
8
 */
9
10
namespace Mailgun\Api;
11
12
use Mailgun\Assert;
13
use Mailgun\Exception\InvalidArgumentException;
14
use Mailgun\Message\BatchMessage;
15
use Mailgun\Model\Message\SendResponse;
16
use Mailgun\Model\Message\ShowResponse;
17
use Psr\Http\Message\ResponseInterface;
18
19
/**
20
 * @author Tobias Nyholm <[email protected]>
21
 */
22
class Message extends HttpApi
23
{
24 14
    public function getBatchMessage(string $domain, bool $autoSend = true): BatchMessage
25
    {
26 14
        return new BatchMessage($this, $domain, $autoSend);
27
    }
28
29
    /**
30
     * @return SendResponse|ResponseInterface
31
     */
32
    public function send(string $domain, array $params)
33
    {
34
        Assert::string($domain);
35
        Assert::notEmpty($domain);
36
        Assert::notEmpty($params);
37
38
        $postDataMultipart = [];
39
        $fields = ['attachment', 'inline'];
40
        foreach ($fields as $fieldName) {
41
            if (!isset($params[$fieldName])) {
42
                continue;
43
            }
44
45
            Assert::isArray($params[$fieldName]);
46
            foreach ($params[$fieldName] as $file) {
47
                $postDataMultipart[] = $this->prepareFile($fieldName, $file);
48
            }
49
50
            unset($params[$fieldName]);
51
        }
52
53
        $postDataMultipart = array_merge($this->prepareMultipartParameters($params), $postDataMultipart);
54
        $response = $this->httpPostRaw(sprintf('/v3/%s/messages', $domain), $postDataMultipart);
55
        $this->closeResources($postDataMultipart);
56
57
        return $this->hydrateResponse($response, SendResponse::class);
58
    }
59
60
    /**
61
     * @param string $domain
62
     * @param array  $recipients with all you send emails to. Including bcc and cc
63
     * @param string $message    Message filepath or content
64
     * @param array  $params
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 string $url
98
     * @param bool   $rawMessage if true we will use "Accept: message/rfc2822" header
99
     *
100
     * @return ShowResponse|ResponseInterface
101
     */
102
    public function show(string $url, bool $rawMessage = false)
103
    {
104
        Assert::notEmpty($url);
105
106
        $headers = [];
107
        if ($rawMessage) {
108
            $headers['Accept'] = 'message/rfc2822';
109
        }
110
111
        $response = $this->httpGet($url, [], $headers);
112
113
        return $this->hydrateResponse($response, ShowResponse::class);
114
    }
115
116
    /**
117
     * @param array $filePath array('fileContent' => 'content') or array('filePath' => '/foo/bar')
118
     *
119
     * @throws InvalidArgumentException
120
     */
121 2
    private function prepareFile(string $fieldName, array $filePath): array
122
    {
123 2
        $filename = isset($filePath['filename']) ? $filePath['filename'] : null;
124
125 2
        if (isset($filePath['fileContent'])) {
126
            // File from memory
127 2
            $resource = fopen('php://temp', 'r+');
128 2
            fwrite($resource, $filePath['fileContent']);
129 2
            rewind($resource);
130
        } elseif (isset($filePath['filePath'])) {
131
            // File form path
132
            $path = $filePath['filePath'];
133
134
            // Remove leading @ symbol
135
            if (0 === strpos($path, '@')) {
136
                $path = substr($path, 1);
137
            }
138
139
            $resource = fopen($path, 'r');
140
        } else {
141
            throw new InvalidArgumentException('When using a file you need to specify parameter "fileContent" or "filePath"');
142
        }
143
144
        return [
145 2
            'name' => $fieldName,
146 2
            'content' => $resource,
147 2
            'filename' => $filename,
148
        ];
149
    }
150
151
    /**
152
     * Prepare multipart parameters. Make sure each POST parameter is split into an array with 'name' and 'content' keys.
153
     */
154 2
    private function prepareMultipartParameters(array $params): array
155
    {
156 2
        $postDataMultipart = [];
157 2
        foreach ($params as $key => $value) {
158
            // If $value is not an array we cast it to an array
159 2
            foreach ((array) $value as $subValue) {
160 2
                $postDataMultipart[] = [
161 2
                    'name' => $key,
162 2
                    'content' => $subValue,
163
                ];
164
            }
165
        }
166
167 2
        return $postDataMultipart;
168
    }
169
170
    /**
171
     * Close open resources.
172
     */
173 2
    private function closeResources(array $params): void
174
    {
175 2
        foreach ($params as $param) {
176 2
            if (is_array($param) && array_key_exists('content', $param) && is_resource($param['content'])) {
177 2
                fclose($param['content']);
178
            }
179
        }
180 2
    }
181
}
182