update v 1.0.7.5

This commit is contained in:
Sujit Prasad
2016-06-13 20:41:55 +05:30
parent aa9786d829
commit 283d97e3ea
5078 changed files with 339851 additions and 175995 deletions

View File

@@ -2,6 +2,5 @@ docs/phpdoc/
test/message.txt
test/testbootstrap.php
test/*.pem
.idea
build/
vendor/

View File

@@ -24,12 +24,12 @@ Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](h
## Why you might need it
Many PHP developers utilize email in their code. The only PHP function that supports this is the mail() function. However, it does not provide any assistance for making use of popular features such as HTML-based emails and attachments.
Many PHP developers utilize email in their code. The only PHP function that supports this is the `mail()` function. However, it does not provide any assistance for making use of popular features such as HTML-based emails and attachments.
Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules - the vast majority of code that you'll find online that uses the mail() function directly is just plain wrong!
Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules - the vast majority of code that you'll find online that uses the `mail()` function directly is just plain wrong!
*Please* don't be tempted to do it yourself - if you don't use PHPMailer, there are many other excellent libraries that you should look at before rolling your own - try SwiftMailer, Zend_Mail, eZcomponents etc.
The PHP mail() function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD and OS X platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server.
The PHP `mail()` function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD and OS X platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server.
## License
@@ -52,7 +52,7 @@ composer require phpmailer/phpmailer
If you want to use the Gmail XOAUTH2 authentication class, you will also need to add a dependency on the `league/oauth2-client` package.
Alternatively, copy the contents of the PHPMailer folder into somewhere that's in your PHP `include_path` setting. If you don't speak git or just want a tarball, click the 'zip' button at the top of the page in GitHub.
Alternatively, copy the contents of the PHPMailer folder into one of the `include_path` directories specified in your PHP configuration. If you don't speak git or just want a tarball, click the 'zip' button at the top of the page in GitHub.
If you're not using composer's autoloader, PHPMailer provides an SPL-compatible autoloader, and that is the preferred way of loading the library - just `require '/path/to/PHPMailerAutoload.php';` and everything should work. The autoloader does not throw errors if it can't find classes so it prepends itself to the SPL list, allowing your own (or your framework's) autoloader to catch errors. SPL autoloading was introduced in PHP 5.1.0, so if you are using a version older than that you will need to require/include each class manually.
@@ -62,7 +62,7 @@ If you want to use Google's XOAUTH2 authentication mechanism, you need to be run
### Minimal installation
While installing the entire package manually or with composer is simple, convenient and reliable, you may want to include only vital files in your project. At the very least you will need [class.phpmailer.php](class.phpmailer.php). If you're using SMTP, you'll need [class.smtp.php](class.smtp.php), and if you're using POP-before SMTP, you'll need [class.pop3.php](class.pop3.php). For all of these, we recommend you use [the autoloader](PHPMailerAutoload.php) too as otherwise you will either have to `require` all classes manually or use some other autoloader. You can skip the [language](language/) folder if you're not showing errors to users and can make do with English-only errors. You may need the additional classes in the [extras](extras/) folder if you are using those features, including NTLM authentication and ics generation. If you're using Google XOAUTH2 you will need `class.phpmaileroauth.php` and `class.oauth.php` classes too, as well as the composer dependencies.
While installing the entire package manually or with composer is simple, convenient and reliable, you may want to include only vital files in your project. At the very least you will need [class.phpmailer.php](https://github.com/PHPMailer/PHPMailer/tree/master/class.phpmailer.php). If you're using SMTP, you'll need [class.smtp.php](https://github.com/PHPMailer/PHPMailer/tree/master/class.smtp.php), and if you're using POP-before SMTP, you'll need [class.pop3.php](https://github.com/PHPMailer/PHPMailer/tree/master/class.pop3.php). For all of these, we recommend you use [the autoloader](https://github.com/PHPMailer/PHPMailer/tree/master/PHPMailerAutoload.php) too as otherwise you will either have to `require` all classes manually or use some other autoloader. You can skip the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder if you're not showing errors to users and can make do with English-only errors. You may need the additional classes in the [extras](extras/) folder if you are using those features, including NTLM authentication and ics generation. If you're using Google XOAUTH2 you will need `class.phpmaileroauth.php` and `class.oauth.php` classes too, as well as the composer dependencies.
## A Simple Example
@@ -105,35 +105,35 @@ if(!$mail->send()) {
}
```
You'll find plenty more to play with in the [examples](examples/) folder.
You'll find plenty more to play with in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder.
That's it. You should now be ready to use PHPMailer!
## Localization
PHPMailer defaults to English, but in the [language](language/) folder you'll find numerous (46 at the time of writing!) translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder you'll find numerous (46 at the time of writing!) translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
```php
// To load the French version
$mail->setLanguage('fr', '/optional/path/to/language/directory/');
```
We welcome corrections and new languages - if you're looking for corrections to do, run the [phpmailerLangTest.php](test/phpmailerLangTest.php) script in the tests folder and it will show any missing translations.
We welcome corrections and new languages - if you're looking for corrections to do, run the [phpmailerLangTest.php](https://github.com/PHPMailer/PHPMailer/tree/master/test/phpmailerLangTest.php) script in the tests folder and it will show any missing translations.
## Documentation
Examples of how to use PHPMailer for common scenarios can be found in the [examples](examples/) folder. If you're looking for a good starting point, we recommend you start with [the gmail example](examples/gmail.phps).
Examples of how to use PHPMailer for common scenarios can be found in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder. If you're looking for a good starting point, we recommend you start with [the Gmail example](https://github.com/PHPMailer/PHPMailer/tree/master/examples/gmail.phps).
There are tips and a troubleshooting guide in the [GitHub wiki](https://github.com/PHPMailer/PHPMailer/wiki). If you're having trouble, this should be the first place you look as it's the most frequently updated.
Complete generated API documentation is [available online](http://phpmailer.github.io/PHPMailer/).
You'll find some basic user-level docs in the [docs](docs/) folder, and you can generate complete API-level documentation using the [generatedocs.sh](docs/generatedocs.sh) shell script in the docs folder, though you'll need to install [PHPDocumentor](http://www.phpdoc.org) first. You may find [the unit tests](test/phpmailerTest.php) a good source of how to do various operations such as encryption.
You'll find some basic user-level docs in the [docs](docs/) folder, and you can generate complete API-level documentation using the [generatedocs.sh](https://github.com/PHPMailer/PHPMailer/tree/master/docs/generatedocs.sh) shell script in the docs folder, though you'll need to install [PHPDocumentor](http://www.phpdoc.org) first. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/tree/master/test/phpmailerTest.php) a good source of how to do various operations such as encryption.
If the documentation doesn't cover what you need, search the [many questions on StackOverflow](http://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting).
If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](http://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting).
## Tests
There is a PHPUnit test script in the [test](test/) folder.
There is a PHPUnit test script in the [test](https://github.com/PHPMailer/PHPMailer/tree/master/test/) folder.
Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](https://travis-ci.org/PHPMailer/PHPMailer)

View File

@@ -1 +1 @@
5.2.14
5.2.16

View File

@@ -1,5 +1,29 @@
# ChangeLog
## Version 5.2.16 (June 6th 2016)
* Added DKIM example
* Fixed empty additional_parameters problem
* Fixed wrong version number in VERSION file!
* Improve line-length tests
* Use instance settings for SMTP::connect by default
* Use more secure auth mechanisms first
## Version 5.2.15 (May 10th 2016)
* Added ability to inject custom address validators, and set the default validator
* Fix TLS 1.2 compatibility
* Remove some excess line breaks in MIME structure
* Updated Polish, Russian, Brazilian Portuguese, Georgian translations
* More DRY!
* Improve error messages
* Update dependencies
* Add example showing how to handle multiple form file uploads
* Improve SMTP example
* Improve Windows compatibility
* Use consistent names for temp files
* Fix gmail XOAUTH2 scope, thanks to @sherryl4george
* Fix extra line break in getSentMIMEMessage()
* Improve DKIM signing to use SHA-2
## Version 5.2.14 (Nov 1st 2015)
* Allow addresses with IDN (Internationalized Domain Name) in PHP 5.3+, thanks to @fbonzon
* Allow access to POP3 errors

View File

@@ -31,7 +31,7 @@ class PHPMailer
* The PHPMailer Version number.
* @var string
*/
public $Version = '5.2.14';
public $Version = '5.2.16';
/**
* Email priority.
@@ -285,7 +285,7 @@ class PHPMailer
/**
* SMTP auth type.
* Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5
* Options are CRAM-MD5, LOGIN, PLAIN, NTLM, XOAUTH2, attempted in that order if not specified
* @var string
*/
public $AuthType = '';
@@ -352,6 +352,7 @@ class PHPMailer
/**
* Whether to split multiple to addresses into multiple messages
* or send them all in one message.
* Only supported in `mail` and `sendmail` transports, not in SMTP.
* @var boolean
*/
public $SingleTo = false;
@@ -394,7 +395,7 @@ class PHPMailer
/**
* DKIM Identity.
* Usually the email address used as the source of the email
* Usually the email address used as the source of the email.
* @var string
*/
public $DKIM_identity = '';
@@ -446,6 +447,15 @@ class PHPMailer
*/
public $XMailer = '';
/**
* Which validator to use by default when validating email addresses.
* May be a callable to inject your own validator, but there are several built-in validators.
* @see PHPMailer::validateAddress()
* @var string|callable
* @static
*/
public static $validator = 'auto';
/**
* An instance of the SMTP sender class.
* @var SMTP
@@ -634,9 +644,11 @@ class PHPMailer
* Constructor.
* @param boolean $exceptions Should we throw external exceptions?
*/
public function __construct($exceptions = false)
public function __construct($exceptions = null)
{
$this->exceptions = (boolean)$exceptions;
if ($exceptions !== null) {
$this->exceptions = (boolean)$exceptions;
}
}
/**
@@ -645,9 +657,7 @@ class PHPMailer
public function __destruct()
{
//Close any open SMTP connection nicely
if ($this->Mailer == 'smtp') {
$this->smtpClose();
}
$this->smtpClose();
}
/**
@@ -671,7 +681,9 @@ class PHPMailer
} else {
$subject = $this->encodeHeader($this->secureHeader($subject));
}
if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
//Can't use additional_parameters in safe_mode
//@link http://php.net/manual/en/function.mail.php
if (ini_get('safe_mode') or !$this->UseSendmailOptions) {
$result = @mail($to, $subject, $body, $header);
} else {
$result = @mail($to, $subject, $body, $header, $params);
@@ -713,7 +725,7 @@ class PHPMailer
case 'echo':
default:
//Normalize line breaks
$str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
$str = preg_replace('/\r\n?/ms', "\n", $str);
echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
"\n",
"\n \t ",
@@ -850,7 +862,7 @@ class PHPMailer
$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
if (($pos = strrpos($address, '@')) === false) {
// At-sign is misssing.
$error_message = $this->lang('invalid_address') . $address;
$error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
@@ -900,7 +912,7 @@ class PHPMailer
return false;
}
if (!$this->validateAddress($address)) {
$error_message = $this->lang('invalid_address') . $address;
$error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
@@ -994,7 +1006,7 @@ class PHPMailer
if (($pos = strrpos($address, '@')) === false or
(!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and
!$this->validateAddress($address)) {
$error_message = $this->lang('invalid_address') . $address;
$error_message = $this->lang('invalid_address') . " (setFrom) $address";
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
@@ -1027,19 +1039,30 @@ class PHPMailer
/**
* Check that a string looks like an email address.
* @param string $address The email address to check
* @param string $patternselect A selector for the validation pattern to use :
* @param string|callable $patternselect A selector for the validation pattern to use :
* * `auto` Pick best pattern automatically;
* * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
* * `pcre` Use old PCRE implementation;
* * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
* * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
* * `noregex` Don't use a regex: super fast, really dumb.
* Alternatively you may pass in a callable to inject your own validator, for example:
* PHPMailer::validateAddress('user@example.com', function($address) {
* return (strpos($address, '@') !== false);
* });
* You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
* @return boolean
* @static
* @access public
*/
public static function validateAddress($address, $patternselect = 'auto')
public static function validateAddress($address, $patternselect = null)
{
if (is_null($patternselect)) {
$patternselect = self::$validator;
}
if (is_callable($patternselect)) {
return call_user_func($patternselect, $address);
}
//Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) {
return false;
@@ -1216,7 +1239,7 @@ class PHPMailer
}
$this->$address_kind = $this->punyencodeAddress($this->$address_kind);
if (!$this->validateAddress($this->$address_kind)) {
$error_message = $this->lang('invalid_address') . $this->$address_kind;
$error_message = $this->lang('invalid_address') . ' (punyEncode) ' . $this->$address_kind;
$this->setError($error_message);
$this->edebug($error_message);
if ($this->exceptions) {
@@ -1227,7 +1250,7 @@ class PHPMailer
}
// Set whether the message is multipart/alternative
if (!empty($this->AltBody)) {
if ($this->alternativeExists()) {
$this->ContentType = 'multipart/alternative';
}
@@ -1404,9 +1427,9 @@ class PHPMailer
}
$to = implode(', ', $toArr);
if (empty($this->Sender)) {
$params = ' ';
} else {
$params = null;
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
if (!empty($this->Sender)) {
$params = sprintf('-f%s', $this->Sender);
}
if ($this->Sender != '' and !ini_get('safe_mode')) {
@@ -1414,7 +1437,7 @@ class PHPMailer
ini_set('sendmail_from', $this->Sender);
}
$result = false;
if ($this->SingleTo && count($toArr) > 1) {
if ($this->SingleTo and count($toArr) > 1) {
foreach ($toArr as $toAddr) {
$result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
$this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
@@ -1520,12 +1543,17 @@ class PHPMailer
* @throws phpmailerException
* @return boolean
*/
public function smtpConnect($options = array())
public function smtpConnect($options = null)
{
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}
//If no options are provided, use whatever is set in the instance
if (is_null($options)) {
$options = $this->SMTPOptions;
}
// Already connected?
if ($this->smtp->connected()) {
return true;
@@ -1595,7 +1623,7 @@ class PHPMailer
if (!$this->smtp->startTLS()) {
throw new phpmailerException($this->lang('connect_host'));
}
// We must resend HELO after tls negotiation
// We must resend EHLO after TLS negotiation
$this->smtp->hello($hello);
}
if ($this->SMTPAuth) {
@@ -1634,7 +1662,7 @@ class PHPMailer
*/
public function smtpClose()
{
if ($this->smtp !== null) {
if (is_a($this->smtp, 'SMTP')) {
if ($this->smtp->connected()) {
$this->smtp->quit();
$this->smtp->close();
@@ -1972,7 +2000,7 @@ class PHPMailer
$result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
}
if ($this->MessageID != '') {
if ('' != $this->MessageID and preg_match('/^<.*@.*>$/', $this->MessageID)) {
$this->lastMessageID = $this->MessageID;
} else {
$this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname());
@@ -2074,7 +2102,7 @@ class PHPMailer
*/
public function getSentMIMEMessage()
{
return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
return rtrim($this->MIMEHeader . $this->mailHeader, "\n\r") . self::CRLF . self::CRLF . $this->MIMEBody;
}
/**
@@ -2104,12 +2132,12 @@ class PHPMailer
//Can we do a 7-bit downgrade?
if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
$bodyEncoding = '7bit';
//All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
$bodyCharSet = 'us-ascii';
}
//If lines are too long, and we're not already using an encoding that will shorten them,
//change to quoted-printable transfer encoding
//change to quoted-printable transfer encoding for the body part only
if ('base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) {
$this->Encoding = 'quoted-printable';
$bodyEncoding = 'quoted-printable';
}
@@ -2118,10 +2146,12 @@ class PHPMailer
//Can we do a 7-bit downgrade?
if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
$altBodyEncoding = '7bit';
//All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
$altBodyCharSet = 'us-ascii';
}
//If lines are too long, change to quoted-printable transfer encoding
if (self::hasLineLongerThanMax($this->AltBody)) {
//If lines are too long, and we're not already using an encoding that will shorten them,
//change to quoted-printable transfer encoding for the alt body part only
if ('base64' != $altBodyEncoding and self::hasLineLongerThanMax($this->AltBody)) {
$altBodyEncoding = 'quoted-printable';
}
//Use this as a preamble in all multipart message types
@@ -2224,8 +2254,10 @@ class PHPMailer
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
default:
// catch case 'plain' and case ''
$body .= $this->encodeString($this->Body, $bodyEncoding);
// Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types
//Reset the `Encoding` property in case we changed it for line length reasons
$this->Encoding = $bodyEncoding;
$body .= $this->encodeString($this->Body, $this->Encoding);
break;
}
@@ -2331,8 +2363,7 @@ class PHPMailer
/**
* Set the message type.
* PHPMailer only supports some preset message types,
* not arbitrary MIME structures.
* PHPMailer only supports some preset message types, not arbitrary MIME structures.
* @access protected
* @return void
*/
@@ -2350,6 +2381,7 @@ class PHPMailer
}
$this->message_type = implode('_', $type);
if ($this->message_type == '') {
//The 'plain' message_type refers to the message having a single body element, not that it is plain-text
$this->message_type = 'plain';
}
}
@@ -3296,7 +3328,7 @@ class PHPMailer
$message
);
}
} elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[A-z]+://#', $url)) {
} elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[a-z][a-z0-9+.-]*://#i', $url)) {
// Do not change urls for absolute images (thanks to corvuscorax)
// Do not change urls that are already inline images
$filename = basename($url);
@@ -3332,7 +3364,7 @@ class PHPMailer
// Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
$this->Body = $this->normalizeBreaks($message);
$this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
if (empty($this->AltBody)) {
if (!$this->alternativeExists()) {
$this->AltBody = 'To view this email message, open it in a program that understands HTML!' .
self::CRLF . self::CRLF;
}
@@ -3657,11 +3689,13 @@ class PHPMailer
if ($this->DKIM_passphrase != '') {
$privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
} else {
$privKey = $privKeyStr;
$privKey = openssl_pkey_get_private($privKeyStr);
}
if (openssl_sign($signHeader, $signature, $privKey)) {
if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) { //sha1WithRSAEncryption
openssl_pkey_free($privKey);
return base64_encode($signature);
}
openssl_pkey_free($privKey);
return '';
}
@@ -3678,7 +3712,7 @@ class PHPMailer
foreach ($lines as $key => $line) {
list($heading, $value) = explode(':', $line, 2);
$heading = strtolower($heading);
$value = preg_replace('/\s+/', ' ', $value); // Compress useless spaces
$value = preg_replace('/\s{2,}/', ' ', $value); // Compress useless spaces
$lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value
}
$signHeader = implode("\r\n", $lines);
@@ -3716,7 +3750,7 @@ class PHPMailer
*/
public function DKIM_Add($headers_line, $subject, $body)
{
$DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
$DKIMsignatureType = 'rsa-sha256'; // Signature & hash algorithms
$DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
$DKIMquery = 'dns/txt'; // Query method
$DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
@@ -3724,6 +3758,7 @@ class PHPMailer
$headers = explode($this->LE, $headers_line);
$from_header = '';
$to_header = '';
$date_header = '';
$current = '';
foreach ($headers as $header) {
if (strpos($header, 'From:') === 0) {
@@ -3732,6 +3767,9 @@ class PHPMailer
} elseif (strpos($header, 'To:') === 0) {
$to_header = $header;
$current = 'to_header';
} elseif (strpos($header, 'Date:') === 0) {
$date_header = $header;
$current = 'date_header';
} else {
if (!empty($$current) && strpos($header, ' =?') === 0) {
$$current .= $header;
@@ -3742,6 +3780,7 @@ class PHPMailer
}
$from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
$to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
$date = str_replace('|', '=7C', $this->DKIM_QP($date_header));
$subject = str_replace(
'|',
'=7C',
@@ -3749,7 +3788,7 @@ class PHPMailer
); // Copied header fields (dkim-quoted-printable)
$body = $this->DKIM_BodyC($body);
$DKIMlen = strlen($body); // Length of body
$DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1 hash of body
$DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body
if ('' == $this->DKIM_identity) {
$ident = '';
} else {
@@ -3762,16 +3801,18 @@ class PHPMailer
$this->DKIM_selector .
";\r\n" .
"\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" .
"\th=From:To:Subject;\r\n" .
"\th=From:To:Date:Subject;\r\n" .
"\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" .
"\tz=$from\r\n" .
"\t|$to\r\n" .
"\t|$date\r\n" .
"\t|$subject;\r\n" .
"\tbh=" . $DKIMb64 . ";\r\n" .
"\tb=";
$toSign = $this->DKIM_HeaderC(
$from_header . "\r\n" .
$to_header . "\r\n" .
$date_header . "\r\n" .
$subject_header . "\r\n" .
$dkimhdrs
);

View File

@@ -49,7 +49,8 @@ class PHPMailerOAuthGoogle
$this->oauthUserEmail = $UserEmail;
}
private function getProvider() {
private function getProvider()
{
return new League\OAuth2\Client\Provider\Google([
'clientId' => $this->oauthClientId,
'clientSecret' => $this->oauthClientSecret

View File

@@ -34,7 +34,7 @@ class POP3
* @var string
* @access public
*/
public $Version = '5.2.14';
public $Version = '5.2.16';
/**
* Default POP3 port number.

View File

@@ -30,7 +30,7 @@ class SMTP
* The PHPMailer SMTP version number.
* @var string
*/
const VERSION = '5.2.14';
const VERSION = '5.2.16';
/**
* SMTP line break constant.
@@ -81,7 +81,7 @@ class SMTP
* @deprecated Use the `VERSION` constant instead
* @see SMTP::VERSION
*/
public $Version = '5.2.14';
public $Version = '5.2.16';
/**
* SMTP server port number.
@@ -336,11 +336,22 @@ class SMTP
if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
return false;
}
//Allow the best TLS version(s) we can
$crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
//PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
//so add them back in manually if we can
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
}
// Begin encrypted connection
if (!stream_socket_enable_crypto(
$this->smtp_conn,
true,
STREAM_CRYPTO_METHOD_TLS_CLIENT
$crypto_method
)) {
return false;
}
@@ -389,7 +400,7 @@ class SMTP
);
if (empty($authtype)) {
foreach (array('LOGIN', 'CRAM-MD5', 'NTLM', 'PLAIN', 'XOAUTH2') as $method) {
foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN', 'NTLM', 'XOAUTH2') as $method) {
if (in_array($method, $this->server_caps['AUTH'])) {
$authtype = $method;
break;
@@ -736,7 +747,7 @@ class SMTP
protected function parseHelloFields($type)
{
$this->server_caps = array();
$lines = explode("\n", $this->last_reply);
$lines = explode("\n", $this->helo_rply);
foreach ($lines as $n => $s) {
//First 4 chars contain response code followed by - or space

View File

@@ -27,8 +27,7 @@
"phpunit/phpunit": "4.7.*"
},
"suggest": {
"league/oauth2-client": "Needed for XOAUTH2 authentication",
"league/oauth2-google": "Needed for Gmail XOAUTH2"
"league/oauth2-google": "Needed for Google XOAUTH2 authentication"
},
"autoload": {
"classmap": [

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
<?php
/**
* This example shows how to use DKIM message authentication with PHPMailer.
* There's more to using DKIM than just this code - check out this article:
* @link https://yomotherboard.com/how-to-setup-email-server-dkim-keys/
* See also the DKIM code in the PHPMailer unit tests,
* which shows how to make a key pair from PHP.
*/
require '../PHPMailerAutoload.php';
//Create a new PHPMailer instance
$mail = new PHPMailer;
//Set who the message is to be sent from
$mail->setFrom('from@example.com', 'First Last');
//Set an alternative reply-to address
$mail->addReplyTo('replyto@example.com', 'First Last');
//Set who the message is to be sent to
$mail->addAddress('whoto@example.com', 'John Doe');
//Set the subject line
$mail->Subject = 'PHPMailer DKIM test';
//This should be the same as the domain of your From address
$mail->DKIM_domain = 'example.com';
//Path to your private key file
$mail->DKIM_private = 'dkim_private.pem';
//Set this to your own selector
$mail->DKIM_selector = 'phpmailer';
//If your private key has a passphrase, set it here
$mail->DKIM_passphrase = '';
//The identity you're signing as - usually your From address
$mail->DKIM_identity = $mail->From;
//send the message, check for errors
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}

View File

@@ -12,7 +12,7 @@ if (array_key_exists('userfile', $_FILES)) {
// Upload handled successfully
// Now create a message
// This should be somewhere in your include_path
require 'PHPMailerAutoload.php';
require '../PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->setFrom('from@example.com', 'First Last');
$mail->addAddress('whoto@example.com', 'John Doe');
@@ -21,19 +21,19 @@ if (array_key_exists('userfile', $_FILES)) {
// Attach the uploaded file
$mail->addAttachment($uploadfile, 'My uploaded file');
if (!$mail->send()) {
$msg = "Mailer Error: " . $mail->ErrorInfo;
$msg .= "Mailer Error: " . $mail->ErrorInfo;
} else {
$msg = "Message sent!";
$msg .= "Message sent!";
}
} else {
$msg = 'Failed to move file to ' . $uploadfile;
$msg .= 'Failed to move file to ' . $uploadfile;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>PHPMailer Upload</title>
</head>
<body>

View File

@@ -0,0 +1,51 @@
<?php
/**
* PHPMailer multiple files upload and send example
*/
$msg = '';
if (array_key_exists('userfile', $_FILES)) {
// Create a message
// This should be somewhere in your include_path
require '../PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->setFrom('from@example.com', 'First Last');
$mail->addAddress('whoto@example.com', 'John Doe');
$mail->Subject = 'PHPMailer file sender';
$mail->msgHTML('My message body');
//Attach multiple files one by one
for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {
$uploadfile = tempnam(sys_get_temp_dir(), sha1($_FILES['userfile']['name'][$ct]));
$filename = $_FILES['userfile']['name'][$ct];
if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
$mail->addAttachment($uploadfile, $filename);
} else {
$msg .= 'Failed to move file to ' . $uploadfile;
}
}
if (!$mail->send()) {
$msg .= "Mailer Error: " . $mail->ErrorInfo;
} else {
$msg .= "Message sent!";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>PHPMailer Upload</title>
</head>
<body>
<?php if (empty($msg)) { ?>
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="100000">
Select one or more files:
<input name="userfile[]" type="file" multiple="multiple">
<input type="submit" value="Send Files">
</form>
<?php } else {
echo $msg;
} ?>
</body>
</html>

View File

@@ -17,24 +17,39 @@ $smtp = new SMTP;
$smtp->do_debug = SMTP::DEBUG_CONNECTION;
try {
//Connect to an SMTP server
if ($smtp->connect('mail.example.com', 25)) {
//Say hello
if ($smtp->hello('localhost')) { //Put your host name in here
//Authenticate
if ($smtp->authenticate('username', 'password')) {
echo "Connected ok!";
} else {
throw new Exception('Authentication failed: ' . $smtp->getLastReply());
}
} else {
throw new Exception('HELO failed: '. $smtp->getLastReply());
}
} else {
//Connect to an SMTP server
if (!$smtp->connect('mail.example.com', 25)) {
throw new Exception('Connect failed');
}
//Say hello
if (!$smtp->hello(gethostname())) {
throw new Exception('EHLO failed: ' . $smtp->getError()['error']);
}
//Get the list of ESMTP services the server offers
$e = $smtp->getServerExtList();
//If server can do TLS encryption, use it
if (array_key_exists('STARTTLS', $e)) {
$tlsok = $smtp->startTLS();
if (!$tlsok) {
throw new Exception('Failed to start encryption: ' . $smtp->getError()['error']);
}
//Repeat EHLO after STARTTLS
if (!$smtp->hello(gethostname())) {
throw new Exception('EHLO (2) failed: ' . $smtp->getError()['error']);
}
//Get new capabilities list, which will usually now include AUTH if it didn't before
$e = $smtp->getServerExtList();
}
//If server supports authentication, do it (even if no encryption)
if (array_key_exists('AUTH', $e)) {
if ($smtp->authenticate('username', 'password')) {
echo "Connected ok!";
} else {
throw new Exception('Authentication failed: ' . $smtp->getError()['error']);
}
}
} catch (Exception $e) {
echo 'SMTP error: '. $e->getMessage(), "\n";
echo 'SMTP error: ' . $e->getMessage(), "\n";
}
//Whatever happened, close the connection.
$smtp->quit(true);

View File

@@ -13,8 +13,15 @@
* PHP Version 5.4
*/
namespace League\OAuth2\Client\Provider;
require 'vendor/autoload.php';
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Token\AccessToken;
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
use Psr\Http\Message\ResponseInterface;
session_start();
//If this automatic URL doesn't work, set it yourself manually
@@ -25,14 +32,109 @@ $redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTT
$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';
$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';
class Google extends AbstractProvider
{
use BearerAuthorizationTrait;
const ACCESS_TOKEN_RESOURCE_OWNER_ID = 'id';
/**
* @var string If set, this will be sent to google as the "access_type" parameter.
* @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline
*/
protected $accessType;
/**
* @var string If set, this will be sent to google as the "hd" parameter.
* @link https://developers.google.com/accounts/docs/OAuth2Login#hd-param
*/
protected $hostedDomain;
/**
* @var string If set, this will be sent to google as the "scope" parameter.
* @link https://developers.google.com/gmail/api/auth/scopes
*/
protected $scope;
public function getBaseAuthorizationUrl()
{
return 'https://accounts.google.com/o/oauth2/auth';
}
public function getBaseAccessTokenUrl(array $params)
{
return 'https://accounts.google.com/o/oauth2/token';
}
public function getResourceOwnerDetailsUrl(AccessToken $token)
{
return ' ';
}
protected function getAuthorizationParameters(array $options)
{
if (is_array($this->scope)) {
$separator = $this->getScopeSeparator();
$this->scope = implode($separator, $this->scope);
}
$params = array_merge(
parent::getAuthorizationParameters($options),
array_filter([
'hd' => $this->hostedDomain,
'access_type' => $this->accessType,
'scope' => $this->scope,
// if the user is logged in with more than one account ask which one to use for the login!
'authuser' => '-1'
])
);
return $params;
}
protected function getDefaultScopes()
{
return [
'email',
'openid',
'profile',
];
}
protected function getScopeSeparator()
{
return ' ';
}
protected function checkResponse(ResponseInterface $response, $data)
{
if (!empty($data['error'])) {
$code = 0;
$error = $data['error'];
if (is_array($error)) {
$code = $error['code'];
$error = $error['message'];
}
throw new IdentityProviderException($error, $code, $data);
}
}
protected function createResourceOwner(array $response, AccessToken $token)
{
return new GoogleUser($response);
}
}
//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
$provider = new League\OAuth2\Client\Provider\Google(
$provider = new Google(
array(
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => $redirectUri,
'scopes' => array('https://mail.google.com/'),
'accessType' => 'offline'
'scope' => array('https://mail.google.com/'),
'accessType' => 'offline'
)
);

View File

@@ -23,4 +23,4 @@ $PHPMAILER_LANG['signing'] = 'ხელმოწერის შე
$PHPMAILER_LANG['smtp_connect_failed'] = 'შეცდომა SMTP სერვერთან დაკავშირებისას';
$PHPMAILER_LANG['smtp_error'] = 'SMTP სერვერის შეცდომა: ';
$PHPMAILER_LANG['variable_set'] = 'შეუძლებელია შემდეგი ცვლადის შექმნა ან შეცვლა: ';
//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
$PHPMAILER_LANG['extension_missing'] = 'ბიბლიოთეკა არ არსებობს: ';

View File

@@ -23,4 +23,4 @@ $PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() zakończone niepowodzeniem.';
$PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';
//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';

View File

@@ -18,9 +18,9 @@ $PHPMAILER_LANG['instantiate'] = 'Невозможно запустит
$PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.';
$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.';
$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: ';
$PHPMAILER_LANG['empty_message'] = 'Пустое тело сообщения';
$PHPMAILER_LANG['empty_message'] = 'Пустое сообщение';
$PHPMAILER_LANG['invalid_address'] = 'Не отослано, неправильный формат email адреса: ';
$PHPMAILER_LANG['signing'] = 'Ошибка подписывания: ';
$PHPMAILER_LANG['signing'] = 'Ошибка подписи: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером';
$PHPMAILER_LANG['smtp_error'] = 'Ошибка SMTP-сервера: ';
$PHPMAILER_LANG['variable_set'] = 'Невозможно установить или переустановить переменную: ';

View File

@@ -13,7 +13,7 @@
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
*/
require_once '../PHPMailerAutoload.php';
require_once realpath('../PHPMailerAutoload.php');
/**
* PHPMailer - PHP email transport unit test class
@@ -49,12 +49,6 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
*/
public $NoteLog = array();
/**
* Default include path
* @var string
*/
public $INCLUDE_DIR = '../';
/**
* PIDs of any processes we need to kill
* @var array
@@ -62,13 +56,19 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
*/
private $pids = array();
/**
* Default include path
* @var string
*/
const INCLUDE_DIR = '../';
/**
* Run before each test is started.
*/
public function setUp()
{
if (file_exists('./testbootstrap.php')) {
include './testbootstrap.php'; //Overrides go in here
if (file_exists('testbootstrap.php')) {
include 'testbootstrap.php'; //Overrides go in here
}
$this->Mail = new PHPMailer;
$this->Mail->SMTPDebug = 3; //Full debug output
@@ -100,7 +100,6 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
$this->Mail->SMTPAuth = false;
$this->Mail->Username = '';
$this->Mail->Password = '';
$this->Mail->PluginDir = $this->INCLUDE_DIR;
$this->Mail->addReplyTo('no_reply@phpmailer.example.com', 'Reply Guy');
$this->Mail->Sender = 'unit_test@phpmailer.example.com';
if (strlen($this->Mail->Host) > 0) {
@@ -300,7 +299,7 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
public function testBootstrap()
{
$this->assertTrue(
file_exists('./testbootstrap.php'),
file_exists('testbootstrap.php'),
'Test config params missing - copy testbootstrap.php to testbootstrap-dist.php and change as appropriate'
);
}
@@ -607,7 +606,9 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
'first.last@[IPv6:a1:a2:a3:a4:b1:b2:b3:]',
'first.last@[IPv6::a2:a3:a4:b1:b2:b3:b4]',
'first.last@[IPv6:a1:a2:a3:a4::b1:b2:b3:b4]',
"(\r\n RCPT TO:websec02@d.mbsd.jp\r\n DATA \\\nSubject: spam10\\\n\r\n Hello,\r\n this is a spam mail.\\\n.\r\n QUIT\r\n ) a@gmail.com" //This is valid RCC5322, but we don't want to allow it
//This is a valid RCC5322 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".
" this is a spam mail.\\\n.\r\n QUIT\r\n ) a@example.net"
);
// IDNs in Unicode and ASCII forms.
$unicodeaddresses = array(
@@ -658,6 +659,53 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
$this->assertFalse(PHPMailer::validateAddress('bad', 'noregex'));
}
/**
* Test injecting a custom validator.
*/
public function testCustomValidator()
{
//Inject a one-off custom validator
$this->assertTrue(
PHPMailer::validateAddress(
'user@example.com',
function ($address) {
return (strpos($address, '@') !== false);
}
),
'Custom validator false negative'
);
$this->assertFalse(
PHPMailer::validateAddress(
'userexample.com',
function ($address) {
return (strpos($address, '@') !== false);
}
),
'Custom validator false positive'
);
//Set the default validator to an injected function
PHPMailer::$validator = function ($address) {
return ('user@example.com' === $address);
};
$this->assertTrue(
$this->Mail->addAddress('user@example.com'),
'Custom default validator false negative'
);
$this->assertFalse(
//Need to pick a failing value which would pass all other validators
//to be sure we're using our custom one
$this->Mail->addAddress('bananas@example.com'),
'Custom default validator false positive'
);
//Set default validator to PHP built-in
PHPMailer::$validator = 'php';
$this->assertFalse(
//This is a valid address that FILTER_VALIDATE_EMAIL thinks is invalid
$this->Mail->addAddress('first.last@example.123'),
'PHP validator not behaving as expected'
);
}
/**
* Word-wrap an ASCII message.
*/
@@ -725,7 +773,7 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
$this->Mail->Body = 'Here is the text body';
$this->Mail->Subject .= ': Plain + Multiple FileAttachments';
if (!$this->Mail->addAttachment('../examples/images/phpmailer.png')) {
if (!$this->Mail->addAttachment(realpath(self::INCLUDE_DIR . 'examples/images/phpmailer.png'))) {
$this->assertTrue(false, $this->Mail->ErrorInfo);
return;
}
@@ -831,7 +879,7 @@ EOT;
//This file is in ISO-8859-1 charset
//Needs to be external because this file is in UTF-8
$content = file_get_contents('../examples/contents.html');
$content = file_get_contents(realpath('../examples/contents.html'));
// This is the string 'éèîüçÅñæß' in ISO-8859-1, base-64 encoded
$check = base64_decode('6eju/OfF8ebf');
//Make sure it really is in ISO-8859-1!
@@ -841,7 +889,7 @@ EOT;
"ISO-8859-1",
mb_detect_encoding($content, "UTF-8, ISO-8859-1, ISO-8859-15", true)
),
'../examples'
realpath(self::INCLUDE_DIR . 'examples')
);
$this->buildBody();
$this->assertTrue(
@@ -905,7 +953,7 @@ EOT;
</html>
EOT;
$this->Mail->addEmbeddedImage(
'../examples/images/phpmailer.png',
realpath(self::INCLUDE_DIR . 'examples/images/phpmailer.png'),
'my-attach',
'phpmailer.png',
'base64',
@@ -941,12 +989,12 @@ EOT;
*/
public function testMsgHTML()
{
$message = file_get_contents('../examples/contentsutf8.html');
$message = file_get_contents(realpath(self::INCLUDE_DIR . 'examples/contentsutf8.html'));
$this->Mail->CharSet = 'utf-8';
$this->Mail->Body = '';
$this->Mail->AltBody = '';
//Uses internal HTML to text conversion
$this->Mail->msgHTML($message, '../examples');
$this->Mail->msgHTML($message, realpath(self::INCLUDE_DIR . 'examples'));
$this->Mail->Subject .= ': msgHTML';
$this->assertNotEmpty($this->Mail->Body, 'Body not set by msgHTML');
@@ -955,7 +1003,7 @@ EOT;
//Again, using a custom HTML to text converter
$this->Mail->AltBody = '';
$this->Mail->msgHTML($message, '../examples', function ($html) {
$this->Mail->msgHTML($message, realpath(self::INCLUDE_DIR . 'examples'), function ($html) {
return strtoupper(strip_tags($html));
});
$this->Mail->Subject .= ' + custom html2text';
@@ -973,7 +1021,9 @@ EOT;
$this->Mail->Subject .= ': HTML + Attachment';
$this->Mail->isHTML(true);
if (!$this->Mail->addAttachment('../examples/images/phpmailer_mini.png', 'phpmailer_mini.png')) {
if (!$this->Mail->addAttachment(
realpath(self::INCLUDE_DIR . 'examples/images/phpmailer_mini.png'), 'phpmailer_mini.png')
) {
$this->assertTrue(false, $this->Mail->ErrorInfo);
return;
}
@@ -995,7 +1045,7 @@ EOT;
$this->Mail->isHTML(true);
if (!$this->Mail->addStringEmbeddedImage(
file_get_contents('../examples/images/phpmailer_mini.png'),
file_get_contents(realpath(self::INCLUDE_DIR . 'examples/images/phpmailer_mini.png')),
md5('phpmailer_mini.png').'@phpmailer.0',
'', //intentionally empty name
'base64',
@@ -1019,12 +1069,12 @@ EOT;
$this->Mail->Subject .= ': HTML + multiple Attachment';
$this->Mail->isHTML(true);
if (!$this->Mail->addAttachment('../examples/images/phpmailer_mini.png', 'phpmailer_mini.png')) {
if (!$this->Mail->addAttachment(realpath(self::INCLUDE_DIR . 'examples/images/phpmailer_mini.png'), 'phpmailer_mini.png')) {
$this->assertTrue(false, $this->Mail->ErrorInfo);
return;
}
if (!$this->Mail->addAttachment('../examples/images/phpmailer.png', 'phpmailer.png')) {
if (!$this->Mail->addAttachment(realpath(self::INCLUDE_DIR . 'examples/images/phpmailer.png'), 'phpmailer.png')) {
$this->assertTrue(false, $this->Mail->ErrorInfo);
return;
}
@@ -1044,7 +1094,7 @@ EOT;
$this->Mail->isHTML(true);
if (!$this->Mail->addEmbeddedImage(
'../examples/images/phpmailer.png',
realpath(self::INCLUDE_DIR . 'examples/images/phpmailer.png'),
'my-attach',
'phpmailer.png',
'base64',
@@ -1073,7 +1123,7 @@ EOT;
$this->Mail->isHTML(true);
if (!$this->Mail->addEmbeddedImage(
'../examples/images/phpmailer.png',
realpath(self::INCLUDE_DIR . 'examples/images/phpmailer.png'),
'my-attach',
'phpmailer.png',
'base64',
@@ -1127,11 +1177,6 @@ EOT;
$this->buildBody();
$this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
if (is_writable('.')) {
file_put_contents('message.txt', $this->Mail->createHeader() . $this->Mail->createBody());
} else {
$this->assertTrue(false, 'Could not write local file - check permissions');
}
}
/**
@@ -1140,7 +1185,7 @@ EOT;
public function testIcal()
{
//Standalone ICS tests
require_once '../extras/EasyPeasyICS.php';
require_once realpath(self::INCLUDE_DIR . 'extras/EasyPeasyICS.php');
$ICS = new EasyPeasyICS("PHPMailer test calendar");
$this->assertNotEmpty(
$ICS->addEvent(
@@ -1266,20 +1311,22 @@ EOT;
}
/**
* Test constructing a message that contains lines that are too long for RFC compliance.
* Test constructing a multipart message that contains lines that are too long for RFC compliance.
*/
public function testLongBody()
{
$oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::CRLF, 10);
$oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::CRLF, 2);
$badlen = str_repeat(str_repeat('1', PHPMailer::MAX_LINE_LENGTH + 1) . PHPMailer::CRLF, 2);
$this->Mail->Body = "This message contains lines that are too long.".
PHPMailer::CRLF . PHPMailer::CRLF . $oklen . $badlen . $oklen;
PHPMailer::CRLF . $oklen . $badlen . $oklen;
$this->assertTrue(
PHPMailer::hasLineLongerThanMax($this->Mail->Body),
'Test content does not contain long lines!'
);
$this->Mail->isHTML();
$this->buildBody();
$this->Mail->AltBody = $this->Mail->Body;
$this->Mail->Encoding = '8bit';
$this->Mail->preSend();
$message = $this->Mail->getSentMIMEMessage();
@@ -1299,7 +1346,7 @@ EOT;
$oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::CRLF, 10);
$this->Mail->Body = "This message does not contain lines that are too long.".
PHPMailer::CRLF . PHPMailer::CRLF . $oklen;
PHPMailer::CRLF . $oklen;
$this->assertFalse(
PHPMailer::hasLineLongerThanMax($this->Mail->Body),
'Test content contains long lines!'
@@ -1421,6 +1468,19 @@ EOT;
),
'Failed to recognise address list (IMAP parser)'
);
$this->assertEquals(
array(
array("name" => 'Joe User', 'address' => 'joe@example.com'),
array("name" => 'Jill User', 'address' => 'jill@example.net'),
array("name" => '', 'address' => 'frank@example.com'),
),
$this->Mail->parseAddresses(
'Joe User <joe@example.com>,'
. 'Jill User <jill@example.net>,'
. 'frank@example.com,'
),
'Parsed addresses'
);
//Test simple address parser
$this->assertCount(
2,
@@ -1507,6 +1567,24 @@ EOT;
$this->assertTrue((strpos($b, 'To: "Tim \"The Book\" O\'Reilly" <foo@example.com>') !== false));
}
/**
* Test MIME structure assembly.
*/
public function testMIMEStructure()
{
$this->Mail->Subject .= ': MIME structure';
$this->Mail->Body = '<h3>MIME structure test.</h3>';
$this->Mail->AltBody = 'MIME structure test.';
$this->buildBody();
$this->Mail->preSend();
$this->assertRegExp(
"/Content-Transfer-Encoding: 8bit\r\n\r\n".
"This is a multi-part message in MIME format./",
$this->Mail->getSentMIMEMessage(),
'MIME structure broken'
);
}
/**
* Test BCC-only addressing.
*/
@@ -1589,8 +1667,8 @@ EOT;
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$password = 'password';
$certfile = 'certfile.txt';
$keyfile = 'keyfile.txt';
$certfile = 'certfile.pem';
$keyfile = 'keyfile.pem';
//Make a new key pair
$pk = openssl_pkey_new($keyconfig);
@@ -1750,7 +1828,7 @@ EOT;
*/
public function testLineLength()
{
$oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH)."\r\n", 10);
$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);
$this->assertTrue(PHPMailer::hasLineLongerThanMax($badlen), 'Long line not detected (only)');
$this->assertTrue(PHPMailer::hasLineLongerThanMax($oklen . $badlen), 'Long line not detected (first)');
@@ -1781,7 +1859,18 @@ EOT;
$this->buildBody();
$this->Mail->preSend();
$lastid = $this->Mail->getLastMessageID();
$this->assertEquals($lastid, $id, 'Custom Message ID mismatch');
$this->assertNotEquals($lastid, $id, 'Invalid Message ID allowed');
$id = '<'.md5(12345).'@example.com>';
$this->Mail->MessageID = $id;
$this->buildBody();
$this->Mail->preSend();
$lastid = $this->Mail->getLastMessageID();
$this->assertEquals($lastid, $id, 'Custom Message ID not used');
$this->Mail->MessageID = '';
$this->buildBody();
$this->Mail->preSend();
$lastid = $this->Mail->getLastMessageID();
$this->assertRegExp('/^<.*@.*>$/', $lastid, 'Invalid default Message ID');
}
/**
@@ -2003,8 +2092,8 @@ EOT;
}
/**
* Use a fake POP3 server to test POP-before-SMTP auth.
* With a known-bad login
* Use a fake POP3 server to test POP-before-SMTP auth
* with a known-bad login.
*/
public function testPopBeforeSmtpBad()
{