Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
47 / 47
100.00% covered (success)
100.00%
10 / 10
CRAP
100.00% covered (success)
100.00%
1 / 1
Mailer
100.00% covered (success)
100.00%
47 / 47
100.00% covered (success)
100.00%
10 / 10
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 makeConfig
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
1
 getConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfigs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCrlf
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCharset
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLogs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 resetLogs
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addLog
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 send
n/a
0 / 0
n/a
0 / 0
0
 setDebugCollector
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php declare(strict_types=1);
2/*
3 * This file is part of Aplus Framework Email Library.
4 *
5 * (c) Natan Felles <natanfelles@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10namespace Framework\Email;
11
12use Framework\Email\Debug\EmailCollector;
13use JetBrains\PhpStorm\ArrayShape;
14use SensitiveParameter;
15
16/**
17 * Class Mailer.
18 *
19 * @package email
20 */
21abstract class Mailer
22{
23    /**
24     * @var array<string,mixed>
25     */
26    protected array $config = [];
27    /**
28     * @var array<int,array<string,mixed>>
29     */
30    protected array $logs = [];
31    protected EmailCollector $debugCollector;
32
33    /**
34     * Mailer constructor.
35     *
36     * @param array<string,mixed>|string $username
37     * @param string|null $password
38     * @param string $host
39     * @param int $port
40     * @param string|null $hostname
41     */
42    public function __construct(
43        #[SensitiveParameter] array | string $username,
44        #[SensitiveParameter] string $password = null,
45        string $host = 'localhost',
46        int $port = 587,
47        string $hostname = null
48    ) {
49        $this->config = \is_array($username)
50            ? $this->makeConfig($username)
51            : $this->makeConfig([
52                'username' => $username,
53                'password' => $password,
54                'host' => $host,
55                'port' => $port,
56                'hostname' => $hostname ?? \gethostname(),
57            ]);
58    }
59
60    /**
61     * Make Base configurations.
62     *
63     * @param array<string,mixed> $config
64     *
65     * @return array<string,mixed>
66     */
67    #[ArrayShape([
68        'host' => 'string',
69        'port' => 'int',
70        'tls' => 'bool',
71        'options' => 'array',
72        'username' => 'string|null',
73        'password' => 'string|null',
74        'charset' => 'string',
75        'crlf' => 'string',
76        'connection_timeout' => 'int',
77        'response_timeout' => 'int',
78        'hostname' => 'string',
79        'keep_alive' => 'bool',
80        'add_logs' => 'bool',
81    ])]
82    protected function makeConfig(#[SensitiveParameter] array $config) : array
83    {
84        return \array_replace_recursive([
85            'host' => 'localhost',
86            'port' => 587,
87            'tls' => true,
88            'options' => [
89                'ssl' => [
90                    'allow_self_signed' => false,
91                    'verify_peer' => true,
92                    'verify_peer_name' => true,
93                ],
94            ],
95            'username' => null,
96            'password' => null,
97            'charset' => 'utf-8',
98            'crlf' => "\r\n",
99            'connection_timeout' => 10,
100            'response_timeout' => 5,
101            'hostname' => \gethostname(),
102            'keep_alive' => false,
103            'add_logs' => true,
104        ], $config);
105    }
106
107    /**
108     * @todo Make public in version 4.0.0
109     *
110     * @param string $key
111     *
112     * @return mixed
113     */
114    protected function getConfig(string $key) : mixed
115    {
116        return $this->config[$key];
117    }
118
119    /**
120     * @return array<string,mixed>
121     */
122    #[ArrayShape([
123        'host' => 'string',
124        'port' => 'int',
125        'tls' => 'bool',
126        'options' => 'array',
127        'username' => 'string|null',
128        'password' => 'string|null',
129        'charset' => 'string',
130        'crlf' => 'string',
131        'connection_timeout' => 'int',
132        'response_timeout' => 'int',
133        'hostname' => 'string',
134        'keep_alive' => 'bool',
135        'add_logs' => 'bool',
136    ])]
137    public function getConfigs() : array
138    {
139        return $this->config;
140    }
141
142    public function getCrlf() : string
143    {
144        return (string) $this->getConfig('crlf');
145    }
146
147    public function getCharset() : string
148    {
149        return (string) $this->getConfig('charset');
150    }
151
152    /**
153     * Get an array of logs.
154     *
155     * Contains commands and responses from the Mailer server.
156     *
157     * @return array<int,array<string,mixed>>
158     */
159    public function getLogs() : array
160    {
161        return $this->logs;
162    }
163
164    /**
165     * Reset logs.
166     *
167     * @return static
168     */
169    public function resetLogs() : static
170    {
171        $this->logs = [];
172        return $this;
173    }
174
175    /**
176     * @param string $command
177     * @param string $response
178     *
179     * @return static
180     */
181    protected function addLog(string $command, string $response) : static
182    {
183        if ( ! $this->getConfig('add_logs')) {
184            return $this;
185        }
186        $this->logs[] = [
187            'command' => $command,
188            'responses' => \explode(\PHP_EOL, $response),
189        ];
190        return $this;
191    }
192
193    abstract public function send(Message $message) : bool;
194
195    public function setDebugCollector(EmailCollector $collector) : static
196    {
197        $collector->setMailer($this);
198        $this->debugCollector = $collector;
199        return $this;
200    }
201}