0
0
mirror of https://github.com/PHPMailer/PHPMailer.git synced 2024-09-19 17:42:14 +02:00

Big cleanup for Symfony coding style and php-cs-fixer, see #1148

This commit is contained in:
Marcus Bointon 2017-09-07 18:21:09 +02:00
parent eb9e7f5f0c
commit 31493b6732
No known key found for this signature in database
GPG Key ID: DE31CD6EB646AA24
21 changed files with 1252 additions and 582 deletions

View File

@ -29,7 +29,8 @@
"zendframework/zend-serializer": "2.7.*", "zendframework/zend-serializer": "2.7.*",
"doctrine/annotations": "1.2.*", "doctrine/annotations": "1.2.*",
"zendframework/zend-eventmanager": "3.0.*", "zendframework/zend-eventmanager": "3.0.*",
"zendframework/zend-i18n": "2.7.3" "zendframework/zend-i18n": "2.7.3",
"friendsofphp/php-cs-fixer": "^2.2"
}, },
"suggest": { "suggest": {
"psr/log": "For optional PSR-3 debug logging", "psr/log": "For optional PSR-3 debug logging",

513
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c83b5cea4ea6633422ee7d0ce4f621b2", "content-hash": "8067184a7c98f5da35efc75d4cf96446",
"packages": [], "packages": [],
"packages-dev": [ "packages-dev": [
{ {
@ -374,17 +374,145 @@
], ],
"time": "2017-03-29T16:04:15+00:00" "time": "2017-03-29T16:04:15+00:00"
}, },
{
"name": "friendsofphp/php-cs-fixer",
"version": "v2.2.6",
"source": {
"type": "git",
"url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
"reference": "c1cc52c242f17c4d52d9601159631da488fac7a4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/c1cc52c242f17c4d52d9601159631da488fac7a4",
"reference": "c1cc52c242f17c4d52d9601159631da488fac7a4",
"shasum": ""
},
"require": {
"doctrine/annotations": "^1.2",
"ext-json": "*",
"ext-tokenizer": "*",
"gecko-packages/gecko-php-unit": "^2.0",
"php": "^5.3.6 || >=7.0 <7.2",
"sebastian/diff": "^1.4",
"symfony/console": "^2.4 || ^3.0",
"symfony/event-dispatcher": "^2.1 || ^3.0",
"symfony/filesystem": "^2.4 || ^3.0",
"symfony/finder": "^2.2 || ^3.0",
"symfony/options-resolver": "^2.6 || ^3.0",
"symfony/polyfill-php54": "^1.0",
"symfony/polyfill-php55": "^1.3",
"symfony/polyfill-php70": "^1.0",
"symfony/polyfill-php72": "^1.4",
"symfony/process": "^2.3 || ^3.0",
"symfony/stopwatch": "^2.5 || ^3.0"
},
"conflict": {
"hhvm": "<3.18"
},
"require-dev": {
"johnkary/phpunit-speedtrap": "^1.0.1",
"justinrainbow/json-schema": "^5.0",
"phpunit/phpunit": "^4.8.35 || ^5.4.3",
"satooshi/php-coveralls": "^1.0",
"symfony/phpunit-bridge": "^3.2.2"
},
"suggest": {
"ext-mbstring": "For handling non-UTF8 characters in cache signature.",
"symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible."
},
"bin": [
"php-cs-fixer"
],
"type": "application",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
}
},
"autoload": {
"psr-4": {
"PhpCsFixer\\": "src/"
},
"classmap": [
"tests/Test/AbstractFixerTestCase.php",
"tests/Test/AbstractIntegrationTestCase.php",
"tests/Test/IntegrationCase.php",
"tests/Test/IntegrationCaseFactory.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dariusz Rumiński",
"email": "dariusz.ruminski@gmail.com"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "A tool to automatically fix PHP code style",
"time": "2017-08-22T14:08:16+00:00"
},
{
"name": "gecko-packages/gecko-php-unit",
"version": "v2.2",
"source": {
"type": "git",
"url": "https://github.com/GeckoPackages/GeckoPHPUnit.git",
"reference": "ab525fac9a9ffea219687f261b02008b18ebf2d1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/GeckoPackages/GeckoPHPUnit/zipball/ab525fac9a9ffea219687f261b02008b18ebf2d1",
"reference": "ab525fac9a9ffea219687f261b02008b18ebf2d1",
"shasum": ""
},
"require": {
"php": "^5.3.6 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.4.3"
},
"suggest": {
"ext-dom": "When testing with xml.",
"ext-libxml": "When testing with xml.",
"phpunit/phpunit": "This is an extension for it so make sure you have it some way."
},
"type": "library",
"autoload": {
"psr-4": {
"GeckoPackages\\PHPUnit\\": "src/PHPUnit"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Additional PHPUnit asserts and constraints.",
"homepage": "https://github.com/GeckoPackages",
"keywords": [
"extension",
"filesystem",
"phpunit"
],
"time": "2017-08-23T07:39:54+00:00"
},
{ {
"name": "herrera-io/json", "name": "herrera-io/json",
"version": "1.0.3", "version": "1.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/kherge-abandoned/php-json.git", "url": "https://github.com/kherge-php/json.git",
"reference": "60c696c9370a1e5136816ca557c17f82a6fa83f1" "reference": "60c696c9370a1e5136816ca557c17f82a6fa83f1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/kherge-abandoned/php-json/zipball/60c696c9370a1e5136816ca557c17f82a6fa83f1", "url": "https://api.github.com/repos/kherge-php/json/zipball/60c696c9370a1e5136816ca557c17f82a6fa83f1",
"reference": "60c696c9370a1e5136816ca557c17f82a6fa83f1", "reference": "60c696c9370a1e5136816ca557c17f82a6fa83f1",
"shasum": "" "shasum": ""
}, },
@ -433,6 +561,7 @@
"schema", "schema",
"validate" "validate"
], ],
"abandoned": "kherge/json",
"time": "2013-10-30T16:51:34+00:00" "time": "2013-10-30T16:51:34+00:00"
}, },
{ {
@ -491,8 +620,51 @@
"phar", "phar",
"update" "update"
], ],
"abandoned": true,
"time": "2013-10-30T17:23:01+00:00" "time": "2013-10-30T17:23:01+00:00"
}, },
{
"name": "ircmaxell/password-compat",
"version": "v1.0.4",
"source": {
"type": "git",
"url": "https://github.com/ircmaxell/password_compat.git",
"reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
"reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "4.*"
},
"type": "library",
"autoload": {
"files": [
"lib/password.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anthony Ferrara",
"email": "ircmaxell@php.net",
"homepage": "http://blog.ircmaxell.com"
}
],
"description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
"homepage": "https://github.com/ircmaxell/password_compat",
"keywords": [
"hashing",
"password"
],
"time": "2014-11-20T16:49:30+00:00"
},
{ {
"name": "jms/metadata", "name": "jms/metadata",
"version": "1.6.0", "version": "1.6.0",
@ -765,6 +937,7 @@
], ],
"description": "A parsing and comparison library for semantic versioning.", "description": "A parsing and comparison library for semantic versioning.",
"homepage": "http://github.com/kherge/Version", "homepage": "http://github.com/kherge/Version",
"abandoned": true,
"time": "2012-08-16T17:13:03+00:00" "time": "2012-08-16T17:13:03+00:00"
}, },
{ {
@ -890,6 +1063,54 @@
], ],
"time": "2015-09-19T14:15:08+00:00" "time": "2015-09-19T14:15:08+00:00"
}, },
{
"name": "paragonie/random_compat",
"version": "v2.0.10",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2017-03-13T16:27:32+00:00"
},
{ {
"name": "phpcollection/phpcollection", "name": "phpcollection/phpcollection",
"version": "0.5.0", "version": "0.5.0",
@ -1738,7 +1959,9 @@
"authors": [ "authors": [
{ {
"name": "Fabien Potencier", "name": "Fabien Potencier",
"email": "fabien@symfony.com" "email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
} }
], ],
"description": "Pimple is a simple Dependency Injection Container for PHP 5.3", "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
@ -2598,6 +2821,60 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-06-01T20:52:29+00:00" "time": "2017-06-01T20:52:29+00:00"
}, },
{
"name": "symfony/options-resolver",
"version": "v3.3.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
"reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/ee4e22978fe885b54ee5da8c7964f0a5301abfb6",
"reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\OptionsResolver\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony OptionsResolver Component",
"homepage": "https://symfony.com",
"keywords": [
"config",
"configuration",
"options"
],
"time": "2017-07-29T21:54:42+00:00"
},
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.4.0", "version": "v1.4.0",
@ -2657,6 +2934,234 @@
], ],
"time": "2017-06-09T14:24:12+00:00" "time": "2017-06-09T14:24:12+00:00"
}, },
{
"name": "symfony/polyfill-php54",
"version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php54.git",
"reference": "b7763422a5334c914ef0298ed21b253d25913a6e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/b7763422a5334c914ef0298ed21b253d25913a6e",
"reference": "b7763422a5334c914ef0298ed21b253d25913a6e",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php54\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2017-06-14T15:44:48+00:00"
},
{
"name": "symfony/polyfill-php55",
"version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php55.git",
"reference": "29b1381d66f16e0581aab0b9f678ccf073288f68"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/29b1381d66f16e0581aab0b9f678ccf073288f68",
"reference": "29b1381d66f16e0581aab0b9f678ccf073288f68",
"shasum": ""
},
"require": {
"ircmaxell/password-compat": "~1.0",
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php55\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2017-06-14T15:44:48+00:00"
},
{
"name": "symfony/polyfill-php70",
"version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php70.git",
"reference": "b6482e68974486984f59449ecea1fbbb22ff840f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/b6482e68974486984f59449ecea1fbbb22ff840f",
"reference": "b6482e68974486984f59449ecea1fbbb22ff840f",
"shasum": ""
},
"require": {
"paragonie/random_compat": "~1.0|~2.0",
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php70\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2017-06-14T15:44:48+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "8abc9097f5001d310f0edba727469c988acc6ea7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8abc9097f5001d310f0edba727469c988acc6ea7",
"reference": "8abc9097f5001d310f0edba727469c988acc6ea7",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2017-07-11T13:25:55+00:00"
},
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v2.8.22", "version": "v2.8.22",

View File

@ -40,7 +40,7 @@ if (file_exists($privatekeyfile)) {
[ [
'digest_alg' => 'sha256', 'digest_alg' => 'sha256',
'private_key_bits' => 2048, 'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA 'private_key_type' => OPENSSL_KEYTYPE_RSA,
] ]
); );
//Save private key //Save private key
@ -71,7 +71,7 @@ $publickey = str_replace(["\r", "\n"], '', $publickey);
$keyparts = str_split($publickey, 253); //Becomes 255 when quotes are included $keyparts = str_split($publickey, 253); //Becomes 255 when quotes are included
//Quote each chunk //Quote each chunk
foreach ($keyparts as $keypart) { foreach ($keyparts as $keypart) {
$dnsvalue .= '"'.trim($keypart).'" '; $dnsvalue .= '"' . trim($keypart) . '" ';
} }
echo "\n\nDNS key:\n\n" . trim($dnskey); echo "\n\nDNS key:\n\n" . trim($dnskey);
echo "\n\nDNS value:\n\n" . trim($dnsvalue); echo "\n\nDNS value:\n\n" . trim($dnsvalue);

View File

