diff --git a/action.php b/action.php index d206954..52a184f 100644 --- a/action.php +++ b/action.php @@ -55,7 +55,8 @@ public function handle_mail_message_send(Doku_Event &$event, $param) { $smtp->setServer( $this->getConf('smtp_host'), $this->getConf('smtp_port'), - $this->getConf('smtp_ssl') + $this->getConf('smtp_ssl'), + $this->getConf('smtp_ssl_allow_insecure') ); if($this->getConf('auth_user')){ $smtp->setAuth( diff --git a/classes/Message.php b/classes/Message.php index 278aff5..62d3c6a 100644 --- a/classes/Message.php +++ b/classes/Message.php @@ -41,7 +41,7 @@ public function getFromEmail() { } /** - * Get a list of all recipients (mail only part) + * Get a list of all recipients (array of email => name, name is omitted) * * @return array */ @@ -51,16 +51,19 @@ public function getTo() { // We need the mail only part of all recipients $addresses = explode(',', $this->rcpt); foreach($addresses as $addr) { - // parse address + // Parse address + $parsedAddr = ''; if(preg_match('#(.*?)<(.*?)>#', $addr, $matches)) { - $rcpt[] = trim($matches[2]); + $parsedAddr = trim($matches[2]); } else { - $rcpt[] = trim($addr); + $parsedAddr = trim($addr); + } + // Insert only non-empty address + if (!empty($parsedAddr)) { + $rcpt[$parsedAddr] = ''; } } - $rcpt = array_filter($rcpt); - $rcpt = array_unique($rcpt); return $rcpt; } diff --git a/conf/default.php b/conf/default.php index 165475c..748aae4 100644 --- a/conf/default.php +++ b/conf/default.php @@ -3,6 +3,7 @@ $conf['smtp_host'] = 'localhost'; $conf['smtp_port'] = 25; $conf['smtp_ssl'] = ''; +$conf['smtp_ssl_allow_insecure'] = 0; $conf['localdomain'] = ''; diff --git a/conf/metadata.php b/conf/metadata.php index 884f908..2e1efa5 100644 --- a/conf/metadata.php +++ b/conf/metadata.php @@ -3,6 +3,7 @@ $meta['smtp_host'] = array('string'); $meta['smtp_port'] = array('numeric'); $meta['smtp_ssl'] = array('multichoice','_choices' => array('','ssl','tls')); +$meta['smtp_ssl_allow_insecure'] = array('onoff'); $meta['auth_user'] = array('string'); $meta['auth_pass'] = array('password'); diff --git a/lang/en/settings.php b/lang/en/settings.php index 9042c43..d787f20 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -8,6 +8,8 @@ $lang['smtp_ssl_o_ssl'] = 'SSL'; $lang['smtp_ssl_o_tls'] = 'TLS'; +$lang['smtp_ssl_allow_insecure'] = 'Allow insecure SSL'; + $lang['auth_user'] = 'If authentication is required, put your user name here.'; $lang['auth_pass'] = 'Password for the above user.'; diff --git a/lang/zh/settings.php b/lang/zh/settings.php index ac9ce47..8af64b0 100644 --- a/lang/zh/settings.php +++ b/lang/zh/settings.php @@ -8,6 +8,8 @@ $lang['smtp_ssl_o_ssl'] = 'SSL'; $lang['smtp_ssl_o_tls'] = 'TLS'; +$lang['smtp_ssl_allow_insecure'] = '允许不安全的SSL'; + $lang['auth_user'] = '如果需要认证,在这里输入您的用户名。'; $lang['auth_pass'] = '对应上面用户名的密码。'; diff --git a/subtree/txtthinking/Mailer/.gitattributes b/subtree/txtthinking/Mailer/.gitattributes new file mode 100644 index 0000000..7769b44 --- /dev/null +++ b/subtree/txtthinking/Mailer/.gitattributes @@ -0,0 +1,8 @@ +* text=auto + +/tests export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/phpunit.xml.dist export-ignore +/README.md export-ignore diff --git a/subtree/txtthinking/Mailer/.gitignore b/subtree/txtthinking/Mailer/.gitignore index c70cc03..96e828d 100644 --- a/subtree/txtthinking/Mailer/.gitignore +++ b/subtree/txtthinking/Mailer/.gitignore @@ -2,3 +2,4 @@ vendor/ composer.lock .idea/ docs/ +phpunit.xml diff --git a/subtree/txtthinking/Mailer/.travis.yml b/subtree/txtthinking/Mailer/.travis.yml new file mode 100644 index 0000000..b174b06 --- /dev/null +++ b/subtree/txtthinking/Mailer/.travis.yml @@ -0,0 +1,11 @@ +language: php +sudo: false +php: + - "7.4" + - "7.3" + - "7.2" + - "7.1" + - "7.0" + - "5.6" +install: composer update +script: ./vendor/bin/phpunit --verbose diff --git a/subtree/txtthinking/Mailer/README.md b/subtree/txtthinking/Mailer/README.md index 682535f..3de0a29 100644 --- a/subtree/txtthinking/Mailer/README.md +++ b/subtree/txtthinking/Mailer/README.md @@ -7,6 +7,8 @@ A lightweight SMTP mail sender ``` $ composer require txthinking/mailer +# or +$ composer require txthinking/mailer:dev-master ``` ### Usage @@ -16,36 +18,16 @@ $ composer require txthinking/mailer use Tx\Mailer; $ok = (new Mailer()) - ->setServer('smtp.ym.163.com', 25) - ->setAuth('', '') // email, password - ->setFrom('You', '') //your name, your email - ->setFakeFrom('heelo', 'bot@fake.com') // if u want, a fake name, a fake email - ->addTo('Cloud', 'cloud@txthinking.com') - ->setSubject('Test Mailer') - ->setBody('Hi, I love you.') + ->setServer('smtp.server.com', 25) + ->setAuth('tom@server.com', 'password') + ->setFrom('Tom', 'tom@server.com') + ->setFakeFrom('Obama', 'fake@address.com') // if u want, a fake name, a fake email + ->addTo('Jerry', 'jerry@server.com') + ->setSubject('Hello') + ->setBody('Hi, Jerry! I love you.') ->addAttachment('host', '/etc/hosts') ->send(); var_dump($ok); ``` -OR -``` -setServer('smtp.ym.163.com', 25) - ->setAuth('bot@ym.txthinking.com', ''); // email, password +More [Example](https://github.com/txthinking/Mailer/tree/master/tests) -$message = new Message(); -$message->setFrom('Tom', 'your@mail.com') // your name, your email - ->setFakeFrom('heelo', 'bot@fake.com') // if u want, a fake name, a fake email - ->addTo('Cloud', 'cloud@txthinking.com') - ->setSubject('Test Mailer') - ->setBody('

For test

') - ->addAttachment('host', '/etc/hosts'); - -$ok = $smtp->send($message); -var_dump($ok); -``` diff --git a/subtree/txtthinking/Mailer/composer.json b/subtree/txtthinking/Mailer/composer.json index 34390bb..e3620d2 100644 --- a/subtree/txtthinking/Mailer/composer.json +++ b/subtree/txtthinking/Mailer/composer.json @@ -22,8 +22,7 @@ "psr/log": "~1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0", - "erb/testing-tools": "dev-master", + "phpunit/phpunit": "~5.0", "monolog/monolog": "~1.13" }, "autoload": { diff --git a/subtree/txtthinking/Mailer/composer.lock b/subtree/txtthinking/Mailer/composer.lock deleted file mode 100644 index 348633c..0000000 --- a/subtree/txtthinking/Mailer/composer.lock +++ /dev/null @@ -1,1127 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "0d4b12d16d8fbbdb98ed9f74ecdf6d4e", - "packages": [ - { - "name": "psr/log", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Psr\\Log\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2012-12-21 11:40:51" - } - ], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14 21:17:01" - }, - { - "name": "erb/testing-tools", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://bitbucket.org/erblearn/testing-tools.git", - "reference": "a898dc79b91c73a6fee7005e4189451d7a4235cc" - }, - "dist": { - "type": "zip", - "url": "https://bitbucket.org/erblearn/testing-tools/get/a898dc79b91c73a6fee7005e4189451d7a4235cc.zip", - "reference": "a898dc79b91c73a6fee7005e4189451d7a4235cc", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "ERB\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Sowers", - "email": "msowers@erblearn.org" - } - ], - "description": "Tools to make it easier to retrieve data from classes via Reflection.", - "homepage": "https://bitbucket.org/erblearn/testing-tools", - "keywords": [ - "reflection", - "testing", - "useful tools" - ], - "time": "2015-04-06 16:00:22" - }, - { - "name": "monolog/monolog", - "version": "1.15.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "dc5150cc608f2334c72c3b6a553ec9668a4156b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/dc5150cc608f2334c72c3b6a553ec9668a4156b0", - "reference": "dc5150cc608f2334c72c3b6a553ec9668a4156b0", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "psr/log": "~1.0" - }, - "provide": { - "psr/log-implementation": "1.0.0" - }, - "require-dev": { - "aws/aws-sdk-php": "^2.4.9", - "doctrine/couchdb": "~1.0@dev", - "graylog2/gelf-php": "~1.0", - "php-console/php-console": "^3.1.3", - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "2.3.0", - "raven/raven": "~0.8", - "ruflin/elastica": ">=0.90 <3.0", - "swiftmailer/swiftmailer": "~5.3", - "videlalvaro/php-amqplib": "~2.4" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-mongo": "Allow sending log messages to a MongoDB server", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "php-console/php-console": "Allow sending log messages to Google Chrome", - "raven/raven": "Allow sending log messages to a Sentry server", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server", - "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15.x-dev" - } - }, - "autoload": { - "psr-4": { - "Monolog\\": "src/Monolog" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "time": "2015-07-12 13:54:09" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2015-02-03 12:10:50" - }, - { - "name": "phpspec/prophecy", - "version": "v1.4.1", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", - "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" - }, - "require-dev": { - "phpspec/phpspec": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2015-04-27 22:15:08" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.1.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "5bd48b86cd282da411bb80baac1398ce3fefac41" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5bd48b86cd282da411bb80baac1398ce3fefac41", - "reference": "5bd48b86cd282da411bb80baac1398ce3fefac41", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "~1.0", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2015-07-26 12:54:47" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2015-06-21 13:08:43" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21 13:50:34" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2015-06-21 08:01:12" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.4.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/7a9b0969488c3c54fd62b4d504b3ec758fd005d9", - "reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2015-06-19 03:43:16" - }, - { - "name": "phpunit/phpunit", - "version": "4.7.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "9b97f9d807b862c2de2a36e86690000801c85724" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b97f9d807b862c2de2a36e86690000801c85724", - "reference": "9b97f9d807b862c2de2a36e86690000801c85724", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "~1.3,>=1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": ">=1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.2", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.7.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2015-07-13 11:28:34" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/18dfbcb81d05e2296c0bcddd4db96cade75e6f42", - "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "~1.0,>=1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2015-07-10 06:54:24" - }, - { - "name": "sebastian/comparator", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2015-07-26 15:48:44" - }, - { - "name": "sebastian/diff", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2015-02-22 15:13:53" - }, - { - "name": "sebastian/environment", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4fe0a44cddd8cc19583a024bdc7374eb2fef0b87", - "reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2015-07-26 06:42:57" - }, - { - "name": "sebastian/exporter", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2015-06-21 07:55:53" - }, - { - "name": "sebastian/global-state", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2014-10-06 09:23:50" - }, - { - "name": "sebastian/recursion-context", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-06-21 08:04:50" - }, - { - "name": "sebastian/version", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21 13:59:46" - }, - { - "name": "symfony/yaml", - "version": "v2.7.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/4bfbe0ed3909bfddd75b70c094391ec1f142f860", - "reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "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 Yaml Component", - "homepage": "https://symfony.com", - "time": "2015-07-01 11:25:50" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "erb/testing-tools": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.3.2" - }, - "platform-dev": [] -} diff --git a/subtree/txtthinking/Mailer/phpunit.xml b/subtree/txtthinking/Mailer/phpunit.xml.dist similarity index 100% rename from subtree/txtthinking/Mailer/phpunit.xml rename to subtree/txtthinking/Mailer/phpunit.xml.dist diff --git a/subtree/txtthinking/Mailer/src/Mailer.php b/subtree/txtthinking/Mailer/src/Mailer.php index 9226041..eab1b6d 100644 --- a/subtree/txtthinking/Mailer/src/Mailer.php +++ b/subtree/txtthinking/Mailer/src/Mailer.php @@ -1,4 +1,4 @@ -smtp = new SMTP($logger); $this->message = new Message(); } @@ -54,10 +58,11 @@ public function __construct(LoggerInterface $logger=null){ * set server and port * @param string $host server * @param int $port port - * @param string $secure ssl tls + * @param string $secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2 * @return $this */ - public function setServer($host, $port, $secure=null){ + public function setServer($host, $port, $secure=null) + { $this->smtp->setServer($host, $port, $secure); return $this; } @@ -68,18 +73,31 @@ public function setServer($host, $port, $secure=null){ * @param string $password * @return $this */ - public function setAuth($username, $password){ + public function setAuth($username, $password) + { $this->smtp->setAuth($username, $password); return $this; } + /** + * auth oauthbearer with server + * @param string $accessToken + * @return $this + */ + public function setOAuth($accessToken) + { + $this->smtp->setOAuth($accessToken); + return $this; + } + /** * set mail from * @param string $name * @param string $email * @return $this */ - public function setFrom($name, $email){ + public function setFrom($name, $email) + { $this->message->setFrom($name, $email); return $this; } @@ -90,30 +108,45 @@ public function setFrom($name, $email){ * @param string $email * @return $this */ - public function setFakeFrom($name, $email){ + public function setFakeFrom($name, $email) + { $this->message->setFakeFrom($name, $email); return $this; } /** - * set mail receiver + * add mail receiver * @param string $name * @param string $email * @return $this */ - public function setTo($name, $email){ + public function addTo($name, $email) + { $this->message->addTo($name, $email); return $this; } /** - * add mail receiver + * add cc mail receiver * @param string $name * @param string $email * @return $this */ - public function addTo($name, $email){ - $this->message->addTo($name, $email); + public function addCc($name, $email) + { + $this->message->addCc($name, $email); + return $this; + } + + /** + * add bcc mail receiver + * @param string $name + * @param string $email + * @return $this + */ + public function addBcc($name, $email) + { + $this->message->addBcc($name, $email); return $this; } @@ -122,7 +155,8 @@ public function addTo($name, $email){ * @param string $subject * @return $this */ - public function setSubject($subject){ + public function setSubject($subject) + { $this->message->setSubject($subject); return $this; } @@ -132,32 +166,33 @@ public function setSubject($subject){ * @param string $body * @return $this */ - public function setBody($body){ + public function setBody($body) + { $this->message->setBody($body); return $this; } /** - * set mail attachment + * add mail attachment * @param $name * @param $path * @return $this - * @internal param string $attachment */ - public function setAttachment($name, $path){ + public function addAttachment($name, $path) + { $this->message->addAttachment($name, $path); return $this; } /** - * add mail attachment - * @param $name - * @param $path + * set mail reply-to + * @param string $name + * @param string $email * @return $this - * @internal param string $attachment */ - public function addAttachment($name, $path){ - $this->message->addAttachment($name, $path); + public function setReplyTo($name, $email) + { + $this->message->setReplyTo($name, $email); return $this; } @@ -165,7 +200,8 @@ public function addAttachment($name, $path){ * Send the message... * @return boolean */ - public function send(){ + public function send() + { return $this->smtp->send($this->message); } diff --git a/subtree/txtthinking/Mailer/src/Mailer/Message.php b/subtree/txtthinking/Mailer/src/Mailer/Message.php index 379c458..7215f88 100644 --- a/subtree/txtthinking/Mailer/src/Mailer/Message.php +++ b/subtree/txtthinking/Mailer/src/Mailer/Message.php @@ -1,4 +1,4 @@ -replyToName = $name; + $this->replyToEmail = $email; + return $this; + } + + /** * set mail from * @param string $name @@ -112,55 +146,60 @@ public function setFakeFrom($name, $email) } /** - * set mail receiver + * add mail receiver * @param string $name * @param string $email * @return $this */ - public function setTo($name, $email){ - $this->to[$name] = $email; + public function addTo($name, $email) + { + $this->to[$email] = $name; return $this; } /** - * add mail receiver + * add cc mail receiver * @param string $name * @param string $email * @return $this */ - public function addTo($name, $email){ - $this->to[$name] = $email; + public function addCc($name, $email) + { + $this->cc[$email] = $name; return $this; } /** - * set mail subject - * @param string $subject + * add bcc mail receiver + * @param string $name + * @param string $email * @return $this */ - public function setSubject($subject){ - $this->subject = $subject; + public function addBcc($name, $email) + { + $this->bcc[$email] = $name; return $this; } /** - * set mail body - * @param string $body + * set mail subject + * @param string $subject * @return $this */ - public function setBody($body){ - $this->body = $body; + public function setSubject($subject) + { + $this->subject = $subject; return $this; } /** - * add mail attachment - * @param $name - * @param $path + * set mail body + * @param string $body * @return $this */ - public function setAttachment($name, $path){ - $this->attachment[$name] = $path; + public function setBody($body) + { + $this->body = $body; return $this; } @@ -170,7 +209,8 @@ public function setAttachment($name, $path){ * @param $path * @return $this */ - public function addAttachment($name, $path){ + public function addAttachment($name, $path) + { $this->attachment[$name] = $path; return $this; } @@ -216,6 +256,22 @@ public function getTo() return $this->to; } + /** + * @return mixed + */ + public function getCc() + { + return $this->cc; + } + + /** + * @return mixed + */ + public function getBcc() + { + return $this->bcc; + } + /** * @return mixed */ @@ -244,24 +300,65 @@ public function getAttachment() * Create mail header * @return $this */ - protected function createHeader(){ + protected function createHeader() + { $this->header['Date'] = date('r'); + $fromName = ""; + $fromEmail = $this->fromEmail; + if(!empty($this->fromName)){ + $fromName = sprintf("=?utf-8?B?%s?= ", base64_encode($this->fromName)); + } if(!empty($this->fakeFromEmail)){ - $this->header['Return-Path'] = $this->fakeFromEmail; - $this->header['From'] = $this->fakeFromName . " <" . $this->fakeFromEmail . ">"; - } else{ - $this->header['Return-Path'] = $this->fromEmail; - $this->header['From'] = $this->fromName . " <" . $this->fromEmail .">"; + if(!empty($this->fakeFromName)){ + $fromName = sprintf("=?utf-8?B?%s?= ", base64_encode($this->fakeFromName)); + } + $fromEmail = $this->fakeFromEmail; } + $this->header['Return-Path'] = $fromEmail; + $this->header['From'] = $fromName . "<" . $fromEmail .">"; $this->header['To'] = ''; - foreach ($this->to as $toName => $toEmail) { - $this->header['To'] .= $toName . " <" . $toEmail . ">, "; + foreach ($this->to as $toEmail => $toName) { + if(!empty($toName)){ + $toName = sprintf("=?utf-8?B?%s?= ", base64_encode($toName)); + } + $this->header['To'] .= $toName . "<" . $toEmail . ">, "; } $this->header['To'] = substr($this->header['To'], 0, -2); - $this->header['Subject'] = $this->subject; - $this->header['Message-ID'] = '<' . md5('TX'.md5(time()).uniqid()) . '@' . $this->fromEmail . '>'; + $this->header['Cc'] = ''; + foreach ($this->cc as $toEmail => $toName) { + if(!empty($toName)){ + $toName = sprintf("=?utf-8?B?%s?= ", base64_encode($toName)); + } + $this->header['Cc'] .= $toName . "<" . $toEmail . ">, "; + } + $this->header['Cc'] = substr($this->header['Cc'], 0, -2); + $this->header['Bcc'] = ''; + foreach ($this->bcc as $toEmail => $toName) { + if(!empty($toName)){ + $toName = sprintf("=?utf-8?B?%s?= ", base64_encode($toName)); + } + $this->header['Bcc'] .= $toName . "<" . $toEmail . ">, "; + } + $this->header['Bcc'] = substr($this->header['Bcc'], 0, -2); + + $replyToName = ""; + if(!empty($this->replyToEmail)){ + if(!empty($this->replyToName)){ + $replyToName = sprintf("=?utf-8?B?%s?= ", base64_encode($this->replyToName)); + } + $this->header['Reply-To'] = $replyToName . "<" . $this->replyToEmail . ">"; + } + + if(empty($this->subject)){ + $subject = ''; + }else{ + $subject = sprintf("=?utf-8?B?%s?= ", base64_encode($this->subject)); + } + $this->header['Subject'] = $subject; + + $this->header['Message-ID'] = '<' . md5(uniqid()) . '@' . $this->fromEmail . '>'; $this->header['X-Priority'] = '3'; $this->header['X-Mailer'] = 'Mailer (https://github.com/txthinking/Mailer)'; $this->header['MIME-Version'] = '1.0'; @@ -278,7 +375,8 @@ protected function createHeader(){ * * @return string */ - protected function createBody(){ + protected function createBody() + { $in = ""; $in .= "Content-Type: multipart/alternative; boundary=\"$this->boundaryAlternative\"" . $this->CRLF; $in .= $this->CRLF; @@ -303,7 +401,8 @@ protected function createBody(){ * * @return string */ - protected function createBodyWithAttachment(){ + protected function createBodyWithAttachment() + { $in = ""; $in .= $this->CRLF; $in .= $this->CRLF; @@ -338,7 +437,8 @@ protected function createBodyWithAttachment(){ return $in; } - public function toString(){ + public function toString() + { $in = ''; $this->createHeader(); foreach ($this->header as $key => $value) { diff --git a/subtree/txtthinking/Mailer/src/Mailer/SMTP.php b/subtree/txtthinking/Mailer/src/Mailer/SMTP.php index e4347af..9ed80ef 100644 --- a/subtree/txtthinking/Mailer/src/Mailer/SMTP.php +++ b/subtree/txtthinking/Mailer/src/Mailer/SMTP.php @@ -42,10 +42,15 @@ class SMTP protected $port; /** - * smtp secure ssl tls + * smtp secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2 */ protected $secure; + /** + * smtp allow insecure ssl + */ + protected $allowInsecure; + /** * EHLO message */ @@ -61,6 +66,11 @@ class SMTP */ protected $password; + /** + * oauth access token + */ + protected $oauthToken; + /** * $this->CRLF * @var string @@ -98,29 +108,43 @@ public function __construct(LoggerInterface $logger=null) * set server and port * @param string $host server * @param int $port port - * @param string $secure ssl tls + * @param string $secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2 * @return $this */ - public function setServer($host, $port, $secure=null) + public function setServer($host, $port, $secure=null, $allowInsecure=null) { $this->host = $host; $this->port = $port; $this->secure = $secure; + $this->allowInsecure = $allowInsecure; if(!$this->ehlo) $this->ehlo = $host; $this->logger && $this->logger->debug("Set: the server"); return $this; } /** - * auth with server + * auth login with server * @param string $username * @param string $password * @return $this */ - public function setAuth($username, $password){ + public function setAuth($username, $password) + { $this->username = $username; $this->password = $password; - $this->logger && $this->logger->debug("Set: the auth"); + $this->logger && $this->logger->debug("Set: the auth login"); + return $this; + } + + /** + * auth oauthbearer with server + * @param string $accessToken + * @return $this + */ + public function setOAuth($accessToken) + { + $this->oauthToken = $accessToken; + $this->logger && $this->logger->debug("Set: the auth oauthbearer"); return $this; } @@ -129,7 +153,8 @@ public function setAuth($username, $password){ * @param $ehlo * @return $this */ - public function setEhlo($ehlo){ + public function setEhlo($ehlo) + { $this->ehlo = $ehlo; return $this; } @@ -138,23 +163,29 @@ public function setEhlo($ehlo){ * Send the message * * @param Message $message - * @return $this + * @return bool * @throws CodeException * @throws CryptoException * @throws SMTPException */ - public function send(Message $message){ + public function send(Message $message) + { $this->logger && $this->logger->debug('Set: a message will be sent'); $this->message = $message; $this->connect() ->ehlo(); - if ($this->secure === 'tls'){ + if ($this->secure === 'tls' || $this->secure === 'tlsv1.0' || $this->secure === 'tlsv1.1' | $this->secure === 'tlsv1.2') { $this->starttls() ->ehlo(); } - $this->authLogin() - ->mailFrom() + + if ($this->username !== null || $this->password !== null) { + $this->authLogin(); + } elseif ($this->oauthToken !== null) { + $this->authOAuthBearer(); + } + $this->mailFrom() ->rcptTo() ->data() ->quit(); @@ -168,10 +199,29 @@ public function send(Message $message){ * @throws CodeException * @throws SMTPException */ - protected function connect(){ + protected function connect() + { $this->logger && $this->logger->debug("Connecting to {$this->host} at {$this->port}"); $host = ($this->secure == 'ssl') ? 'ssl://' . $this->host : $this->host; - $this->smtp = @fsockopen($host, $this->port); + // Create connection + $context = null; + if ($this->allowInsecure) { + $context = stream_context_create([ + 'ssl' => [ + 'security_level' => 0, + 'verify_peer' => false, + 'verify_peer_name' => false + ] + ]); + } + $this->smtp = stream_socket_client( + $host.':'.$this->port, + $error_code, + $error_message, + ini_get('default_socket_timeout'), + STREAM_CLIENT_CONNECT, + $context + ); //set block mode // stream_set_blocking($this->smtp, 1); if (!$this->smtp){ @@ -192,13 +242,36 @@ protected function connect(){ * @throws CryptoException * @throws SMTPException */ - protected function starttls(){ + protected function starttls() + { $in = "STARTTLS" . $this->CRLF; $code = $this->pushStack($in); if ($code !== '220'){ throw new CodeException('220', $code, array_pop($this->resultStack)); } - if(!stream_socket_enable_crypto($this->smtp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { + + if ($this->secure !== 'tls' && version_compare(phpversion(), '5.6.0', '<')) { + throw new CryptoException('Crypto type expected PHP 5.6 or greater'); + } + + switch ($this->secure) { + case 'tlsv1.0': + $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT; + break; + case 'tlsv1.1': + $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; + break; + case 'tlsv1.2': + $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; + break; + default: + $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | + STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | + STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; + break; + } + + if(!\stream_socket_enable_crypto($this->smtp, true, $crypto_type)) { throw new CryptoException("Start TLS failed to enable crypto"); } return $this; @@ -211,7 +284,8 @@ protected function starttls(){ * @throws CodeException * @throws SMTPException */ - protected function ehlo(){ + protected function ehlo() + { $in = "EHLO " . $this->ehlo . $this->CRLF; $code = $this->pushStack($in); if ($code !== '250'){ @@ -231,12 +305,6 @@ protected function ehlo(){ */ protected function authLogin() { - if ($this->username === null && $this->password === null) { - // Unless the user has specifically set a username/password - // Do not try to authorize. - return $this; - } - $in = "AUTH LOGIN" . $this->CRLF; $code = $this->pushStack($in); if ($code !== '334'){ @@ -255,6 +323,60 @@ protected function authLogin() return $this; } + /** + * SMTP AUTH OAUTHBEARER + * SUCCESS 235 + * @return $this + * @throws CodeException + * @throws SMTPException + */ + protected function authOAuthBearer() + { + $authStr = sprintf("n,a=%s,%shost=%s%sport=%s%sauth=Bearer %s%s%s", + $this->message->getFromEmail(), + chr(1), + $this->host, + chr(1), + $this->port, + chr(1), + $this->oauthToken, + chr(1), + chr(1) + ); + $authStr = base64_encode($authStr); + $in = "AUTH OAUTHBEARER $authStr" . $this->CRLF; + $code = $this->pushStack($in); + if ($code !== '235'){ + throw new CodeException('235', $code, array_pop($this->resultStack)); + } + return $this; + } + + /** + * SMTP AUTH XOAUTH2 + * SUCCESS 235 + * @return $this + * @throws CodeException + * @throws SMTPException + */ + protected function authXOAuth2() + { + $authStr = sprintf("user=%s%sauth=Bearer %s%s%s", + $this->message->getFromEmail(), + chr(1), + $this->oauthToken, + chr(1), + chr(1) + ); + $authStr = base64_encode($authStr); + $in = "AUTH XOAUTH2 $authStr" . $this->CRLF; + $code = $this->pushStack($in); + if ($code !== '235'){ + throw new CodeException('235', $code, array_pop($this->resultStack)); + } + return $this; + } + /** * SMTP MAIL FROM * SUCCESS 250 @@ -262,7 +384,8 @@ protected function authLogin() * @throws CodeException * @throws SMTPException */ - protected function mailFrom(){ + protected function mailFrom() + { $in = "MAIL FROM:<{$this->message->getFromEmail()}>" . $this->CRLF; $code = $this->pushStack($in); if ($code !== '250') { @@ -278,8 +401,14 @@ protected function mailFrom(){ * @throws CodeException * @throws SMTPException */ - protected function rcptTo(){ - foreach ($this->message->getTo() as $toEmail) { + protected function rcptTo() + { + $to = array_merge( + $this->message->getTo(), + $this->message->getCc(), + $this->message->getBcc() + ); + foreach ($to as $toEmail=>$_) { $in = "RCPT TO:<" . $toEmail . ">" . $this->CRLF; $code = $this->pushStack($in); if ($code !== '250') { @@ -297,7 +426,8 @@ protected function rcptTo(){ * @throws CodeException * @throws SMTPException */ - protected function data(){ + protected function data() + { $in = "DATA" . $this->CRLF; $code = $this->pushStack($in); if ($code !== '354') { @@ -318,7 +448,8 @@ protected function data(){ * @throws CodeException * @throws SMTPException */ - protected function quit(){ + protected function quit() + { $in = "QUIT" . $this->CRLF; $code = $this->pushStack($in); if ($code !== '221'){ @@ -341,7 +472,8 @@ protected function pushStack($string) * @return string * @throws SMTPException */ - protected function getCode() { + protected function getCode() + { while ($str = fgets($this->smtp, 515)) { $this->logger && $this->logger->debug("Got: ". $str); $this->resultStack[] = $str; diff --git a/subtree/txtthinking/Mailer/tests/MailerTest.php b/subtree/txtthinking/Mailer/tests/MailerTest.php index e2bbd75..55f54e1 100644 --- a/subtree/txtthinking/Mailer/tests/MailerTest.php +++ b/subtree/txtthinking/Mailer/tests/MailerTest.php @@ -6,45 +6,29 @@ use \Tx\Mailer\Exceptions\SMTPException; use \Monolog\Logger; -class MailerTest extends TestCase { +class MailerTest extends TestCase +{ - protected $smtp; - protected $message; - - public function setup(){ - $this->smtp = new SMTP(new Logger('SMTP')); - $this->message = new Message(); - } - - public function testSMTP(){ - $this->smtp - ->setServer('smtp.ym.163.com', 25) - ->setAuth('bot@ym.txthinking.com', ''); // email, password - - $this->message - ->setFrom('Tom', 'bot@ym.txthinking.com') // your name, your email - ->setFakeFrom('heelo', 'bot@hello.com') // a fake name, a fake email - ->addTo('Cloud', 'cloud@txthinking.com') - ->setSubject('Test SMTP ' . time()) - ->setBody('

for test

') - ->addAttachment('host', '/etc/hosts'); - - $status = $this->smtp->send($this->message); - $this->assertTrue($status); + public function setup() + { } - public function testSend(){ - $status = (new Mailer(new Logger('Mailer'))) - ->setServer('smtp.ym.163.com', 25) - ->setAuth('bot@ym.txthinking.com', '') // email, password - ->setFrom('Tom', 'bot@ym.txthinking.com') // your name, your email - ->setFakeFrom('张全蛋', 'zhangquandan@hello.com') // a fake name, a fake email - ->addTo('Cloud', 'cloud@txthinking.com') - ->setSubject('hello '. time()) + public function testSend() + { + $mail = new Mailer(new Logger('Mailer')); + $status = $mail->setServer(self::SERVER, self::PORT_TLS, 'tls') + ->setAuth(self::USER, self::PASS) // email, password + ->setFrom(self::FROM_NAME, self::FROM_EMAIL) // your name, your email + //->setFakeFrom('张全蛋', 'zhangquandan@hello.com') // a fake name, a fake email + ->addTo(self::TO_NAME, self::TO_EMAIL) + ->addCc(self::CC_NAME, self::CC_EMAIL) + ->addBcc(self::BCC_NAME, self::BCC_EMAIL) + ->setSubject('Test Mailer '. time()) ->setBody('Hi, boy') - ->addAttachment('host', '/etc/hosts') + ->addAttachment('test', __FILE__) ->send(); $this->assertTrue($status); + usleep(self::DELAY); } } diff --git a/subtree/txtthinking/Mailer/tests/OAuthTest.php b/subtree/txtthinking/Mailer/tests/OAuthTest.php new file mode 100644 index 0000000..c9a55d5 --- /dev/null +++ b/subtree/txtthinking/Mailer/tests/OAuthTest.php @@ -0,0 +1,30 @@ +setServer(self::OAUTH_SERVER, self::OAUTH_PORT, 'tls') + ->setOAuth(self::OAUTH_TOKEN) + ->setFrom(self::OAUTH_FROM_NAME, self::OAUTH_FROM_EMAIL) + ->addTo(self::TO_NAME, self::TO_EMAIL) + ->addCc(self::CC_NAME, self::CC_EMAIL) + ->addBcc(self::BCC_NAME, self::BCC_EMAIL) + ->setSubject('Test Mailer OAuth2'. time()) + ->setBody('Hi, boy') + ->addAttachment('test', __FILE__) + ->send(); + $this->assertTrue($status); + } +} + diff --git a/subtree/txtthinking/Mailer/tests/SMTPTest.php b/subtree/txtthinking/Mailer/tests/SMTPTest.php index de257ac..1e885cd 100644 --- a/subtree/txtthinking/Mailer/tests/SMTPTest.php +++ b/subtree/txtthinking/Mailer/tests/SMTPTest.php @@ -8,7 +8,7 @@ use Tx\Mailer\SMTP; use Tx\Mailer\Message; -use ERB\Testing\Tools\TestHelper; +use \Monolog\Logger; /** * Class SMTPTest @@ -17,7 +17,8 @@ * This test set requires the use of an open SMTP server mock. Currently, I'm using FakeSMTPServer * */ -class SMTPTest extends TestCase { +class SMTPTest extends TestCase +{ /** * @var SMTP @@ -25,66 +26,97 @@ class SMTPTest extends TestCase { protected $smtp; /** - * @var TestHelper + * @var Message */ - protected $testHelper; + protected $message; public function setup() { - $this->smtp = new SMTP(); - $this->testHelper = new TestHelper(); - + $this->message = new Message(); + $this->message + ->setFrom(self::FROM_NAME, self::FROM_EMAIL) // your name, your email + //->setFakeFrom('Hello', 'bot@fakeemail.com') // a fake name, a fake email + ->addTo(self::TO_NAME, self::TO_EMAIL) + ->addCc(self::CC_NAME, self::CC_EMAIL) + ->addBcc(self::BCC_NAME, self::BCC_EMAIL) + ->setSubject('Test SMTP ' . time()) + ->setBody('

for test

') + ->addAttachment('test', __FILE__); + usleep(self::DELAY); } - public function testSetServer() + public function testSend() { - $result = $this->smtp->setServer("localhost", "25", null); - $this->assertEquals('localhost', $this->testHelper->getPropertyValue($this->smtp, 'host')); - $this->assertEquals('25', $this->testHelper->getPropertyValue($this->smtp, 'port')); - $this->assertSame($this->smtp, $result); + $this->smtp = new SMTP(new Logger('SMTP')); + $this->smtp + ->setServer(self::SERVER, self::PORT) + ->setAuth(self::USER, self::PASS); + + $status = $this->smtp->send($this->message); + $this->assertTrue($status); + usleep(self::DELAY); } - public function testSetAuth() + public function testTLSSend() { - $result = $this->smtp->setAuth('none', 'none'); + $this->smtp = new SMTP(new Logger('SMTP.tls')); + $this->smtp + ->setServer(self::SERVER, self::PORT_TLS, 'tls') + ->setAuth(self::USER, self::PASS); - $this->assertEquals('none', $this->testHelper->getPropertyValue($this->smtp, 'username')); - $this->assertEquals('none', $this->testHelper->getPropertyValue($this->smtp, 'password')); - $this->assertSame($this->smtp, $result); + $status = $this->smtp->send($this->message); + $this->assertTrue($status); + usleep(self::DELAY); } - public function testMessage() + public function testTLSv10Send() { - $this->smtp->setServer("localhost", "25", null) - ->setAuth('none', 'none'); + $this->smtp = new SMTP(new Logger('SMTP.tlsv1.0')); + $this->smtp + ->setServer(self::SERVER, self::PORT_TLS, 'tlsv1.0') + ->setAuth(self::USER, self::PASS); - $message = new Message(); - $message->setFrom('You', 'nobody@nowhere.no') - ->setTo('Them', 'them@nowhere.no') - ->setSubject('This is a test') - ->setBody('This is a test part two'); + $status = $this->smtp->send($this->message); + $this->assertTrue($status); + usleep(self::DELAY); + } - $status = $this->smtp->send($message); + public function testTLSv11Send() + { + $this->smtp = new SMTP(new Logger('SMTP.tlsv1.1')); + $this->smtp + ->setServer(self::SERVER, self::PORT_TLS, 'tlsv1.1') + ->setAuth(self::USER, self::PASS); + + $status = $this->smtp->send($this->message); $this->assertTrue($status); + usleep(self::DELAY); } + public function testTLSv12Send() + { + $this->smtp = new SMTP(new Logger('SMTP.tlsv1.2')); + $this->smtp + ->setServer(self::SERVER, self::PORT_TLS, 'tlsv1.2') + ->setAuth(self::USER, self::PASS); + + $status = $this->smtp->send($this->message); + $this->assertTrue($status); + usleep(self::DELAY); + } /** * @expectedException \Tx\Mailer\Exceptions\SMTPException */ public function testConnectSMTPException() { - $this->smtp->setServer("localhost", "99999", null) + $this->smtp = new SMTP(new Logger('SMTP.FakePort')); + $this->smtp + ->setServer('localhost', "99999", null) ->setAuth('none', 'none'); - $message = new Message(); - $message->setFrom('You', 'nobody@nowhere.no') - ->setTo('Them', 'them@nowhere.no') - ->setSubject('This is a test') - ->setBody('This is a test part two'); - - $this->smtp->send($message); + $this->smtp->send($this->message); + usleep(self::DELAY); } - } diff --git a/subtree/txtthinking/Mailer/tests/TestCase.php b/subtree/txtthinking/Mailer/tests/TestCase.php index d3479f4..d3b2495 100644 --- a/subtree/txtthinking/Mailer/tests/TestCase.php +++ b/subtree/txtthinking/Mailer/tests/TestCase.php @@ -1,5 +1,44 @@