Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
48 / 48 |
|
100.00% |
19 / 19 |
CRAP | |
100.00% |
1 / 1 |
AbstractMessage | |
100.00% |
48 / 48 |
|
100.00% |
19 / 19 |
37 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
addHeader | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
addHeaders | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
hasHeader | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getHeader | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getHeaders | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getContentType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getCharSet | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setContentType | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setCharSet | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getHeaderAsString | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
getHeadersAsString | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
15 | |||
setIdHeader | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getIdHeader | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setId | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
generateId | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getRandomId | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
getBody | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
render | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
renderAsLines | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
__toString | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Mail\Message; |
15 | |
16 | use Pop\Mail\Message; |
17 | |
18 | /** |
19 | * Abstract mail message class |
20 | * |
21 | * @category Pop |
22 | * @package Pop\Mail |
23 | * @author Nick Sagona, III <dev@nolainteractive.com> |
24 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
25 | * @license http://www.popphp.org/license New BSD License |
26 | * @version 4.0.0 |
27 | */ |
28 | abstract class AbstractMessage implements MessageInterface |
29 | { |
30 | |
31 | /** |
32 | * Headers |
33 | * @var array |
34 | */ |
35 | protected array $headers = []; |
36 | |
37 | /** |
38 | * Content type |
39 | * @var ?string |
40 | */ |
41 | protected ?string $contentType = null; |
42 | |
43 | /** |
44 | * Character set |
45 | * @var ?string |
46 | */ |
47 | protected ?string $charSet = null; |
48 | |
49 | /** |
50 | * Message or part ID |
51 | * @var ?string |
52 | */ |
53 | protected ?string $id = null; |
54 | |
55 | /** |
56 | * Message or part ID header name |
57 | * @var ?string |
58 | */ |
59 | protected ?string $idHeader = null; |
60 | |
61 | /** |
62 | * Constructor |
63 | * |
64 | * Instantiate the message object |
65 | */ |
66 | public function __construct() |
67 | { |
68 | |
69 | } |
70 | |
71 | /** |
72 | * Add message part header |
73 | * |
74 | * @param string $header |
75 | * @param string $value |
76 | * @return AbstractMessage |
77 | */ |
78 | public function addHeader(string $header, string $value): AbstractMessage |
79 | { |
80 | $this->headers[$header] = $value; |
81 | return $this; |
82 | } |
83 | |
84 | /** |
85 | * Add message part headers |
86 | * |
87 | * @param array $headers |
88 | * @return AbstractMessage |
89 | */ |
90 | public function addHeaders(array $headers): AbstractMessage |
91 | { |
92 | foreach ($headers as $header => $value) { |
93 | $this->addHeader($header, $value); |
94 | } |
95 | return $this; |
96 | } |
97 | |
98 | /** |
99 | * Determine if message part has header |
100 | * |
101 | * @param string $header |
102 | * @return bool |
103 | */ |
104 | public function hasHeader(string $header): bool |
105 | { |
106 | return isset($this->headers[$header]); |
107 | } |
108 | |
109 | /** |
110 | * Get message part header |
111 | * |
112 | * @param string $header |
113 | * @return ?string |
114 | */ |
115 | public function getHeader(string $header): ?string |
116 | { |
117 | return $this->headers[$header] ?? null; |
118 | } |
119 | |
120 | /** |
121 | * Get all message part headers |
122 | * |
123 | * @return array |
124 | */ |
125 | public function getHeaders(): array |
126 | { |
127 | return $this->headers; |
128 | } |
129 | |
130 | /** |
131 | * Get message part content type |
132 | * |
133 | * @return ?string |
134 | */ |
135 | public function getContentType(): ?string |
136 | { |
137 | return $this->contentType; |
138 | } |
139 | |
140 | /** |
141 | * Get message part character set |
142 | * |
143 | * @return ?string |
144 | */ |
145 | public function getCharSet(): ?string |
146 | { |
147 | return $this->charSet; |
148 | } |
149 | |
150 | /** |
151 | * Set message part content type |
152 | * |
153 | * @param string $contentType |
154 | * @return AbstractMessage |
155 | */ |
156 | public function setContentType(string $contentType): AbstractMessage |
157 | { |
158 | $this->contentType = $contentType; |
159 | return $this; |
160 | } |
161 | |
162 | /** |
163 | * Set message part character set |
164 | * |
165 | * @param ?string $charSet |
166 | * @return AbstractMessage |
167 | */ |
168 | public function setCharSet(?string $charSet = null): AbstractMessage |
169 | { |
170 | $this->charSet = $charSet; |
171 | return $this; |
172 | } |
173 | |
174 | /** |
175 | * Get header as string |
176 | * |
177 | * @param string $header |
178 | * @return string|null |
179 | */ |
180 | public function getHeaderAsString(string $header): string|null |
181 | { |
182 | return ($this->hasHeader($header)) ? $header . ': ' . $this->getHeader($header) : null; |
183 | } |
184 | |
185 | /** |
186 | * Get all message headers as string |
187 | * |
188 | * @param array $omitHeaders |
189 | * @return string |
190 | */ |
191 | public function getHeadersAsString(array $omitHeaders = []): string |
192 | { |
193 | $headers = null; |
194 | |
195 | foreach ($this->headers as $header => $value) { |
196 | if (!in_array($header, $omitHeaders) && !empty($value)) { |
197 | $headers .= $header . ': ' . $value . Message::CRLF; |
198 | } |
199 | } |
200 | |
201 | if ($this->id !== null) { |
202 | if ($this->idHeader === null) { |
203 | $this->setIdHeader((($this instanceof Message) ? 'Message-ID' : 'Content-ID')); |
204 | } |
205 | |
206 | if (!in_array($this->idHeader, $omitHeaders)) { |
207 | $headers .= $this->idHeader . ': ' . $this->id . Message::CRLF; |
208 | } |
209 | } |
210 | |
211 | if (($this->contentType !== null) && !in_array('Content-Type', $omitHeaders)) { |
212 | $headers .= 'Content-Type: ' . $this->contentType; |
213 | if (!empty($this->charSet) && (stripos($this->contentType, 'charset') === false)) { |
214 | $headers .= '; charset="' . $this->charSet . '"'; |
215 | } |
216 | $headers .= Message::CRLF; |
217 | } |
218 | |
219 | if ((!str_contains($headers, 'Content-Type')) && (count($this->parts) == 1)) { |
220 | $contentType = $this->parts[0]->getContentType(); |
221 | if ($contentType !== null) { |
222 | $headers .= 'Content-Type: ' . $contentType . Message::CRLF; |
223 | } |
224 | } |
225 | |
226 | return $headers; |
227 | } |
228 | |
229 | /** |
230 | * Set the ID header name |
231 | * |
232 | * @param string $header |
233 | * @return AbstractMessage |
234 | */ |
235 | public function setIdHeader(string $header): AbstractMessage |
236 | { |
237 | $this->idHeader = $header; |
238 | return $this; |
239 | } |
240 | |
241 | /** |
242 | * Get the ID |
243 | * |
244 | * @return ?string |
245 | */ |
246 | public function getIdHeader(): ?string |
247 | { |
248 | return $this->idHeader; |
249 | } |
250 | |
251 | /** |
252 | * Set the ID |
253 | * |
254 | * @param string $id |
255 | * @return AbstractMessage |
256 | */ |
257 | public function setId(string $id): AbstractMessage |
258 | { |
259 | $this->id = $id; |
260 | return $this; |
261 | } |
262 | |
263 | /** |
264 | * Get the ID |
265 | * |
266 | * @return ?string |
267 | */ |
268 | public function getId(): ?string |
269 | { |
270 | return $this->id; |
271 | } |
272 | |
273 | /** |
274 | * Generate a new ID |
275 | * |
276 | * @string ?string $domain |
277 | * @return string |
278 | */ |
279 | public function generateId(?string $domain = null): string |
280 | { |
281 | $this->setId($this->getRandomId($domain)); |
282 | return $this->id; |
283 | } |
284 | |
285 | /** |
286 | * Returns a random ID |
287 | * |
288 | * @string ?string $idRight |
289 | * @return string |
290 | */ |
291 | protected function getRandomId(?string $idRight = null): string |
292 | { |
293 | $idLeft = md5(getmypid().'.'.time().'.'.uniqid(mt_rand(), true)); |
294 | if ($idRight === null) { |
295 | $idRight = !empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost'; |
296 | } |
297 | return '<' . $idLeft . '@' . $idRight . '>'; |
298 | } |
299 | |
300 | /** |
301 | * Get body |
302 | * |
303 | * @return ?string |
304 | */ |
305 | abstract public function getBody(): ?string; |
306 | |
307 | /** |
308 | * Render |
309 | * |
310 | * @return string |
311 | */ |
312 | abstract public function render(): string; |
313 | |
314 | /** |
315 | * Render as an array of lines |
316 | * |
317 | * @return array |
318 | */ |
319 | abstract public function renderAsLines(): array; |
320 | |
321 | /** |
322 | * Render message to string |
323 | * |
324 | * @return string |
325 | */ |
326 | public function __toString(): string |
327 | { |
328 | return $this->render(); |
329 | } |
330 | |
331 | } |