@ -13,12 +13,13 @@ require '../vendor/autoload.php';
* Example PHPMailer callback function. * Example PHPMailer callback function.
* This is a global function, but you can also pass a closure (or any other callable) * This is a global function, but you can also pass a closure (or any other callable)
* to the `action_function` property. * to the `action_function` property.
* @param bool $result result of the send action *
* @param array $to email address of the recipient * @param bool $result result of the send action
* @param array $cc cc email addresses * @param array $to email address of the recipient
* @param array $bcc bcc email addresses * @param array $cc cc email addresses
* @param string $subject the subject * @param array $bcc bcc email addresses
* @param string $body the email body * @param string $subject the subject
* @param string $body the email body
*/ */
function callbackAction($result, $to, $cc, $bcc, $subject, $body) function callbackAction($result, $to, $cc, $bcc, $subject, $body)
{ {

View File

@ -20,8 +20,9 @@ class myPHPMailer extends PHPMailer
{ {
/** /**
* myPHPMailer constructor. * myPHPMailer constructor.
*
* @param bool|null $exceptions * @param bool|null $exceptions
* @param string $body A default HTML message body * @param string $body A default HTML message body
*/ */
public function __construct($exceptions, $body = '') public function __construct($exceptions, $body = '')
{ {
@ -48,7 +49,8 @@ class myPHPMailer extends PHPMailer
{ {
$this->Subject = '[Yay for me!] ' . $this->Subject; $this->Subject = '[Yay for me!] ' . $this->Subject;
$r = parent::send(); $r = parent::send();
echo "I sent a message with subject ". $this->Subject; echo "I sent a message with subject " . $this->Subject;
return $r; return $r;
} }
} }
@ -64,5 +66,5 @@ try {
$mail->send(); //no need to check for errors - the exception handler will do it $mail->send(); //no need to check for errors - the exception handler will do it
} catch (Exception $e) { } catch (Exception $e) {
//Note that this is catching the PHPMailer Exception class, not the global \Exception type! //Note that this is catching the PHPMailer Exception class, not the global \Exception type!
echo "Caught a ".get_class($e).": " . $e->getMessage(); echo "Caught a " . get_class($e) . ": " . $e->getMessage();
} }

View File

@ -83,7 +83,8 @@ if (!$mail->send()) {
//Function to call which uses the PHP imap_*() functions to save messages: https://php.net/manual/en/book.imap.php //Function to call which uses the PHP imap_*() functions to save messages: https://php.net/manual/en/book.imap.php
//You can use imap_getmailboxes($imapStream, '/imap/ssl') to get a list of available folders or labels, this can //You can use imap_getmailboxes($imapStream, '/imap/ssl') to get a list of available folders or labels, this can
//be useful if you are trying to get this working on a non-Gmail IMAP server. //be useful if you are trying to get this working on a non-Gmail IMAP server.
function save_mail($mail) { function save_mail($mail)
{
//You can change 'Sent Mail' to any other folder or tag //You can change 'Sent Mail' to any other folder or tag
$path = "{imap.gmail.com:993/imap/ssl}[Gmail]/Sent Mail"; $path = "{imap.gmail.com:993/imap/ssl}[Gmail]/Sent Mail";

View File

@ -56,20 +56,24 @@ $clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';
$refreshToken = 'RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0'; $refreshToken = 'RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0';
//Create a new OAuth2 provider instance //Create a new OAuth2 provider instance
$provider = new Google([ $provider = new Google(
'clientId' => $clientId, [
'clientSecret' => $clientSecret 'clientId' => $clientId,
]); 'clientSecret' => $clientSecret,
]
);
//Pass the OAuth provider instance to PHPMailer //Pass the OAuth provider instance to PHPMailer
$mail->setOAuth( $mail->setOAuth(
new OAuth([ new OAuth(
'provider' => $provider, [
'clientId' => $clientId, 'provider' => $provider,
'clientSecret' => $clientSecret, 'clientId' => $clientId,
'refreshToken' => $refreshToken, 'clientSecret' => $clientSecret,
'userName' => $email 'refreshToken' => $refreshToken,
]) 'userName' => $email,
]
)
); );
//Set who the message is to be sent from //Set who the message is to be sent from

View File

@ -39,7 +39,7 @@ $mail->AltBody = 'To view the message, please use an HTML compatible email viewe
//You'll need to alter this to match your database //You'll need to alter this to match your database
$mysql = mysqli_connect('localhost', 'username', 'password'); $mysql = mysqli_connect('localhost', 'username', 'password');
mysqli_select_db($mysql, 'mydb'); mysqli_select_db($mysql, 'mydb');
$result = mysqli_query($mysql, 'SELECT full_name, email, photo FROM mailinglist WHERE sent = false'); $result = mysqli_query($mysql, 'SELECT full_name, email, photo FROM mailinglist WHERE sent = FALSE');
foreach ($result as $row) { foreach ($result as $row) {
$mail->addAddress($row['email'], $row['full_name']); $mail->addAddress($row['email'], $row['full_name']);
@ -55,7 +55,7 @@ foreach ($result as $row) {
//Mark it as sent in the DB //Mark it as sent in the DB
mysqli_query( mysqli_query(
$mysql, $mysql,
"UPDATE mailinglist SET sent = true WHERE email = '" . "UPDATE mailinglist SET sent = TRUE WHERE email = '" .
mysqli_real_escape_string($mysql, $row['email']) . "'" mysqli_real_escape_string($mysql, $row['email']) . "'"
); );
} }

View File

@ -38,8 +38,8 @@ if (array_key_exists('to', $_POST)) {
//Validate to address //Validate to address
//Never allow arbitrary input for the 'to' address as it will turn your form into a spam gateway! //Never allow arbitrary input for the 'to' address as it will turn your form into a spam gateway!
//Substitute appropriate addresses from your own domain, or simply use a single, fixed address //Substitute appropriate addresses from your own domain, or simply use a single, fixed address
if (array_key_exists('to', $_POST) and in_array($_POST['to'], ['sales','support','accounts'])) { if (array_key_exists('to', $_POST) and in_array($_POST['to'], ['sales', 'support', 'accounts'])) {
$to = $_POST['to'].'@example.com'; $to = $_POST['to'] . '@example.com';
} else { } else {
$to = 'support@example.com'; $to = 'support@example.com';
} }
@ -59,7 +59,7 @@ if (array_key_exists('to', $_POST)) {
//It's important not to use the submitter's address as the from address as it's forgery, //It's important not to use the submitter's address as the from address as it's forgery,
//which will cause your messages to fail SPF checks. //which will cause your messages to fail SPF checks.
//Use an address in your own domain as the from address, put the submitter's address in a reply-to //Use an address in your own domain as the from address, put the submitter's address in a reply-to
$mail->setFrom('contact@example.com', (empty($name)? 'Contact form': $name)); $mail->setFrom('contact@example.com', (empty($name) ? 'Contact form' : $name));
$mail->addAddress($to); $mail->addAddress($to);
$mail->addReplyTo($email, $name); $mail->addReplyTo($email, $name);
$mail->Subject = 'Contact form: ' . $subject; $mail->Subject = 'Contact form: ' . $subject;
@ -70,7 +70,7 @@ if (array_key_exists('to', $_POST)) {
$msg .= "Message sent!"; $msg .= "Message sent!";
} }
} }
}?> } ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@ -96,6 +96,6 @@ if (array_key_exists('to', $_POST)) {
</form> </form>
<?php } else { <?php } else {
echo $msg; echo $msg;
}?> } ?>
</body> </body>
</html> </html>

View File

@ -104,6 +104,7 @@ class SMTPLowMemory extends SMTP
$result = $this->sendCommand('DATA END', '.', 250); $result = $this->sendCommand('DATA END', '.', 250);
//Restore timelimit //Restore timelimit
$this->Timelimit = $savetimelimit; $this->Timelimit = $savetimelimit;
return $result; return $result;
} }
} }
@ -123,6 +124,7 @@ class PHPMailerLowMemory extends PHPMailer
if (!is_object($this->smtp)) { if (!is_object($this->smtp)) {
$this->smtp = new SMTPLowMemory; $this->smtp = new SMTPLowMemory;
} }
return $this->smtp; return $this->smtp;
} }
} }

View File

@ -35,14 +35,14 @@ $mail->SMTPSecure = 'tls';
//Custom connection options //Custom connection options
//Note that these settings are INSECURE //Note that these settings are INSECURE
$mail->SMTPOptions = array ( $mail->SMTPOptions = array(
'ssl' => [ 'ssl' => [
'verify_peer' => true, 'verify_peer' => true,
'verify_depth' => 3, 'verify_depth' => 3,
'allow_self_signed' => true, 'allow_self_signed' => true,
'peer_name' => 'smtp.example.com', 'peer_name' => 'smtp.example.com',
'cafile' => '/etc/ssl/ca_cert.pem' 'cafile' => '/etc/ssl/ca_cert.pem',
] ],
); );
//Whether to use SMTP authentication //Whether to use SMTP authentication

View File

@ -8,7 +8,7 @@
* @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder) * @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2016 Marcus Bointon * @copyright 2012 - 2017 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License

View File

