Files
xxx/tests/php/Support/Mail.php
T
tim ed959888b4 Add PHP unit tests and page tests.
Run "composer install", then "composer test".
2026-09-26 03:48:09 +02:00

42 lines
1.8 KiB
PHP

<?php
namespace Xxx\Tests\Support;
/*
* Mail sent by code in a subprocess. PHP reads sendmail_path only at
* start-up, so code that sends mail runs in a new PHP process with
* tests/php/fixtures/fake-sendmail.php as its sendmail.
*/
class Mail {
/*
* PhpProcess::run() with the fake sendmail. The result has an extra
* 'mails' entry: a list of array('headers' => name => value,
* 'subject' => ..., 'body' => ...), decoded.
*/
public static function run(string $code, array $env = array(), array $ini = array()): array {
$log = tempnam(sys_get_temp_dir(), 'xxx-mail-');
$sendmail = escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg(XXX_ROOT . '/tests/php/fixtures/fake-sendmail.php');
$result = PhpProcess::run($code, array('MAIL_LOG' => $log) + $env, array('sendmail_path' => $sendmail) + $ini);
$result['mails'] = array();
foreach (file($log, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line)
$result['mails'][] = self::parse(json_decode($line, TRUE)['message']);
unlink($log);
return $result;
}
public static function parse(string $message): array {
list($head, $body) = preg_split('/\r?\n\r?\n/', $message, 2) + array('', '');
$headers = array();
foreach (preg_split('/\r?\n(?![ \t])/', $head) as $line) {
list($name, $value) = explode(':', $line, 2) + array('', '');
$headers[strtolower(trim($name))] = trim(preg_replace('/\r?\n[ \t]+/', ' ', $value));
}
$encoding = strtolower($headers['content-transfer-encoding'] ?? '');
if ($encoding === 'base64')
$body = base64_decode($body);
else if ($encoding === 'quoted-printable')
$body = quoted_printable_decode($body);
return array('headers' => $headers, 'subject' => mb_decode_mimeheader($headers['subject'] ?? ''),
'body' => str_replace("\r\n", "\n", $body));
}
}