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)); } }