@ -1,15 +1,15 @@
<?php <?php
/** /**
* PHPMailer Exception class. * PHPMailer Exception class.
* PHP Version 5.5 * PHP Version 5.5.
* *
* @package PHPMailer
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder) * @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2016 Marcus Bointon * @copyright 2012 - 2017 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
@ -21,15 +21,14 @@
namespace PHPMailer\PHPMailer; namespace PHPMailer\PHPMailer;
/** /**
* PHPMailer exception handler * PHPMailer exception handler.
* *
* @package PHPMailer
* @author Marcus Bointon <phpmailer@synchromedia.co.uk> * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/ */
class Exception extends \Exception class Exception extends \Exception
{ {
/** /**
* Prettify error message output * Prettify error message output.
* *
* @return string * @return string
*/ */

View File

@ -1,11 +1,10 @@
<?php <?php
/** /**
* PHPMailer - PHP email creation and transport class. * PHPMailer - PHP email creation and transport class.
* PHP Version 5.5 * PHP Version 5.5.
* *
* @package PHPMailer
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
@ -22,15 +21,15 @@
namespace PHPMailer\PHPMailer; namespace PHPMailer\PHPMailer;
use League\OAuth2\Client\Grant\RefreshToken; use League\OAuth2\Client\Grant\RefreshToken;
use League\OAuth2\Client\Token\AccessToken;
use League\OAuth2\Client\Provider\AbstractProvider; use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Token\AccessToken;
/** /**
* OAuth - OAuth2 authentication wrapper class. * OAuth - OAuth2 authentication wrapper class.
* Uses the oauth2-client package from the League of Extraordinary Packages * Uses the oauth2-client package from the League of Extraordinary Packages.
* *
* @see http://oauth2-client.thephpleague.com * @see http://oauth2-client.thephpleague.com
* @package PHPMailer *
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
*/ */
class OAuth class OAuth
@ -82,7 +81,7 @@ class OAuth
* OAuth constructor. * OAuth constructor.
* *
* @param array $options Associative array containing * @param array $options Associative array containing
* `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements * `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements
*/ */
public function __construct($options) public function __construct($options)
{ {
@ -100,7 +99,7 @@ class OAuth
*/ */
protected function getGrant() protected function getGrant()
{ {
return new RefreshToken; return new RefreshToken();
} }
/** /**
@ -127,6 +126,7 @@ class OAuth
if (null === $this->oauthToken or $this->oauthToken->hasExpired()) { if (null === $this->oauthToken or $this->oauthToken->hasExpired()) {
$this->oauthToken = $this->getToken(); $this->oauthToken = $this->getToken();
} }
return base64_encode( return base64_encode(
'user=' . 'user=' .
$this->oauthUserEmail . $this->oauthUserEmail .

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,15 @@
<?php <?php
/** /**
* PHPMailer POP-Before-SMTP Authentication Class. * PHPMailer POP-Before-SMTP Authentication Class.
* PHP Version 5.5 * PHP Version 5.5.
* *
* @package PHPMailer
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder) * @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2016 Marcus Bointon * @copyright 2012 - 2017 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
@ -33,7 +33,6 @@ namespace PHPMailer\PHPMailer;
* enough to do authentication. * enough to do authentication.
* If you want a more complete class there are other POP3 classes for PHP available. * If you want a more complete class there are other POP3 classes for PHP available.
* *
* @package PHPMailer
* @author Richard Davey (original author) <rich@corephp.co.uk> * @author Richard Davey (original author) <rich@corephp.co.uk>
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
@ -64,7 +63,7 @@ class POP3
/** /**
* Debug display level. * Debug display level.
* Options: 0 = no, 1+ = yes * Options: 0 = no, 1+ = yes.
* *
* @var int * @var int
*/ */
@ -92,7 +91,7 @@ class POP3
public $tval; public $tval;
/** /**
* POP3 username * POP3 username.
* *
* @var string * @var string
*/ */
@ -127,19 +126,19 @@ class POP3
protected $errors = []; protected $errors = [];
/** /**
* Line break constant * Line break constant.
*/ */
const LE = "\r\n"; const LE = "\r\n";
/** /**
* Simple static wrapper for all-in-one POP before SMTP * Simple static wrapper for all-in-one POP before SMTP.
* *
* @param string $host * @param string $host
* @param int|bool $port The port number to connect to * @param int|bool $port The port number to connect to
* @param int|bool $timeout The timeout value * @param int|bool $timeout The timeout value
* @param string $username * @param string $username
* @param string $password * @param string $password
* @param int $debug_level * @param int $debug_level
* *
* @return bool * @return bool
*/ */
@ -151,7 +150,8 @@ class POP3
$password = '', $password = '',
$debug_level = 0 $debug_level = 0
) { ) {
$pop = new POP3; $pop = new self();
return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level); return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
} }
@ -160,12 +160,12 @@ class POP3
* A connect, login, disconnect sequence * A connect, login, disconnect sequence
* appropriate for POP-before SMTP authorisation. * appropriate for POP-before SMTP authorisation.
* *
* @param string $host The hostname to connect to * @param string $host The hostname to connect to
* @param int|bool $port The port number to connect to * @param int|bool $port The port number to connect to
* @param int|bool $timeout The timeout value * @param int|bool $timeout The timeout value
* @param string $username * @param string $username
* @param string $password * @param string $password
* @param int $debug_level * @param int $debug_level
* *
* @return bool * @return bool
*/ */
@ -176,13 +176,13 @@ class POP3
if (false === $port) { if (false === $port) {
$this->port = static::DEFAULT_PORT; $this->port = static::DEFAULT_PORT;
} else { } else {
$this->port = (integer)$port; $this->port = (int) $port;
} }
// If no timeout value provided, use default // If no timeout value provided, use default
if (false === $timeout) { if (false === $timeout) {
$this->tval = static::DEFAULT_TIMEOUT; $this->tval = static::DEFAULT_TIMEOUT;
} else { } else {
$this->tval = (integer)$timeout; $this->tval = (int) $timeout;
} }
$this->do_debug = $debug_level; $this->do_debug = $debug_level;
$this->username = $username; $this->username = $username;
@ -195,20 +195,22 @@ class POP3
$login_result = $this->login($this->username, $this->password); $login_result = $this->login($this->username, $this->password);
if ($login_result) { if ($login_result) {
$this->disconnect(); $this->disconnect();
return true; return true;
} }
} }
// We need to disconnect regardless of whether the login succeeded // We need to disconnect regardless of whether the login succeeded
$this->disconnect(); $this->disconnect();
return false; return false;
} }
/** /**
* Connect to a POP3 server. * Connect to a POP3 server.
* *
* @param string $host * @param string $host
* @param int|bool $port * @param int|bool $port
* @param int $tval * @param int $tval
* *
* @return bool * @return bool
*/ */
@ -244,6 +246,7 @@ class POP3
$this->setError( $this->setError(
"Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr" "Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr"
); );
return false; return false;
} }
@ -256,8 +259,10 @@ class POP3
if ($this->checkResponse($pop3_response)) { if ($this->checkResponse($pop3_response)) {
// The connection is established and the POP3 server is talking // The connection is established and the POP3 server is talking
$this->connected = true; $this->connected = true;
return true; return true;
} }
return false; return false;
} }
@ -293,6 +298,7 @@ class POP3
return true; return true;
} }
} }
return false; return false;
} }
@ -308,14 +314,13 @@ class POP3
@fclose($this->pop_conn); @fclose($this->pop_conn);
} catch (Exception $e) { } catch (Exception $e) {
//Do nothing //Do nothing
}; }
} }
/** /**
* Get a response from the POP3 server. * Get a response from the POP3 server.
* $size is the maximum number of bytes to retrieve
* *
* @param int $size * @param int $size The maximum number of bytes to retrieve
* *
* @return string * @return string
*/ */
@ -325,6 +330,7 @@ class POP3
if ($this->do_debug >= 1) { if ($this->do_debug >= 1) {
echo 'Server -> Client: ', $response; echo 'Server -> Client: ', $response;
} }
return $response; return $response;
} }
@ -341,8 +347,10 @@ class POP3
if ($this->do_debug >= 2) { //Show client messages when debug >= 2 if ($this->do_debug >= 2) { //Show client messages when debug >= 2
echo 'Client -> Server: ', $string; echo 'Client -> Server: ', $string;
} }
return fwrite($this->pop_conn, $string, strlen($string)); return fwrite($this->pop_conn, $string, strlen($string));
} }
return 0; return 0;
} }
@ -358,10 +366,11 @@ class POP3
{ {
if (substr($string, 0, 3) !== '+OK') { if (substr($string, 0, 3) !== '+OK') {
$this->setError("Server reported an error: $string"); $this->setError("Server reported an error: $string");
return false; return false;
} else {
return true;
} }
return true;
} }
/** /**
@ -395,15 +404,15 @@ class POP3
/** /**
* POP3 connection error handler. * POP3 connection error handler.
* *
* @param int $errno * @param int $errno
* @param string $errstr * @param string $errstr
* @param string $errfile * @param string $errfile
* @param int $errline * @param int $errline
*/ */
protected function catchWarning($errno, $errstr, $errfile, $errline) protected function catchWarning($errno, $errstr, $errfile, $errline)
{ {
$this->setError( $this->setError(
'Connecting to the POP3 server raised a PHP warning:'. 'Connecting to the POP3 server raised a PHP warning:' .
"errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline" "errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline"
); );
} }

View File

