42 lines
1.8 KiB
PHP
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));
|
|
}
|
|
}
|