diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7769b44 --- /dev/null +++ b/.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/.gitignore b/.gitignore index c70cc03..96e828d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ vendor/ composer.lock .idea/ docs/ +phpunit.xml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b174b06 --- /dev/null +++ b/.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/README.md b/README.md index 682535f..3de0a29 100644 --- a/README.md +++ b/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/composer.json b/composer.json index b07579a..e3620d2 100644 --- a/composer.json +++ b/composer.json @@ -19,11 +19,11 @@ ], "require": { "php": ">=5.3.2", - "monolog/monolog": "~1.13" + "psr/log": "~1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0", - "erb/testing-tools": "dev-master" + "phpunit/phpunit": "~5.0", + "monolog/monolog": "~1.13" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock deleted file mode 100644 index b6d1c21..0000000 --- a/composer.lock +++ /dev/null @@ -1,1123 +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": "6f23b14407b2e8daca111b6b0379a606", - "packages": [ - { - "name": "monolog/monolog", - "version": "1.13.1", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c31a2c4e8db5da8b46c74cf275d7f109c0f249ac", - "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac", - "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, >2.4.8", - "doctrine/couchdb": "~1.0@dev", - "graylog2/gelf-php": "~1.0", - "phpunit/phpunit": "~4.0", - "raven/raven": "~0.5", - "ruflin/elastica": "0.90.*", - "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", - "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.13.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-03-09 09:58:04" - }, - { - "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.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", - "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.*@ALPHA" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Instantiator\\": "src" - } - }, - "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": "2014-10-13 12:58:55" - }, - { - "name": "erb/testing-tools", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://bitbucket.org/erblearn/testing-tools.git", - "reference": "05c7bd6b2a55ac0455c208cb2588babdfd09d9a3" - }, - "dist": { - "type": "zip", - "url": "https://bitbucket.org/erblearn/testing-tools/get/05c7bd6b2a55ac0455c208cb2588babdfd09d9a3.zip", - "reference": "05c7bd6b2a55ac0455c208cb2588babdfd09d9a3", - "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", - "time": "2015-03-31 18:07:12" - }, - { - "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": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", - "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", - "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-03-27 19:31:25" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.0.15", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "34cc484af1ca149188d0d9e91412191e398e0b67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67", - "reference": "34cc484af1ca149188d0d9e91412191e398e0b67", - "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.0.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-01-24 10:06:35" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.3.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "File/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "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": "2013-10-10 15:34:57" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "Text/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2014-01-30 17:20:04" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "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": "2013-08-02 07:42:54" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", - "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", - "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-01-17 09:51:32" - }, - { - "name": "phpunit/phpunit", - "version": "4.5.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d6429b0995b24a2d9dfe5587ee3a7071c1161af4", - "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4", - "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.0,>=2.0.11", - "phpunit/php-file-iterator": "~1.3.2", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "~1.0.2", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.1", - "sebastian/environment": "~1.2", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.5.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-03-29 09:24:05" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "c63d2367247365f688544f0d500af90a11a44c65" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", - "reference": "c63d2367247365f688544f0d500af90a11a44c65", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "~1.0,>=1.0.1", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.3" - }, - "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": "2014-10-03 05:12:11" - }, - { - "name": "sebastian/comparator", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", - "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", - "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.1.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-01-29 16:28:08" - }, - { - "name": "sebastian/diff", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", - "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-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": "2014-08-15 10:29:00" - }, - { - "name": "sebastian/environment", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", - "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.3" - }, - "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": "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": "2014-10-25 08:00:45" - }, - { - "name": "sebastian/exporter", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "84839970d05254c73cde183a721c7af13aede943" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", - "reference": "84839970d05254c73cde183a721c7af13aede943", - "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-01-27 07:23:06" - }, - { - "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.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "3989662bbb30a29d20d9faa04a846af79b276252" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", - "reference": "3989662bbb30a29d20d9faa04a846af79b276252", - "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-01-24 09:48:32" - }, - { - "name": "sebastian/version", - "version": "1.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", - "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", - "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": "2014-12-15 14:25:24" - }, - { - "name": "symfony/yaml", - "version": "v2.6.5", - "target-dir": "Symfony/Component/Yaml", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/0cd8e72071e46e15fc072270ae39ea1b66b10a9d", - "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2015-03-12 10:28:44" - } - ], - "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/phpunit.xml b/phpunit.xml.dist similarity index 100% rename from phpunit.xml rename to phpunit.xml.dist diff --git a/src/Mailer.php b/src/Mailer.php index 9226041..eab1b6d 100644 --- a/src/Mailer.php +++ b/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/src/Mailer/Message.php b/src/Mailer/Message.php index 379c458..7215f88 100644 --- a/src/Mailer/Message.php +++ b/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/src/Mailer/SMTP.php b/src/Mailer/SMTP.php index 0be065c..9ed80ef 100644 --- a/src/Mailer/SMTP.php +++ b/src/Mailer/SMTP.php @@ -42,10 +42,20 @@ 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 + */ + protected $ehlo; + /** * smtp username */ @@ -56,6 +66,11 @@ class SMTP */ protected $password; + /** + * oauth access token + */ + protected $oauthToken; + /** * $this->CRLF * @var string @@ -93,28 +108,54 @@ 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; + } + + /** + * set the EHLO message + * @param $ehlo + * @return $this + */ + public function setEhlo($ehlo) + { + $this->ehlo = $ehlo; return $this; } @@ -122,23 +163,29 @@ public function setAuth($username, $password){ * 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(); @@ -152,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){ @@ -176,12 +242,36 @@ protected function connect(){ * @throws CryptoException * @throws SMTPException */ - protected function starttls(){ - $code = $this->pushStack("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; @@ -194,8 +284,9 @@ protected function starttls(){ * @throws CodeException * @throws SMTPException */ - protected function ehlo(){ - $in = "EHLO " . $this->host . $this->CRLF; + protected function ehlo() + { + $in = "EHLO " . $this->ehlo . $this->CRLF; $code = $this->pushStack($in); if ($code !== '250'){ throw new CodeException('250', $code, array_pop($this->resultStack)); @@ -214,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'){ @@ -238,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 @@ -245,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') { @@ -261,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') { @@ -280,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') { @@ -301,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'){ @@ -324,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/tests/MailerTest.php b/tests/MailerTest.php index e2bbd75..55f54e1 100644 --- a/tests/MailerTest.php +++ b/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/tests/OAuthTest.php b/tests/OAuthTest.php new file mode 100644 index 0000000..c9a55d5 --- /dev/null +++ b/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/tests/SMTPTest.php b/tests/SMTPTest.php index de257ac..1e885cd 100644 --- a/tests/SMTPTest.php +++ b/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/tests/TestCase.php b/tests/TestCase.php index d3479f4..d3b2495 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,5 +1,44 @@