@ -1,15 +1,14 @@
<?php <?php
/** /**
* PHPMailer RFC821 SMTP email transport class. * PHPMailer RFC821 SMTP email transport class.
* PHP Version 5.5 * PHP Version 5.5.
* *
* @package PHPMailer
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder) * @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2016 Marcus Bointon * @copyright 2012 - 2017 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
@ -24,7 +23,6 @@ namespace PHPMailer\PHPMailer;
* PHPMailer RFC821 SMTP email transport class. * PHPMailer RFC821 SMTP email transport class.
* Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server. * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server.
* *
* @package PHPMailer
* @author Chris Ryan * @author Chris Ryan
* @author Marcus Bointon <phpmailer@synchromedia.co.uk> * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/ */
@ -52,34 +50,34 @@ class SMTP
const DEFAULT_PORT = 25; const DEFAULT_PORT = 25;
/** /**
* The maximum line length allowed by RFC 2822 section 2.1.1 * The maximum line length allowed by RFC 2822 section 2.1.1.
* *
* @var int * @var int
*/ */
const MAX_LINE_LENGTH = 998; const MAX_LINE_LENGTH = 998;
/** /**
* Debug level for no output * Debug level for no output.
*/ */
const DEBUG_OFF = 0; const DEBUG_OFF = 0;
/** /**
* Debug level to show client -> server messages * Debug level to show client -> server messages.
*/ */
const DEBUG_CLIENT = 1; const DEBUG_CLIENT = 1;
/** /**
* Debug level to show client -> server and server -> client messages * Debug level to show client -> server and server -> client messages.
*/ */
const DEBUG_SERVER = 2; const DEBUG_SERVER = 2;
/** /**
* Debug level to show connection status, client -> server and server -> client messages * Debug level to show connection status, client -> server and server -> client messages.
*/ */
const DEBUG_CONNECTION = 3; const DEBUG_CONNECTION = 3;
/** /**
* Debug level to show all messages * Debug level to show all messages.
*/ */
const DEBUG_LOWLEVEL = 4; const DEBUG_LOWLEVEL = 4;
@ -90,7 +88,7 @@ class SMTP
* * self::DEBUG_CLIENT (`1`) Client commands * * self::DEBUG_CLIENT (`1`) Client commands
* * self::DEBUG_SERVER (`2`) Client commands and server responses * * self::DEBUG_SERVER (`2`) Client commands and server responses
* * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status
* * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages.
* *
* @var int * @var int
*/ */
@ -121,23 +119,25 @@ class SMTP
* *
* @see http://en.wikipedia.org/wiki/Variable_envelope_return_path * @see http://en.wikipedia.org/wiki/Variable_envelope_return_path
* @see http://www.postfix.org/VERP_README.html Info on VERP * @see http://www.postfix.org/VERP_README.html Info on VERP
*
* @var bool * @var bool
*/ */
public $do_verp = false; public $do_verp = false;
/** /**
* The timeout value for connection, in seconds. * The timeout value for connection, in seconds.
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
* This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure. * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
* *
* @see http://tools.ietf.org/html/rfc2821#section-4.5.3.2 * @see http://tools.ietf.org/html/rfc2821#section-4.5.3.2
*
* @var int * @var int
*/ */
public $Timeout = 300; public $Timeout = 300;
/** /**
* How long to wait for commands to complete, in seconds. * How long to wait for commands to complete, in seconds.
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
* *
* @var int * @var int
*/ */
@ -152,7 +152,7 @@ class SMTP
'exim' => '/[0-9]{3} OK id=(.*)/', 'exim' => '/[0-9]{3} OK id=(.*)/',
'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/', 'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/',
'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/', 'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/',
'Microsoft_ESMTP' => '/[0-9]{3} 2.[0-9].0 (.*)@(?:.*) Queued mail for delivery/' 'Microsoft_ESMTP' => '/[0-9]{3} 2.[0-9].0 (.*)@(?:.*) Queued mail for delivery/',
]; ];
/** /**
@ -210,8 +210,8 @@ class SMTP
/** /**
* Output debugging info via a user-selected method. * Output debugging info via a user-selected method.
* *
* @param string $str Debug string to output * @param string $str Debug string to output
* @param int $level The debug level of this message; see DEBUG_* constants * @param int $level The debug level of this message; see DEBUG_* constants
* *
* @see SMTP::$Debugoutput * @see SMTP::$Debugoutput
* @see SMTP::$do_debug * @see SMTP::$do_debug
@ -224,11 +224,13 @@ class SMTP
//Is this a PSR-3 logger? //Is this a PSR-3 logger?
if (is_a($this->Debugoutput, 'Psr\Log\LoggerInterface')) { if (is_a($this->Debugoutput, 'Psr\Log\LoggerInterface')) {
$this->Debugoutput->debug($str); $this->Debugoutput->debug($str);
return; return;
} }
//Avoid clash with built-in function names //Avoid clash with built-in function names
if (!in_array($this->Debugoutput, ['error_log', 'html', 'echo']) and is_callable($this->Debugoutput)) { if (!in_array($this->Debugoutput, ['error_log', 'html', 'echo']) and is_callable($this->Debugoutput)) {
call_user_func($this->Debugoutput, $str, $level); call_user_func($this->Debugoutput, $str, $level);
return; return;
} }
switch ($this->Debugoutput) { switch ($this->Debugoutput) {
@ -249,27 +251,27 @@ class SMTP
//Normalize line breaks //Normalize line breaks
$str = preg_replace('/\r\n|\r/ms', "\n", $str); $str = preg_replace('/\r\n|\r/ms', "\n", $str);
echo gmdate('Y-m-d H:i:s'), echo gmdate('Y-m-d H:i:s'),
"\t", "\t",
//Trim trailing space //Trim trailing space
trim( trim(
//Indent for readability, except for trailing break //Indent for readability, except for trailing break
str_replace( str_replace(
"\n", "\n",
"\n \t ", "\n \t ",
trim($str) trim($str)
) )
), ),
"\n"; "\n";
} }
} }
/** /**
* Connect to an SMTP server. * Connect to an SMTP server.
* *
* @param string $host SMTP server IP or host name * @param string $host SMTP server IP or host name
* @param int $port The port number to connect to * @param int $port The port number to connect to
* @param int $timeout How long to wait for the connection to open * @param int $timeout How long to wait for the connection to open
* @param array $options An array of options for stream_context_create() * @param array $options An array of options for stream_context_create()
* *
* @return bool * @return bool
*/ */
@ -287,6 +289,7 @@ class SMTP
if ($this->connected()) { if ($this->connected()) {
// Already connected, generate error // Already connected, generate error
$this->setError('Already connected to a server'); $this->setError('Already connected to a server');
return false; return false;
} }
if (empty($port)) { if (empty($port)) {
@ -295,7 +298,7 @@ class SMTP
// Connect to the SMTP server // Connect to the SMTP server
$this->edebug( $this->edebug(
"Connection: opening to $host:$port, timeout=$timeout, options=" . "Connection: opening to $host:$port, timeout=$timeout, options=" .
(count($options) > 0 ? var_export($options, true): 'array()'), (count($options) > 0 ? var_export($options, true) : 'array()'),
self::DEBUG_CONNECTION self::DEBUG_CONNECTION
); );
$errno = 0; $errno = 0;
@ -304,7 +307,7 @@ class SMTP
$socket_context = stream_context_create($options); $socket_context = stream_context_create($options);
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
$this->smtp_conn = stream_socket_client( $this->smtp_conn = stream_socket_client(
$host . ":" . $port, $host . ':' . $port,
$errno, $errno,
$errstr, $errstr,
$timeout, $timeout,
@ -315,7 +318,7 @@ class SMTP
} else { } else {
//Fall back to fsockopen which should work in more places, but is missing some features //Fall back to fsockopen which should work in more places, but is missing some features
$this->edebug( $this->edebug(
"Connection: stream_socket_client not available, falling back to fsockopen", 'Connection: stream_socket_client not available, falling back to fsockopen',
self::DEBUG_CONNECTION self::DEBUG_CONNECTION
); );
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
@ -333,14 +336,15 @@ class SMTP
$this->setError( $this->setError(
'Failed to connect to server', 'Failed to connect to server',
'', '',
(string)$errno, (string) $errno,
(string)$errstr (string) $errstr
); );
$this->edebug( $this->edebug(
'SMTP ERROR: ' . $this->error['error'] 'SMTP ERROR: ' . $this->error['error']
. ": $errstr ($errno)", . ": $errstr ($errno)",
self::DEBUG_CLIENT self::DEBUG_CLIENT
); );
return false; return false;
} }
$this->edebug('Connection: opened', self::DEBUG_CONNECTION); $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
@ -357,6 +361,7 @@ class SMTP
// Get any announcement // Get any announcement
$announce = $this->get_lines(); $announce = $this->get_lines();
$this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER); $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
return true; return true;
} }
@ -389,20 +394,22 @@ class SMTP
$crypto_method $crypto_method
); );
restore_error_handler(); restore_error_handler();
return (bool)$crypto_ok;
return (bool) $crypto_ok;
} }
/** /**
* Perform SMTP authentication. * Perform SMTP authentication.
* Must be run after hello(). * Must be run after hello().
* *
* @see hello()
*
* @param string $username The user name * @param string $username The user name
* @param string $password The password * @param string $password The password
* @param string $authtype The auth type (CRAM-MD5, PLAIN, LOGIN, XOAUTH2) * @param string $authtype The auth type (CRAM-MD5, PLAIN, LOGIN, XOAUTH2)
* @param OAuth $OAuth An optional OAuth instance for XOAUTH2 authentication * @param OAuth $OAuth An optional OAuth instance for XOAUTH2 authentication
* *
* @return bool True if successfully authenticated. * @return bool True if successfully authenticated
* @see hello()
*/ */
public function authenticate( public function authenticate(
$username, $username,
@ -412,6 +419,7 @@ class SMTP
) { ) {
if (!$this->server_caps) { if (!$this->server_caps) {
$this->setError('Authentication is not allowed before HELO/EHLO'); $this->setError('Authentication is not allowed before HELO/EHLO');
return false; return false;
} }
@ -421,6 +429,7 @@ class SMTP
$this->setError('Authentication is not allowed at this stage'); $this->setError('Authentication is not allowed at this stage');
// 'at this stage' means that auth may be allowed after the stage changes // 'at this stage' means that auth may be allowed after the stage changes
// e.g. after STARTTLS // e.g. after STARTTLS
return false; return false;
} }
@ -447,6 +456,7 @@ class SMTP
} }
if (empty($authtype)) { if (empty($authtype)) {
$this->setError('No supported authentication methods found'); $this->setError('No supported authentication methods found');
return false; return false;
} }
self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL); self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL);
@ -454,6 +464,7 @@ class SMTP
if (!in_array($authtype, $this->server_caps['AUTH'])) { if (!in_array($authtype, $this->server_caps['AUTH'])) {
$this->setError("The requested authentication method \"$authtype\" is not supported by the server"); $this->setError("The requested authentication method \"$authtype\" is not supported by the server");
return false; return false;
} }
} elseif (empty($authtype)) { } elseif (empty($authtype)) {
@ -480,10 +491,10 @@ class SMTP
if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
return false; return false;
} }
if (!$this->sendCommand("Username", base64_encode($username), 334)) { if (!$this->sendCommand('Username', base64_encode($username), 334)) {
return false; return false;
} }
if (!$this->sendCommand("Password", base64_encode($password), 235)) { if (!$this->sendCommand('Password', base64_encode($password), 235)) {
return false; return false;
} }
break; break;
@ -514,18 +525,20 @@ class SMTP
break; break;
default: default:
$this->setError("Authentication method \"$authtype\" is not supported"); $this->setError("Authentication method \"$authtype\" is not supported");
return false; return false;
} }
return true; return true;
} }
/** /**
* Calculate an MD5 HMAC hash. * Calculate an MD5 HMAC hash.
* Works like hash_hmac('md5', $data, $key) * Works like hash_hmac('md5', $data, $key)
* in case that function is not available * in case that function is not available.
* *
* @param string $data The data to hash * @param string $data The data to hash
* @param string $key The key to hash with * @param string $key The key to hash with
* *
* @return string * @return string
*/ */
@ -559,7 +572,7 @@ class SMTP
/** /**
* Check connection state. * Check connection state.
* *
* @return bool True if connected. * @return bool True if connected
*/ */
public function connected() public function connected()
{ {
@ -572,10 +585,13 @@ class SMTP
self::DEBUG_CLIENT self::DEBUG_CLIENT
); );
$this->close(); $this->close();
return false; return false;
} }
return true; // everything looks good return true; // everything looks good
} }
return false; return false;
} }
@ -605,7 +621,7 @@ class SMTP
* that is to be send with the headers. Each header needs to be * that is to be send with the headers. Each header needs to be
* on a single line followed by a <CRLF> with the message headers * on a single line followed by a <CRLF> with the message headers
* and the message body being separated by an additional <CRLF>. * and the message body being separated by an additional <CRLF>.
* Implements RFC 821: DATA <CRLF> * Implements RFC 821: DATA <CRLF>.
* *
* @param string $msg_data Message data to send * @param string $msg_data Message data to send
* *
@ -688,6 +704,7 @@ class SMTP
$this->recordLastTransactionID(); $this->recordLastTransactionID();
//Restore timelimit //Restore timelimit
$this->Timelimit = $savetimelimit; $this->Timelimit = $savetimelimit;
return $result; return $result;
} }
@ -705,17 +722,18 @@ class SMTP
public function hello($host = '') public function hello($host = '')
{ {
//Try extended hello first (RFC 2821) //Try extended hello first (RFC 2821)
return (bool)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host)); return (bool) ($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
} }
/** /**
* Send an SMTP HELO or EHLO command. * Send an SMTP HELO or EHLO command.
* Low-level implementation used by hello() * Low-level implementation used by hello().
* *
* @param string $hello The HELO string * @param string $hello The HELO string
* @param string $host The hostname to say we are * @param string $host The hostname to say we are
* *
* @return bool * @return bool
*
* @see hello() * @see hello()
*/ */
protected function sendHello($hello, $host) protected function sendHello($hello, $host)
@ -727,6 +745,7 @@ class SMTP
} else { } else {
$this->server_caps = null; $this->server_caps = null;
} }
return $noerror; return $noerror;
} }
@ -778,7 +797,7 @@ class SMTP
* $from. Returns true if successful or false otherwise. If True * $from. Returns true if successful or false otherwise. If True
* the mail transaction is started and then one or more recipient * the mail transaction is started and then one or more recipient
* commands may be called followed by a data command. * commands may be called followed by a data command.
* Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF> * Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF>.
* *
* @param string $from Source address of this message * @param string $from Source address of this message
* *
@ -787,6 +806,7 @@ class SMTP
public function mail($from) public function mail($from)
{ {
$useVerp = ($this->do_verp ? ' XVERP' : ''); $useVerp = ($this->do_verp ? ' XVERP' : '');
return $this->sendCommand( return $this->sendCommand(
'MAIL FROM', 'MAIL FROM',
'MAIL FROM:<' . $from . '>' . $useVerp, 'MAIL FROM:<' . $from . '>' . $useVerp,
@ -797,7 +817,7 @@ class SMTP
/** /**
* Send an SMTP QUIT command. * Send an SMTP QUIT command.
* Closes the socket if there is no error or the $close_on_error argument is true. * Closes the socket if there is no error or the $close_on_error argument is true.
* Implements from RFC 821: QUIT <CRLF> * Implements from RFC 821: QUIT <CRLF>.
* *
* @param bool $close_on_error Should the connection close if an error occurs? * @param bool $close_on_error Should the connection close if an error occurs?
* *
@ -811,6 +831,7 @@ class SMTP
$this->close(); $this->close();
$this->error = $err; //Restore any error from the quit command $this->error = $err; //Restore any error from the quit command
} }
return $noerror; return $noerror;
} }
@ -818,7 +839,7 @@ class SMTP
* Send an SMTP RCPT command. * Send an SMTP RCPT command.
* Sets the TO argument to $toaddr. * Sets the TO argument to $toaddr.
* Returns true if the recipient was accepted false if it was rejected. * Returns true if the recipient was accepted false if it was rejected.
* Implements from RFC 821: RCPT <SP> TO:<forward-path> <CRLF> * Implements from RFC 821: RCPT <SP> TO:<forward-path> <CRLF>.
* *
* @param string $address The address the message is being sent to * @param string $address The address the message is being sent to
* *
@ -836,9 +857,9 @@ class SMTP
/** /**
* Send an SMTP RSET command. * Send an SMTP RSET command.
* Abort any transaction that is currently in progress. * Abort any transaction that is currently in progress.
* Implements RFC 821: RSET <CRLF> * Implements RFC 821: RSET <CRLF>.
* *
* @return bool True on success. * @return bool True on success
*/ */
public function reset() public function reset()
{ {
@ -848,21 +869,23 @@ class SMTP
/** /**
* Send a command to an SMTP server and check its return code. * Send a command to an SMTP server and check its return code.
* *
* @param string $command The command name - not sent to the server * @param string $command The command name - not sent to the server
* @param string $commandstring The actual command to send * @param string $commandstring The actual command to send
* @param int|array $expect One or more expected integer success codes * @param int|array $expect One or more expected integer success codes
* *
* @return bool True on success. * @return bool True on success
*/ */
protected function sendCommand($command, $commandstring, $expect) protected function sendCommand($command, $commandstring, $expect)
{ {
if (!$this->connected()) { if (!$this->connected()) {
$this->setError("Called $command without being connected"); $this->setError("Called $command without being connected");
return false; return false;
} }
//Reject line breaks in all commands //Reject line breaks in all commands
if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) { if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
$this->setError("Command '$command' contained line breaks"); $this->setError("Command '$command' contained line breaks");
return false; return false;
} }
$this->client_send($commandstring . static::LE); $this->client_send($commandstring . static::LE);
@ -870,13 +893,13 @@ class SMTP
$this->last_reply = $this->get_lines(); $this->last_reply = $this->get_lines();
// Fetch SMTP code and possible error code explanation // Fetch SMTP code and possible error code explanation
$matches = []; $matches = [];
if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) { if (preg_match('/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/', $this->last_reply, $matches)) {
$code = $matches[1]; $code = $matches[1];
$code_ex = (count($matches) > 2 ? $matches[2] : null); $code_ex = (count($matches) > 2 ? $matches[2] : null);
// Cut off error code from each response line // Cut off error code from each response line
$detail = preg_replace( $detail = preg_replace(
"/{$code}[ -]" . "/{$code}[ -]" .
($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . "/m", ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . '/m',
'', '',
$this->last_reply $this->last_reply
); );
@ -889,7 +912,7 @@ class SMTP
$this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
if (!in_array($code, (array)$expect)) { if (!in_array($code, (array) $expect)) {
$this->setError( $this->setError(
"$command command failed", "$command command failed",
$detail, $detail,
@ -900,10 +923,12 @@ class SMTP
'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply, 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
self::DEBUG_CLIENT self::DEBUG_CLIENT
); );
return false; return false;
} }
$this->setError(''); $this->setError('');
return true; return true;
} }
@ -915,7 +940,7 @@ class SMTP
* commands may be called followed by a data command. This command * commands may be called followed by a data command. This command
* will send the message to the users terminal if they are logged * will send the message to the users terminal if they are logged
* in and send them an email. * in and send them an email.
* Implements RFC 821: SAML <SP> FROM:<reverse-path> <CRLF> * Implements RFC 821: SAML <SP> FROM:<reverse-path> <CRLF>.
* *
* @param string $from The address the message is from * @param string $from The address the message is from
* *
@ -940,7 +965,7 @@ class SMTP
/** /**
* Send an SMTP NOOP command. * Send an SMTP NOOP command.
* Used to keep keep-alives alive, doesn't actually do anything * Used to keep keep-alives alive, doesn't actually do anything.
* *
* @return bool * @return bool
*/ */
@ -953,8 +978,8 @@ class SMTP
* Send an SMTP TURN command. * Send an SMTP TURN command.
* This is an optional command for SMTP that this class does not support. * This is an optional command for SMTP that this class does not support.
* This method is here to make the RFC821 Definition complete for this class * This method is here to make the RFC821 Definition complete for this class
* and _may_ be implemented in future * and _may_ be implemented in future.
* Implements from RFC 821: TURN <CRLF> * Implements from RFC 821: TURN <CRLF>.
* *
* @return bool * @return bool
*/ */
@ -962,6 +987,7 @@ class SMTP
{ {
$this->setError('The SMTP TURN command is not implemented'); $this->setError('The SMTP TURN command is not implemented');
$this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT); $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);
return false; return false;
} }
@ -978,6 +1004,7 @@ class SMTP
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
$result = fwrite($this->smtp_conn, $data); $result = fwrite($this->smtp_conn, $data);
restore_error_handler(); restore_error_handler();
return $result; return $result;
} }
@ -992,7 +1019,7 @@ class SMTP
} }
/** /**
* Get SMTP extensions available on the server * Get SMTP extensions available on the server.
* *
* @return array|null * @return array|null
*/ */
@ -1002,21 +1029,17 @@ class SMTP
} }
/** /**
* A multipurpose method * Get metadata about the SMTP server from its HELO/EHLO response.
* The method works in three ways, dependent on argument value and current state * The method works in three ways, dependent on argument value and current state:
* 1. HELO/EHLO was not sent - returns null and set up $this->error * 1. HELO/EHLO has not been sent - returns null and populates $this->error.
* 2. HELO was sent * 2. HELO has been sent -
* $name = 'HELO': returns server name * $name == 'HELO': returns server name
* $name = 'EHLO': returns boolean false * $name == 'EHLO': returns boolean false
* $name = any string: returns null and set up $this->error * $name == any other string: returns null and populates $this->error
* 3. EHLO was sent * 3. EHLO has been sent -
* $name = 'HELO'|'EHLO': returns server name * $name == 'HELO'|'EHLO': returns the server name
* $name = any string: if extension $name exists, returns boolean True * $name == any other string: if extension $name exists, returns True
* or its options. Otherwise returns boolean False * or its options (e.g. AUTH mechanisms supported). Otherwise returns False.
* In other words, one can use this method to detect 3 conditions:
* - null returned: handshake was not or we don't know about ext (refer to $this->error)
* - false returned: the requested feature exactly not exists
* - positive value returned: the requested feature exists
* *
* @param string $name Name of SMTP extension or 'HELO'|'EHLO' * @param string $name Name of SMTP extension or 'HELO'|'EHLO'
* *
@ -1026,10 +1049,10 @@ class SMTP
{ {
if (!$this->server_caps) { if (!$this->server_caps) {
$this->setError('No HELO/EHLO was sent'); $this->setError('No HELO/EHLO was sent');
return null;
return;
} }
// the tight logic knot ;)
if (!array_key_exists($name, $this->server_caps)) { if (!array_key_exists($name, $this->server_caps)) {
if ('HELO' == $name) { if ('HELO' == $name) {
return $this->server_caps['EHLO']; return $this->server_caps['EHLO'];
@ -1037,8 +1060,9 @@ class SMTP
if ('EHLO' == $name || array_key_exists('EHLO', $this->server_caps)) { if ('EHLO' == $name || array_key_exists('EHLO', $this->server_caps)) {
return false; return false;
} }
$this->setError('HELO handshake was used. Client knows nothing about server extensions'); $this->setError('HELO handshake was used; No information about server extensions available');
return null;
return;
} }
return $this->server_caps[$name]; return $this->server_caps[$name];
@ -1115,6 +1139,7 @@ class SMTP
break; break;
} }
} }
return $data; return $data;
} }
@ -1141,9 +1166,9 @@ class SMTP
/** /**
* Set error messages and codes. * Set error messages and codes.
* *
* @param string $message The error message * @param string $message The error message
* @param string $detail Further detail on the error * @param string $detail Further detail on the error
* @param string $smtp_code An associated SMTP error code * @param string $smtp_code An associated SMTP error code
* @param string $smtp_code_ex Extended SMTP code * @param string $smtp_code_ex Extended SMTP code
*/ */
protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '') protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '')
@ -1152,7 +1177,7 @@ class SMTP
'error' => $message, 'error' => $message,
'detail' => $detail, 'detail' => $detail,
'smtp_code' => $smtp_code, 'smtp_code' => $smtp_code,
'smtp_code_ex' => $smtp_code_ex 'smtp_code_ex' => $smtp_code_ex,
]; ];
} }
@ -1199,7 +1224,7 @@ class SMTP
/** /**
* Set SMTP timeout. * Set SMTP timeout.
* *
* @param int $timeout * @param int $timeout The timeout duration in seconds
*/ */
public function setTimeout($timeout = 0) public function setTimeout($timeout = 0)
{ {
@ -1219,10 +1244,10 @@ class SMTP
/** /**
* Reports an error number and string. * Reports an error number and string.
* *
* @param int $errno The error number returned by PHP * @param int $errno The error number returned by PHP
* @param string $errmsg The error message returned by PHP * @param string $errmsg The error message returned by PHP
* @param string $errfile The file the error occurred in * @param string $errfile The file the error occurred in
* @param int $errline The line number the error occurred on * @param int $errline The line number the error occurred on
*/ */
protected function errorHandler($errno, $errmsg, $errfile = '', $errline = 0) protected function errorHandler($errno, $errmsg, $errfile = '', $errline = 0)
{ {
@ -1230,7 +1255,7 @@ class SMTP
$this->setError( $this->setError(
$notice, $notice,
$errmsg, $errmsg,
(string)$errno (string) $errno
); );
$this->edebug( $this->edebug(
"$notice Error #$errno: $errmsg [$errfile line $errline]", "$notice Error #$errno: $errmsg [$errfile line $errline]",
@ -1244,6 +1269,7 @@ class SMTP
* Relies on the host providing the ID in response to a DATA command. * Relies on the host providing the ID in response to a DATA command.
* If no reply has been received yet, it will return null. * If no reply has been received yet, it will return null.
* If no pattern was matched, it will return false. * If no pattern was matched, it will return false.
*
* @return bool|null|string * @return bool|null|string
*/ */
protected function recordLastTransactionID() protected function recordLastTransactionID()
@ -1268,7 +1294,9 @@ class SMTP
* Get the queue/transaction ID of the last SMTP transaction * Get the queue/transaction ID of the last SMTP transaction
* If no reply has been received yet, it will return null. * If no reply has been received yet, it will return null.
* If no pattern was matched, it will return false. * If no pattern was matched, it will return false.
*
* @return bool|null|string * @return bool|null|string
*
* @see recordLastTransactionID() * @see recordLastTransactionID()
*/ */
public function getLastTransactionID() public function getLastTransactionID()

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* PHPUnit bootstrap file * PHPUnit bootstrap file.
*/ */
ini_set('sendmail_path', '/usr/sbin/sendmail -t -i '); ini_set('sendmail_path', '/usr/sbin/sendmail -t -i ');
if (file_exists('vendor/autoload.php')) { if (file_exists('vendor/autoload.php')) {

View File

@ -1,13 +1,12 @@
<?php <?php
/** /**
* PHPMailer - language file tests * PHPMailer - language file tests.
* *
* PHP version 5.5 * PHP version 5.5.
* *
* @package PHPMailer
* @author Marcus Bointon <phpmailer@synchromedia.co.uk> * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
* @author Andy Prevost * @author Andy Prevost
* @copyright 2010 - 2016 Marcus Bointon * @copyright 2010 - 2017 Marcus Bointon
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
*/ */
@ -15,8 +14,7 @@
namespace PHPMailer\PHPMailer; namespace PHPMailer\PHPMailer;
/** /**
* PHPMailer - PHP email transport unit test class * Check language files for missing or excess translations.
* Performs authentication tests
*/ */
class PHPMailerLangTest extends \PHPUnit_Framework_TestCase class PHPMailerLangTest extends \PHPUnit_Framework_TestCase
{ {
@ -28,7 +26,7 @@ class PHPMailerLangTest extends \PHPUnit_Framework_TestCase
public $Mail; public $Mail;
/** /**
* Default include path * Default include path.
* *
* @var string * @var string
*/ */
@ -39,12 +37,12 @@ class PHPMailerLangTest extends \PHPUnit_Framework_TestCase
*/ */
public function setUp() public function setUp()
{ {
$this->Mail = new PHPMailer; $this->Mail = new PHPMailer();
} }
/** /**
* Test language files for missing and excess translations * Test language files for missing and excess translations.
* All languages are compared with English * All languages are compared with English.
* *
* @group languages * @group languages
*/ */

View File

@ -1,13 +1,11 @@
<?php <?php
/** /**
* PHPMailer - PHP email transport unit tests. * PHPMailer - PHP email transport unit tests.
* PHP version 5.5.
* *
* PHP version 5.5
*
* @package PHPMailer
* @author Marcus Bointon <phpmailer@synchromedia.co.uk> * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
* @author Andy Prevost * @author Andy Prevost
* @copyright 2012 - 2016 Marcus Bointon * @copyright 2012 - 2017 Marcus Bointon
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
*/ */
@ -20,7 +18,7 @@ namespace PHPMailer\PHPMailer;
class PHPMailerTest extends \PHPUnit_Framework_TestCase class PHPMailerTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* Holds the phpmailer instance. * Holds the PHPMailer instance.
* *
* @var PHPMailer * @var PHPMailer
*/ */
@ -48,14 +46,14 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
public $NoteLog = []; public $NoteLog = [];
/** /**
* Default include path * Default include path.
* *
* @var string * @var string
*/ */
public $INCLUDE_DIR = '..'; public $INCLUDE_DIR = '..';
/** /**
* PIDs of any processes we need to kill * PIDs of any processes we need to kill.
* *
* @var array * @var array
*/ */
@ -70,7 +68,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
if (file_exists($this->INCLUDE_DIR . '/test/testbootstrap.php')) { if (file_exists($this->INCLUDE_DIR . '/test/testbootstrap.php')) {
include $this->INCLUDE_DIR . '/test/testbootstrap.php'; //Overrides go in here include $this->INCLUDE_DIR . '/test/testbootstrap.php'; //Overrides go in here
} }
$this->Mail = new PHPMailer; $this->Mail = new PHPMailer();
$this->Mail->SMTPDebug = 3; //Full debug output $this->Mail->SMTPDebug = 3; //Full debug output
$this->Mail->Priority = 3; $this->Mail->Priority = 3;
$this->Mail->Encoding = '8bit'; $this->Mail->Encoding = '8bit';
@ -186,7 +184,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
$ReportBody .= '-------' . $eol; $ReportBody .= '-------' . $eol;
$ReportBody .= $list_start; $ReportBody .= $list_start;
for ($i = 0; $i < count($this->ChangeLog); $i++) { for ($i = 0; $i < count($this->ChangeLog); ++$i) {
$ReportBody .= $bullet_start . $this->ChangeLog[$i][0] . ' was changed to [' . $ReportBody .= $bullet_start . $this->ChangeLog[$i][0] . ' was changed to [' .
$this->ChangeLog[$i][1] . ']' . $bullet_end; $this->ChangeLog[$i][1] . ']' . $bullet_end;
} }
@ -199,7 +197,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
$ReportBody .= '-----' . $eol; $ReportBody .= '-----' . $eol;
$ReportBody .= $list_start; $ReportBody .= $list_start;
for ($i = 0; $i < count($this->NoteLog); $i++) { for ($i = 0; $i < count($this->NoteLog); ++$i) {
$ReportBody .= $bullet_start . $this->NoteLog[$i] . $bullet_end; $ReportBody .= $bullet_start . $this->NoteLog[$i] . $bullet_end;
} }
$ReportBody .= $list_end; $ReportBody .= $list_end;
@ -265,7 +263,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
} }
/** /**
* Adds all of the addresses * Adds all of the addresses.
* *
* @param string $sAddress * @param string $sAddress
* @param string $sName * @param string $sName
@ -283,6 +281,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
case 'bcc': case 'bcc':
return $this->Mail->addBCC($sAddress, $sName); return $this->Mail->addBCC($sAddress, $sName);
} }
return false; return false;
} }
@ -292,15 +291,15 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
*/ */
public function testBootstrap() public function testBootstrap()
{ {
$this->assertTrue( $this->assertFileExists(
file_exists($this->INCLUDE_DIR . '/test/testbootstrap.php'), $this->INCLUDE_DIR . '/test/testbootstrap.php',
'Test config params missing - copy testbootstrap.php to testbootstrap-dist.php and change as appropriate' 'Test config params missing - copy testbootstrap.php to testbootstrap-dist.php and change as appropriate'
); );
} }
/** /**
* Test CRAM-MD5 authentication. * Test CRAM-MD5 authentication.
* Needs a connection to a server that supports this auth mechanism, so commented out by default * Needs a connection to a server that supports this auth mechanism, so commented out by default.
*/ */
public function testAuthCRAMMD5() public function testAuthCRAMMD5()
{ {
@ -399,7 +398,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
'cdburgess+!#$%&\'*-/=?+_{}|~test@example.com', 'cdburgess+!#$%&\'*-/=?+_{}|~test@example.com',
'test@test.com', 'test@test.com',
'test@xn--example.com', 'test@xn--example.com',
'test@example.com' 'test@example.com',
]; ];
//These are invalid according to PHP's filter_var //These are invalid according to PHP's filter_var
//which doesn't allow dotless domains, numeric TLDs or unbracketed IPv4 literals //which doesn't allow dotless domains, numeric TLDs or unbracketed IPv4 literals
@ -474,7 +473,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
'first.last@sub.do,com', 'first.last@sub.do,com',
'first\@last@iana.org', 'first\@last@iana.org',
'123456789012345678901234567890123456789012345678901234567890' . '123456789012345678901234567890123456789012345678901234567890' .
'@12345678901234567890123456789012345678901234 [...]', '@12345678901234567890123456789012345678901234 [...]',
'first.last', 'first.last',
'12345678901234567890123456789012345678901234567890123456789012345@iana.org', '12345678901234567890123456789012345678901234567890123456789012345@iana.org',
'.first.last@iana.org', '.first.last@iana.org',
@ -487,7 +486,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
'first\@last@iana.org', 'first\@last@iana.org',
'first.last@', 'first.last@',
'x@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.' . 'x@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.' .
'x23456789.x23456789.x23456789.x23 [...]', 'x23456789.x23456789.x23456789.x23 [...]',
'first.last@[.12.34.56.78]', 'first.last@[.12.34.56.78]',
'first.last@[12.34.56.789]', 'first.last@[12.34.56.789]',
'first.last@[::12.34.56.78]', 'first.last@[::12.34.56.78]',
@ -534,7 +533,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
'test@example.', 'test@example.',
'test@.org', 'test@.org',
'test@12345678901234567890123456789012345678901234567890123456789012345678901234567890' . 'test@12345678901234567890123456789012345678901234567890123456789012345678901234567890' .
'12345678901234567890 [...]', '12345678901234567890 [...]',
'test@[123.123.123.123', 'test@[123.123.123.123',
'test@123.123.123.123]', 'test@123.123.123.123]',
'NotAnEmail', 'NotAnEmail',
@ -559,10 +558,10 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
'cal(foo)bar)@iamcal.com', 'cal(foo)bar)@iamcal.com',
'cal(foo\)@iamcal.com', 'cal(foo\)@iamcal.com',
'first(12345678901234567890123456789012345678901234567890)last@(1234567890123456789' . 'first(12345678901234567890123456789012345678901234567890)last@(1234567890123456789' .
'01234567890123456789012 [...]', '01234567890123456789012 [...]',
'first(middle)last@iana.org', 'first(middle)last@iana.org',
'first(abc("def".ghi).mno)middle(abc("def".ghi).mno).last@(abc("def".ghi).mno)example' . 'first(abc("def".ghi).mno)middle(abc("def".ghi).mno).last@(abc("def".ghi).mno)example' .
'(abc("def".ghi).mno). [...]', '(abc("def".ghi).mno). [...]',
'a(a(b(c)d(e(f))g)(h(i)j)@iana.org', 'a(a(b(c)d(e(f))g)(h(i)j)@iana.org',
'.@', '.@',
'@bar.com', '@bar.com',
@ -609,9 +608,9 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
'first.last@[IPv6:a1:a2:a3:a4:b1:b2:b3:]', 'first.last@[IPv6:a1:a2:a3:a4:b1:b2:b3:]',
'first.last@[IPv6::a2:a3:a4:b1:b2:b3:b4]', 'first.last@[IPv6::a2:a3:a4:b1:b2:b3:b4]',
'first.last@[IPv6:a1:a2:a3:a4::b1:b2:b3:b4]', 'first.last@[IPv6:a1:a2:a3:a4::b1:b2:b3:b4]',
//This is a valid RCC5322 address, but we don't want to allow it for obvious reasons! //This is a valid RFC5322 address, but we don't want to allow it for obvious reasons!
"(\r\n RCPT TO:user@example.com\r\n DATA \\\nSubject: spam10\\\n\r\n Hello," . "(\r\n RCPT TO:user@example.com\r\n DATA \\\nSubject: spam10\\\n\r\n Hello," .
"\r\n this is a spam mail.\\\n.\r\n QUIT\r\n ) a@example.net" "\r\n this is a spam mail.\\\n.\r\n QUIT\r\n ) a@example.net",
]; ];
// IDNs in Unicode and ASCII forms. // IDNs in Unicode and ASCII forms.
$unicodeaddresses = [ $unicodeaddresses = [
@ -672,7 +671,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
PHPMailer::validateAddress( PHPMailer::validateAddress(
'user@example.com', 'user@example.com',
function ($address) { function ($address) {
return (strpos($address, '@') !== false); return strpos($address, '@') !== false;
} }
), ),
'Custom validator false negative' 'Custom validator false negative'
@ -681,29 +680,29 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
PHPMailer::validateAddress( PHPMailer::validateAddress(
'userexample.com', 'userexample.com',
function ($address) { function ($address) {
return (strpos($address, '@') !== false); return strpos($address, '@') !== false;
} }
), ),
'Custom validator false positive' 'Custom validator false positive'
); );
//Set the default validator to an injected function //Set the default validator to an injected function
PHPMailer::$validator = function ($address) { PHPMailer::$validator = function ($address) {
return ('user@example.com' === $address); return 'user@example.com' === $address;
}; };
$this->assertTrue( $this->assertTrue(
$this->Mail->addAddress('user@example.com'), $this->Mail->addAddress('user@example.com'),
'Custom default validator false negative' 'Custom default validator false negative'
); );
$this->assertFalse( $this->assertFalse(
//Need to pick a failing value which would pass all other validators //Need to pick a failing value which would pass all other validators
//to be sure we're using our custom one //to be sure we're using our custom one
$this->Mail->addAddress('bananas@example.com'), $this->Mail->addAddress('bananas@example.com'),
'Custom default validator false positive' 'Custom default validator false positive'
); );
//Set default validator to PHP built-in //Set default validator to PHP built-in
PHPMailer::$validator = 'php'; PHPMailer::$validator = 'php';
$this->assertFalse( $this->assertFalse(
//This is a valid address that FILTER_VALIDATE_EMAIL thinks is invalid //This is a valid address that FILTER_VALIDATE_EMAIL thinks is invalid
$this->Mail->addAddress('first.last@example.123'), $this->Mail->addAddress('first.last@example.123'),
'PHP validator not behaving as expected' 'PHP validator not behaving as expected'
); );
@ -778,11 +777,13 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
if (!$this->Mail->addAttachment(realpath($this->INCLUDE_DIR . '/examples/images/phpmailer.png'))) { if (!$this->Mail->addAttachment(realpath($this->INCLUDE_DIR . '/examples/images/phpmailer.png'))) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
if (!$this->Mail->addAttachment(__FILE__, 'test.txt')) { if (!$this->Mail->addAttachment(__FILE__, 'test.txt')) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
@ -858,7 +859,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
$noencode = 'eeeeeeeeee'; $noencode = 'eeeeeeeeee';
$this->Mail->isMail(); $this->Mail->isMail();
//Expected results //Expected results
$bencoderes = '=?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6k=?='.PHPMailer::getLE(). $bencoderes = '=?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6k=?=' . PHPMailer::getLE() .
' =?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6k=?=' . PHPMailer::getLE() . ' =?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6k=?=' . PHPMailer::getLE() .
' =?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6k=?=' . PHPMailer::getLE() . ' =?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6k=?=' . PHPMailer::getLE() .
' =?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6k=?='; ' =?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6k=?=';
@ -866,7 +867,7 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
' =?UTF-8?Q?eeeeeeeeeeeeeeeeeeeeeeeeee=C3=A9?='; ' =?UTF-8?Q?eeeeeeeeeeeeeeeeeeeeeeeeee=C3=A9?=';
$bencodenofoldres = '=?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6k=?='; $bencodenofoldres = '=?UTF-8?B?w6nDqcOpw6nDqcOpw6nDqcOpw6k=?=';
$qencodenofoldres = '=?UTF-8?Q?eeeeeeeee=C3=A9?='; $qencodenofoldres = '=?UTF-8?Q?eeeeeeeee=C3=A9?=';
$justfoldres = 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'. $justfoldres = 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' .
'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' . PHPMailer::getLE() . ' eeeeeeeeee'; 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' . PHPMailer::getLE() . ' eeeeeeeeee';
$noencoderes = 'eeeeeeeeee'; $noencoderes = 'eeeeeeeeee';
$this->assertEquals( $this->assertEquals(
@ -907,9 +908,9 @@ class PHPMailerTest extends \PHPUnit_Framework_TestCase
public function testHtml() public function testHtml()
{ {
$this->Mail->isHTML(true); $this->Mail->isHTML(true);
$this->Mail->Subject .= ": HTML only"; $this->Mail->Subject .= ': HTML only';
$this->Mail->Body = <<<EOT $this->Mail->Body = <<<'EOT'
<html> <html>
<head> <head>
<title>HTML email test</title> <title>HTML email test</title>
@ -935,7 +936,7 @@ EOT;
public function testHtmlIso8859() public function testHtmlIso8859()
{ {
$this->Mail->isHTML(true); $this->Mail->isHTML(true);
$this->Mail->Subject .= ": ISO-8859-1 HTML"; $this->Mail->Subject .= ': ISO-8859-1 HTML';
$this->Mail->CharSet = 'iso-8859-1'; $this->Mail->CharSet = 'iso-8859-1';
//This file is in ISO-8859-1 charset //This file is in ISO-8859-1 charset
@ -947,8 +948,8 @@ EOT;
$this->Mail->msgHTML( $this->Mail->msgHTML(
mb_convert_encoding( mb_convert_encoding(
$content, $content,
"ISO-8859-1", 'ISO-8859-1',
mb_detect_encoding($content, "UTF-8, ISO-8859-1, ISO-8859-15", true) mb_detect_encoding($content, 'UTF-8, ISO-8859-1, ISO-8859-15', true)
), ),
realpath($this->INCLUDE_DIR . '/examples') realpath($this->INCLUDE_DIR . '/examples')
); );
@ -966,10 +967,10 @@ EOT;
public function testHtmlUtf8() public function testHtmlUtf8()
{ {
$this->Mail->isHTML(true); $this->Mail->isHTML(true);
$this->Mail->Subject .= ": UTF-8 HTML Пустое тело сообщения"; $this->Mail->Subject .= ': UTF-8 HTML Пустое тело сообщения';
$this->Mail->CharSet = 'UTF-8'; $this->Mail->CharSet = 'UTF-8';
$this->Mail->Body = <<<EOT $this->Mail->Body = <<<'EOT'
<html> <html>
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
@ -995,10 +996,10 @@ EOT;
public function testUtf8WithEmbeddedImage() public function testUtf8WithEmbeddedImage()
{ {
$this->Mail->isHTML(true); $this->Mail->isHTML(true);
$this->Mail->Subject .= ": UTF-8 with embedded image"; $this->Mail->Subject .= ': UTF-8 with embedded image';
$this->Mail->CharSet = 'UTF-8'; $this->Mail->CharSet = 'UTF-8';
$this->Mail->Body = <<<EOT $this->Mail->Body = <<<'EOT'
<html> <html>
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
@ -1030,10 +1031,10 @@ EOT;
public function testPlainUtf8() public function testPlainUtf8()
{ {
$this->Mail->isHTML(false); $this->Mail->isHTML(false);
$this->Mail->Subject .= ": UTF-8 plain text"; $this->Mail->Subject .= ': UTF-8 plain text';
$this->Mail->CharSet = 'UTF-8'; $this->Mail->CharSet = 'UTF-8';
$this->Mail->Body = <<<EOT $this->Mail->Body = <<<'EOT'
Chinese text: 郵件內容為空 Chinese text: 郵件內容為空
Russian text: Пустое тело сообщения Russian text: Пустое тело сообщения
Armenian text: Հաղորդագրությունը դատարկ է Armenian text: Հաղորդագրությունը դատարկ է
@ -1046,7 +1047,7 @@ EOT;
} }
/** /**
* Test simple message builder and html2text converters * Test simple message builder and html2text converters.
*/ */
public function testMsgHTML() public function testMsgHTML()
{ {
@ -1067,7 +1068,7 @@ EOT;
$this->Mail->AltBody = ''; $this->Mail->AltBody = '';
$this->Mail->msgHTML( $this->Mail->msgHTML(
$message, $message,
realpath($this->INCLUDE_DIR .'/examples'), realpath($this->INCLUDE_DIR . '/examples'),
function ($html) { function ($html) {
return strtoupper(strip_tags($html)); return strtoupper(strip_tags($html));
} }
@ -1092,7 +1093,10 @@ EOT;
//Test that absolute URLs are ignored //Test that absolute URLs are ignored
$this->Mail->msgHTML('<img src="https://github.com/PHPMailer/PHPMailer/blob/master/composer.json">test'); $this->Mail->msgHTML('<img src="https://github.com/PHPMailer/PHPMailer/blob/master/composer.json">test');
$this->assertTrue( $this->assertTrue(
strpos($this->Mail->Body, 'src="https://github.com/PHPMailer/PHPMailer/blob/master/composer.json"') !== false strpos(
$this->Mail->Body,
'src="https://github.com/PHPMailer/PHPMailer/blob/master/composer.json"'
) !== false
); );
//Test that absolute URLs with anonymous/relative protocol are ignored //Test that absolute URLs with anonymous/relative protocol are ignored
//Note that such URLs will not work in email anyway because they have no protocol to be relative to //Note that such URLs will not work in email anyway because they have no protocol to be relative to
@ -1106,7 +1110,7 @@ EOT;
} }
/** /**
* Simple HTML and attachment test * Simple HTML and attachment test.
*/ */
public function testHTMLAttachment() public function testHTMLAttachment()
{ {
@ -1121,6 +1125,7 @@ EOT;
) )
) { ) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
@ -1132,7 +1137,7 @@ EOT;
} }
/** /**
* Test embedded image without a name * Test embedded image without a name.
*/ */
public function testHTMLStringEmbedNoName() public function testHTMLStringEmbedNoName()
{ {
@ -1142,13 +1147,14 @@ EOT;
if (!$this->Mail->addStringEmbeddedImage( if (!$this->Mail->addStringEmbeddedImage(
file_get_contents(realpath($this->INCLUDE_DIR . '/examples/images/phpmailer_mini.png')), file_get_contents(realpath($this->INCLUDE_DIR . '/examples/images/phpmailer_mini.png')),
hash('sha256', 'phpmailer_mini.png').'@phpmailer.0', hash('sha256', 'phpmailer_mini.png') . '@phpmailer.0',
'', //Intentionally empty name '', //Intentionally empty name
'base64', 'base64',
'', //Intentionally empty MIME type '', //Intentionally empty MIME type
'inline' 'inline'
)) { )) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
@ -1157,7 +1163,7 @@ EOT;
} }
/** /**
* Simple HTML and multiple attachment test * Simple HTML and multiple attachment test.
*/ */
public function testHTMLMultiAttachment() public function testHTMLMultiAttachment()
{ {
@ -1171,6 +1177,7 @@ EOT;
) )
) { ) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
@ -1180,6 +1187,7 @@ EOT;
) )
) { ) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
@ -1207,6 +1215,7 @@ EOT;
) )
) { ) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
@ -1237,11 +1246,13 @@ EOT;
) )
) { ) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
if (!$this->Mail->addAttachment(__FILE__, 'test.txt')) { if (!$this->Mail->addAttachment(__FILE__, 'test.txt')) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
@ -1255,11 +1266,11 @@ EOT;
public function testAltBody() public function testAltBody()
{ {
$this->Mail->Body = 'This is the <strong>HTML</strong> part of the email.'; $this->Mail->Body = 'This is the <strong>HTML</strong> part of the email.';
$this->Mail->AltBody = 'Here is the text body of this message. ' . $this->Mail->AltBody = 'Here is the plain text body of this message. ' .
'It should be quite a few lines. It should be wrapped at the ' . 'It should be quite a few lines. It should be wrapped at ' .
'40 characters. Make sure that it is.'; '40 characters. Make sure that it is.';
$this->Mail->WordWrap = 40; $this->Mail->WordWrap = 40;
$this->addNote('This is a mulipart alternative email'); $this->addNote('This is a multipart/alternative email');
$this->Mail->Subject .= ': AltBody + Word Wrap'; $this->Mail->Subject .= ': AltBody + Word Wrap';
$this->buildBody(); $this->buildBody();
@ -1267,7 +1278,7 @@ EOT;
} }
/** /**
* Simple HTML and attachment test * Simple HTML and attachment test.
*/ */
public function testAltBodyAttachment() public function testAltBodyAttachment()
{ {
@ -1278,6 +1289,7 @@ EOT;
if (!$this->Mail->addAttachment(__FILE__, 'test_attach.txt')) { if (!$this->Mail->addAttachment(__FILE__, 'test_attach.txt')) {
$this->assertTrue(false, $this->Mail->ErrorInfo); $this->assertTrue(false, $this->Mail->ErrorInfo);
return; return;
} }
@ -1379,7 +1391,7 @@ EOT;
//Use +2 to ensure line length is over limit - LE may only be 1 char //Use +2 to ensure line length is over limit - LE may only be 1 char
$badlen = str_repeat(str_repeat('1', PHPMailer::MAX_LINE_LENGTH + 2) . PHPMailer::getLE(), 2); $badlen = str_repeat(str_repeat('1', PHPMailer::MAX_LINE_LENGTH + 2) . PHPMailer::getLE(), 2);
$this->Mail->Body = "This message contains lines that are too long.". $this->Mail->Body = 'This message contains lines that are too long.' .
PHPMailer::getLE() . $oklen . $badlen . $oklen; PHPMailer::getLE() . $oklen . $badlen . $oklen;
$this->assertTrue( $this->assertTrue(
PHPMailer::hasLineLongerThanMax($this->Mail->Body), PHPMailer::hasLineLongerThanMax($this->Mail->Body),
@ -1393,7 +1405,7 @@ EOT;
$message = $this->Mail->getSentMIMEMessage(); $message = $this->Mail->getSentMIMEMessage();
$this->assertFalse( $this->assertFalse(
PHPMailer::hasLineLongerThanMax($message), PHPMailer::hasLineLongerThanMax($message),
'Long line not corrected (Max: '.(PHPMailer::MAX_LINE_LENGTH + strlen(PHPMailer::getLE())). ' chars)' 'Long line not corrected (Max: ' . (PHPMailer::MAX_LINE_LENGTH + strlen(PHPMailer::getLE())) . ' chars)'
); );
$this->assertContains( $this->assertContains(
'Content-Transfer-Encoding: quoted-printable', 'Content-Transfer-Encoding: quoted-printable',
@ -1409,7 +1421,7 @@ EOT;
{ {
$oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::getLE(), 10); $oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::getLE(), 10);
$this->Mail->Body = "This message does not contain lines that are too long.". $this->Mail->Body = 'This message does not contain lines that are too long.' .
PHPMailer::getLE() . $oklen; PHPMailer::getLE() . $oklen;
$this->assertFalse( $this->assertFalse(
PHPMailer::hasLineLongerThanMax($this->Mail->Body), PHPMailer::hasLineLongerThanMax($this->Mail->Body),
@ -1446,7 +1458,7 @@ EOT;
} }
/** /**
* Tests this denial of service attack: * Test this denial of service attack.
* *
* @see http://www.cybsec.com/vuln/PHPMailer-DOS.pdf * @see http://www.cybsec.com/vuln/PHPMailer-DOS.pdf
*/ */
@ -1460,7 +1472,7 @@ EOT;
} }
/** /**
* Tests this denial of service attack: * Tests this denial of service attack.
* *
* @see https://sourceforge.net/p/phpmailer/bugs/383/ * @see https://sourceforge.net/p/phpmailer/bugs/383/
* According to the ticket, this should get stuck in a loop, though I can't make it happen. * According to the ticket, this should get stuck in a loop, though I can't make it happen.
@ -1534,15 +1546,15 @@ EOT;
'Failed to recognise address list (IMAP parser)' 'Failed to recognise address list (IMAP parser)'
); );
$this->assertEquals( $this->assertEquals(
array( [
array("name" => 'Joe User', 'address' => 'joe@example.com'), ['name' => 'Joe User', 'address' => 'joe@example.com'],
array("name" => 'Jill User', 'address' => 'jill@example.net'), ['name' => 'Jill User', 'address' => 'jill@example.net'],
array("name" => '', 'address' => 'frank@example.com'), ['name' => '', 'address' => 'frank@example.com'],
), ],
$this->Mail->parseAddresses( $this->Mail->parseAddresses(
'Joe User <joe@example.com>,' 'Joe User <joe@example.com>,'
. 'Jill User <jill@example.net>,' . 'Jill User <jill@example.net>,'
. 'frank@example.com,' . 'frank@example.com,'
), ),
'Parsed addresses' 'Parsed addresses'
); );
@ -1643,8 +1655,8 @@ EOT;
$this->buildBody(); $this->buildBody();
$this->Mail->preSend(); $this->Mail->preSend();
$this->assertRegExp( $this->assertRegExp(
"/Content-Transfer-Encoding: 8bit\r\n\r\n". "/Content-Transfer-Encoding: 8bit\r\n\r\n" .
"This is a multi-part message in MIME format./", 'This is a multi-part message in MIME format./',
$this->Mail->getSentMIMEMessage(), $this->Mail->getSentMIMEMessage(),
'MIME structure broken' 'MIME structure broken'
); );
@ -1712,6 +1724,7 @@ EOT;
$this->buildBody(); $this->buildBody();
$this->assertTrue($this->Mail->send(), 'Base64 encoding failed'); $this->assertTrue($this->Mail->send(), 'Base64 encoding failed');
} }
/** /**
* S/MIME Signing tests (self-signed). * S/MIME Signing tests (self-signed).
* *
@ -1730,12 +1743,12 @@ EOT;
'organizationName' => 'PHP', 'organizationName' => 'PHP',
'organizationalUnitName' => 'PHPMailer', 'organizationalUnitName' => 'PHPMailer',
'commonName' => 'PHPMailer Test', 'commonName' => 'PHPMailer Test',
'emailAddress' => 'phpmailer@example.com' 'emailAddress' => 'phpmailer@example.com',
]; ];
$keyconfig = [ $keyconfig = [
"digest_alg" => "sha256", 'digest_alg' => 'sha256',
"private_key_bits" => 2048, 'private_key_bits' => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA, 'private_key_type' => OPENSSL_KEYTYPE_RSA,
]; ];
$password = 'password'; $password = 'password';
$certfile = 'certfile.pem'; $certfile = 'certfile.pem';
@ -1771,7 +1784,7 @@ EOT;
* S/MIME Signing tests using a CA chain cert. * S/MIME Signing tests using a CA chain cert.
* To test that a generated message is signed correctly, save the message in a file called `signed.eml` * To test that a generated message is signed correctly, save the message in a file called `signed.eml`
* and use openssl along with the certs generated by this script: * and use openssl along with the certs generated by this script:
* `openssl smime -verify -in signed.eml -signer certfile.pem -CAfile cacertfile.pem` * `openssl smime -verify -in signed.eml -signer certfile.pem -CAfile cacertfile.pem`.
* *
* @requires extension openssl * @requires extension openssl
*/ */
@ -1788,7 +1801,7 @@ EOT;
'organizationName' => 'PHP', 'organizationName' => 'PHP',
'organizationalUnitName' => 'PHPMailer', 'organizationalUnitName' => 'PHPMailer',
'commonName' => 'PHPMailer Test', 'commonName' => 'PHPMailer Test',
'emailAddress' => 'phpmailer@example.com' 'emailAddress' => 'phpmailer@example.com',
]; ];
$cacertprops = [ $cacertprops = [
'countryName' => 'UK', 'countryName' => 'UK',
@ -1797,7 +1810,7 @@ EOT;
'organizationName' => 'PHP', 'organizationName' => 'PHP',
'organizationalUnitName' => 'PHPMailer CA', 'organizationalUnitName' => 'PHPMailer CA',
'commonName' => 'PHPMailer Test CA', 'commonName' => 'PHPMailer Test CA',
'emailAddress' => 'phpmailer@example.com' 'emailAddress' => 'phpmailer@example.com',
]; ];
$keyconfig = [ $keyconfig = [
'digest_alg' => 'sha256', 'digest_alg' => 'sha256',
@ -1905,7 +1918,7 @@ EOT;
$pk = openssl_pkey_new( $pk = openssl_pkey_new(
[ [
'private_key_bits' => 2048, 'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA 'private_key_type' => OPENSSL_KEYTYPE_RSA,
] ]
); );
openssl_pkey_export_to_file($pk, $privatekeyfile); openssl_pkey_export_to_file($pk, $privatekeyfile);
@ -1952,11 +1965,11 @@ EOT;
} }
/** /**
* Test line length detection * Test line length detection.
*/ */
public function testLineLength() public function testLineLength()
{ {
$oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH)."\r\n", 2); $oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . "\r\n", 2);
$badlen = str_repeat(str_repeat('1', PHPMailer::MAX_LINE_LENGTH + 1) . "\r\n", 2); $badlen = str_repeat(str_repeat('1', PHPMailer::MAX_LINE_LENGTH + 1) . "\r\n", 2);
$this->assertTrue(PHPMailer::hasLineLongerThanMax($badlen), 'Long line not detected (only)'); $this->assertTrue(PHPMailer::hasLineLongerThanMax($badlen), 'Long line not detected (only)');
$this->assertTrue(PHPMailer::hasLineLongerThanMax($oklen . $badlen), 'Long line not detected (first)'); $this->assertTrue(PHPMailer::hasLineLongerThanMax($oklen . $badlen), 'Long line not detected (first)');
@ -1967,7 +1980,7 @@ EOT;
); );
$this->assertFalse(PHPMailer::hasLineLongerThanMax($oklen), 'Long line false positive'); $this->assertFalse(PHPMailer::hasLineLongerThanMax($oklen), 'Long line false positive');
$this->Mail->isHTML(false); $this->Mail->isHTML(false);
$this->Mail->Subject .= ": Line length test"; $this->Mail->Subject .= ': Line length test';
$this->Mail->CharSet = 'UTF-8'; $this->Mail->CharSet = 'UTF-8';
$this->Mail->Encoding = '8bit'; $this->Mail->Encoding = '8bit';
$this->Mail->Body = $oklen . $badlen . $oklen . $badlen; $this->Mail->Body = $oklen . $badlen . $oklen . $badlen;
@ -1988,7 +2001,7 @@ EOT;
$this->Mail->preSend(); $this->Mail->preSend();
$lastid = $this->Mail->getLastMessageID(); $lastid = $this->Mail->getLastMessageID();
$this->assertNotEquals($lastid, $id, 'Invalid Message ID allowed'); $this->assertNotEquals($lastid, $id, 'Invalid Message ID allowed');
$id = '<'. hash('sha256', 12345).'@example.com>'; $id = '<' . hash('sha256', 12345) . '@example.com>';
$this->Mail->MessageID = $id; $this->Mail->MessageID = $id;
$this->buildBody(); $this->buildBody();
$this->Mail->preSend(); $this->Mail->preSend();
@ -2086,13 +2099,13 @@ EOT;
'127.0.0.1', '127.0.0.1',
trim(str_repeat('a0123456789.', 21), '.'), trim(str_repeat('a0123456789.', 21), '.'),
'[::1]', '[::1]',
'[0:1234:dc0:41:216:3eff:fe67:3e01]' '[0:1234:dc0:41:216:3eff:fe67:3e01]',
]; ];
$bad = [ $bad = [
null, null,
123, 123,
1.5, 1.5,
new \stdClass, new \stdClass(),
[], [],
'', '',
'999.0.0.0', '999.0.0.0',
@ -2100,17 +2113,18 @@ EOT;
'[1234:::1]', '[1234:::1]',
trim(str_repeat('a0123456789.', 22), '.'), trim(str_repeat('a0123456789.', 22), '.'),
'0:1234:dc0:41:216:3eff:fe67:3e01', '0:1234:dc0:41:216:3eff:fe67:3e01',
'[012q:1234:dc0:41:216:3eff:fe67:3e01]' '[012q:1234:dc0:41:216:3eff:fe67:3e01]',
]; ];
foreach ($good as $h) { foreach ($good as $h) {
$this->assertTrue(PHPMailer::isValidHost($h), 'Good hostname denied: '.$h); $this->assertTrue(PHPMailer::isValidHost($h), 'Good hostname denied: ' . $h);
} }
foreach ($bad as $h) { foreach ($bad as $h) {
$this->assertFalse(PHPMailer::isValidHost($h), 'Bad hostname accepted: ' . var_export($h, true)); $this->assertFalse(PHPMailer::isValidHost($h), 'Bad hostname accepted: ' . var_export($h, true));
} }
} }
/** /**
* Tests the Custom header getter * Tests the Custom header getter.
*/ */
public function testCustomHeaderGetter() public function testCustomHeaderGetter()
{ {
@ -2121,7 +2135,7 @@ EOT;
$this->assertEquals( $this->assertEquals(
[ [
['foo', 'bar'], ['foo', 'bar'],
['foo', 'baz'] ['foo', 'baz'],
], ],
$this->Mail->getCustomHeaders() $this->Mail->getCustomHeaders()
); );
@ -2136,7 +2150,7 @@ EOT;
$this->assertEquals( $this->assertEquals(
[ [
['yux'], ['yux'],
['Content-Type', ' application/json'] ['Content-Type', ' application/json'],
], ],
$this->Mail->getCustomHeaders() $this->Mail->getCustomHeaders()
); );
@ -2272,8 +2286,7 @@ EOT;
} }
/** /**
* Use a fake POP3 server to test POP-before-SMTP auth. * Use a fake POP3 server to test POP-before-SMTP auth with a known-good login.
* With a known-good login
* *
* @group pop3 * @group pop3
*/ */
@ -2328,7 +2341,7 @@ EOT;
/** /**
* Test SMTP host connections. * Test SMTP host connections.
* This test can take a long time, so run it last * This test can take a long time, so run it last.
* *
* @group slow * @group slow
*/ */
@ -2337,14 +2350,14 @@ EOT;
$this->Mail->SMTPDebug = 4; //Show connection-level errors $this->Mail->SMTPDebug = 4; //Show connection-level errors
$this->assertTrue($this->Mail->smtpConnect(), 'SMTP single connect failed'); $this->assertTrue($this->Mail->smtpConnect(), 'SMTP single connect failed');
$this->Mail->smtpClose(); $this->Mail->smtpClose();
$this->Mail->Host = "localhost:12345;10.10.10.10:54321;" . $_REQUEST['mail_host']; $this->Mail->Host = 'localhost:12345;10.10.10.10:54321;' . $_REQUEST['mail_host'];
$this->assertTrue($this->Mail->smtpConnect(), 'SMTP multi-connect failed'); $this->assertTrue($this->Mail->smtpConnect(), 'SMTP multi-connect failed');
$this->Mail->smtpClose(); $this->Mail->smtpClose();
$this->Mail->Host = "[::1]:" . $this->Mail->Port . ';' . $_REQUEST['mail_host']; $this->Mail->Host = '[::1]:' . $this->Mail->Port . ';' . $_REQUEST['mail_host'];
$this->assertTrue($this->Mail->smtpConnect(), 'SMTP IPv6 literal multi-connect failed'); $this->assertTrue($this->Mail->smtpConnect(), 'SMTP IPv6 literal multi-connect failed');
$this->Mail->smtpClose(); $this->Mail->smtpClose();
//All these hosts are expected to fail //All these hosts are expected to fail
$this->Mail->Host = "xyz://bogus:25;tls://[bogus]:25;ssl://localhost:12345;tls://localhost:587;10.10.10.10:54321;localhost:12345;10.10.10.10"; $this->Mail->Host = 'xyz://bogus:25;tls://[bogus]:25;ssl://localhost:12345;tls://localhost:587;10.10.10.10:54321;localhost:12345;10.10.10.10';
$this->assertFalse($this->Mail->smtpConnect(), 'SMTP bad multi-connect succeeded'); $this->assertFalse($this->Mail->smtpConnect(), 'SMTP bad multi-connect succeeded');
$this->Mail->smtpClose(); $this->Mail->smtpClose();
$this->Mail->Host = ' localhost:12345 ; ' . $_REQUEST['mail_host'] . ' '; $this->Mail->Host = ' localhost:12345 ; ' . $_REQUEST['mail_host'] . ' ';
@ -2359,7 +2372,7 @@ EOT;
} }
} }
/** /*
* This is a sample form for setting appropriate test values through a browser * This is a sample form for setting appropriate test values through a browser
* These values can also be set using a file called testbootstrap.php (not in repo) in the same folder as this script * These values can also be set using a file called testbootstrap.php (not in repo) in the same folder as this script
* which is probably more useful if you run these tests a lot * which is probably more useful if you run these tests a lot

View File

@ -1,4 +1,5 @@
<?php <?php
$_REQUEST['submitted'] = 1; $_REQUEST['submitted'] = 1;
$_REQUEST['mail_to'] = 'somebody@example.com'; $_REQUEST['mail_to'] = 'somebody@example.com';
$_REQUEST['mail_from'] = 'phpunit@example.com'; $_REQUEST['mail_from'] = 'phpunit@example.com';