Browse Source
Follow-up to remove IMAP ext (#13248)
Follow-up to remove IMAP ext (#13248)
Fixed and optimized tests that depend on imap in standard ext tests. Also, the location of the setup script for hmailserver has changed.pull/13364/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 636 additions and 1315 deletions
-
6.github/actions/setup-x64/action.yml
-
2.github/scripts/windows/test_task.bat
-
46.github/setup_hmailserver.php
-
32ext/imap/tests/setup/clean.inc
-
47ext/imap/tests/setup/dovecot.conf
-
1ext/imap/tests/setup/dovecotpass
-
213ext/imap/tests/setup/imap_include.inc
-
6ext/imap/tests/setup/setup.sh
-
11ext/imap/tests/setup/skipif.inc
-
95ext/standard/tests/mail/bug72964.phpt
-
102ext/standard/tests/mail/bug80706.phpt
-
129ext/standard/tests/mail/bug80751.phpt
-
90ext/standard/tests/mail/mail_basic_alt1-win32.phpt
-
87ext/standard/tests/mail/mail_basic_alt2-win32.phpt
-
87ext/standard/tests/mail/mail_basic_alt3-win32.phpt
-
88ext/standard/tests/mail/mail_basic_alt4-win32.phpt
-
102ext/standard/tests/mail/mail_basic_win.phpt
-
150ext/standard/tests/mail/mail_include.inc
-
25ext/standard/tests/mail/mail_skipif.inc
-
261ext/standard/tests/mail/mail_util.inc
-
89ext/standard/tests/mail/mail_variation_alt1-win32.phpt
-
89ext/standard/tests/mail/mail_variation_alt2-win32.phpt
-
88ext/standard/tests/mail/mail_variation_alt3-win32.phpt
-
90ext/standard/tests/mail/mail_variation_win.phpt
-
15ext/standard/tests/mail/mail_windows_skipif.inc
@ -1,21 +1,25 @@ |
|||
<?php |
|||
|
|||
require __DIR__ . "/../ext/imap/tests/setup/imap_include.inc"; |
|||
|
|||
$hmail = new COM("hMailServer.Application"); |
|||
$hmail->authenticate("Administrator", ""); |
|||
|
|||
$domain = $hmail->Domains->Add(); |
|||
$domain->Name = IMAP_MAIL_DOMAIN; |
|||
$domain->Active = true; |
|||
$domain->Save(); |
|||
|
|||
$accounts = $domain->accounts(); |
|||
|
|||
foreach (IMAP_USERS as $user) { |
|||
$account = $accounts->Add(); |
|||
$account->Address = "$user@" . IMAP_MAIL_DOMAIN; |
|||
$account->Password = IMAP_MAILBOX_PASSWORD; |
|||
$account->Active = true; |
|||
$account->Save(); |
|||
} |
|||
<?php |
|||
|
|||
/** If required change these values to make the test runs */ |
|||
const IMAP_MAIL_DOMAIN = 'example.com'; |
|||
const IMAP_MAILBOX_PASSWORD = 'p4ssw0rd'; |
|||
/** Tests require 4 valid userids */ |
|||
const IMAP_USERS = ["webmaster", "info", "admin", "foo"]; |
|||
|
|||
$hmail = new COM("hMailServer.Application"); |
|||
$hmail->authenticate("Administrator", ""); |
|||
|
|||
$domain = $hmail->Domains->Add(); |
|||
$domain->Name = IMAP_MAIL_DOMAIN; |
|||
$domain->Active = true; |
|||
$domain->Save(); |
|||
|
|||
$accounts = $domain->accounts(); |
|||
|
|||
foreach (IMAP_USERS as $user) { |
|||
$account = $accounts->Add(); |
|||
$account->Address = "$user@" . IMAP_MAIL_DOMAIN; |
|||
$account->Password = IMAP_MAILBOX_PASSWORD; |
|||
$account->Active = true; |
|||
$account->Save(); |
|||
} |
@ -1,32 +0,0 @@ |
|||
<?php |
|||
require_once 'imap_include.inc'; |
|||
|
|||
if (!isset($mailbox_suffix)) { throw new Exception("No suffix provided"); } |
|||
|
|||
$imap_stream = imap_open(IMAP_DEFAULT_MAILBOX, IMAP_MAILBOX_USERNAME, IMAP_MAILBOX_PASSWORD); |
|||
|
|||
// delete all msgs in default mailbox, i.e INBOX |
|||
$check = imap_check($imap_stream); |
|||
for ($i = 1; $i <= $check->Nmsgs; $i++) { |
|||
imap_delete($imap_stream, $i); |
|||
} |
|||
|
|||
|
|||
$mailboxes = imap_getmailboxes($imap_stream, IMAP_SERVER, '*'); |
|||
|
|||
if (!is_array($mailbox_suffix)) { |
|||
$mailbox_suffixes = [$mailbox_suffix]; |
|||
} else { |
|||
$mailbox_suffixes = $mailbox_suffix; |
|||
} |
|||
|
|||
foreach ($mailbox_suffixes as $mailbox_suffix) { |
|||
foreach($mailboxes as $value) { |
|||
// Only delete mailbox with our prefix (+ optional test suffix) |
|||
if (preg_match('/\{.*?\}INBOX\.' . IMAP_MAILBOX_PHPT_PREFIX . $mailbox_suffix .'$/', $value->name, $match) == 1) { |
|||
imap_deletemailbox($imap_stream, $value->name); |
|||
} |
|||
} |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
@ -1,47 +0,0 @@ |
|||
# 2.2.33.2 (d6601f4ec): /etc/dovecot/dovecot.conf |
|||
# Pigeonhole version 0.4.21 (92477967) |
|||
listen = *, :: |
|||
|
|||
# For SSL need to setup a certificate |
|||
# See https://wiki.dovecot.org/SSL/DovecotConfiguration |
|||
ssl = no |
|||
|
|||
# Disable plaintext to prevent a warning at each login |
|||
disable_plaintext_auth = yes |
|||
|
|||
auth_mechanisms = cram-md5 |
|||
auth_username_format = %u |
|||
auth_verbose = yes |
|||
auth_debug = yes |
|||
auth_failure_delay = 1secs |
|||
|
|||
# This need dovecot 2.3.12. |
|||
# login_proxy_timeout = 500milliseconds |
|||
# ^ This would allow to kill login processes early, but needs testing. So would use v instead |
|||
# login_proxy_timeout = 5s |
|||
# There is a 1 second delay between each reconnection attempt. |
|||
# https://doc.dovecot.org/settings/core/#login-proxy-max-reconnects |
|||
# This need dovecot 2.3.12. |
|||
# login_proxy_max_reconnects = 3 |
|||
|
|||
# Log config |
|||
log_path = /var/log/dovecot.log |
|||
# If not set, use the value from log_path |
|||
info_log_path = /var/log/dovecot-info.log |
|||
# If not set, use the value from info_log_path |
|||
debug_log_path = /var/log/dovecot-debug.log |
|||
## Mailbox locations and namespaces |
|||
mail_location = maildir:/var/vmail/dovecot/mail/%d/%n/Maildir |
|||
passdb { |
|||
args = scheme=cram-md5 /etc/dovecot/dovecotpass |
|||
driver = passwd-file |
|||
} |
|||
protocols = imap |
|||
service auth { |
|||
user = root |
|||
} |
|||
userdb { |
|||
args = /etc/dovecot/dovecotpass |
|||
driver = passwd-file |
|||
override_fields = home=/var/vmail/dovecot/mail/%d/%n |
|||
} |
@ -1 +0,0 @@ |
|||
webmaster@example.com:{CRAM-MD5}be5f3177e9c7c06403272f25d983ba630df4ef40476b353bb3087a8401713451:vmail:vmail |
@ -1,213 +0,0 @@ |
|||
<?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]; |
|||
} |
@ -1,6 +0,0 @@ |
|||
sudo service dovecot stop |
|||
sudo groupadd -g 5000 vmail |
|||
sudo useradd -m -d /var/vmail -s /bin/false -u 5000 -g vmail vmail |
|||
sudo cp ext/imap/tests/setup/dovecot.conf /etc/dovecot/dovecot.conf |
|||
sudo cp ext/imap/tests/setup/dovecotpass /etc/dovecot/dovecotpass |
|||
sudo service dovecot start |
@ -1,11 +0,0 @@ |
|||
<?php |
|||
include __DIR__ . '/imap_include.inc'; |
|||
|
|||
$options = OP_HALFOPEN; // this should be enough to verify server present |
|||
$retries = 0; // don't retry connect on failure |
|||
|
|||
$mbox = @imap_open(IMAP_SERVER, IMAP_MAILBOX_USERNAME, IMAP_MAILBOX_PASSWORD, $options, $retries); |
|||
if (!$mbox) { |
|||
die("skip could not connect to mailbox " . IMAP_SERVER); |
|||
} |
|||
imap_close($mbox); |
@ -1,77 +1,64 @@ |
|||
--TEST-- |
|||
Bug #72964 (White space not unfolded for CC/Bcc headers) |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
if (PHP_OS_FAMILY !== 'Windows') die('skip Windows only test'); |
|||
if (getenv("SKIP_SLOW_TESTS")) die('skip slow test'); |
|||
require_once __DIR__ . '/mail_skipif.inc'; |
|||
require_once __DIR__.'/mail_windows_skipif.inc'; |
|||
?> |
|||
--INI-- |
|||
SMTP=localhost |
|||
smtp_port=25 |
|||
sendmail_from=from@example.com |
|||
--FILE-- |
|||
<?php |
|||
require_once __DIR__ . '/mail_include.inc'; |
|||
|
|||
function find_and_delete_message($username, $subject) { |
|||
global $default_mailbox, $password; |
|||
require_once __DIR__.'/mail_util.inc'; |
|||
$users = MailBox::USERS; |
|||
|
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
die("Cannot connect to IMAP server $server: " . imap_last_error() . "\n"); |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$num_messages = imap_check($imap_stream)->Nmsgs; |
|||
for ($i = $num_messages; $i > 0; $i--) { |
|||
$info = imap_headerinfo($imap_stream, $i); |
|||
if ($info->subject === $subject) { |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
$repeat_count--; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
return $found; |
|||
} |
|||
|
|||
$to = "{$users[2]}@$domain"; |
|||
$subject = bin2hex(random_bytes(16)); |
|||
$to = $users[0]; |
|||
$from = ini_get('sendmail_from'); |
|||
$cc = ['cc1' => $users[0], 'cc2' => $users[1]]; |
|||
$bcc = ['bcc1' => $users[2], 'bcc2' => $users[3]]; |
|||
$subject = 'mail_bug72964'; |
|||
$message = 'hello'; |
|||
$headers = "From: webmaster@example.com\r\n" |
|||
. "Cc: {$users[0]}@$domain,\r\n\t{$users[1]}@$domain\r\n" |
|||
. "Bcc: {$users[2]}@$domain,\r\n {$users[3]}@$domain\r\n"; |
|||
$headers = "From: {$from}\r\n" |
|||
. "Cc: {$cc['cc1']},\r\n\t{$cc['cc2']}\r\n" |
|||
. "Bcc: {$bcc['bcc1']},\r\n {$bcc['bcc2']}\r\n"; |
|||
|
|||
$res = mail($to, $subject, $message, $headers); |
|||
|
|||
if ($res !== true) { |
|||
die("TEST FAILED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Message sent OK\n"; |
|||
die("Unable to send the email.\n"); |
|||
} |
|||
|
|||
foreach ($users as $user) { |
|||
if (!find_and_delete_message("$user@$domain", $subject)) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Message sent and deleted OK\n"; |
|||
echo "Email sent.\n"; |
|||
|
|||
foreach ([['to' => $to], $cc, $bcc] as $mailAddresses) { |
|||
foreach ($mailAddresses as $recipient => $mailAddress) { |
|||
$mailBox = MailBox::login($mailAddress); |
|||
$mail = $mailBox->getMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
|
|||
if ($mail->isAsExpected($from, $to, $subject, $message)) { |
|||
echo "Found the email. {$recipient} received.\n"; |
|||
} |
|||
} |
|||
} |
|||
?> |
|||
--CLEAN-- |
|||
<?php |
|||
require_once __DIR__.'/mail_util.inc'; |
|||
$subject = 'mail_bug72964'; |
|||
foreach (MailBox::USERS as $mailAddress) { |
|||
$mailBox = MailBox::login($mailAddress); |
|||
$mailBox->deleteMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
} |
|||
?> |
|||
--EXPECT-- |
|||
Message sent OK |
|||
TEST PASSED: Message sent and deleted OK |
|||
TEST PASSED: Message sent and deleted OK |
|||
TEST PASSED: Message sent and deleted OK |
|||
TEST PASSED: Message sent and deleted OK |
|||
Email sent. |
|||
Found the email. to received. |
|||
Found the email. cc1 received. |
|||
Found the email. cc2 received. |
|||
Found the email. bcc1 received. |
|||
Found the email. bcc2 received. |
@ -1,80 +1,66 @@ |
|||
--TEST-- |
|||
Bug #72964 (White space not unfolded for CC/Bcc headers) |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
Bug #80706 (Headers after Bcc headers may be ignored) |
|||
--SKIPIF-- |
|||
<?php |
|||
if (PHP_OS_FAMILY !== 'Windows') die('skip Windows only test'); |
|||
if (getenv("SKIP_SLOW_TESTS")) die('skip slow test'); |
|||
require_once __DIR__ . '/mail_skipif.inc'; |
|||
require_once __DIR__.'/mail_windows_skipif.inc'; |
|||
?> |
|||
--INI-- |
|||
SMTP=localhost |
|||
smtp_port=25 |
|||
sendmail_from=from@example.com |
|||
--FILE-- |
|||
<?php |
|||
require_once __DIR__ . '/mail_include.inc'; |
|||
|
|||
function find_and_delete_message($username, $subject) { |
|||
global $default_mailbox, $password; |
|||
require_once __DIR__.'/mail_util.inc'; |
|||
$users = MailBox::USERS; |
|||
|
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
die("Cannot connect to IMAP server $server: " . imap_last_error() . "\n"); |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$num_messages = imap_check($imap_stream)->Nmsgs; |
|||
for ($i = $num_messages; $i > 0; $i--) { |
|||
$info = imap_headerinfo($imap_stream, $i); |
|||
if ($info->subject === $subject) { |
|||
$header = imap_fetchheader($imap_stream, $i); |
|||
echo "X-Mailer header found: "; |
|||
var_dump(strpos($header, 'X-Mailer: bug80706') !== false); |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
$repeat_count--; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
return $found; |
|||
} |
|||
|
|||
$to = "{$users[1]}@$domain"; |
|||
$subject = bin2hex(random_bytes(16)); |
|||
$to = $users[0]; |
|||
$from = ini_get('sendmail_from'); |
|||
$bcc = $users[2]; |
|||
$subject = 'mail_bug80706'; |
|||
$message = 'hello'; |
|||
$headers = "From: webmaster@example.com\r\n" |
|||
. "Bcc: {$users[2]}@$domain\r\n" |
|||
. "X-Mailer: bug80706"; |
|||
$xMailer = 'bug80706_x_mailer'; |
|||
$headers = "From: {$from}\r\n" |
|||
. "Bcc: {$bcc}\r\n" |
|||
. "X-Mailer: {$xMailer}"; |
|||
|
|||
$res = mail($to, $subject, $message, $headers); |
|||
|
|||
if ($res !== true) { |
|||
die("TEST FAILED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Message sent OK\n"; |
|||
die("Unable to send the email.\n"); |
|||
} |
|||
|
|||
foreach ([$users[1], $users[2]] as $user) { |
|||
if (!find_and_delete_message("$user@$domain", $subject)) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Message sent and deleted OK\n"; |
|||
echo "Email sent.\n"; |
|||
|
|||
foreach (['to' => $to, 'bcc' => $bcc] as $recipient => $mailAddress) { |
|||
$mailBox = MailBox::login($mailAddress); |
|||
$mail = $mailBox->getMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
|
|||
if ($mail->isAsExpected($from, $to, $subject, $message)) { |
|||
echo "Found the email. {$recipient} received.\n"; |
|||
} |
|||
|
|||
if ($mail->getHeader('X-Mailer') === $xMailer) { |
|||
echo "The specified x-Mailer exists.\n\n"; |
|||
} |
|||
} |
|||
?> |
|||
--CLEAN-- |
|||
<?php |
|||
require_once __DIR__.'/mail_util.inc'; |
|||
$subject = 'mail_bug80706'; |
|||
foreach ([MailBox::USERS[0], MailBox::USERS[2]] as $mailAddress) { |
|||
$mailBox = MailBox::login($mailAddress); |
|||
$mailBox->deleteMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
} |
|||
?> |
|||
--EXPECT-- |
|||
Message sent OK |
|||
X-Mailer header found: bool(true) |
|||
TEST PASSED: Message sent and deleted OK |
|||
X-Mailer header found: bool(true) |
|||
TEST PASSED: Message sent and deleted OK |
|||
Email sent. |
|||
Found the email. to received. |
|||
The specified x-Mailer exists. |
|||
|
|||
Found the email. bcc received. |
|||
The specified x-Mailer exists. |
@ -1,97 +1,82 @@ |
|||
--TEST-- |
|||
Bug #80751 (Comma in recipient name breaks email delivery) |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
if (PHP_OS_FAMILY !== 'Windows') die('skip Windows only test'); |
|||
if (getenv("SKIP_SLOW_TESTS")) die('skip slow test'); |
|||
require_once __DIR__ . '/mail_skipif.inc'; |
|||
require_once __DIR__.'/mail_windows_skipif.inc'; |
|||
?> |
|||
--INI-- |
|||
SMTP=localhost |
|||
smtp_port=25 |
|||
--FILE-- |
|||
<?php |
|||
require_once __DIR__ . '/mail_include.inc'; |
|||
|
|||
function find_and_delete_message($username, $subject) { |
|||
global $default_mailbox, $password, $users, $domain; |
|||
require_once __DIR__.'/mail_util.inc'; |
|||
$users = MailBox::USERS; |
|||
|
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
die("Cannot connect to IMAP server $server: " . imap_last_error() . "\n"); |
|||
} |
|||
$to = $users[0]; |
|||
$toLine = "\"<bug80751_to_name@example.com>\" <{$to}>"; |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$num_messages = imap_check($imap_stream)->Nmsgs; |
|||
for ($i = $num_messages; $i > 0; $i--) { |
|||
$info = imap_headerinfo($imap_stream, $i); |
|||
if ($info->subject === $subject) { |
|||
$header = imap_fetchheader($imap_stream, $i); |
|||
echo "Return-Path header found: "; |
|||
var_dump(strpos($header, 'Return-Path: joe@example.com') !== false); |
|||
echo "To header found: "; |
|||
var_dump(strpos($header, "To: \"<bob@example.com>\" <{$users[1]}@$domain>") !== false); |
|||
echo "From header found: "; |
|||
var_dump(strpos($header, 'From: "<bob@example.com>" <joe@example.com>') !== false); |
|||
echo "Cc header found: "; |
|||
var_dump(strpos($header, "Cc: \"Lastname, Firstname\\\\\" <{$users[2]}@$domain>") !== false); |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
$repeat_count--; |
|||
} |
|||
$from = 'bug80751_from@example.com'; |
|||
$fromLine = "\"<bug80751_from_name@example.com>\" <{$from}>"; |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
return $found; |
|||
} |
|||
$cc = $users[1]; |
|||
$ccLine = "\"Lastname, Firstname\\\\\" <{$cc}>"; |
|||
|
|||
$to = "\"<bob@example.com>\" <{$users[1]}@$domain>"; |
|||
$subject = bin2hex(random_bytes(16)); |
|||
$bcc = $users[2]; |
|||
$subject = 'mail_bug80751'; |
|||
$message = 'hello'; |
|||
$headers = "From: \"<bob@example.com>\" <joe@example.com>\r\n" |
|||
. "Cc: \"Lastname, Firstname\\\\\" <{$users[2]}@$domain>\r\n" |
|||
. "Bcc: \"Firstname \\\"Ni,ck\\\" Lastname\" <{$users[3]}@$domain>\r\n"; |
|||
|
|||
$res = mail($to, $subject, $message, $headers); |
|||
$headers = "From: {$fromLine}\r\n" |
|||
. "Cc: {$ccLine}\r\n" |
|||
. "Bcc: \"Firstname \\\"Ni,ck\\\" Lastname\" <{$bcc}>\r\n"; |
|||
|
|||
$res = mail($toLine, $subject, $message, $headers); |
|||
|
|||
if ($res !== true) { |
|||
die("TEST FAILED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Message sent OK\n"; |
|||
die("Unable to send the email.\n"); |
|||
} |
|||
|
|||
foreach ([$users[1], $users[2], $users[3]] as $user) { |
|||
if (!find_and_delete_message("$user@$domain", $subject)) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Message sent and deleted OK\n"; |
|||
echo "Email sent.\n"; |
|||
|
|||
foreach (['to' => $to, 'cc' => $cc, 'bcc' => $bcc] as $recipient => $mailAddress) { |
|||
$mailBox = MailBox::login($mailAddress); |
|||
$mail = $mailBox->getMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
|
|||
if ($mail->isAsExpected($fromLine, $toLine, $subject, $message)) { |
|||
echo "Found the email. {$recipient} received.\n"; |
|||
} |
|||
|
|||
if ($mail->getHeader('Return-Path') === $from) { |
|||
echo "Return-Path is as expected.\n"; |
|||
} |
|||
|
|||
if ($mail->getHeader('Cc') === $ccLine) { |
|||
echo "Cc header is as expected.\n\n"; |
|||
} |
|||
} |
|||
?> |
|||
--CLEAN-- |
|||
<?php |
|||
require_once __DIR__.'/mail_util.inc'; |
|||
$subject = 'mail_bug80751'; |
|||
foreach ([MailBox::USERS[0], MailBox::USERS[1], MailBox::USERS[2]] as $mailAddress) { |
|||
$mailBox = MailBox::login($mailAddress); |
|||
$mailBox->deleteMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
} |
|||
?> |
|||
--EXPECT-- |
|||
Message sent OK |
|||
Return-Path header found: bool(true) |
|||
To header found: bool(true) |
|||
From header found: bool(true) |
|||
Cc header found: bool(true) |
|||
TEST PASSED: Message sent and deleted OK |
|||
Return-Path header found: bool(true) |
|||
To header found: bool(true) |
|||
From header found: bool(true) |
|||
Cc header found: bool(true) |
|||
TEST PASSED: Message sent and deleted OK |
|||
Return-Path header found: bool(true) |
|||
To header found: bool(true) |
|||
From header found: bool(true) |
|||
Cc header found: bool(true) |
|||
TEST PASSED: Message sent and deleted OK |
|||
Email sent. |
|||
Found the email. to received. |
|||
Return-Path is as expected. |
|||
Cc header is as expected. |
|||
|
|||
Found the email. cc received. |
|||
Return-Path is as expected. |
|||
Cc header is as expected. |
|||
|
|||
Found the email. bcc received. |
|||
Return-Path is as expected. |
|||
Cc header is as expected. |
@ -1,90 +0,0 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
|
|||
if( substr(PHP_OS, 0, 3) != 'WIN' ) { |
|||
die('skip...Windows only test'); |
|||
} |
|||
|
|||
require_once(__DIR__.'/mail_skipif.inc'); |
|||
?> |
|||
--INI-- |
|||
max_execution_time = 120 |
|||
--FILE-- |
|||
<?php |
|||
ini_set("SMTP", "localhost"); |
|||
ini_set("smtp_port", 25); |
|||
ini_set("sendmail_from", "user@example.com"); |
|||
|
|||
echo "*** Testing mail() : basic functionality ***\n"; |
|||
require_once(__DIR__.'/mail_include.inc'); |
|||
$subject_prefix = "!**PHPT**!"; |
|||
|
|||
$to = "$username"; |
|||
$subject = "$subject_prefix: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$res = mail($to, $subject, $message); |
|||
|
|||
if ($res !== true) { |
|||
exit("TEST FAILED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Msg sent OK\n"; |
|||
} |
|||
|
|||
// Search for email message on the mail server using imap. |
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
echo "Cannot connect to IMAP server $server: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
|
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$current_msg_count = imap_check($imap_stream)->Nmsgs; |
|||
|
|||
// Iterate over recent msgs to find the one we sent above |
|||
for ($i = 1; $i <= $current_msg_count; $i++) { |
|||
// get hdr details |
|||
$hdr = imap_headerinfo($imap_stream, $i); |
|||
|
|||
if (substr($hdr->Subject, 0 , strlen($subject_prefix)) == $subject_prefix) { |
|||
echo "Id of msg just sent is $i\n"; |
|||
echo ".. delete it\n"; |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
$repeat_count -= 1; |
|||
} |
|||
|
|||
if (!$found) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Msgs sent and deleted OK\n"; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
?> |
|||
--EXPECTF-- |
|||
*** Testing mail() : basic functionality *** |
|||
Msg sent OK |
|||
Id of msg just sent is %d |
|||
.. delete it |
|||
TEST PASSED: Msgs sent and deleted OK |
@ -1,87 +0,0 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
if( substr(PHP_OS, 0, 3) != 'WIN' ) { |
|||
die('skip...Windows only test'); |
|||
} |
|||
|
|||
require_once(__DIR__.'/mail_skipif.inc'); |
|||
?> |
|||
--INI-- |
|||
max_execution_time = 120 |
|||
--FILE-- |
|||
<?php |
|||
echo "*** Testing mail() : basic functionality ***\n"; |
|||
require_once(__DIR__.'/mail_include.inc'); |
|||
$subject_prefix = "!**PHPT**!"; |
|||
|
|||
$to = "$username"; |
|||
$subject = "$subject_prefix: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$extra_headers = "from: user@example.com"; |
|||
|
|||
$res = mail($to, $subject, $message, $extra_headers); |
|||
|
|||
if ($res !== true) { |
|||
exit("TEST FAILED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Msg sent OK\n"; |
|||
} |
|||
|
|||
// Search for email message on the mail server using imap. |
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
echo "Cannot connect to IMAP server $server: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
|
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$current_msg_count = imap_check($imap_stream)->Nmsgs; |
|||
|
|||
// Iterate over recent msgs to find the one we sent above |
|||
for ($i = 1; $i <= $current_msg_count; $i++) { |
|||
// get hdr details |
|||
$hdr = imap_headerinfo($imap_stream, $i); |
|||
|
|||
if (substr($hdr->Subject, 0 , strlen($subject_prefix)) == $subject_prefix) { |
|||
echo "Id of msg just sent is $i\n"; |
|||
echo ".. delete it\n"; |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
$repeat_count -= 1; |
|||
} |
|||
|
|||
if (!$found) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Msgs sent and deleted OK\n"; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
?> |
|||
--EXPECTF-- |
|||
*** Testing mail() : basic functionality *** |
|||
Msg sent OK |
|||
Id of msg just sent is %d |
|||
.. delete it |
|||
TEST PASSED: Msgs sent and deleted OK |
@ -1,87 +0,0 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
if( substr(PHP_OS, 0, 3) != 'WIN' ) { |
|||
die('skip...Windows only test'); |
|||
} |
|||
|
|||
require_once(__DIR__.'/mail_skipif.inc'); |
|||
?> |
|||
--INI-- |
|||
max_execution_time = 120 |
|||
--FILE-- |
|||
<?php |
|||
echo "*** Testing mail() : basic functionality ***\n"; |
|||
require_once(__DIR__.'/mail_include.inc'); |
|||
$subject_prefix = "!**PHPT**!"; |
|||
|
|||
$to = "$username"; |
|||
$subject = "$subject_prefix: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$extra_headers = "FRom: user@example.com"; |
|||
|
|||
$res = mail($to, $subject, $message, $extra_headers); |
|||
|
|||
if ($res !== true) { |
|||
exit("TEST FAILED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Msg sent OK\n"; |
|||
} |
|||
|
|||
// Search for email message on the mail server using imap. |
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
echo "Cannot connect to IMAP server $server: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
|
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$current_msg_count = imap_check($imap_stream)->Nmsgs; |
|||
|
|||
// Iterate over recent msgs to find the one we sent above |
|||
for ($i = 1; $i <= $current_msg_count; $i++) { |
|||
// get hdr details |
|||
$hdr = imap_headerinfo($imap_stream, $i); |
|||
|
|||
if (substr($hdr->Subject, 0 , strlen($subject_prefix)) == $subject_prefix) { |
|||
echo "Id of msg just sent is $i\n"; |
|||
echo ".. delete it\n"; |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
$repeat_count -= 1; |
|||
} |
|||
|
|||
if (!$found) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Msgs sent and deleted OK\n"; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
?> |
|||
--EXPECTF-- |
|||
*** Testing mail() : basic functionality *** |
|||
Msg sent OK |
|||
Id of msg just sent is %d |
|||
.. delete it |
|||
TEST PASSED: Msgs sent and deleted OK |
@ -1,88 +0,0 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
if( substr(PHP_OS, 0, 3) != 'WIN' ) { |
|||
die('skip...Windows only test'); |
|||
} |
|||
|
|||
require_once(__DIR__.'/mail_skipif.inc'); |
|||
?> |
|||
--INI-- |
|||
max_execution_time = 120 |
|||
--FILE-- |
|||
<?php |
|||
echo "*** Testing mail() : basic functionality ***\n"; |
|||
require_once(__DIR__.'/mail_include.inc'); |
|||
$subject_prefix = "!**PHPT**!"; |
|||
|
|||
$to = "$username"; |
|||
$subject = "$subject_prefix: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$extra_headers = "from: user@example.com"; |
|||
$extra_parameters = "addons"; // should be ignored |
|||
|
|||
$res = mail($to, $subject, $message, $extra_headers, $extra_parameters); |
|||
|
|||
if ($res !== true) { |
|||
exit("TEST FAILED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Msg sent OK\n"; |
|||
} |
|||
|
|||
// Search for email message on the mail server using imap. |
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
echo "Cannot connect to IMAP server $server: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
|
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$current_msg_count = imap_check($imap_stream)->Nmsgs; |
|||
|
|||
// Iterate over recent msgs to find the one we sent above |
|||
for ($i = 1; $i <= $current_msg_count; $i++) { |
|||
// get hdr details |
|||
$hdr = imap_headerinfo($imap_stream, $i); |
|||
|
|||
if (substr($hdr->Subject, 0 , strlen($subject_prefix)) == $subject_prefix) { |
|||
echo "Id of msg just sent is $i\n"; |
|||
echo ".. delete it\n"; |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
$repeat_count -= 1; |
|||
} |
|||
|
|||
if (!$found) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Msgs sent and deleted OK\n"; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
?> |
|||
--EXPECTF-- |
|||
*** Testing mail() : basic functionality *** |
|||
Msg sent OK |
|||
Id of msg just sent is %d |
|||
.. delete it |
|||
TEST PASSED: Msgs sent and deleted OK |
@ -0,0 +1,102 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality (win) |
|||
--SKIPIF-- |
|||
<?php require_once __DIR__.'/mail_windows_skipif.inc'; ?> |
|||
--INI-- |
|||
SMTP=localhost |
|||
smtp_port=25 |
|||
--FILE-- |
|||
<?php |
|||
|
|||
require_once __DIR__.'/mail_util.inc'; |
|||
$users = MailBox::USERS; |
|||
|
|||
$cases = [ |
|||
[ |
|||
'from' => 'from@example.com', |
|||
'premise' => function ($from, $to, $subject, $message) { |
|||
ini_set('sendmail_from', $from); |
|||
return mail($to, $subject, $message); |
|||
} |
|||
], |
|||
[ |
|||
'from' => 'ex_from@example.com', |
|||
'premise' => function ($from, $to, $subject, $message) { |
|||
ini_restore('sendmail_from'); |
|||
$headers = "from: {$from}"; |
|||
return mail($to, $subject, $message, $headers); |
|||
} |
|||
], |
|||
[ |
|||
'from' => 'ex_from@example.com', |
|||
'premise' => function ($from, $to, $subject, $message) { |
|||
ini_restore('sendmail_from'); |
|||
$headers = "FRom: {$from}"; |
|||
return mail($to, $subject, $message, $headers); |
|||
} |
|||
], |
|||
[ |
|||
'from' => 'ex_from@example.com', |
|||
'premise' => function ($from, $to, $subject, $message) { |
|||
ini_restore('sendmail_from'); |
|||
$headers = "from: {$from}"; |
|||
$parameters = 'addons'; // should be ignored |
|||
return mail($to, $subject, $message, $headers, $parameters); |
|||
} |
|||
], |
|||
]; |
|||
|
|||
foreach ($cases as $index => ['from' => $from, 'premise' => $premise]) { |
|||
echo "========== Case {$index} ==========\n"; |
|||
|
|||
$to = $users[$index]; |
|||
$subject = "{$index}: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$res = $premise($from, $to, $subject, $message); |
|||
|
|||
if ($res !== true) { |
|||
die("Unable to send the email.\n"); |
|||
} |
|||
|
|||
echo "Email sent.\n"; |
|||
|
|||
$mailBox = MailBox::login($to); |
|||
$mail = $mailBox->getMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
|
|||
if ($mail->isAsExpected($from, $to, $subject, $message)) { |
|||
echo "Found the email.\n\n"; |
|||
} |
|||
} |
|||
?> |
|||
--CLEAN-- |
|||
<?php |
|||
require_once __DIR__.'/mail_util.inc'; |
|||
for ($i = 0; $i <= 3; $i++) { |
|||
$subject = "{$i}: Basic PHPT test for mail() function"; |
|||
$mailBox = MailBox::login(MailBox::USERS[$i]); |
|||
$mailBox->deleteMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
} |
|||
?> |
|||
--EXPECT-- |
|||
========== Case 0 ========== |
|||
Email sent. |
|||
Found the email. |
|||
|
|||
========== Case 1 ========== |
|||
Email sent. |
|||
Found the email. |
|||
|
|||
========== Case 2 ========== |
|||
Email sent. |
|||
Found the email. |
|||
|
|||
========== Case 3 ========== |
|||
Email sent. |
|||
Found the email. |
@ -1,150 +0,0 @@ |
|||
<?php |
|||
// Change these to make tests run successfully |
|||
$server = '{127.0.0.1:143}'; |
|||
$default_mailbox = $server . "INBOX"; |
|||
$domain = "example.com"; |
|||
$admin_user = "webmaster"; // a user with admin access |
|||
$username = "$admin_user@$domain"; |
|||
$password = 'p4ssw0rd'; |
|||
$users = array("webmaster", "info", "admin", "foo"); // tests require 4 valid userids |
|||
$mailbox_prefix = "phpttest"; // name used for test mailbox |
|||
|
|||
/** |
|||
* Create a test mailbox and populate with msgs |
|||
* |
|||
* @para, string mailbox_suffix Suffix used to uniquely identify mailboxes |
|||
* @param int message_count number of test msgs to be written to new mailbox |
|||
* |
|||
* @return IMAP stream to new mailbox on success; FALSE on failure |
|||
*/ |
|||
function setup_test_mailbox($mailbox_suffix, $message_count, &$new_mailbox = null, $msg_type = "simple"){ |
|||
global $server, $default_mailbox, $username, $password; |
|||
|
|||
// open a stream to default mailbox |
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
|
|||
if ($imap_stream === false) { |
|||
echo "Cannot connect to IMAP server $server: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
echo "Create a temporary mailbox and add " . $message_count . " msgs\n"; |
|||
$new_mailbox = create_mailbox($imap_stream, $mailbox_suffix, $message_count, $msg_type); |
|||
if ($new_mailbox === false) { |
|||
echo "Can't create a temporary mailbox: " . imap_last_error(). "\n"; |
|||
return false; |
|||
} |
|||
|
|||
echo ".. mailbox '$new_mailbox' created\n"; |
|||
|
|||
// reopen stream to new mailbox |
|||
if (imap_reopen($imap_stream, $new_mailbox) === false) { |
|||
echo "can't re-open '$new_mailbox' mailbox: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
return $imap_stream; |
|||
} |
|||
|
|||
/** |
|||
* Create mailbox and fill with generic emails |
|||
* |
|||
* @param resource $imap_stream |
|||
* @param string $mailbox |
|||
*/ |
|||
function create_mailbox($imap_stream, $mailbox_suffix, $message_count, $msg_type= "simple"){ |
|||
global $default_mailbox, $mailbox_prefix; |
|||
$mailbox = $default_mailbox . "." . $mailbox_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) { |
|||
exit ("TEST FAILED : Mailbox '$mailbox' already exists\n"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (imap_createmailbox($imap_stream, $mailbox) === false) { |
|||
return false; |
|||
} |
|||
|
|||
// Add number of test msgs requested |
|||
if ($message_count > 0) { |
|||
populate_mailbox($imap_stream, $mailbox, $message_count, $msg_type); |
|||
} |
|||
|
|||
return $mailbox; |
|||
} |
|||
|
|||
/** |
|||
* Populate a mailbox with generic emails |
|||
* |
|||
* @param resource $imap_stream |
|||
* @param string $mailbox |
|||
*/ |
|||
function populate_mailbox($imap_stream, $mailbox, $message_count, $msg_type = "simple"){ |
|||
|
|||
global $users, $domain; |
|||
|
|||
for($i = 1; $i <= $message_count; $i++) { |
|||
if ($msg_type == "simple") { |
|||
$msg = "From: foo@anywhere.com\r\n" |
|||
. "To: $users[0]@$domain\r\n" |
|||
. "Subject: test$i\r\n" |
|||
. "\r\n" |
|||
. "$i: this is a test message, please ignore\r\n"; |
|||
} else { |
|||
$envelope["from"]= "foo@anywhere.com"; |
|||
$envelope["to"] = "$users[0]@$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 mailbox name |
|||
*/ |
|||
function get_mailbox_name($mailbox){ |
|||
|
|||
if (preg_match('/\{.*?\}(.*)/', $mailbox, $match) != 1) { |
|||
echo "Unrecpognized mailbox name\n"; |
|||
return false; |
|||
} |
|||
|
|||
return $match[1]; |
|||
} |
|||
|
|||
?> |
@ -1,25 +0,0 @@ |
|||
<?php |
|||
|
|||
if( substr(PHP_OS, 0, 3) == 'WIN' && extension_loaded('sockets')) { |
|||
// be sure mail server is accessible... on PHP 5.3.13 release build, using test-pack PHP-5.3-r1af8b3f, |
|||
// the code below didn't skip test even though there was no mail server |
|||
// test then failed (no mail server to test against) |
|||
$socket = socket_create(AF_INET, SOCK_RAW, 1); |
|||
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 10, 'usec' => 10)); |
|||
// imap uses tcp port 143 |
|||
socket_connect($socket, "localhost", 143) or die ("skip can't socket to mail server"); |
|||
} |
|||
|
|||
// Change these to make tests run successfully |
|||
$mailbox = '{127.0.0.1:143}'; |
|||
$username = 'webmaster@example.com'; |
|||
$password = 'p4ssw0rd'; |
|||
$options = OP_HALFOPEN; // this should be enough to verify server present |
|||
$retries = 0; // don't retry connect on failure |
|||
|
|||
$mbox = @imap_open($mailbox, $username, $password, $options, $retries); |
|||
if (!$mbox) { |
|||
die("skip could not connect to mailbox $mailbox"); |
|||
} |
|||
imap_close($mbox); |
|||
?> |
@ -0,0 +1,261 @@ |
|||
<?php |
|||
|
|||
class MailConnecter |
|||
{ |
|||
private $fp = null; |
|||
private static $instance; |
|||
private static $init = false; |
|||
|
|||
private const HOST = 'localhost'; |
|||
private const PORT = 143; |
|||
private const TIMEOUT = 10; |
|||
|
|||
private function __construct() |
|||
{ |
|||
if (($this->fp = @fsockopen(self::HOST, self::PORT)) === false) { |
|||
die('cannot open imap socket'); |
|||
} |
|||
} |
|||
|
|||
public static function getConnection(): self |
|||
{ |
|||
if (!static::$init) { |
|||
static::$instance = new self(); |
|||
} |
|||
|
|||
return static::$instance; |
|||
} |
|||
|
|||
public function disconnect(): void |
|||
{ |
|||
fclose($this->fp); |
|||
} |
|||
|
|||
public function fail(string $message): void |
|||
{ |
|||
$this->disconnect(); |
|||
die($message); |
|||
} |
|||
|
|||
public function send(string $tag, string $command): void |
|||
{ |
|||
fputs($this->fp, "{$tag} {$command}\r\n"); |
|||
} |
|||
|
|||
public function isSuccess(string $tag): bool |
|||
{ |
|||
$start = time(); |
|||
while (!feof($this->fp)) { |
|||
$line = fgets($this->fp); |
|||
if (!$line) { |
|||
return false; |
|||
} |
|||
if (str_contains($line, $tag)) { |
|||
if (preg_match('/(NO|BAD|failed|Failure)/i', $line)) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
if (time() - $start > self::TIMEOUT) { |
|||
$this->fail("{$tag} timeout"); |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public function getResponse(string $tag, bool $returnArray = false): string|array |
|||
{ |
|||
$start = time(); |
|||
$output = $returnArray ? [] : ''; |
|||
while (!feof($this->fp)) { |
|||
$line = fgets($this->fp); |
|||
if (!$line) { |
|||
$this->fail("{$tag} failed"); |
|||
} |
|||
if ($returnArray) { |
|||
$output[] = $line; |
|||
} else { |
|||
$output .= $line; |
|||
} |
|||
if (str_contains($line, $tag)) { |
|||
if (preg_match('/(NO|BAD|failed|Failure)/i', $line)) { |
|||
$this->fail("{$tag} failed"); |
|||
} |
|||
return $output; |
|||
} |
|||
if (time() - $start > self::TIMEOUT) { |
|||
$this->fail("{$tag} timeout"); |
|||
} |
|||
} |
|||
$this->fail("{$tag} failed"); |
|||
} |
|||
} |
|||
|
|||
class MailBox |
|||
{ |
|||
private MailConnecter $mailConnecter; |
|||
private const PASSWORD = 'p4ssw0rd'; |
|||
public const USERS = [ |
|||
'webmaster@example.com', |
|||
'info@example.com', |
|||
'admin@example.com', |
|||
'foo@example.com', |
|||
]; |
|||
|
|||
private const LOGIN = 'A00001'; |
|||
private const LOGOUT = 'A00002'; |
|||
private const SELECT_MAILBOX = 'A00003'; |
|||
private const SEARCH = 'A00004'; |
|||
private const FETCH_HEADERS = 'A00005'; |
|||
private const FETCH_BODY = 'A00006'; |
|||
private const DELETE = 'A00007'; |
|||
private const EXPUNGE = 'A00008'; |
|||
|
|||
private function __construct() |
|||
{ |
|||
$this->mailConnecter = MailConnecter::getConnection(); |
|||
} |
|||
|
|||
public static function login(string $user): self |
|||
{ |
|||
$self = new self(); |
|||
$self->mailConnecter->send(self::LOGIN, 'LOGIN '.$user.' '.self::PASSWORD); |
|||
if (!$self->mailConnecter->isSuccess(self::LOGIN)) { |
|||
$self->mailConnecter->fail('login failed'); |
|||
} |
|||
return $self; |
|||
} |
|||
|
|||
public function logout(): void |
|||
{ |
|||
$this->mailConnecter->send(self::LOGOUT, 'LOGOUT'); |
|||
if (!$this->mailConnecter->isSuccess(self::LOGOUT)) { |
|||
$this->mailConnecter->fail('logout failed'); |
|||
} |
|||
} |
|||
|
|||
private function getUidsBySubject(string $subject): array |
|||
{ |
|||
$this->mailConnecter->send(self::SELECT_MAILBOX, 'SELECT "INBOX"'); |
|||
if (!$this->mailConnecter->isSuccess(self::SELECT_MAILBOX)) { |
|||
$this->mailConnecter->fail('select mailbox failed'); |
|||
} |
|||
|
|||
$this->mailConnecter->send(self::SEARCH, "UID SEARCH SUBJECT \"{$subject}\""); |
|||
$res = $this->mailConnecter->getResponse(self::SEARCH); |
|||
preg_match('/SEARCH ([0-9 ]+)/is', $res, $matches); |
|||
return isset($matches[1]) ? explode(' ', trim($matches[1])) : []; |
|||
} |
|||
|
|||
public function getMailsBySubject(string $subject): MailCollection |
|||
{ |
|||
return new MailCollection(array_map( |
|||
fn($uid) => $this->getHeaders($uid) + ['Body' => $this->getBody($uid)], |
|||
$this->getUidsBySubject($subject), |
|||
)); |
|||
} |
|||
|
|||
private function getHeaders(int $uid): array |
|||
{ |
|||
$this->mailConnecter->send(self::FETCH_HEADERS, "UID FETCH {$uid} (BODY[HEADER])"); |
|||
$res = $this->mailConnecter->getResponse(self::FETCH_HEADERS, true); |
|||
|
|||
$headers = []; |
|||
foreach ($res as $line) { |
|||
$line = trim($line); |
|||
if (!$line) { |
|||
continue; |
|||
} |
|||
$items = explode(':', $line); |
|||
preg_match('/^(.+?):(.+?)$/', $line, $matches); |
|||
$key = trim($matches[1] ?? ''); |
|||
$val = trim($matches[2] ?? ''); |
|||
if (!$key || !$val || $val === self::FETCH_HEADERS.' OK UID completed' || $val === ')') { |
|||
continue; |
|||
} |
|||
|
|||
$headers[$key] = $val; |
|||
} |
|||
return $headers; |
|||
} |
|||
|
|||
private function getBody(int $uid): string |
|||
{ |
|||
$this->mailConnecter->send(self::FETCH_BODY, "UID FETCH {$uid} (BODY[TEXT])"); |
|||
$body = $this->mailConnecter->getResponse(self::FETCH_BODY, true); |
|||
$count = count($body); |
|||
if ($count <= 3) { |
|||
return ''; |
|||
} |
|||
|
|||
return implode('', array_slice($body, 1, $count - 3)); |
|||
} |
|||
|
|||
public function deleteMailsBySubject(string $subject): void |
|||
{ |
|||
array_map( |
|||
fn($uid) => $this->mailConnecter->send(self::DELETE, "UID STORE {$uid} +FLAGS (\\Deleted)"), |
|||
$this->getUidsBySubject($subject), |
|||
); |
|||
$this->mailConnecter->send(self::EXPUNGE, 'EXPUNGE'); |
|||
} |
|||
} |
|||
|
|||
class MailCollection |
|||
{ |
|||
public function __construct(private ?array $mailData) {} |
|||
|
|||
public function isAsExpected(string $from, string $to, string $subject, string $message): bool |
|||
{ |
|||
$result = true; |
|||
|
|||
if (!$this->mailData) { |
|||
$result = false; |
|||
echo "Email data does not exist.\n"; |
|||
} |
|||
if (!$this->count() > 1) { |
|||
$result = false; |
|||
echo "Multiple email data exist.\n"; |
|||
} |
|||
if ($this->getHeader('From', true) !== $from) { |
|||
$result = false; |
|||
echo "from does not match.\n"; |
|||
} |
|||
if ($this->getHeader('To', true) !== $to) { |
|||
$result = false; |
|||
echo "to does not match.\n"; |
|||
} |
|||
if ($this->getHeader('Subject', true) !== $subject) { |
|||
$result = false; |
|||
echo "subject does not match.\n"; |
|||
} |
|||
if (trim($this->getBody()) !== trim($message)) { |
|||
$result = false; |
|||
echo "body does not match.\n"; |
|||
} |
|||
|
|||
return $result; |
|||
} |
|||
|
|||
public function count(): int |
|||
{ |
|||
return count($this->mailData); |
|||
} |
|||
|
|||
public function getHeader(string $field, bool $ignoreCases = false, int $offset = 0) |
|||
{ |
|||
if ($ignoreCases) { |
|||
$mail = array_change_key_case($this->mailData[$offset] ?? []); |
|||
$field = strtolower($field); |
|||
} else { |
|||
$mail = $this->mailData[$offset] ?? []; |
|||
} |
|||
|
|||
return $mail[$field] ?? null; |
|||
} |
|||
|
|||
public function getBody(int $offset = 0): ?string |
|||
{ |
|||
return $this->mailData[$offset]['Body'] ?? null; |
|||
} |
|||
} |
@ -1,89 +0,0 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
if( substr(PHP_OS, 0, 3) != 'WIN' ) { |
|||
die('skip...Windows only test'); |
|||
} |
|||
|
|||
require_once(__DIR__.'/mail_skipif.inc'); |
|||
?> |
|||
--INI-- |
|||
max_execution_time = 120 |
|||
--FILE-- |
|||
<?php |
|||
ini_set("SMTP", "localhost"); |
|||
ini_set("smtp_port", 2525); |
|||
ini_set("sendmail_from", "user@example.com"); |
|||
|
|||
echo "*** Testing mail() : basic functionality ***\n"; |
|||
require_once(__DIR__.'/mail_include.inc'); |
|||
$subject_prefix = "!**PHPT**!"; |
|||
|
|||
$to = "$username"; |
|||
$subject = "$subject_prefix: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$res = mail($to, $subject, $message); |
|||
|
|||
if ($res !== true) { |
|||
exit("TEST COMPLETED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Msg sent OK\n"; |
|||
} |
|||
|
|||
// Search for email message on the mail server using imap. |
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
echo "Cannot connect to IMAP server $server: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
|
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$current_msg_count = imap_check($imap_stream)->Nmsgs; |
|||
|
|||
// Iterate over recent msgs to find the one we sent above |
|||
for ($i = 1; $i <= $current_msg_count; $i++) { |
|||
// get hdr details |
|||
$hdr = imap_headerinfo($imap_stream, $i); |
|||
|
|||
if (substr($hdr->Subject, 0 , strlen($subject_prefix)) == $subject_prefix) { |
|||
echo "Id of msg just sent is $i\n"; |
|||
echo ".. delete it\n"; |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
$repeat_count -= 1; |
|||
} |
|||
|
|||
if (!$found) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Msgs sent and deleted OK\n"; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
?> |
|||
===DONE=== |
|||
--EXPECTF-- |
|||
*** Testing mail() : basic functionality *** |
|||
|
|||
Warning: mail(): Failed to connect to mailserver at "localhost" port 2525, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in %s on line %d |
|||
TEST COMPLETED : Unable to send test email |
@ -1,89 +0,0 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
if( substr(PHP_OS, 0, 3) != 'WIN' ) { |
|||
die('skip...Windows only test'); |
|||
} |
|||
|
|||
require_once(__DIR__.'/mail_skipif.inc'); |
|||
?> |
|||
--INI-- |
|||
max_execution_time = 120 |
|||
--FILE-- |
|||
<?php |
|||
ini_set("SMTP", "localplace"); |
|||
ini_set("smtp_port", 25); |
|||
ini_set("sendmail_from", "user@example.com"); |
|||
|
|||
echo "*** Testing mail() : basic functionality ***\n"; |
|||
require_once(__DIR__.'/mail_include.inc'); |
|||
$subject_prefix = "!**PHPT**!"; |
|||
|
|||
$to = "$username"; |
|||
$subject = "$subject_prefix: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$res = mail($to, $subject, $message); |
|||
|
|||
if ($res !== true) { |
|||
exit("TEST COMPLETED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Msg sent OK\n"; |
|||
} |
|||
|
|||
// Search for email message on the mail server using imap. |
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
echo "Cannot connect to IMAP server $server: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
|
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$current_msg_count = imap_check($imap_stream)->Nmsgs; |
|||
|
|||
// Iterate over recent msgs to find the one we sent above |
|||
for ($i = 1; $i <= $current_msg_count; $i++) { |
|||
// get hdr details |
|||
$hdr = imap_headerinfo($imap_stream, $i); |
|||
|
|||
if (substr($hdr->Subject, 0 , strlen($subject_prefix)) == $subject_prefix) { |
|||
echo "Id of msg just sent is $i\n"; |
|||
echo ".. delete it\n"; |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
$repeat_count -= 1; |
|||
} |
|||
|
|||
if (!$found) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Msgs sent and deleted OK\n"; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
?> |
|||
===DONE=== |
|||
--EXPECTF-- |
|||
*** Testing mail() : basic functionality *** |
|||
|
|||
Warning: mail(): Failed to connect to mailserver at "localplace" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in %s on line %d |
|||
TEST COMPLETED : Unable to send test email |
@ -1,88 +0,0 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality |
|||
--EXTENSIONS-- |
|||
imap |
|||
--CONFLICTS-- |
|||
imap |
|||
--SKIPIF-- |
|||
<?php |
|||
if( substr(PHP_OS, 0, 3) != 'WIN' ) { |
|||
die('skip...Windows only test'); |
|||
} |
|||
|
|||
require_once(__DIR__.'/mail_skipif.inc'); |
|||
?> |
|||
--INI-- |
|||
max_execution_time = 120 |
|||
--FILE-- |
|||
<?php |
|||
ini_set("SMTP", "localhost"); |
|||
ini_set("smtp_port", 25); |
|||
|
|||
echo "*** Testing mail() : basic functionality ***\n"; |
|||
require_once(__DIR__.'/mail_include.inc'); |
|||
$subject_prefix = "!**PHPT**!"; |
|||
|
|||
$to = "$username"; |
|||
$subject = "$subject_prefix: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$res = mail($to, $subject, $message); |
|||
|
|||
if ($res !== true) { |
|||
exit("TEST COMPLETED : Unable to send test email\n"); |
|||
} else { |
|||
echo "Msg sent OK\n"; |
|||
} |
|||
|
|||
// Search for email message on the mail server using imap. |
|||
$imap_stream = imap_open($default_mailbox, $username, $password); |
|||
if ($imap_stream === false) { |
|||
echo "Cannot connect to IMAP server $server: " . imap_last_error() . "\n"; |
|||
return false; |
|||
} |
|||
|
|||
$found = false; |
|||
$repeat_count = 20; // we will repeat a max of 20 times |
|||
while (!$found && $repeat_count > 0) { |
|||
|
|||
// sleep for a while to allow msg to be delivered |
|||
sleep(1); |
|||
|
|||
$current_msg_count = imap_check($imap_stream)->Nmsgs; |
|||
|
|||
// Iterate over recent msgs to find the one we sent above |
|||
for ($i = 1; $i <= $current_msg_count; $i++) { |
|||
// get hdr details |
|||
$hdr = imap_headerinfo($imap_stream, $i); |
|||
|
|||
if (substr($hdr->Subject, 0 , strlen($subject_prefix)) == $subject_prefix) { |
|||
echo "Id of msg just sent is $i\n"; |
|||
echo ".. delete it\n"; |
|||
imap_delete($imap_stream, $i); |
|||
$found = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
$repeat_count -= 1; |
|||
} |
|||
|
|||
if (!$found) { |
|||
echo "TEST FAILED: email not delivered\n"; |
|||
} else { |
|||
echo "TEST PASSED: Msgs sent and deleted OK\n"; |
|||
} |
|||
|
|||
imap_close($imap_stream, CL_EXPUNGE); |
|||
?> |
|||
===DONE=== |
|||
--EXPECTF-- |
|||
*** Testing mail() : basic functionality *** |
|||
|
|||
Warning: mail(): Bad Message Return Path in %s on line %d |
|||
TEST COMPLETED : Unable to send test email |
@ -0,0 +1,90 @@ |
|||
--TEST-- |
|||
Test mail() function : basic functionality (win) |
|||
--SKIPIF-- |
|||
<?php die('skip test'); require_once __DIR__.'/mail_windows_skipif.inc'; ?> |
|||
--INI-- |
|||
SMTP=localhost |
|||
smtp_port=25 |
|||
--FILE-- |
|||
<?php |
|||
|
|||
require_once __DIR__.'/mail_util.inc'; |
|||
$users = MailBox::USERS; |
|||
|
|||
$from = ini_get('sendmail_from'); |
|||
|
|||
$cases = [ |
|||
[ |
|||
'label' => 'From is not set', |
|||
'premise' => function () { |
|||
ini_set('SMTP', 'localhost'); |
|||
ini_set('smtp_port', 25); |
|||
} |
|||
], |
|||
[ |
|||
'label' => 'Invalid port', |
|||
'premise' => function () { |
|||
ini_set('SMTP', 'localhost'); |
|||
ini_set('smtp_port', 2525); |
|||
ini_set('sendmail_from', 'from@example.com'); |
|||
} |
|||
], |
|||
[ |
|||
'label' => 'Invalid host', |
|||
'premise' => function () { |
|||
ini_set('SMTP', 'localplace'); |
|||
ini_set('smtp_port', 25); |
|||
ini_set('sendmail_from', 'from@example.com'); |
|||
} |
|||
], |
|||
]; |
|||
|
|||
foreach ($cases as $index => ['label' => $label, 'premise' => $premise]) { |
|||
echo "========== {$label} ==========\n"; |
|||
|
|||
$premise(); |
|||
|
|||
$to = $users[$index]; |
|||
$subject = "{$index}: Basic PHPT test for mail() function"; |
|||
$message = <<<HERE |
|||
Description |
|||
bool mail ( string \$to , string \$subject , string \$message [, string \$additional_headers [, string \$additional_parameters]] ) |
|||
Send an email message |
|||
HERE; |
|||
|
|||
$res = mail($to, $subject, $message); |
|||
|
|||
if ($res === true) { |
|||
echo "Email sent.\n"; |
|||
} |
|||
|
|||
$mailBox = MailBox::login($to); |
|||
$mail = $mailBox->getMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
|
|||
if ($mail->count() > 0) { |
|||
echo "Found the email.\n\n"; |
|||
} |
|||
} |
|||
?> |
|||
--CLEAN-- |
|||
<?php |
|||
require_once __DIR__.'/mail_util.inc'; |
|||
for ($i = 0; $i <= 2; $i++) { |
|||
$subject = "{$i}: Basic PHPT test for mail() function"; |
|||
$mailBox = MailBox::login(MailBox::USERS[$i]); |
|||
$mailBox->deleteMailsBySubject($subject); |
|||
$mailBox->logout(); |
|||
} |
|||
?> |
|||
--EXPECTF-- |
|||
========== From is not set ========== |
|||
|
|||
Warning: mail(): Bad Message Return Path in %s on line %d |
|||
========== Invalid port ========== |
|||
|
|||
Warning: mail(): Failed to connect to mailserver at "localhost" port 2525, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in %s on line %d |
|||
========== Invalid host ========== |
|||
|
|||
Warning: mail(): Failed to connect to mailserver at "localplace" port 1025, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in %s on line %d |
|||
|
@ -0,0 +1,15 @@ |
|||
<?php |
|||
if(substr(PHP_OS, 0, 3) !== 'WIN') { |
|||
die('skip windows only test'); |
|||
} |
|||
|
|||
$connection = @fsockopen('localhost', 25); |
|||
if ($connection === false) { |
|||
die('skip unable to open smtp socket'); |
|||
} |
|||
|
|||
$connection = @fsockopen('localhost', 143); |
|||
if ($connection === false) { |
|||
die('skip unable to open imap socket'); |
|||
} |
|||
?> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue