Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
Mailgun
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
2 / 2
13
100.00% covered (success)
100.00%
1 / 1
 createClient
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 send
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <dev@noladev.com>
8 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Mail\Transport;
16
17use Pop\Http\Client;
18use Pop\Mail\Api\AbstractHttp;
19use Pop\Mail\Message;
20
21/**
22 * Mailgun API transport class
23 *
24 * @category   Pop
25 * @package    Pop\Mail
26 * @author     Nick Sagona, III <dev@noladev.com>
27 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
28 * @license    https://www.popphp.org/license     New BSD License
29 * @version    5.0.0
30 */
31class Mailgun extends AbstractHttp implements TransportInterface
32{
33
34    /**
35     * Create the API client
36     *
37     * @param  array|string $options
38     * @throws Exception|Client\Exception|\Pop\Mail\Api\Exception
39     * @return Mailgun
40     */
41    public function createClient(array|string $options): Mailgun
42    {
43        if (is_string($options)) {
44            $options = $this->parseOptions($options);
45        }
46
47        if (!isset($options['api_url']) || !isset($options['api_key'])) {
48            throw new Exception('Error: The required client options were not provided.');
49        }
50
51        $request = new Client\Request($options['api_url'], 'POST');
52        $request->addHeader('Authorization', 'Basic ' . base64_encode('api:' . $options['api_key']));
53
54        $this->client = new Client($request, new Client\Handler\Curl(), ['force_custom_method' => true]);
55
56        return $this;
57    }
58
59    /**
60     * Send the message
61     *
62     * @param  Message $message
63     * @return mixed
64     */
65    public function send(Message $message): mixed
66    {
67        $fields         = [];
68        $headers        = $message->getHeaders();
69        $parts          = $message->getParts();
70        $primaryHeaders = ['Subject', 'To', 'From', 'CC', 'BCC'];
71
72        foreach ($headers as $header => $value) {
73            if (!in_array($header, $primaryHeaders)) {
74                $header = 'h:' . $header;
75            } else {
76                $header = strtolower($header);
77            }
78            $fields[$header] = $value;
79        }
80
81        $i = 0;
82
83        foreach ($parts as $part) {
84            if ($part instanceof Message\Text) {
85                $fields['text'] = $part->getContent();
86            } else if ($part instanceof Message\Html) {
87                $fields['html'] = $part->getContent();
88            } else if ($part instanceof Message\Attachment) {
89                $contentType = $part->getContentType();
90                if (str_contains($contentType, ';')) {
91                    $contentType = trim(substr($contentType, 0, strpos($contentType, ';')));
92                }
93                $fields['attachment[' . $i . ']'] = curl_file_create($part->getFilename(), $contentType, $part->getBasename());
94                $i++;
95            }
96        }
97
98        $this->client->setData($fields);
99
100        if ($i > 0) {
101            $this->client->getRequest()->addHeader('Content-Type', 'multipart/form-data');
102            $this->client->getRequest()
103                ->setNoContentLength(true)
104                ->setRawData(true);
105        }
106
107        return $this->client->send();
108    }
109
110}