mirror of
https://github.com/php/php-src.git
synced 2025-08-16 22:18:50 +02:00

We setup the currently latest version of hMailServer[1] as mail server, and configure according to imap_include.inc. To not require further configuration, we adapt mail_skipif.inc and mail_include.inc to match that configuration. However, we also change the default domain to the reserved `example.com`. We also update the standard mail tests to use the `--EXTENSIONS--` section (instead of skipping the tests if ext/imap is not available). Finally, we fix bug80751.phpt to expect the configured To and Cc mail addresses. [1] <https://www.hmailserver.com/> Closes GH-8357.
213 lines
6.6 KiB
PHP
213 lines
6.6 KiB
PHP
<?php
|
|
/** If required change these values to make the test runs */
|
|
const IMAP_SERVER_NO_DEBUG = '{127.0.0.1:143/norsh}';
|
|
const IMAP_SERVER_DEBUG = '{127.0.0.1:143/debug/norsh}';
|
|
const IMAP_SERVER = IMAP_SERVER_DEBUG;
|
|
const IMAP_DEFAULT_MAILBOX = IMAP_SERVER . 'INBOX';
|
|
const IMAP_MAIL_DOMAIN = 'example.com';
|
|
const IMAP_ADMIN_USER = 'webmaster'; // a user with admin access
|
|
const IMAP_MAILBOX_USERNAME = IMAP_ADMIN_USER . '@' . IMAP_MAIL_DOMAIN;
|
|
const IMAP_MAILBOX_PASSWORD = 'p4ssw0rd';
|
|
const IMAP_MAILBOX_PHPT_PREFIX = 'phpttest';
|
|
/** Tests require 4 valid userids */
|
|
const IMAP_USERS = ["webmaster", "info", "admin", "foo"];
|
|
|
|
/** list of fields to expect */
|
|
const MANDATORY_OVERVIEW_FIELDS = [
|
|
'size',
|
|
'uid',
|
|
'msgno',
|
|
'recent',
|
|
'flagged',
|
|
'answered',
|
|
'deleted',
|
|
'seen',
|
|
'draft',
|
|
'udate',
|
|
];
|
|
|
|
// record test start time (used by displayOverviewFields())
|
|
$start_time = time();
|
|
|
|
/**
|
|
* Display all fields in an element from an imap_fetch_overview() response
|
|
*
|
|
* Special handling for 'udate', which will vary run-to-run; assumes an IMAP
|
|
* server with its clock synced to the current system, which is consistent with
|
|
* setup instructions in ext/imap/tests/README.md
|
|
*
|
|
* @param $resp
|
|
* @param string[] $fields
|
|
*/
|
|
function displayOverviewFields($resp, array $fields = MANDATORY_OVERVIEW_FIELDS) {
|
|
global $start_time;
|
|
foreach ($fields as $mf) {
|
|
$z = $resp->$mf;
|
|
if ($mf == 'udate') {
|
|
if (($z >= $start_time) && ($z <= time())) {
|
|
echo "$mf is OK\n";
|
|
} else {
|
|
echo "$mf is BAD ($z)\n";
|
|
}
|
|
} else {
|
|
echo "$mf is $z\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Create a test mailbox and populate with msgs
|
|
*
|
|
* @param string mailbox_suffix Suffix used to uniquely identify mailboxes
|
|
* @param int message_count number of test msgs to be written to new mailbox
|
|
* @param null $new_mailbox
|
|
* @param bool $simpleMessages
|
|
* @param int $flags OP_* (or CL_EXPUNGE) flags to pass to imap_open() sub-call
|
|
* @return resource IMAP stream to new mailbox
|
|
* @throws Exception
|
|
*/
|
|
function setup_test_mailbox(
|
|
string $mailbox_suffix,
|
|
int $message_count,
|
|
&$new_mailbox = null,
|
|
bool $simpleMessages = true,
|
|
int $flags = 0,
|
|
){
|
|
// open a stream to default mailbox
|
|
$imap_stream = imap_open(IMAP_DEFAULT_MAILBOX, IMAP_MAILBOX_USERNAME, IMAP_MAILBOX_PASSWORD, flags: $flags);
|
|
|
|
if ($imap_stream === false) {
|
|
throw new Exception("Cannot connect to IMAP server " . IMAP_SERVER . ": " . imap_last_error());
|
|
}
|
|
|
|
echo "Create a temporary mailbox and add " . $message_count . " msgs\n";
|
|
$new_mailbox = create_mailbox($imap_stream, $mailbox_suffix, $message_count, $simpleMessages);
|
|
|
|
echo "New mailbox created\n";
|
|
|
|
// reopen stream to new mailbox
|
|
if (imap_reopen($imap_stream, $new_mailbox) === false) {
|
|
throw new Exception("Can't re-open '$new_mailbox' mailbox: " . imap_last_error());
|
|
}
|
|
|
|
return $imap_stream;
|
|
}
|
|
|
|
/**
|
|
* Create mailbox and fill with generic emails
|
|
*
|
|
* @param resource $imap_stream
|
|
* @param string $mailbox_suffix
|
|
* @param int $message_count
|
|
* @param bool $simpleMessages
|
|
* @return string
|
|
* @throws Exception
|
|
*/
|
|
function create_mailbox($imap_stream, string $mailbox_suffix, int $message_count, bool $simpleMessages = true): string {
|
|
$mailbox = IMAP_DEFAULT_MAILBOX . '.' . IMAP_MAILBOX_PHPT_PREFIX . $mailbox_suffix;
|
|
|
|
$mailboxes = imap_getmailboxes($imap_stream, $mailbox, '*');
|
|
|
|
// check mailbox does not already exist
|
|
if ($mailboxes) {
|
|
foreach($mailboxes as $value) {
|
|
if ($value->name == $mailbox) {
|
|
throw new Exception("Mailbox '$mailbox' already exists");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (imap_createmailbox($imap_stream, $mailbox) === false) {
|
|
throw new Exception("Can't create a temporary mailbox: " . imap_last_error());
|
|
}
|
|
|
|
// Add number of test msgs requested
|
|
if ($message_count > 0) {
|
|
populate_mailbox($imap_stream, $mailbox, $message_count, $simpleMessages);
|
|
}
|
|
|
|
return $mailbox;
|
|
}
|
|
|
|
function setup_test_mailbox_for_uid_tests(string $mailbox_suffix, &$msg_no = null, &$msg_uid = null)
|
|
{
|
|
$mail_box = setup_test_mailbox($mailbox_suffix, 10);
|
|
echo "Delete 4 messages for Unique ID generation\n";
|
|
// Delete messages to remove the numerical ordering
|
|
imap_delete($mail_box, 3);
|
|
imap_delete($mail_box, 4);
|
|
imap_delete($mail_box, 5);
|
|
imap_delete($mail_box, 6);
|
|
imap_expunge($mail_box);
|
|
$msg_no = 5;
|
|
$msg_uid = 9;
|
|
|
|
return $mail_box;
|
|
}
|
|
|
|
/**
|
|
* Populate a mailbox with generic emails
|
|
*
|
|
* @param resource $imap_stream
|
|
* @param string $mailbox
|
|
* @param int $message_count
|
|
* @param bool $simpleMessages
|
|
*/
|
|
function populate_mailbox($imap_stream, string $mailbox, int $message_count, bool $simpleMessages = true): void {
|
|
for ($i = 1; $i <= $message_count; $i++) {
|
|
if ($simpleMessages) {
|
|
$msg = "From: foo@anywhere.com\r\n"
|
|
. "To: ". IMAP_USERS[0] . "@" . IMAP_MAIL_DOMAIN . "\r\n"
|
|
. "Subject: test$i\r\n"
|
|
. "\r\n"
|
|
. "$i: this is a test message, please ignore\r\nnewline";
|
|
} else {
|
|
$envelope["from"]= "foo@anywhere.com";
|
|
$envelope["to"] = IMAP_USERS[0] . "@" . IMAP_MAIL_DOMAIN;
|
|
$envelope["subject"] = "Test msg $i";
|
|
|
|
$part1["type"] = TYPEMULTIPART;
|
|
$part1["subtype"] = "mixed";
|
|
|
|
$part2["type"] = TYPETEXT;
|
|
$part2["subtype"] = "plain";
|
|
$part2["description"] = "imap_mail_compose() function";
|
|
$part2["contents.data"] = "message 1:xxxxxxxxxxxxxxxxxxxxxxxxxx";
|
|
|
|
$part3["type"] = TYPETEXT;
|
|
$part3["subtype"] = "plain";
|
|
$part3["description"] = "Example";
|
|
$part3["contents.data"] = "message 2:yyyyyyyyyyyyyyyyyyyyyyyyyy";
|
|
|
|
$part4["type"] = TYPETEXT;
|
|
$part4["subtype"] = "plain";
|
|
$part4["description"] = "Return Values";
|
|
$part4["contents.data"] = "message 3:zzzzzzzzzzzzzzzzzzzzzzzzzz";
|
|
|
|
$body[1] = $part1;
|
|
$body[2] = $part2;
|
|
$body[3] = $part3;
|
|
$body[4] = $part4;
|
|
|
|
$msg = imap_mail_compose($envelope, $body);
|
|
}
|
|
|
|
imap_append($imap_stream, $mailbox, $msg);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the mailbox name from a mailbox description, i.e strip off server details.
|
|
*
|
|
* @param string mailbox complete mailbox name
|
|
* @return string mailbox name
|
|
*/
|
|
function get_mailbox_name(string $mailboxName): string {
|
|
|
|
if (preg_match('/\{.*?\}(.*)/', $mailboxName, $match) != 1) {
|
|
throw new Exception("Unrecognized mailbox name '$mailboxName'");
|
|
}
|
|
|
|
return $match[1];
|
|
}
|