From ea34e14ba1afffd8e6ecfa258836236419d2b46e Mon Sep 17 00:00:00 2001 From: David Siegfried Date: Fri, 27 Feb 2026 14:25:11 +0100 Subject: replace old email_messaging with symfony/mailer, fixes #2311 --- app/controllers/admin/user.php | 4 +- composer.json | 3 +- composer.lock | 932 +++-- config/config_defaults.inc.php | 3 - lib/bootstrap.php | 29 +- lib/classes/StudipDebugTransport.php | 58 + lib/classes/StudipMail.php | 332 +- tests/functional/_bootstrap.php | 4 +- vendor/email_message/blackhole_message.php | 21 - vendor/email_message/debug_message.php | 31 - .../documentation/email_message_class.html | 1036 ------ .../documentation/pickup_message_class.html | 170 - .../documentation/qmail_message_class.html | 156 - .../documentation/sendmail_message_class.html | 214 -- vendor/email_message/documentation/smtp_class.html | 584 --- .../documentation/smtp_message_class.html | 417 --- vendor/email_message/email_message.php | 3873 -------------------- vendor/email_message/php_message.php | 13 - vendor/email_message/pickup_message.php | 275 -- vendor/email_message/qmail_message.php | 207 -- vendor/email_message/sendmail_message.php | 268 -- vendor/email_message/smtp.php | 1912 ---------- vendor/email_message/smtp_message.php | 782 ---- vendor/sasl/LICENSE | 27 - vendor/sasl/basic_sasl_client.php | 61 - vendor/sasl/cram_md5_sasl_client.php | 67 - vendor/sasl/digest_sasl_client.php | 135 - vendor/sasl/documentation/sasl_class.html | 193 - vendor/sasl/login_sasl_client.php | 69 - vendor/sasl/ntlm_sasl_client.php | 180 - vendor/sasl/plain_sasl_client.php | 99 - vendor/sasl/sasl.php | 422 --- 32 files changed, 908 insertions(+), 11669 deletions(-) create mode 100644 lib/classes/StudipDebugTransport.php delete mode 100644 vendor/email_message/blackhole_message.php delete mode 100644 vendor/email_message/debug_message.php delete mode 100644 vendor/email_message/documentation/email_message_class.html delete mode 100644 vendor/email_message/documentation/pickup_message_class.html delete mode 100644 vendor/email_message/documentation/qmail_message_class.html delete mode 100644 vendor/email_message/documentation/sendmail_message_class.html delete mode 100644 vendor/email_message/documentation/smtp_class.html delete mode 100644 vendor/email_message/documentation/smtp_message_class.html delete mode 100644 vendor/email_message/email_message.php delete mode 100644 vendor/email_message/php_message.php delete mode 100644 vendor/email_message/pickup_message.php delete mode 100644 vendor/email_message/qmail_message.php delete mode 100644 vendor/email_message/sendmail_message.php delete mode 100644 vendor/email_message/smtp.php delete mode 100644 vendor/email_message/smtp_message.php delete mode 100644 vendor/sasl/LICENSE delete mode 100644 vendor/sasl/basic_sasl_client.php delete mode 100644 vendor/sasl/cram_md5_sasl_client.php delete mode 100644 vendor/sasl/digest_sasl_client.php delete mode 100644 vendor/sasl/documentation/sasl_class.html delete mode 100644 vendor/sasl/login_sasl_client.php delete mode 100644 vendor/sasl/ntlm_sasl_client.php delete mode 100644 vendor/sasl/plain_sasl_client.php delete mode 100644 vendor/sasl/sasl.php diff --git a/app/controllers/admin/user.php b/app/controllers/admin/user.php index 2a29ea7..ac0a328 100644 --- a/app/controllers/admin/user.php +++ b/app/controllers/admin/user.php @@ -16,7 +16,6 @@ * @since 2.1 */ -require_once 'vendor/email_message/blackhole_message.php'; require_once 'lib/statusgruppe.inc.php'; /** @@ -642,9 +641,8 @@ class Admin_UserController extends AuthenticatedController } if (!Request::int('u_edit_send_mail')) { - $dev_null = new blackhole_message_class(); $default_mailer = StudipMail::getDefaultTransporter(); - StudipMail::setDefaultTransporter($dev_null); + StudipMail::setDefaultTransporter(StudipMail::NULL_TRANSPORTER); $GLOBALS['MAIL_VALIDATE_BOX'] = false; $GLOBALS['MAIL_VALIDATE_HOST'] = false; } diff --git a/composer.json b/composer.json index 6b4bc22..799e8c3 100644 --- a/composer.json +++ b/composer.json @@ -144,7 +144,8 @@ "lcobucci/jwt": "^4.3", "guzzlehttp/guzzle": "^7.9.2", "phpoffice/phpword": "^1.4", - "sqids/sqids": "^0.5.0" + "sqids/sqids": "^0.5.0", + "symfony/mailer": "^6.4" }, "replace": { "symfony/polyfill-php54": "*", diff --git a/composer.lock b/composer.lock index 3631892..3340c6a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8feee31dc79bc7310e499e9f3d0788e0", + "content-hash": "5b42a1fd190f724d0c251156b26fe884", "packages": [ { "name": "algo26-matthias/idna-convert", @@ -443,6 +443,83 @@ "time": "2023-06-19T06:10:36+00:00" }, { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { "name": "edu-sharing/auth-plugin", "version": "8.0.x-dev", "source": { @@ -490,6 +567,73 @@ "time": "2024-07-19T11:24:30+00:00" }, { + "name": "egulias/email-validator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2025-03-06T22:45:56+00:00" + }, + { "name": "erusev/parsedown", "version": "1.7.4", "source": { @@ -4123,6 +4267,56 @@ "time": "2021-11-05T16:47:00+00:00" }, { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { "name": "psr/http-client", "version": "1.0.3", "source": { @@ -5416,31 +5610,45 @@ "time": "2024-09-25T14:20:29+00:00" }, { - "name": "symfony/filesystem", + "name": "symfony/event-dispatcher", "version": "v6.4.13", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/4856c9cf585d5a0313d8d35afd681a526f038dd3", - "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", + "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { - "symfony/process": "^5.4|^6.4|^7.0" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Filesystem\\": "" + "Symfony\\Component\\EventDispatcher\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5460,10 +5668,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides basic utilities for the filesystem", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.13" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.13" }, "funding": [ { @@ -5479,44 +5687,39 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:07:50+00:00" + "time": "2024-09-25T14:18:03+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.31.0", + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { - "php": ">=7.2" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, "type": "library", "extra": { "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" + "Symfony\\Contracts\\EventDispatcher\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -5525,24 +5728,26 @@ ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "Generic abstractions related to dispatching event", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { @@ -5558,27 +5763,424 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", + "name": "symfony/filesystem", + "version": "v6.4.13", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + "url": "https://github.com/symfony/filesystem.git", + "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/4856c9cf585d5a0313d8d35afd681a526f038dd3", + "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" }, - "suggest": { - "ext-intl": "For best performance" + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.4.13" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-25T15:07:50+00:00" + }, + { + "name": "symfony/mailer", + "version": "v6.4.31", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "8835f93333474780fda1b987cae37e33c3e026ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/8835f93333474780fda1b987cae37e33c3e026ca", + "reference": "8835f93333474780fda1b987cae37e33c3e026ca", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.1", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/messenger": "<6.2", + "symfony/mime": "<6.2", + "symfony/twig-bridge": "<6.2.1" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.2|^7.0", + "symfony/twig-bridge": "^6.2|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.4.31" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-12-12T07:33:25+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.4.32", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "7409686879ca36c09fc970a5fa8ff6e93504dba4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/7409686879ca36c09fc970a5fa8ff6e93504dba4", + "reference": "7409686879ca36c09fc970a5fa8ff6e93504dba4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.4.32" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-04T11:53:14+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { @@ -5592,7 +6194,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + "Symfony\\Polyfill\\Intl\\Idn\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -5601,26 +6203,30 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's grapheme_* functions", + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "grapheme", + "idn", "intl", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" }, "funding": [ { @@ -5632,11 +6238,15 @@ "type": "github" }, { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-09-10T14:38:51+00:00" }, { "name": "symfony/polyfill-intl-normalizer", @@ -8423,56 +9033,6 @@ "time": "2024-12-05T13:48:26+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" - }, - "time": "2019-01-08T18:20:26+00:00" - }, - { "name": "rector/rector", "version": "2.0.14", "source": { @@ -9732,162 +10292,6 @@ "time": "2024-09-25T14:18:03+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v6.4.13", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", - "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/event-dispatcher-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/service-contracts": "<2.5" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^5.4|^6.0|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.13" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:18:03+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/event-dispatcher": "^1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.5-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:20:29+00:00" - }, - { "name": "symfony/finder", "version": "v6.4.17", "source": { @@ -10293,5 +10697,5 @@ "platform-overrides": { "php": "8.1" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/config/config_defaults.inc.php b/config/config_defaults.inc.php index a550c5b..2251d80 100644 --- a/config/config_defaults.inc.php +++ b/config/config_defaults.inc.php @@ -109,7 +109,6 @@ possible settings for $MAIL_TRANSPORT: smtp use smtp to deliver to $MAIL_HOST_NAME php use php's mail() function sendmail use local sendmail script -qmail use local Qmail MTA debug mails are only written to a file in $TMP_PATH */ $MAIL_TRANSPORT = $_ENV['STUDIP_MAIL_TRANSPORT'] ?? 'smtp'; @@ -134,8 +133,6 @@ $MAIL_ENV_FROM = ""; //sender mail adress, defaul $MAIL_FROM = ""; //name of sender, defaults to "Stud.IP" $MAIL_ABUSE = ""; //mail adress to reply to in case of abuse, defaults to abuse @ $MAIL_LOCALHOST -$MAIL_BULK_DELIVERY = FALSE; //try to improve the message queueing rate (experimental, does not work for php transport) - $MAIL_VALIDATE_HOST = TRUE; //check for valid mail host when user enters email adress $MAIL_VALIDATE_BOX = FALSE; //check for valid mail account when user enters email adress; set to false if the webserver got no valid MX record diff --git a/lib/bootstrap.php b/lib/bootstrap.php index 312f208..dd1beb0 100644 --- a/lib/bootstrap.php +++ b/lib/bootstrap.php @@ -252,31 +252,4 @@ Navigation::setRootNavigation(new StudipNavigation('')); /* set default umask to a sane value */ umask(022); -/*mail settings -----------------------------------------------------------------*/ -if ($GLOBALS['MAIL_TRANSPORT']) { - $mail_transporter_name = mb_strtolower($GLOBALS['MAIL_TRANSPORT']) . '_message'; -} else { - $mail_transporter_name = 'smtp_message'; -} -include 'vendor/email_message/email_message.php'; -include 'vendor/email_message/' . $mail_transporter_name . '.php'; -$mail_transporter_class = $mail_transporter_name . '_class'; -$mail_transporter = new $mail_transporter_class; -if ($mail_transporter_name == 'smtp_message') { - include 'vendor/email_message/smtp.php'; - $mail_transporter->localhost = $GLOBALS['MAIL_LOCALHOST'] ?: $_SERVER['SERVER_NAME']; - $mail_transporter->smtp_host = $GLOBALS['MAIL_HOST_NAME'] ?: 'localhost'; - if (is_array($GLOBALS['MAIL_SMTP_OPTIONS'])) { - foreach ($GLOBALS['MAIL_SMTP_OPTIONS'] as $key => $value) { - $mail_transporter->{"smtp_$key"} = $value; - } - if ($mail_transporter->smtp_user !== '') { - include 'vendor/sasl/sasl.php'; - } - } -} -$mail_transporter->default_charset = 'UTF-8'; -$mail_transporter->SetBulkMail((int)$GLOBALS['MAIL_BULK_DELIVERY']); -StudipMail::setDefaultTransporter($mail_transporter); -unset($mail_transporter); +StudipMail::setDefaultTransporter($GLOBALS['MAIL_TRANSPORT'] ?? StudipMail::SMTP_TRANSPORTER); diff --git a/lib/classes/StudipDebugTransport.php b/lib/classes/StudipDebugTransport.php new file mode 100644 index 0000000..6d740a6 --- /dev/null +++ b/lib/classes/StudipDebugTransport.php @@ -0,0 +1,58 @@ +logfile = $logfile; + } + + protected function doSend(SentMessage $message): void + { + $email = $message->getOriginalMessage(); + + if (!$email instanceof Email) { + return; + } + + $username = $GLOBALS['user']->username ?? 'unknown'; + + $entry = "\n-- " . date('d.m.Y H:i:s') . " " . $username; + $entry .= "\nTo: " . implode(', ', array_map(fn($a) => $a->toString(), $email->getTo())); + $entry .= "\nSubject: " . $email->getSubject(); + + + $headers = ''; + foreach ($email->getHeaders()->all() as $header) { + $headers .= $header->toString() . "\n"; + } + + if (strlen(trim($headers))) { + $entry .= "\n" . $headers; + } + + $entry .= "\n"; + + if ($email->getTextBody()) { + $entry .= $email->getTextBody(); + } elseif ($email->getHtmlBody()) { + $entry .= $email->getHtmlBody(); + } + + $entry .= "\n"; + + file_put_contents($this->logfile, $entry, FILE_APPEND); + } + + public function __toString(): string + { + return 'studip-debug://default'; + } +} diff --git a/lib/classes/StudipMail.php b/lib/classes/StudipMail.php index e1dd8dd..7fb7eec 100644 --- a/lib/classes/StudipMail.php +++ b/lib/classes/StudipMail.php @@ -1,4 +1,11 @@ 'sendmail://default', + self::NATIVE_TRANSPORTER => 'native://default', + self::NULL_TRANSPORTER => 'null://null', + default => $this->buildSmtpDsn() + }; + if (!self::$mailer) { + if (self::getDefaultTransporter() === self::DEBUG_TRANSPORTER) { + $transport = new StudipDebugTransport( + $GLOBALS['TMP_PATH'] . '/' . + ($GLOBALS['DEBUG_MAIL_LOG_FILE_NAME'] ?? 'studip-mail-debug.log') + ); + } else { + $transport = Transport::fromDsn($dsn); + } + self::$mailer = new Mailer($transport); + } + $this->mailer = self::$mailer; $mail_localhost = $GLOBALS['MAIL_LOCALHOST'] ?: $_SERVER['SERVER_NAME']; $this->setSenderEmail($GLOBALS['MAIL_ENV_FROM'] ?: "wwwrun@{$mail_localhost}"); $this->setSenderName($GLOBALS['MAIL_FROM'] ?: 'Stud.IP - ' . Config::get()->UNI_NAME_CLEAN); @@ -147,6 +174,45 @@ class StudipMail } } + private function buildSmtpDsn(): string + { + $host = $GLOBALS['MAIL_HOST_NAME'] ?: 'localhost'; + $port = $GLOBALS['MAIL_SMTP_OPTIONS']['port'] ?? 25; + $user = $GLOBALS['MAIL_SMTP_OPTIONS']['user'] ?? ''; + $pass = $GLOBALS['MAIL_SMTP_OPTIONS']['password'] ?? ''; + + $query = []; + + if (!empty($GLOBALS['MAIL_SMTP_OPTIONS']['ssl'])) { + $query['encryption'] = 'ssl'; + } elseif (!empty($GLOBALS['MAIL_SMTP_OPTIONS']['start_tls'])) { + $query['encryption'] = 'tls'; + } + + if (!empty($GLOBALS['MAIL_SMTP_OPTIONS']['authentication_mechanism'])) { + $query['auth_mode'] = $GLOBALS['MAIL_SMTP_OPTIONS']['authentication_mechanism']; + } + + $mail_localhost = $GLOBALS['MAIL_LOCALHOST'] ?: $_SERVER['SERVER_NAME']; + + if ($mail_localhost) { + $query['local_domain'] = $mail_localhost; + } + + $credentials = ''; + if ($user !== '') { + $credentials = urlencode($user); + if ($pass !== '') { + $credentials .= ':' . urlencode($pass); + } + $credentials .= '@'; + } + + $qs = $query ? '?' . http_build_query($query) : ''; + + return "smtp://{$credentials}{$host}:{$port}{$qs}"; + } + /** * @param string $mail * @return StudipMail provides fluent interface @@ -272,15 +338,6 @@ class StudipMail } /** - * @param $mail - * @return bool - */ - public function isRecipient($mail) - { - return isset($this->recipients[$mail]); - } - - /** * @param $file_name * @param $name * @param $type @@ -295,19 +352,6 @@ class StudipMail } /** - * @param $data - * @param $name - * @param $type - * @param $disposition - * @return StudipMail provides fluent interface - */ - public function addDataAttachment($data, $name, $type = 'automatic/name', $disposition = 'attachment') - { - $this->attachments[$name] = compact('data', 'name', 'type', 'disposition'); - return $this; - } - - /** * @param FileRef $file_ref The FileRef object of a file that shall be added to a mail * @return StudipMail provides fluent interface */ @@ -334,16 +378,6 @@ class StudipMail } /** - * @param $name - * @return StudipMail provides fluent interface - */ - public function removeAttachment($name) - { - unset($this->attachments[$name]); - return $this; - } - - /** * @return array */ public function getAttachments() @@ -352,15 +386,6 @@ class StudipMail } /** - * @param $name - * @return bool - */ - public function isAttachment($name) - { - return isset($this->attachments[$name]); - } - - /** * @param $body * @return StudipMail provides fluent interface */ @@ -397,94 +422,91 @@ class StudipMail } /** - * quotes the given string if it contains any characters - * reserved for special interpretation in RFC 2822. - */ - protected static function quoteString($string) - { - // list of reserved characters in RFC 2822 - if (strcspn($string, '()<>[]:;@\\,.') < mb_strlen($string)) { - $string = '"' . addcslashes($string, "\r\"\\") . '"'; - } - return $string; - } - - /** - * send the mail using the given transporter object, or the - * set default transporter + * send the mail * - * @param email_message_class|null $transporter * @return bool */ - public function send(?email_message_class $transporter = null) + public function send(): bool { - if ($transporter === null) { - $transporter = self::$transporter; - } - if ($transporter === null) { - throw new Exception('no mail transport defined'); - } - $transporter->ResetMessage(); - $transporter->SetHeader('Return-Path', $this->getSenderEmail()); - $transporter->SetEncodedEmailHeader('From', $this->getSenderEmail(), self::quoteString($this->getSenderName())); - if($this->getReplyToEmail()){ - $transporter->SetEncodedEmailHeader('Reply-To', $this->getReplyToEmail(), self::quoteString($this->getReplyToName())); - } - - $recipients_by_type = []; - foreach($this->getRecipients() as $recipient) { - if (!isset($recipients_by_type[$recipient['type']])) { - $recipients_by_type[$recipient['type']] = []; + try { + $email = new Email(); + $email->returnPath($this->getSenderEmail()); + $email->from( + new Address( + $this->getSenderEmail(), + $this->getSenderName() + ) + ); + if ($this->getReplyToEmail()) { + $email->replyTo( + new Address( + $this->getReplyToEmail(), + $this->getReplyToName() + ) + ); + } + foreach ($this->getRecipients() as $recipient) { + $address = new Address( + $recipient['mail'], + $recipient['name'] + ); + + switch ($recipient['type']) { + case 'Cc': + $email->cc($address); + break; + case 'Bcc': + $email->bcc($address); + break; + default: + $email->to($address); + } } - $recipients_by_type[$recipient['type']][$recipient['mail']] = self::quoteString($recipient['name']); - } - foreach ($recipients_by_type as $type => $recipients){ - $transporter->SetMultipleEncodedEmailHeader($type, $recipients); - } - $transporter->SetEncodedHeader('Subject', $this->getSubject()); - if($this->getBodyHtml()) { - $html_part = 0; - $transporter->CreateQuotedPrintableHTMLPart($this->getBodyHtml(), "", $html_part); - $text_part = ''; - $text_message = $this->getBodyText(); - - if(!$text_message){ - $text_message = _('Diese Nachricht ist im HTML-Format verfasst. Sie benötigen eine E-Mail-Anwendung, die das HTML-Format anzeigen kann.'); + $email->subject($this->getSubject()); + + if ($this->getBodyHtml()) { + $text_message = $this->getBodyText(); + if (!$text_message) { + $text_message = _( + 'Diese Nachricht ist im HTML-Format verfasst. Sie benötigen eine E-Mail-Anwendung, die das HTML-Format anzeigen kann.' + ); + } + $email->text($text_message); + $email->html($this->getBodyHtml()); + + foreach ($this->related_attachments as $attachment) { + $part = new DataPart( + fopen($attachment['FileName'], 'r'), + $attachment['Content-ID'], + $attachment['Content-Type'] + ); + $part->asInline(); + $email->addPart($part); + } + } else { + $email->text($this->getBodyText()); } - $transporter->CreateQuotedPrintableTextPart($transporter->WrapText($text_message), "", $text_part); - - $part = [$text_part, $html_part]; - if (count($this->related_attachments) > 0) { - $relparts = [$html_part]; - $i = 99; - $multipart = 0; - foreach ($this->related_attachments as $one) { - $transporter->CreateFilePart($one, $i); - $relparts[] = $i; + + foreach ($this->getAttachments() as $attachment) { + if (!empty($attachment['file_name'])) { + $email->attachFromPath( + $attachment['file_name'], + $attachment['name'], + $attachment['type'] !== 'automatic/name' ? $attachment['type'] : null + ); + } elseif (!empty($attachment['data'])) { + $email->attach( + $attachment['data'], + $attachment['name'], + $attachment['type'] !== 'automatic/name' ? $attachment['type'] : null + ); } - $transporter->CreateRelatedMultipart($relparts, $multipart); - $part = [$text_part, $multipart]; } - $transporter->AddAlternativeMultipart($part); - } else { - $transporter->AddQuotedPrintableTextPart($this->getBodyText()); - } - foreach($this->getAttachments() as $attachment){ - $part = [ - 'FileName' => $attachment['file_name'] ?? null, - 'Data' => $attachment['data'] ?? null, - 'Name' => $attachment['name'], - 'Content-Type' => $attachment['type'], - 'Disposition' => $attachment['disposition'], - ]; - $transporter->addFilePart($part); - } - $error = $transporter->Send(); - if (mb_strlen($error) === 0) { + $this->mailer->send($email); return true; - } else { - Log::error(get_class($transporter) . '::Send() - ' . $error); + } catch (\Throwable $e) { + Log::error('StudipMail::send - ' . $e->getMessage()); return false; } } diff --git a/tests/functional/_bootstrap.php b/tests/functional/_bootstrap.php index 1897878..93fc1d1 100644 --- a/tests/functional/_bootstrap.php +++ b/tests/functional/_bootstrap.php @@ -41,9 +41,7 @@ require $GLOBALS['STUDIP_BASE_PATH'] . '/config/config.inc.php';; require_once __DIR__ . '/../../lib/bootstrap-autoload.php'; // Do not send mails of any kind during tests -require 'vendor/email_message/email_message.php'; -require 'vendor/email_message/debug_message.php'; -StudipMail::setDefaultTransporter(new debug_message_class()); +StudipMail::setDefaultTransporter(StudipMail::DEBUG_TRANSPORTER); $GLOBALS['template_factory'] = new Flexi\Factory(dirname(dirname(__DIR__)) . '/templates'); diff --git a/vendor/email_message/blackhole_message.php b/vendor/email_message/blackhole_message.php deleted file mode 100644 index fdfe4f3..0000000 --- a/vendor/email_message/blackhole_message.php +++ /dev/null @@ -1,21 +0,0 @@ - \ No newline at end of file diff --git a/vendor/email_message/debug_message.php b/vendor/email_message/debug_message.php deleted file mode 100644 index 4882570..0000000 --- a/vendor/email_message/debug_message.php +++ /dev/null @@ -1,31 +0,0 @@ -logfile = implode('/', [ - $GLOBALS['TMP_PATH'], - $GLOBALS['DEBUG_MAIL_LOG_FILE_NAME'] ?? 'studip-mail-debug.log' - ]); - } - - function SendMail($to,$subject,$body,$headers,$return_path) { - if ($log = fopen($this->logfile, "a")){ - if(strlen($headers)) $headers.="\n"; - fwrite($log, "\n-- " . strftime("%x %X"). ' ' . $GLOBALS['user']->username); - fwrite($log, "\nTo: ".$to."\nSubject: ".$subject."\n".$headers."\n"); - fwrite($log,$body."\n"); - fclose($log); - } - } -} -?> diff --git a/vendor/email_message/documentation/email_message_class.html b/vendor/email_message/documentation/email_message_class.html deleted file mode 100644 index b9606b9..0000000 --- a/vendor/email_message/documentation/email_message_class.html +++ /dev/null @@ -1,1036 +0,0 @@ - - - -Class: MIME E-mail message composing and sending - - -

Class: MIME E-mail message composing and sending

-
- -
- -
- -
- - -
-
Manuel Lemos (mlemos-at-acm.org)
- - diff --git a/vendor/email_message/documentation/pickup_message_class.html b/vendor/email_message/documentation/pickup_message_class.html deleted file mode 100644 index dade063..0000000 --- a/vendor/email_message/documentation/pickup_message_class.html +++ /dev/null @@ -1,170 +0,0 @@ - - - -Class: MIME E-mail message composing and sending using a Windows mail - server pickup directory - - -

Class: MIME E-mail message composing and sending using a Windows mail - server pickup directory

-
- -
- -
- - -
- - - -
-
Manuel Lemos (mlemos-at-acm.org)
- - diff --git a/vendor/email_message/documentation/qmail_message_class.html b/vendor/email_message/documentation/qmail_message_class.html deleted file mode 100644 index 5f1362b..0000000 --- a/vendor/email_message/documentation/qmail_message_class.html +++ /dev/null @@ -1,156 +0,0 @@ - - - -Class: MIME E-mail message composing and sending using Qmail - - -

Class: MIME E-mail message composing and sending using Qmail

-
- -
- -
- - -
- - - -
-
Manuel Lemos (mlemos-at-acm.org)
- - diff --git a/vendor/email_message/documentation/sendmail_message_class.html b/vendor/email_message/documentation/sendmail_message_class.html deleted file mode 100644 index e2fcbf6..0000000 --- a/vendor/email_message/documentation/sendmail_message_class.html +++ /dev/null @@ -1,214 +0,0 @@ - - - -Class: MIME E-mail message composing and sending using Sendmail - - -

Class: MIME E-mail message composing and sending using Sendmail

-
- -
- -
- - -
- - - -
-
Manuel Lemos (mlemos-at-acm.org)
- - diff --git a/vendor/email_message/documentation/smtp_class.html b/vendor/email_message/documentation/smtp_class.html deleted file mode 100644 index 4caa60d..0000000 --- a/vendor/email_message/documentation/smtp_class.html +++ /dev/null @@ -1,584 +0,0 @@ - - - -Class: Sending e-mail messages via SMTP protocol - - -

Class: Sending e-mail messages via SMTP protocol

-
- -
- -
- -
- - -
-
Manuel Lemos (mlemos-at-acm.org)
- - diff --git a/vendor/email_message/documentation/smtp_message_class.html b/vendor/email_message/documentation/smtp_message_class.html deleted file mode 100644 index 3bec125..0000000 --- a/vendor/email_message/documentation/smtp_message_class.html +++ /dev/null @@ -1,417 +0,0 @@ - - - -Class: MIME E-mail message composing and sending via SMTP - - -

Class: MIME E-mail message composing and sending via SMTP

-
- -
- -
- - -
- - - -
-
Manuel Lemos (mlemos-at-acm.org)
- - diff --git a/vendor/email_message/email_message.php b/vendor/email_message/email_message.php deleted file mode 100644 index a94e996..0000000 --- a/vendor/email_message/email_message.php +++ /dev/null @@ -1,3873 +0,0 @@ - - - - net.manuellemos.mimemessage - - @(#) $Id: email_message.php,v 1.99 2013/09/08 22:44:46 mlemos Exp $ - Copyright © (C) Manuel Lemos 1999-2004 - MIME E-mail message composing and sending - Manuel Lemos - mlemos-at-acm.org - - - en - Compose and send e-mail messages according to the MIME - standards. - If you are interested in translating the documentation of - this class to your own idiom, please - contact the author - mailto:authoraddress - . - Technical support for using this class may be obtained in the - mimemessage-dev mailing list. Just go to the mailing list - page to browse the list archives, learn how to to join and post - support request messages: - - http://groups-beta.google.com/group/mimemessage-dev - http://groups-beta.google.com/group/mimemessage-dev - - To used this class just create a new object as follows, set any - variables to configure its behavior and call the functions you need - to compose and send your messages. - require('email_message.php');
-
- $message_object = new email_message_class;
- - Set the sender and recipients - You can set the message sender and one or more recipient addresses - using the SetHeader or the - SetEncodedEmailHeader functions - specifying the addresses for the From, To, - Cc and Bcc headers. - - - Formatting text messages - You can use the WrapText to assure that - a text message does not have more than 75 columns by breaking the - longer lines between words. - - If you are composing a reply to another text message, you can use the - QuoteText function to conveniently mark - the text quoted from the original message. - - - Add a plain text message body - If the text of the message that you want to send only contains ASCII - characters (7 bits), use the - AddPlainTextPart function to add the - text to the message. - - - Add a text message with non-ASCII characters - If your message text may contains non-ASCII characters (8 bits or - more), use the - AddQuotedPrintableTextPart function - to add the text to the message. - - If the text uses a character set other than - ISO-8859-1 (ISO Latin 1), set the - default_charset variable to change the - default character set. - - - Setting the error message bounce address - This class provides a means to specify the address where error - messages should be bounced in case it is not possible to deliver a - message. That can be done by setting the header Return-Path - with the SetHeader - function. - - - Request message receipt notification - If you would like to be receive an notification when a message that - is sent is received, just use the - SetHeader function with the - Disposition-Notification-To header to specify the address to - where you want to receive the notification message. - Keep in mind that this header just expresses that you want to get a - receipt notification, but it may be denied or ignored by the - recipient, which does not mean the message was not - received. - - - Avoding temporary delivery failure warning messages - Sometimes it is not possible to deliver a message immediately due - to a networking failure or some other problem. In that case, the mail - transfer system usually leaves the message in a queue and keeps - retrying to deliver the message until it succeeds or it has reached - the limit number of days before it gives up. When it gives up the - the message is bounced to the return-path address. - However some systems send a warning message to the original sender - when it is not delivered after the first few hours. This may be an - useful notification when the message is sent by a human but it maybe - inconvinient when you are sending messages to many users like for - instance newsletters or messages to subscribers of mailing lists. - If you want to hint the mail transfer system to not send temporary - delivery failure warning messages, just use the - SetHeader function to set the - Precedence header to bulk. - Setting this header this way is a convention used by mailing list - manager programs precisely for this purpose. It may also hint some - mail receiving systems to not send auto-response messages, for - instance when the recipient user is away on vaction. However, not all - systems are aware of this convention and still send auto-response - messages when you set this header. - - - Send the message - Once you have set the message sender, the recipients and added the - message text, use the Send function - to send the message. This class uses the PHP function mail() - to send messages. - - If for some reason you need to use a different message delivery - method, you may use one of the existing sub-classes that are - specialized in delivering messages by connecting to an SMTP server or - using directly the programs sendmail and qmail. - - - Add an HTML message body - If you want to send an HTML message you can use the - AddHTMLPart function if it contains - only ASCII characters. If it contains non-ASCII characters, you - should the AddQuotedPrintableHTMLPart - function instead. - - - Add alternative text body for HTML messages - Not every e-mail program can display HTML messages. Therefore, when - you send an HTML message, you should also include an alternative text - part to be displayed by programs that do not support HTML - messages. - - This is achieved by composing multipart/alternative - messages. This type of message is composed by creating the HTML - message part with the CreateHTMLPart or - the CreateQuotedPrintableHTMLPart - functions, then create the alternative text part with the - CreatePlainTextPart or the - CreateQuotedPrintableTextPart - functions, and finally use the - AddAlternativeMultipart function to add - an assembly of both message parts. - Note that the text part should be the first to be specified in the - array of parts passed to the - AddAlternativeMultipart function, or - else it will not appear correctly. - Despite this procedure adds a little complexity to the process of - sending HTML messages, it is the same procedure that is followed by - e-mail programs that are used by most people to send HTML - messages. - Therefore, you are strongly recommended to follow the same procedure - because some of the modern spam filter programs discard HTML messages - without an alternative plain text part, as it constitutes a pattern - that identifies messages composed by some of the spam sending - programs. - - - - Embed images in HTML messages - embed-image - - One way to show an image in an HTML message is to use - <img> tag with src attribute set to the - remote site URL of the image that is meant to be displayed. - However, since the message recipient user may not be online when - they will check their e-mail, an image referenced this way may not - appear. - Alternatively, an image file can be embedded in an HTML message using - multipart/related message parts. This type of message part - is composed by creating the image file part with the - CreateFilePart function. - Then use the GetPartContentID function - the image part identifier text. Prepend the string - cid: to this identifier to form a special - URL that should be used in the HTML part to reference the image part - like this: - $image_tag = <img src="cid: . - $message_object->GetPartContentID($image_part) . - "> ; - When you have composed the whole HTML document, create the HTML - message part with the CreateHTMLPart or - the CreateQuotedPrintableHTMLPart - functions, and finally use the - CreateRelatedMultipart function to - create a message part that can be added to the message with the - function AddAlternativeMultipart like - HTML messages with alternative text parts described - before. - Note that the HTML part must be the first listed in the parts array - argument that is passed to the function - CreateRelatedMultipart, or else the - message may not appear correctly. - Note also that when you are composing an HTML message with embedded - images and an alternative text part, first you need to create the - multipart/alternative part with the HTML and the text parts - using the CreateAlternativeMultipart - function, and then you add the multipart/related part to - the message with the - AddRelatedMultipart function, - passing an array of parts that lists first the - multipart/alternative part and then the image part created - before. - - - Attach files to messages - To send a message with attached files, it is necessary to compose a - multipart/mixed message. This is a type of message made by a - text or HTML part followed by one or more file - parts. - If you add multiple parts to a message, this class implicitly turns - it into a multipart/mixed message. Therefore you only need - to use the function AddFilePart for each - file that you want to attach and the class will automatically - generate the message treating any parts added after the first as - attachments. - - - Forward received messages - To forward an e-mail message received from somewhere, just use the - function AddMessagePart passing the - message complete with the original headers and body data. The message - is forwarded as an attachment that most mail programs can - display. - - - Sending messages to many recipients (mass or bulk mailing) - Sending messages to many recipients is an activity also known as - mass or bulk mailing. There are several alternatives for mass - mailing. One way consists on specifying all recipient addresses - with the Bcc header, separating the addresses with commas - (,), or using the - SetMultipleEncodedEmailHeader function. - This way you only need to send one message that is distributed to all - recipients by your mail transfer system. - Unfortunately, many mail account providers like Hotmail, tend to - consider messages sent this way as spam because the real recipients - addresses are not visible in To of Cc headers. - So, this method is no longer a good solution these - days. - The alternative is to send a separate message to each recipient by - iteratively setting the To header with each recipient - address and calling the Send function. - This way tends to take too much time and CPU as the number of - recipients grow. - When sending messages to many recipients, call the - SetBulkMail function to hint the class - to optimize the way it works to make the delivery of the messages - more efficient and eventually faster. - The actual optimizations that are performed depend on the delivery - method that is used by this class or any of its subclasses - specialized on the different delivery methods that are supported. - Check the documentation of the subclass that you use to learn about - the optimizations that are performed, if any. - If you intend to send messages with the same body to all recipients, - the class can optimize the generation of the messages and reduce - significantly the composition time if you set the - cache_body variable to - 1. - If you really need to personalize the content of a message part with - different text, HTML or file to each recipient, you should use the - ReplacePart function to avoid as much - as possible the overhead of composing a new message to each of the - recipients of the mailing. - If you are sending personalized messages to multiple recipients but - the messages include attached or embedded files that are the same - for all recipients, you should also set the - Cached option of the - file - CreateFilePart - parameter of the - CreateFilePart function. - Other than that, take a look at the documentation of the this class - sub-classes that may be used in your PHP environment, as these may - provide more efficient delivery solutions for mass mailing. - - - Error handling - Most of the functions of this class that may fail, return an error - message string that describes the error that has occurred. If there - was no error, the functions return an empty string. - Verifying the return value of all the functions to determine - whether there was an error is a tedious task to implement for most - developers. To avoid this problem, this class supports cumulative - error checking. - Cumulative error checking means that when an error occurs, the class - stores the error message in the error - variable. Then, when another function that may fail is called, it - does nothing and immediately returns the same error - message. - This way, the developers only need to check the return value of the - last function that is called, which is usually the - Send function. -
-
- -{/metadocument} -*/ - -class email_message_class -{ - /* Private variables */ - - var $headers=array("To"=>"","Subject"=>""); - var $body=-1; - var $body_parts=0; - var $parts=array(); - var $total_parts=0; - var $free_parts=array(); - var $total_free_parts=0; - var $delivery=array("State"=>""); - var $next_token=""; - var $php_version=0; - var $mailings=array(); - var $last_mailing=0; - var $header_length_limit=512; - var $auto_message_id=1; - var $mailing_path=""; - var $body_cache=array(); - var $line_break="\n"; - var $line_length=76; - var $ruler="_"; - var $email_address_pattern="([-!#\$%&'*+./0-9=?A-Z^_`a-z{|}~])+@([-!#\$%&'*+/0-9=?A-Z^_`a-z{|}~]+\\.)+[a-zA-Z]{2,6}"; - var $bulk_mail=0; - - /* Public variables */ - -/* -{metadocument} - - email_regular_expression - STRING - ^([-!#$%&'*+./0-9=?A-Z^_`a-z{|}~])+@([-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+\.)+[a-zA-Z]{2,6}$ - - Specify the regular expression that is used by the - ValidateEmailAddress function to - verify whether a given e-mail address may be valid. - Do not change this variable unless you have reason to believe - that it is rejecting existing e-mail addresses that are known to be - valid. - - -{/metadocument} -*/ - var $email_regular_expression="^([-!#\$%&'*+./0-9=?A-Z^_`a-z{|}~])+@([-!#\$%&'*+/0-9=?A-Z^_`a-z{|}~]+\\.)+[a-zA-Z]{2,6}\$"; - -/* -{metadocument} - - mailer - STRING - http://www.phpclasses.org/mimemessage $Revision: 1.99 $ - - Specify the base text that is used identify the name and the - version of the class that is used to send the message by setting an - implicit the X-Mailer message header. This is meant - mostly to assist on the debugging of delivery problems. - Change this to set another mailer identification string or - leave it to an empty string to prevent that the X-Mailer - header be added to the message. - - -{/metadocument} -*/ - var $mailer=''; - -/* -{metadocument} - - mailer_delivery - STRING - mail - - Specify the text that is used to identify the mail - delivery class or sub-class. This text is appended to the - X-Mailer header text defined by the - mailer variable. - This variable should only be redefined by the different mail - delivery sub-classes. - - -{/metadocument} -*/ - var $mailer_delivery='mail'; - -/* -{metadocument} - - default_charset - STRING - ISO-8859-1 - - Specify the default character set to be assumed for the - message headers and body text. - Change this variable to the correct character set name if it - is different than the default. - - -{/metadocument} -*/ - var $default_charset="ISO-8859-1"; - -/* -{metadocument} - - line_quote_prefix - STRING - > - - Specify the default line quote prefix text used by the - QuoteText function. - Change it only if you prefer to quote lines marking them with - a different line prefix. - - -{/metadocument} -*/ - var $line_quote_prefix="> "; - -/* -{metadocument} - - break_long_lines - BOOLEAN - 1 - - Determine whether lines exceeding the length limit will be - broken by the line break character when using the - WrapText function. - Change it only if you want to avoid breaking long lines - without any space characters, like for instance of messages with - long URLs. - - -{/metadocument} -*/ - var $break_long_lines=1; - -/* -{metadocument} - - file_buffer_length - INTEGER - 8000 - - Specify the length of the buffer that is used to read - files in chunks of limited size. - The default value may be increased if you have plenty of - memory and want to benefit from additional speed when processing - the files that are used to compose messages. - - -{/metadocument} -*/ - var $file_buffer_length=8000; - -/* -{metadocument} - - debug - STRING - - - Specify the name of a function that is called whenever an - error occurs. - If you need to track the errors that may happen during the use - of the class, set this variable to the name of a callback function. - It should take only one argument that is the error message. When - this variable is set to an empty string, no debug callback function - is called. - - -{/metadocument} -*/ - var $debug=""; - -/* -{metadocument} - - cache_body - BOOLEAN - 0 - - Specify whether the message bodies that are generated by the - class before sending, should be cached in memory to be reused on - the next message delivery. - Set this variable to 1 - if you intend to send the a message with the same body to many - recipients, so the class avoids the overhead of regenerating - messages with the same content. - - -{/metadocument} -*/ - var $cache_body=0; - -/* -{metadocument} - - error - STRING - - - Store the last error return by any function that may fail - due to some error. - Do not change this variable value unless you intend to clear - the error status by setting it to an empty string. - - -{/metadocument} -*/ - var $error=""; - -/* -{metadocument} - - localhost - STRING - - - Specify the domain name of the computer sending the - message. - This value is used as default domain of the sender e-mail - address when generating automatic Message-Id - headers. - - -{/metadocument} -*/ - var $localhost=""; - - /* Private methods */ - - Function Tokenize($string,$separator="") - { - if(!strcmp($separator,"")) - { - $separator=$string; - $string=$this->next_token; - } - for($character=0;$characternext_token=substr($string,$found+1); - return(substr($string,0,$found)); - } - else - { - $this->next_token=""; - return($string); - } - } - - Function GetFilenameExtension($filename) - { - return(GetType($dot=strrpos($filename,"."))=="integer" ? substr($filename,$dot) : ""); - } - - Function OutputError($error) - { - if(strcmp($function=$this->debug,"") - && strcmp($error,"")) - $function($error); - return($this->error=$error); - } - - Function OutputPHPError($error, &$php_error_message) - { - if(IsSet($php_error_message) - && strlen($php_error_message)) - $error.=": ".$php_error_message; - return($this->OutputError($error)); - } - - Function GetPHPVersion() - { - if($this->php_version==0) - { - $version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7"); - $this->php_version=$version[0]*1000000+$version[1]*1000+$version[2]; - } - return($this->php_version); - } - - Function EscapePattern($pattern) - { - return('/'.str_replace('/', '\\/', $pattern).'/'); - } - - Function GetRFC822Addresses($address,&$addresses) - { - if(function_exists("imap_rfc822_parse_adrlist")) - { - if(GetType($parsed_addresses=@imap_rfc822_parse_adrlist($address,$this->localhost))!="array") - return("it was not specified a valid address list"); - for($entry=0;$entryhost) - || $parsed_addresses[$entry]->host==".SYNTAX-ERROR.") - return($parsed_addresses[$entry]->mailbox." .SYNTAX-ERROR."); - $parsed_address=$parsed_addresses[$entry]->mailbox."@".$parsed_addresses[$entry]->host; - if(IsSet($addresses[$parsed_address])) - ++$addresses[$parsed_address]; - else - $addresses[$parsed_address]=1; - } - } - else - { - $length=strlen($address); - for($position=0;$position<$length;) - { - $match=preg_split($this->EscapePattern($this->email_address_pattern),strtolower(substr($address,$position)),2); - if(count($match)<2) - break; - $position+=strlen($match[0]); - $next_position=$length-strlen($match[1]); - $found=substr($address,$position,$next_position-$position); - if(!strcmp($found,"")) - break; - if(IsSet($addresses[$found])) - ++$addresses[$found]; - else - $addresses[$found]=1; - $position=$next_position; - } - } - return(""); - } - - Function FormatHeader($header_name,$header_value) - { - $length=strlen($header_value); - for($header_data="",$header_line=$header_name.": ",$line_length=strlen($header_line),$position=0;$position<$length;) - { - for($space=$position,$line_length=strlen($header_line);$space<$length;) - { - if(GetType($next=strpos($header_value," ",$space+1))!="integer") - $next=$length; - if($next-$position+$line_length>$this->header_length_limit) - { - if($space==$position) - $space=$next; - break; - } - $space=$next; - } - $header_data.=$header_line.substr($header_value,$position,$space-$position); - if($space<$length) - $header_line=""; - $position=$space; - if($position<$length) - $header_data.=$this->line_break; - } - return($header_data); - } - - Function GenerateMessageID($sender) - { - $micros=$this->Tokenize(microtime()," "); - $seconds=$this->Tokenize(""); - $local=$this->Tokenize($sender,"@"); - $host=$this->Tokenize(" @"); - if(strlen($host) - && $host[strlen($host)-1]=="-") - $host=substr($host,0,strlen($host)-1); - return($this->FormatHeader("Message-ID", "<".strftime("%Y%m%d%H%M%S", $seconds).substr($micros,1,5).".".preg_replace('/[^A-Za-z]/', '-', $local)."@".preg_replace('/[^.A-Za-z_-]/', '', $host).">")); - } - - Function SendMail($to, $subject, $body, $headers, $return_path) - { - $ini_safemode_chk = false; - if (version_compare(PHP_VERSION, '5.3.0', '<')) { - $ini_safemode_chk = ini_get('safe_mode'); - } - if(!function_exists("mail")) - return($this->OutputError("the mail() function is not available in this PHP installation")); - if(strlen($return_path)) - { - if(!defined("PHP_OS")) - return($this->OutputError("it is not possible to set the Return-Path header with your PHP version")); - if(!strcmp(substr(PHP_OS,0,3),"WIN")) - return($this->OutputError("it is not possible to set the Return-Path header directly from a PHP script on Windows")); - if($this->GetPHPVersion()<4000005) - return($this->OutputError("it is not possible to set the Return-Path header in PHP version older than 4.0.5")); - if(function_exists("ini_get") - && $ini_safemode_chk) - return($this->OutputError("it is not possible to set the Return-Path header due to PHP safe mode restrictions")); - $success=@mail($to,$subject,$body,$headers,"-f".$return_path); - } - else - $success=@mail($to,$subject,$body,$headers); - return($success ? "" : $this->OutputPHPError("it was not possible to send e-mail message", error_get_last()['message'])); - } - - Function StartSendingMessage() - { - if(strcmp($this->delivery["State"],"")) - return($this->OutputError("the message was already started to be sent")); - $this->delivery=array("State"=>"SendingHeaders"); - return(""); - } - - Function SendMessageHeaders($headers) - { - if(strcmp($this->delivery["State"],"SendingHeaders")) - { - if(!strcmp($this->delivery["State"],"")) - return($this->OutputError("the message was not yet started to be sent")); - else - return($this->OutputError("the message headers were already sent")); - } - $this->delivery["Headers"]=$headers; - $this->delivery["State"]="SendingBody"; - return(""); - } - - Function SendMessageBody($data) - { - if(strcmp($this->delivery["State"],"SendingBody")) - return($this->OutputError("the message headers were not yet sent")); - if(IsSet($this->delivery["Body"])) - $this->delivery["Body"].=$data; - else - $this->delivery["Body"]=$data; - return(""); - } - - Function EndSendingMessage() - { - if(strcmp($this->delivery["State"],"SendingBody")) - return($this->OutputError("the message body data was not yet sent")); - if(!IsSet($this->delivery["Headers"]) - || count($this->delivery["Headers"])==0) - return($this->OutputError("message has no headers")); - $line_break=((defined("PHP_OS") && !strcmp(substr(PHP_OS,0,3),"WIN")) ? "\r\n" : $this->line_break); - $headers=$this->delivery["Headers"]; - for($has=array(),$headers_text="",$header=0,Reset($headers);$headerline_break.$header_line; - else - $headers_text=$header_line; - } - } - if(strlen($has["to"])==0 - && !IsSet($has["cc"]) - && !IsSet($has["bcc"])) - return($this->OutputError("it were not specified a valid To:, Cc: or Bcc: headers")); - if(!IsSet($has["subject"])) - return($this->OutputError("it was not specified a valid Subject: header")); - if(!IsSet($has["message-id"]) - && $this->auto_message_id) - { - $sender = $senders = array(); - if(IsSet($has["return-path"])) - $sender[] = $has["return-path"]; - if(IsSet($has["from"])) - $sender[] = $has["from"]; - $sender[] = $has["to"]; - $ts = count($sender); - for($s = 0; $s < $ts; ++$s) - { - $error = $this->GetRFC822Addresses($sender[$s], $senders); - if(strlen($error) == 0 - && count($senders)) - break; - } - if(count($senders) == 0) - return('it was not specified a valid sender address'.(strlen($error) ? ': '.$error : '')); - Reset($senders); - $sender=Key($senders); - $header_line=$this->GenerateMessageID($sender); - if(strlen($headers_text)) - $headers_text.=$this->line_break.$header_line; - else - $headers_text=$header_line; - } - if(strcmp($error=$this->SendMail(strlen($has["to"]) ? $has["to"] : (IsSet($has["cc"]) ? "" : "undisclosed-recipients: ;"), $has["subject"], $this->delivery["Body"], $headers_text, IsSet($has["return-path"]) ? $has["return-path"] : ""),"")) - return($error); - $this->delivery=array("State"=>""); - return(""); - } - - Function StopSendingMessage() - { - $this->delivery=array("State"=>""); - return(""); - } - - Function GetPartBoundary($part) - { - if(!IsSet($this->parts[$part]["BOUNDARY"])) - $this->parts[$part]["BOUNDARY"]=md5(uniqid($part.time())); - } - - Function GetPartHeaders(&$headers,$part) - { - if(IsSet($this->parts[$part]['CachedHeaders'])) - { - $headers = $this->parts[$part]['CachedHeaders']; - return(''); - } - if(!IsSet($this->parts[$part]["Content-Type"])) - return($this->OutputError("it was added a part without Content-Type: defined")); - $type=$this->Tokenize($full_type=strtolower($this->parts[$part]["Content-Type"]),"/"); - $sub_type=$this->Tokenize(""); - switch($type) - { - case "text": - case "image": - case "audio": - case "video": - case "application": - case "message": - if(IsSet($this->parts[$part]["NAME"])) - $filename = $this->QuotedPrintableEncode($this->parts[$part]["NAME"], $this->default_charset, 1, 1); - $headers["Content-Type"]=$full_type.(IsSet($this->parts[$part]["CHARSET"]) ? "; charset=".$this->parts[$part]["CHARSET"] : "").(IsSet($this->parts[$part]["NAME"]) ? "; name=\"".$filename."\"" : ""); - if(IsSet($this->parts[$part]["Content-Transfer-Encoding"])) - $headers["Content-Transfer-Encoding"]=$this->parts[$part]["Content-Transfer-Encoding"]; - if(IsSet($this->parts[$part]["DISPOSITION"]) - && strlen($this->parts[$part]["DISPOSITION"])) - $headers["Content-Disposition"]=$this->parts[$part]["DISPOSITION"].(IsSet($this->parts[$part]["NAME"]) ? "; filename=\"".$filename."\"" : ""); - break; - case "multipart": - switch($sub_type) - { - case "alternative": - case "related": - case "mixed": - case "parallel": - $this->GetPartBoundary($part); - $headers["Content-Type"]=$full_type."; boundary=\"".$this->parts[$part]["BOUNDARY"]."\""; - break; - default: - return($this->OutputError("multipart Content-Type sub_type $sub_type not yet supported")); - } - break; - default: - return($this->OutputError("Content-Type: $full_type not yet supported")); - } - if(IsSet($this->parts[$part]["Content-ID"])) - $headers["Content-ID"]="<".$this->parts[$part]["Content-ID"].">"; - if(IsSet($this->parts[$part]['Cache']) - && $this->parts[$part]['Cache']) - $this->parts[$part]['CachedHeaders'] = $headers; - return(""); - } - - Function GetPartBody(&$body,$part) - { - if(IsSet($this->parts[$part]['CachedBody'])) - { - $body = $this->parts[$part]['CachedBody']; - return(''); - } - if(!IsSet($this->parts[$part]["Content-Type"])) - return($this->OutputError("it was added a part without Content-Type: defined")); - $type=$this->Tokenize($full_type=strtolower($this->parts[$part]["Content-Type"]),"/"); - $sub_type=$this->Tokenize(""); - $body=""; - switch($type) - { - case "text": - case "image": - case "audio": - case "video": - case "application": - case "message": - if(IsSet($this->parts[$part]["FILENAME"])) - { - $size=@filesize($this->parts[$part]["FILENAME"]); - if(!($file=@fopen($this->parts[$part]["FILENAME"],"rb"))) - return($this->OutputPHPError("could not open part file ".$this->parts[$part]["FILENAME"], error_get_last()['message'])); - while(!feof($file)) - { - if(GetType($block=@fread($file,$this->file_buffer_length))!="string") - { - fclose($file); - return($this->OutputPHPError("could not read part file", error_get_last()['message'])); - } - $body.=$block; - } - fclose($file); - if((GetType($size)=="integer" - && strlen($body)>$size) - || (function_exists("get_magic_quotes_runtime") - && get_magic_quotes_runtime())) - $body=StripSlashes($body); - if(GetType($size)=="integer" - && strlen($body)!=$size) - return($this->OutputError("the length of the file that was read does not match the size of the part file ".$this->parts[$part]["FILENAME"]." due to possible data corruption")); - } - else - { - if(!IsSet($this->parts[$part]["DATA"])) - return($this->OutputError("it was added a part without a body PART")); - $body=$this->parts[$part]["DATA"]; - } - $encoding=(IsSet($this->parts[$part]["Content-Transfer-Encoding"]) ? strtolower($this->parts[$part]["Content-Transfer-Encoding"]) : ""); - switch($encoding) - { - case "base64": - $body=chunk_split(base64_encode($body), $this->line_length, $this->line_break); - break; - case "": - case "quoted-printable": - case "7bit": - break; - default: - return($this->OutputError($encoding." is not yet a supported encoding type")); - } - break; - case "multipart": - switch($sub_type) - { - case "alternative": - case "related": - case "mixed": - case "parallel": - $this->GetPartBoundary($part); - $boundary="--".$this->parts[$part]["BOUNDARY"]; - $parts=count($this->parts[$part]["PARTS"]); - $b = $this->line_break; - $lb = strlen($b); - for($multipart=0;$multipart<$parts;$multipart++) - { - if(strlen($body) >= $lb - && strcmp(substr($body, -$lb), $b)) - $body.=$b; - $body.=$boundary.$this->line_break; - $part_headers=array(); - $sub_part=$this->parts[$part]["PARTS"][$multipart]; - if(strlen($error=$this->GetPartHeaders($part_headers,$sub_part))) - return($error); - for($part_header=0,Reset($part_headers);$part_headerGetPartBody($part_body,$sub_part))) - return($error); - $body.=$part_body; - } - if(strlen($body) >= $lb - && strcmp(substr($body, -$lb), $b)) - $body.=$b; - $body.=$boundary."--".$b; - break; - default: - return($this->OutputError("multipart Content-Type sub_type $sub_type not yet supported")); - } - break; - default: - return($this->OutputError("Content-Type: $full_type not yet supported")); - } - if(IsSet($this->parts[$part]['Cache']) - && $this->parts[$part]['Cache']) - $this->parts[$part]['CachedBody'] = $body; - return(""); - } - - /* Public functions */ - -/* -{metadocument} - - ValidateEmailAddress - BOOLEAN - - Determine whether a given e-mail address may be - valid. - Just pass the e-mail - ValidateEmailAddress - address - to be checked as function argument. This function - uses the regular expression defined by the - email_regular_expression variable to - check the address. - The function returns - 1 if the specified address - may be valid. - - - address - STRING - - Specify the e-mail address to be validated. - - - -{/metadocument} -*/ - Function ValidateEmailAddress($address) - { - return(preg_match('/'.str_replace('/', '\\/', $this->email_regular_expression).'/i',$address)); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function EncodeCharacter($matches) - { - return sprintf('=%02X', Ord($matches[1])); - } - - Function QuotedPrintableEncode($text, $header_charset='', $break_lines=1, $email_header = 0) - { - $ln=strlen($text); - $h=(strlen($header_charset)>0); - if($h) - { - $encode = array( - '='=>1, - '?'=>1, - '_'=>1, - '('=>1, - ')'=>1, - '<'=>1, - '>'=>1, - '@'=>1, - ','=>1, - ';'=>1, - '"'=>1, - '\\'=>1, - '['=>1, - ']'=>1, - ':'=>1, -/* - '/'=>1, - '.'=>1, -*/ - ); - $s=($email_header ? $encode : array()); - $b=$space=$break_lines=0; - for($i=0; $i<$ln; ++$i) - { - $c = $text[$i]; - if(IsSet($s[$c])) - { - $b=1; - break; - } - switch($o=Ord($c)) - { - case 9: - case 32: - $space=$i+1; - $b=1; - break 2; - case 10: - case 13: - break 2; - default: - if($o<32 - || $o>127) - { - $b=1; - $s = $encode; - break 2; - } - } - } - if($i==$ln) - return($text); - if($space>0) - return(substr($text,0,$space).($space<$ln ? $this->QuotedPrintableEncode(substr($text,$space), $header_charset, $break_lines, $email_header) : "")); - } - elseif(function_exists('quoted_printable_encode')) - { - $different = strcmp($this->line_break, "\r\n"); - if($different) - $text = str_replace($this->line_break, "\r\n", str_replace("\r\n", $this->line_break, $text)); - $encoded = preg_replace_callback('/^(f|F|\\.)/m', array($this, 'EncodeCharacter'), quoted_printable_encode($text)); - if($different) - $encoded = str_replace("\r\n", $this->line_break, $encoded); - return $encoded; - } - for($w=$e='',$n=0, $l=0,$i=0;$i<$ln; ++$i) - { - $c = $text[$i]; - $o=Ord($c); - $en=0; - switch($o) - { - case 9: - case 32: - if(!$h) - { - $w=$c; - $c=''; - } - else - { - if($b) - { - if($o==32) - $c='_'; - else - $en=1; - } - } - break; - case 10: - case 13: - if(strlen($w)) - { - if($break_lines - && $l+3>75) - { - $e.='='.$this->line_break; - $l=0; - } - $e.=sprintf('=%02X',Ord($w)); - $l+=3; - $w=''; - } - $e.=$c; - if($h) - $e.="\t"; - $l=0; - continue 2; - case 46: - case 70: - case 102: - $en=(!$h && ($l==0 || $l+1>75)); - break; - default: - if($o>127 - || $o<32 - || !strcmp($c,'=')) - $en=1; - elseif($h - && IsSet($s[$c])) - $en=1; - break; - } - if(strlen($w)) - { - if($break_lines - && $l+1>75) - { - $e.='='.$this->line_break; - $l=0; - } - $e.=$w; - ++$l; - $w=''; - } - if(strlen($c)) - { - if($en) - { - $c=sprintf('=%02X',$o); - $el=3; - $n=1; - $b=1; - } - else - $el=1; - if($break_lines - && $l+$el>75) - { - $e.='='.$this->line_break; - $l=0; - } - $e.=$c; - $l+=$el; - } - } - if(strlen($w)) - { - if($break_lines - && $l+3>75) - $e.='='.$this->line_break; - $e.=sprintf('=%02X',Ord($w)); - } - if($h - && $n) - return('=?'.$header_charset.'?q?'.$e.'?='); - else - return($e); - } - -/* -{metadocument} - - WrapText - STRING - - Split a text in lines that do not exceed the length limit - avoiding to break it in the middle of any words. - Just pass the - WrapText - text - to be wrapped. - The wrapped text eventually broken in multiple lines - that do not exceed the line length limit. - - - text - STRING - - Text to be wrapped. - - - - line_length - INTEGER - 0 - - Line length limit. Pass a value different than - 0 to use a line length - limit other than the default of 75 characters. - - - - line_break - STRING - - - Character sequence that is used to break the lines longer - than the length limit. Pass a non-empty to use a line breaking - sequence other than the default - . - - - - line_prefix - STRING - - - Character sequence that is used to insert in the beginning - of all lines. - - - -{/metadocument} -*/ - Function WrapText($text,$line_length=0,$line_break="",$line_prefix="") - { - if(strlen($line_break)==0) - $line_break=$this->line_break; - if($line_length==0) - $line_length=$this->line_length; - $lines=explode("\n",str_replace("\r","\n",str_replace("\r\n","\n",$text))); - for($wrapped="",$line=0;$line$line_length;) - { - if(GetType($cut=strrpos(substr($text_line,0,$line_length)," "))!="integer" - || $cutbreak_long_lines) - { - $wrapped.=substr($text_line,0,$line_length).$line_break; - $cut=$line_length; - } - elseif(GetType($cut=strpos($text_line," ",$line_length))=="integer") - { - $wrapped.=substr($text_line, 0, $cut).$line_break; - ++$cut; - } - else - { - $wrapped.=$text_line.$line_break; - $cut=strlen($text_line); - } - } - else - { - $wrapped.=substr($text_line,0,$cut).$line_break; - ++$cut; - } - $text_line=substr($text_line,$cut); - } - } - $wrapped.=$text_line.$line_break; - } - return($wrapped); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - CenterText - STRING - - Center a text in the middle of line. - Just pass the - CenterText - text - to be centered. - The centered text. - - - text - STRING - - Text to be centered. - - - - line_length - INTEGER - 0 - - Line length limit. Pass a value different than - 0 to use a line length - limit other than the default of 75 characters. - - - -{/metadocument} -*/ - Function CenterText($text, $line_length=0) - { - if($line_length==0) - $line_length=$this->line_length; - $length = strlen($text); - if($length<$line_length) - $text = str_repeat(' ', ($line_length-$length)/2).$text; - return($text); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - Ruler - STRING - - Generate a line with characters that can be displayed as a - separator ruler in a text message. - The ruler line string. - - - line_length - INTEGER - 0 - - Line length limit. Pass a value different than - 0 to use a line length - limit other than the default of 75 characters. - - - -{/metadocument} -*/ - Function Ruler($line_length=0) - { - if($line_length==0) - $line_length=$this->line_length; - return(str_repeat($this->ruler, $line_length)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - QuoteText - STRING - - Mark a text block to appear like in reply messages composed - with common e-mail programs that include text from the original - message being replied. - Just pass the - QuoteText - text - to be marked as a quote. - The quoted text with all lines prefixed with a quote - prefix mark. - - - text - STRING - - Text to be quoted. - - - - quote_prefix - STRING - - - Character sequence that is inserted in the beginning of - all lines as a quote mark. Set to an empty string to tell the - function to use the default specified by the - line_quote_prefix variable. - - - -{/metadocument} -*/ - Function QuoteText($text,$quote_prefix="") - { - if(strlen($quote_prefix)==0) - $quote_prefix=$this->line_quote_prefix; - return($this->WrapText($text,$line_length=0,$line_break="",$quote_prefix)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - SetHeader - STRING - - Set the value of a message header. - Use this function to set the values of the headers of the - message that may be needed. There are some message headers that are - automatically set by the class when the message is sent. Others - must be defined before sending. Here follows the list of the names - of the headers that must be set before sending: - - Message subject - Subject - Sender address - From - Recipient addresses - To, Cc and - Bcc - Each of the recipient address headers may contain one or more - addresses. Multiple addresses must be separated by a comma and a - space. - Return path address - Return-Path - Optional header to specify the address where the message should be - bounced in case it is not possible to deliver it. - In reality this is a virtual header. This means that adding this - header to a message will not do anything by itself. However, this - class looks for this header to adjust the message delivery - procedure in such way that the Message Transfer Agent (MTA) system - is hinted to direct any bounced messages to the address specified - by this header. - Note that under some systems there is no way to set the return path - address programmatically. This is the case when using the PHP - mail() function under Windows where the return path - address should be set in the php.ini configuration - file. - Keep in mind that even when it is possible to set the return path - address, the systems of some e-mail account providers may ignore - this address and send bounced messages to the sender address. This - is a bug of those systems. There is nothing that can be done other - than complain. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - header - STRING - - Name of the header. - - - - value - STRING - - Text value for the header. - - - - encoding_charset - STRING - - - Character set used in the header value. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - -{/metadocument} -*/ - Function SetHeader($header, $value, $encoding_charset="") - { - if(strlen($this->error)) - return($this->error); - $this->headers[strval($header)]=(!strcmp($encoding_charset,"") ? strval($value) : $this->QuotedPrintableEncode($value, $encoding_charset, 1, 0)); - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - SetEncodedHeader - STRING - - The same as the SetHeader - function assuming the default character set specified by the - default_charset variable. - See the SetHeader function. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - header - STRING - - Name of the header. - - - - value - STRING - - Text value for the header. - - - - encoding_charset - STRING - - - Character set used in the header value. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - -{/metadocument} -*/ - Function SetEncodedHeader($header,$value, $encoding_charset = '') - { - return($this->SetHeader($header,$value,strlen($encoding_charset) ? $encoding_charset : $this->default_charset)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - SetEncodedEmailHeader - STRING - - Set the value of an header that is meant to represent the - e-mail address of a person or entity with a known name. This is - meant mostly to set the From, To, Cc and - Bcc headers. - Use this function like the - SetHeader specifying the e-mail - - SetEncodedEmailHeader - address - as header value and also specifying the - - SetEncodedEmailHeader - name - of the known person or entity. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - header - STRING - - Name of the header. - - - - address - STRING - - E-mail address value. - - - - name - STRING - - Person or entity name associated with the specified e-mail - address. - - - - encoding_charset - STRING - - - Character set used in the header value. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - -{/metadocument} -*/ - Function SetEncodedEmailHeader($header, $address, $name, $encoding_charset = '') - { - return($this->SetHeader($header,$this->QuotedPrintableEncode($name, strlen($encoding_charset) ? $encoding_charset : $this->default_charset, 1, 1).' <'.$address.'>')); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - SetMultipleEncodedEmailHeader - STRING - - Set the value of an header that is meant to represent a list - of e-mail addresses of names of people or entities. This is meant - mostly to set the To, Cc and Bcc - headers. - Use this function specifying the - SetMultipleEncodedEmailHeader - header - and all the - SetMultipleEncodedEmailHeader - addresses - in an associative array that should have - the email addresses as entry indexes and the name of the respective - people or entities as entry values. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. -
$message_object->SetMultipleEncodedEmailHeader('Bcc', array(
-  'peter@gabriel.org' => 'Peter Gabriel',
-  'paul@simon.net' => 'Paul Simon',
-  'mary@chain.com' => 'Mary Chain'
-));
-
- - header - STRING - - Name of the header. - - - - addresses - HASH - - List of all email addresses and associated person or - entity names. - - - - encoding_charset - STRING - - - Character set used in the header value. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - -{/metadocument} -*/ - Function SetMultipleEncodedEmailHeader($header,$addresses, $encoding_charset = '') - { - Reset($addresses); - $end=(GetType($address=Key($addresses))!="string"); - for($value="";!$end;) - { - if(strlen($value)) - $value.=", "; - $value.=$this->QuotedPrintableEncode($addresses[$address], strlen($encoding_charset) ? $encoding_charset : $this->default_charset, 1, 1).' <'.$address.'>'; - Next($addresses); - $end=(GetType($address=Key($addresses))!="string"); - } - return($this->SetHeader($header,$value)); - } -/* -{metadocument} - -
-{/metadocument} -*/ - -/* -{metadocument} - - ResetMessage - VOID - - Restore the content of the message to the initial state when - the class object is created, i.e. without any headers or body - parts. - Use this function if you want to start composing a completely - new message. - - -{/metadocument} -*/ - Function ResetMessage() - { - $this->headers=array(); - $this->body=-1; - $this->body_parts=0; - $this->parts=array(); - $this->total_parts=0; - $this->free_parts=array(); - $this->total_free_parts=0; - $this->delivery=array("State"=>""); - $this->error=""; - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function CreatePart(&$definition,&$part) - { - $part=-1; - if(strlen($this->error)) - return($this->error); - if($this->total_free_parts) - { - $this->total_free_parts--; - $part=$this->free_parts[$this->total_free_parts]; - Unset($this->free_parts[$this->total_free_parts]); - } - else - { - $part=$this->total_parts; - ++$this->total_parts; - } - $this->parts[$part]=$definition; - return(""); - } - -/* -{metadocument} - - AddPart - STRING - - Add a previously created part to the message. - Use any of the functions to create standalone message parts - and then use this function to add them to the message. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - part - INTEGER - - Number of the part as returned by the function that - originally created it. - - - -{/metadocument} -*/ - Function AddPart($part) - { - if(strlen($this->error)) - return($this->error); - switch($this->body_parts) - { - case 0; - $this->body=$part; - break; - case 1: - $parts=array( - $this->body, - $part - ); - if(strlen($error=$this->CreateMixedMultipart($parts,$body))) - return($error); - $this->body=$body; - break; - default: - $this->parts[$this->body]["PARTS"][]=$part; - break; - } - ++$this->body_parts; - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - ReplacePart - STRING - - Replace a message part already added to the message with a - newly created part. The replaced part gets the definition of the - replacing part. The replacing part is discarded and its part number - becomes free for creation of a new part. - Use one of the functions to create message parts and then pass - the returned part numbers to this function. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - old_part - INTEGER - - Number of the previously added part. - - - - new_part - INTEGER - - Number of the replacing part. - - - -{/metadocument} -*/ - Function ReplacePart($old_part,$new_part) - { - if(strlen($this->error)) - return($this->error); - if(!IsSet($this->parts[$old_part])) - return($this->error="it was attempted to replace an invalid message part"); - if(IsSet($this->parts[$old_part]["FREE"])) - return($this->error="it was attempted to replace a message part that is no longer valid"); - if(!IsSet($this->parts[$new_part])) - return($this->error="it was attempted to use an invalid message replacecement part"); - if(IsSet($this->parts[$new_part]["FREE"])) - return($this->error="it was attempted to use a message replacecement part that is no longer valid"); - $this->parts[$old_part]=$this->parts[$new_part]; - $this->parts[$new_part]=array("FREE"=>1); - $this->free_parts[$this->total_free_parts]=$new_part; - ++$this->total_free_parts; - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function CreateAndAddPart(&$definition) - { - if(strlen($error=$this->CreatePart($definition,$part)) - || strlen($error=$this->AddPart($part))) - return($error); - return(""); - } - -/* -{metadocument} - - CreatePlainTextPart - STRING - - Create a plain text message part. - Pass an ASCII (7 bits) - CreatePlainTextPart - text - string and get the created part number in the - - CreatePlainTextPart - part - that is returned by reference. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - text - STRING - - Text of the message part to create. - - - - charset - STRING - - Character set used in the part text. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreatePlainTextPart($text,$charset,&$part) - { - if(!strcmp($charset,"")) - $charset=$this->default_charset; - $definition=array( - "Content-Type"=>"text/plain", - "DATA"=>$text - ); - if(strcmp(strtoupper($charset),"ASCII")) - $definition["CHARSET"]=$charset; - return($this->CreatePart($definition,$part)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - AddPlainTextPart - STRING - - Add a plain text part to the message. - Pass an ASCII (7 bits) - AddPlainTextPart - text - string. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - text - STRING - - Text of the message part to add. - - - - charset - STRING - - - Character set used in the part text. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - -{/metadocument} -*/ - Function AddPlainTextPart($text,$charset="") - { - if(strlen($error=$this->CreatePlainTextPart($text,$charset,$part)) - || strlen($error=$this->AddPart($part))) - return($error); - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function CreateEncodedQuotedPrintableTextPart($text,$charset,&$part) - { - if(!strcmp($charset,"")) - $charset=$this->default_charset; - $definition=array( - "Content-Type"=>"text/plain", - "Content-Transfer-Encoding"=>"quoted-printable", - "CHARSET"=>$charset, - "DATA"=>$text - ); - return($this->CreatePart($definition,$part)); - } - - Function AddEncodedQuotedPrintableTextPart($text,$charset="") - { - if(strlen($error=$this->CreateEncodedQuotedPrintableTextPart($text,$charset,$part)) - || strlen($error=$this->AddPart($part))) - return($error); - return(""); - } - -/* -{metadocument} - - CreateQuotedPrintableTextPart - STRING - - Create a text message part that may contain non-ASCII - characters (8 bits or more). - Pass a - CreateQuotedPrintableTextPart - text - string and get the created part number in the - - CreateQuotedPrintableTextPart - part - that is returned by reference. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - text - STRING - - Text of the message part to create. - - - - charset - STRING - - Character set used in the part text. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreateQuotedPrintableTextPart($text,$charset,&$part) - { - return($this->CreateEncodedQuotedPrintableTextPart($this->QuotedPrintableEncode($text),$charset,$part)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - AddQuotedPrintableTextPart - STRING - - Add a text part to the message that may contain non-ASCII - characters (8 bits or more). - Pass a - AddQuotedPrintableTextPart - text - string. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - text - STRING - - Text of the message part to create. - - - - charset - STRING - - - Character set used in the part text. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - -{/metadocument} -*/ - Function AddQuotedPrintableTextPart($text,$charset="") - { - return($this->AddEncodedQuotedPrintableTextPart($this->QuotedPrintableEncode($text),$charset)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - CreateHTMLPart - STRING - - Create an HTML message part only with ASCII characters (7 bit). - Pass an ASCII (7 bits) - CreateHTMLPart - html - text string and get the created part number in the - - CreateHTMLPart - part - that is returned by reference. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - html - STRING - - HTML of the message part to create. - - - - charset - STRING - - Character set used in the part text. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreateHTMLPart($html,$charset,&$part) - { - if(!strcmp($charset,"")) - $charset=$this->default_charset; - $definition=array( - "Content-Type"=>"text/html", - "CHARSET"=>$charset, - "DATA"=>$html - ); - return($this->CreatePart($definition,$part)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - AddHTMLPart - STRING - - Add an HTML part to the message only with ASCII characters. - Pass an - AddHTMLPart - html - text string. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - html - STRING - - HTML of the message part to create. - - - - charset - STRING - - - Character set used in the part text. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - -{/metadocument} -*/ - Function AddHTMLPart($html,$charset="") - { - if(strlen($error=$this->CreateHTMLPart($html,$charset,$part)) - || strlen($error=$this->AddPart($part))) - return($error); - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function CreateEncodedQuotedPrintableHTMLPart($html,$charset,&$part) - { - if(!strcmp($charset,"")) - $charset=$this->default_charset; - $definition=array( - "Content-Type"=>"text/html", - "Content-Transfer-Encoding"=>"quoted-printable", - "CHARSET"=>$charset, - "DATA"=>$html - ); - return($this->CreatePart($definition,$part)); - } - - Function AddEncodedQuotedPrintableHTMLPart($html,$charset="") - { - if(strlen($error=$this->CreateEncodedQuotedPrintableHTMLPart($html,$charset,$part)) - || strlen($error=$this->AddPart($part))) - return($error); - return(""); - } - -/* -{metadocument} - - CreateQuotedPrintableHTMLPart - STRING - - Create an HTML message part that may contain non-ASCII - characters (8 bits or more). - Pass a - CreateQuotedPrintableHTMLPart - html - text string and get the created part number in the - - CreateQuotedPrintableHTMLPart - part - that is returned by reference. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - html - STRING - - HTML of the message part to create. - - - - charset - STRING - - Character set used in the part text. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreateQuotedPrintableHTMLPart($html,$charset,&$part) - { - return($this->CreateEncodedQuotedPrintableHTMLPart($this->QuotedPrintableEncode($html),$charset,$part)); - } -/* -{metadocument} - - -{/metadocument} -*/ - - -/* -{metadocument} - - AddQuotedPrintableHTMLPart - STRING - - Add an HTML part to the message that may contain non-ASCII - characters (8 bits or more). - Pass a - AddQuotedPrintableHTMLPart - html - text string. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - html - STRING - - HTML of the message part to create. - - - - charset - STRING - - - Character set used in the part text. If it is set to an - empty string, it is assumed the character set defined by the - default_charset variable. - - - -{/metadocument} -*/ - Function AddQuotedPrintableHTMLPart($html,$charset="") - { - return($this->AddEncodedQuotedPrintableHTMLPart($this->QuotedPrintableEncode($html),$charset)); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function GetFileDefinition($file, &$definition, $require_name=1) - { - if(strlen($this->error)) - return($this->error); - $name=""; - if(IsSet($file["FileName"])) - $name=basename($file["FileName"]); - else - { - if(!IsSet($file["Data"])) - return($this->OutputError("it was not specified the file part file name")); - } - if(IsSet($file["Name"])) - $name=$file["Name"]; - if($require_name - && strlen($name)==0) - return($this->OutputError("it was not specified the file part name")); - $encoding="base64"; - if(IsSet($file["Content-Type"])) - { - $content_type=$file["Content-Type"]; - $type=$this->Tokenize(strtolower($content_type),"/"); - $sub_type=$this->Tokenize(""); - switch($type) - { - case "text": - case "image": - case "audio": - case "video": - case "application": - break; - case "message": - $encoding="7bit"; - break; - case "automatic": - switch($sub_type) - { - case "name": - if(strlen($name)==0) - return($this->OutputError("it is not possible to determine content type from the name")); - switch(strtolower($this->GetFilenameExtension($name))) - { - case ".xls": - $content_type="application/excel"; - break; - case ".hqx": - $content_type="application/macbinhex40"; - break; - case ".doc": - case ".dot": - case ".wrd": - $content_type="application/msword"; - break; - case ".pdf": - $content_type="application/pdf"; - break; - case ".pgp": - $content_type="application/pgp"; - break; - case ".ps": - case ".eps": - case ".ai": - $content_type="application/postscript"; - break; - case ".ppt": - $content_type="application/powerpoint"; - break; - case ".rtf": - $content_type="application/rtf"; - break; - case ".tgz": - case ".gtar": - $content_type="application/x-gtar"; - break; - case ".gz": - $content_type="application/x-gzip"; - break; - case ".php": - case ".php3": - $content_type="application/x-httpd-php"; - break; - case ".js": - $content_type="application/x-javascript"; - break; - case ".ppd": - case ".psd": - $content_type="application/x-photoshop"; - break; - case ".swf": - case ".swc": - case ".rf": - $content_type="application/x-shockwave-flash"; - break; - case ".tar": - $content_type="application/x-tar"; - break; - case ".zip": - $content_type="application/zip"; - break; - case ".mid": - case ".midi": - case ".kar": - $content_type="audio/midi"; - break; - case ".mp2": - case ".mp3": - case ".mpga": - $content_type="audio/mpeg"; - break; - case ".ra": - $content_type="audio/x-realaudio"; - break; - case ".wav": - $content_type="audio/wav"; - break; - case ".bmp": - $content_type="image/bitmap"; - break; - case ".gif": - $content_type="image/gif"; - break; - case ".iff": - $content_type="image/iff"; - break; - case ".jb2": - $content_type="image/jb2"; - break; - case ".jpg": - case ".jpe": - case ".jpeg": - $content_type="image/jpeg"; - break; - case ".jpx": - $content_type="image/jpx"; - break; - case ".png": - $content_type="image/png"; - break; - case ".tif": - case ".tiff": - $content_type="image/tiff"; - break; - case ".wbmp": - $content_type="image/vnd.wap.wbmp"; - break; - case ".xbm": - $content_type="image/xbm"; - break; - case ".css": - $content_type="text/css"; - break; - case ".txt": - $content_type="text/plain"; - break; - case ".htm": - case ".html": - $content_type="text/html"; - break; - case ".xml": - $content_type="text/xml"; - break; - case ".mpg": - case ".mpe": - case ".mpeg": - $content_type="video/mpeg"; - break; - case ".qt": - case ".mov": - $content_type="video/quicktime"; - break; - case ".avi": - $content_type="video/x-ms-video"; - break; - case ".eml": - $content_type="message/rfc822"; - $encoding="7bit"; - break; - default: - $content_type="application/octet-stream"; - break; - } - break; - default: - return($this->OutputError($content_type." is not a supported automatic content type detection method")); - } - break; - default: - return($this->OutputError($content_type." is not a supported file content type")); - } - } - else - $content_type="application/octet-stream"; - $definition=array( - "Content-Type"=>$content_type, - "Content-Transfer-Encoding"=>$encoding, - "NAME"=>$name - ); - if(IsSet($file["Disposition"])) - { - switch(strtolower($file["Disposition"])) - { - case "inline": - case "attachment": - break; - default: - return($this->OutputError($file["Disposition"]." is not a supported message part content disposition")); - } - $definition["DISPOSITION"]=$file["Disposition"]; - } - if(IsSet($file["FileName"])) - $definition["FILENAME"]=$file["FileName"]; - else - { - if(IsSet($file["Data"])) - $definition["DATA"]=$file["Data"]; - } - if(IsSet($file['Cache']) - && $file['Cache']) - $definition['Cache'] = 1; - if(IsSet($file['Content-ID']) - && $file['Content-ID']) - $definition['Content-ID'] = $file['Content-ID']; - return(""); - } - -/* -{metadocument} - - CreateFilePart - STRING - - Create a message part to be handled as a file. - Pass a - CreateFilePart - file - definition associative array and get the created - part number in the - CreateFilePart - part - that is returned by reference. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - file - HASH - - Associative array to specify parameters that describe the - file part. Here follows the list of supported parameters that - should be used as indexes of the array: - FileName - Name of the file from which the part data will be read when the - message is generated. It may be a remote URL as long as your PHP - installation is configured to allow accessing remote files with - the fopen() function. - Data - String that specifies the data of the file. This should be used - as alternative data source to FileName for passing data - available in memory, like for instance files stored in a database - that was queried dynamically and the file contents was fetched - into a string variable. - Name - Name of the file that will appear in the message. If this - parameter is missing the base name of the FileName - parameter is used, if present. - Content-Type - Content type of the part: text/plain for text, - text/html for HTML, image/gif for GIF images, - etc.. - There is one special type named automatic/name that may - be used to tell the class to try to guess the content type from - the file name. Many file types are recognized from the file name - extension. If the file name extension is not recognized, the - default for binary data application/octet-stream is - assumed. - Disposition - Information to whether this file part is meant to be used as a - file attachment or as a part meant to be displayed - inline, eventually integrated with another related - part. - Cache - Boolean flag that indicates that this message part should be - cached when generating the message body. Use only when sending - many messages to multiple recipients, but this part does not - change between each of the messages that are sent. - Note that it is also not worth using this option when setting the - cache_body, as that variable makes - the class cache the whole message body and the internal message - parts will not be rebuilt. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreateFilePart(&$file,&$part) - { - if(strlen($this->GetFileDefinition($file,$definition))) - return($this->error); - return($this->CreatePart($definition,$part)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - AddFilePart - STRING - - Add a message part to be handled as a file. - Pass a - AddFilePart - file - definition associative array. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - file - HASH - - Associative array to specify parameters that describe the - file part. See the - CreateFilePart - file - argument description of the - CreateFilePart function for an - explanation about the supported file parameters. - - - -{/metadocument} -*/ - Function AddFilePart(&$file) - { - if(strlen($error=$this->CreateFilePart($file,$part)) - || strlen($error=$this->AddPart($part))) - return($error); - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - CreateMessagePart - STRING - - Create a message part to encapsulate another message. This - is usually meant to create an attachment that contains a message - that was received and is being forwarded intact with the original - the headers and body data. - This function should be used like the - CreateFilePart function, passing the - same parameters to the - CreateMessagePart - message - argument. - The message to be encapsulated can be specified either as an - existing file with the FileName parameter, or as string - of data in memory with the Data - parameter. - The Content-Type and Disposition file parameters - do not need to be specified because they are overridden by this - function. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - message - HASH - - Associative array that specifies definition parameters of - the message file part. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreateMessagePart(&$message,&$part) - { - $message["Content-Type"]="message/rfc822"; - $message["Disposition"]="inline"; - if(strlen($this->GetFileDefinition($message,$definition))) - return($this->error); - return($this->CreatePart($definition,$part)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - AddMessagePart - STRING - - Add a message part that encapsulates another message. This - is usually meant to add an attachment that contains a message that - was received and is being forwarded intact with the original the - headers and body data. - This function should be used like the - AddFilePart function, passing the - same parameters to the - AddMessagePart - message - argument. See the - CreateFilePart function for more - details. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - message - HASH - - Associative array that specifies definition parameters of - the message file part. - - - -{/metadocument} -*/ - Function AddMessagePart(&$message) - { - if(strlen($error=$this->CreateMessagePart($message,$part)) - || strlen($error=$this->AddPart($part))) - return($error); - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function CreateMultipart(&$parts,&$part,$type) - { - $definition=array( - "Content-Type"=>"multipart/".$type, - "PARTS"=>$parts - ); - return($this->CreatePart($definition,$part)); - } - - Function AddMultipart(&$parts,$type) - { - if(strlen($error=$this->CreateMultipart($parts,$part,$type)) - || strlen($error=$this->AddPart($part))) - return($error); - return(""); - } - -/* -{metadocument} - - CreateAlternativeMultipart - STRING - - Create a message part composed of multiple parts that can be - displayed by the recipient e-mail program in alternative - formats. - This is usually meant to create HTML messages with an alternative - text part to be displayed by programs that cannot display HTML - messages. - Create all the alternative message parts that are going to be - sent and pass their numbers to the - CreateAlternativeMultipart - parts - array argument. - The least sophisticated part, usually the text part, should appear - first in the parts array because the e-mail programs that support - displaying more sophisticated message parts will pick the last part - in the message that is supported. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - parts - ARRAY - - Array with the numbers with all the alternative parts. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreateAlternativeMultipart(&$parts,&$part) - { - return($this->CreateMultiPart($parts,$part,"alternative")); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - AddAlternativeMultipart - STRING - - Add a message part composed of multiple parts that can be - displayed by the recipient e-mail program in alternative - formats. - This is usually meant to create HTML messages with an alternative - text part to be displayed by programs that cannot display HTML - messages. - Create all the alternative message parts that are going to be - sent and pass their numbers to the - AddAlternativeMultipart - parts - array argument. - The least sophisticated part, usually the text part, should appear - first in the parts array because the e-mail programs that support - displaying more sophisticated message parts will pick the last part - in the message that is supported. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - parts - ARRAY - - Array with the numbers with all the alternative parts. - - - -{/metadocument} -*/ - Function AddAlternativeMultipart(&$parts) - { - return($this->AddMultipart($parts,"alternative")); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - CreateRelatedMultipart - STRING - - Create a message part that groups several related - parts. - This is usually meant to group an HTML message part with images or - other types of files that should be embedded in the same message - and be displayed as a single part by the recipient e-mail - program. - Create all the related message parts that are going to be - sent and pass their numbers to the - CreateRelatedMultipart - parts - array argument. - When using this function to group an HTML message with embedded - images or other related files, make sure that the HTML part number - is the first listed in the - CreateRelatedMultipart - parts - array argument, or else the message may not appear - correctly. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - parts - ARRAY - - Array with the numbers with all the related parts. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreateRelatedMultipart(&$parts,&$part) - { - return($this->CreateMultipart($parts,$part,"related")); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - AddRelatedMultipart - STRING - - Add a message part that groups several related - parts. - This is usually meant to group an HTML message part with images or - other types of files that should be embedded in the same message - and be displayed as a single part by the recipient e-mail - program. - Create all the related message parts that are going to be - sent and pass their numbers to the - AddRelatedMultipart - parts - array argument. - When using this function to group an HTML message with embedded - images or other related files, make sure that the HTML part number - is the first listed in the - AddRelatedMultipart - parts - array argument, or else the message may not appear - correctly. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - parts - ARRAY - - Array with the numbers with all the related parts. - - - -{/metadocument} -*/ - Function AddRelatedMultipart(&$parts) - { - return($this->AddMultipart($parts,"related")); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - CreateMixedMultipart - STRING - - Create a message part that groups several independent - parts. - Usually this is meant compose messages with one or more file - attachments. However, it is not necessary to use this function as - the class implicitly creates a multipart/mixed message - when more than one part is added to the message. - Create all the independent message parts that are going to be - sent and pass their numbers to the - CreateMixedMultipart - parts - array argument. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - parts - ARRAY - - Array with the numbers with all the related parts. - - - - part - INTEGER - - - Number of the created part that is returned by reference. - - - -{/metadocument} -*/ - Function CreateMixedMultipart(&$parts,&$part) - { - return($this->CreateMultipart($parts,$part,"mixed")); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - AddMixedMultipart - STRING - - Add a message part that groups several independent - parts. - Usually this is meant compose messages with one or more file - attachments. However, it is not necessary to use this function as - the class implicitly creates a multipart/mixed message - when more than one part is added to the message. - Create all the independent message parts that are going to be - sent and pass their numbers to the - AddMixedMultipart - parts - array argument. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - parts - ARRAY - - Array with the numbers with all the related parts. - - - -{/metadocument} -*/ - Function AddMixedMultipart(&$parts) - { - return($this->AddMultipart($parts,"mixed")); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function CreateParallelMultipart(&$parts,&$part) - { - return($this->CreateMultipart($parts,$part,"paralell")); - } - - Function AddParalellMultipart(&$parts) - { - return($this->AddMultipart($parts,"paralell")); - } - -/* -{metadocument} - - GetPartContentID - STRING - - Retrieve the content identifier associated to a given - message part. - Create a message part and pass its number to the - GetPartContentID - part - argument. - This function is usually meant to create an URL that can be used - in an HTML message part to reference related parts like images, CSS - (Cascaded Style Sheets), or any other type of files related to the - HTML part that are embedded in the same message as part of a - multipart/related composite part. - To use the part content identifier returned by this function you - need to prepend the string cid: - to form a special URL that can be used in the HTML document this - part file. - You may read more about using this function in the class usage - section about - embedding images in HTML messages - embed-image - . - The content identifier text string. - If it is specified an invalid message part, this function returns - an empty string. - - - part - INTEGER - - Number of the part as returned by the function that - originally created it. - - - -{/metadocument} -*/ - Function GetPartContentID($part) - { - if(!IsSet($this->parts[$part])) - return(""); - if(!IsSet($this->parts[$part]["Content-ID"])) - { - $extension=(IsSet($this->parts[$part]["NAME"]) ? $this->GetFilenameExtension($this->parts[$part]["NAME"]) : ""); - $this->parts[$part]["Content-ID"]=md5(uniqid($part.time())).$extension; - } - return($this->parts[$part]["Content-ID"]); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - GetDataURL - STRING - - Generate a data: URL according to the - RFC 2397 - http://www.ietf.org/rfc/rfc2397.txt - suitable for using in HTML messages to represent an image - or other type of file on which the data is directly embedded in the - HTML code instead of being fetched from a separate file or remote - URL. - Note that not all e-mail programs are capable of displaying images - or other types of files embedded in HTML messages this way. - Pass a - GetDataURL - file - part definition array like for the - CreateFilePart function. - The data: representing the described file or an - empty string in case there was an error. - - - file - HASH - - File definition. - - - -{/metadocument} -*/ - Function GetDataURL($file) - { - $ini_magic_quotes_runtime_chk = false; - if (version_compare(PHP_VERSION, '5.3.0', '<')) { - $ini_magic_quotes_runtime_chk = ini_get('magic_quotes_runtime'); - } - if(strlen($this->GetFileDefinition($file,$definition,0))) - return($this->error); - if(IsSet($definition["FILENAME"])) - { - $size=@filesize($definition["FILENAME"]); - if(!($file=@fopen($definition["FILENAME"],"rb"))) - return($this->OutputPHPError("could not open data file ".$definition["FILENAME"], error_get_last()['message'])); - for($body="";!feof($file);) - { - if(GetType($block=@fread($file,$this->file_buffer_length))!="string") - { - $this->OutputPHPError("could not read data file", error_get_last()['message']); - fclose($file); - return(""); - } - $body.=$block; - } - fclose($file); - if(GetType($size)=="integer" - && strlen($body)!=$size) - { - $this->OutputError("the length of the file that was read does not match the size of the part file ".$definition["FILENAME"]." due to possible data corruption"); - return(""); - } - if(function_exists("ini_get") - && $ini_magic_quotes_runtime_chk) - $body=StripSlashes($body); - $body=chunk_split(base64_encode($body), $this->line_length, $this->line_break); - } - else - { - if(!IsSet($definition["DATA"])) - { - $this->OutputError("it was not specified a file or data block"); - return(""); - } - $body=chunk_split(base64_encode($definition["DATA"]), $this->line_length, $this->line_break); - } - return("data:".$definition["Content-Type"].";base64,".$body); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function GetHeadersAndBody(&$headers, &$body) - { - $headers=$this->headers; - if(strcmp($this->mailer,"")) - { - $headers["X-Mailer"]=$this->mailer; - if(strlen($this->mailer_delivery)) - $headers["X-Mailer"].=' ('.$this->mailer_delivery.')'; - } - $headers["MIME-Version"]="1.0"; - if($this->body_parts==0) - return($this->OutputError("message has no body parts")); - if(strlen($error=$this->GetPartHeaders($headers,$this->body))) - return($error); - if($this->cache_body - && IsSet($this->body_cache[$this->body])) - $body=$this->body_cache[$this->body]; - else - { - if(strlen($error=$this->GetPartBody($body,$this->body))) - return($error); - if($this->cache_body) - $this->body_cache[$this->body]=$body; - } - return(""); - } - -/* -{metadocument} - - Send - STRING - - Send a composed message. - Use this function after you have set the necessary message - headers and added the message body parts. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - -{/metadocument} -*/ - Function Send() - { - if(strlen($this->error)) - return($this->error); - if(strlen($error=$this->GetHeadersAndBody($headers, $body))) - return($error); - if(strcmp($error=$this->StartSendingMessage(),"")) - return($error); - if(strlen($error=$this->SendMessageHeaders($headers))==0 - && strlen($error=$this->SendMessageBody($body))==0) - $error=$this->EndSendingMessage(); - $this->StopSendingMessage(); - return($error); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - GetMessage - STRING - - Get the whole message headers and body. - Use this function to retrieve the message headers and body - without sending it. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - message - STRING - - - Reference to a string variable to store the text of the - message headers and body. - - - -{/metadocument} -*/ - Function GetMessage(&$message) - { - if(strlen($this->error)) - return($this->error); - if(strlen($error=$this->GetHeadersAndBody($headers, $body))) - return($error); - for($message="", $h=0, Reset($headers); $hline_break; - } - $message.=$this->line_break; - $message.=$body; - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - GetMessageSize - STRING - - Get the size of the whole message headers and body. - Use this function to retrieve the size in bytes of the - message headers and body without sending it. - An error message in case there was an error or an empty - string otherwise. This return value may be safely ignored if the - function parameters are set correctly. - - - message - STRING - - - Reference to an integer variable to store the size of the - message headers and body. - - - -{/metadocument} -*/ - Function GetMessageSize(&$size) - { - if(strlen($error=$this->GetMessage($message))) - return($error); - $size=strlen($message); - return(""); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - Mail - BOOLEAN - - Emulate the PHP mail() function by composing and - sending a message given the same arguments. - This is mostly meant to provide a solution for sending messages - with alternative delivery methods provided by this class - sub-classes. It uses the same arguments as the PHP mail() - function. Developers willing to use this alternative do not need to - change much their scripts that already use the mail() - function. - Use this function passing the same arguments as to PHP - - mail() - http://www.php.net/manual/en/function.mail.php - function. - If this function succeeds, it returns - 1. - - - to - STRING - - Recipient e-mail address. - - - - subject - STRING - - Message subject. - - - - message - STRING - - Message body. - - - - additional_headers - STRING - - - Text string headers and the respective values. There - should be one header and value per line with line breaks - separating each line. - - - - additional_parameters - STRING - - - Text string with additional parameters. In the original - PHP mail() function these were actual switches to be - passed in the sendmail program invocation command line. This - function only supports the -f switch followed by an - e-mail address meant to specify the message bounce return path - address. - - - -{/metadocument} -*/ - Function Mail($to, $subject, $message, $additional_headers="", $additional_parameters="") - { - $this->ResetMessage(); - $this->headers=array("To"=>$to,"Subject"=>$subject); - $content_type=""; - while(strlen($additional_headers)) - { - preg_match("/([^\r\n]+)(\r?\n)?(.*)\$/",$additional_headers,$matches); - $header=$matches[1]; - $additional_headers=$matches[3]; - if(!preg_match("/^([^:]+):[ \t]+(.+)\$/",$header,$matches)) - { - $this->error="invalid header \"$header\""; - return(0); - } - if(strtolower($matches[1])=="content-type") - { - if(strlen($content_type)) - { - $this->error="the content-type header was specified more than once."; - return(0); - } - $content_type=$matches[2]; - } - else - $this->SetHeader($matches[1],$matches[2]); - } - if(strlen($additional_parameters)) - { - if(preg_match("/^[ \t]*-f[ \t]*([^@]+@[^ \t]+)[ \t]*(.*)\$/", $additional_parameters, $matches)) - { - if(!preg_match('/'.str_replace('/', '\\/', $this->email_regular_expression).'/i', $matches[1])) - { - $this->error="it was specified an invalid e-mail address for the additional parameter -f"; - return(0); - } - if(strlen($matches[2])) - { - $this->error="it were specified some additional parameters after -f e-mail address parameter that are not supported"; - return(0); - } - $this->SetHeader("Return-Path",$matches[1]); - } - else - { - $this->error="the additional parameters that were specified are not supported"; - return(0); - } - } - if(strlen($content_type)==0) - $content_type="text/plain"; - $definition=array( - "Content-Type"=>$content_type, - "DATA"=>$message - ); - $this->CreateAndAddPart($definition); - $this->Send(); - return(strlen($this->error)==0); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function ChangeBulkMail($on) - { - return(1); - } - -/* -{metadocument} - - SetBulkMail - BOOLEAN - - Hint the class to adjust itself in order to send individual - messages to many recipients more efficiently. - Call this function before starting sending messages to many - recipients passing 1 to the - - SetBulkMail - on - argument. Then call this function again after the - bulk mailing delivery has ended passing passing - 1 to the - SetBulkMail - on - argument. - If this function succeeds, it returns - 1. - - - on - BOOLEAN - - Boolean flag that indicates whether a bulk delivery is - going to start if set to 1 or that - the bulk delivery has ended if set to - 0. - - - -{/metadocument} -*/ - Function SetBulkMail($on) - { - if(strlen($this->error)) - return(0); - if(!$this->bulk_mail==!$on) - return(1); - if(!$this->ChangeBulkMail($on)) - return(0); - $this->bulk_mail=!!$on; - return(1); - } -/* -{metadocument} - - -{/metadocument} -*/ - - Function OpenMailing(&$mailing,&$mailing_properties) - { - if(strlen($this->error)) - return($this->error); - if(!IsSet($mailing_properties["Name"]) - || strlen($mailing_properties["Name"])==0) - return($this->OutputError("it was not specified a valid mailing Name")); - if(!IsSet($mailing_properties["Return-Path"]) - || strlen($mailing_properties["Return-Path"])==0) - return($this->OutputError("it was not specified a valid mailing Return-Path")); - $separator=""; - $directory_separator=(defined("DIRECTORY_SEPARATOR") ? DIRECTORY_SEPARATOR : ((defined("PHP_OS") && !strcmp(substr(PHP_OS,0,3),"WIN")) ? "\\" : "/")); - $length=strlen($this->mailing_path); - if($length) - { - if($this->mailing_path[$length-1]!=$directory_separator) - $separator=$directory_separator; - } - $base_path=$this->mailing_path.$separator.$mailing_properties["Name"]; - if($this->body_parts==0) - return($this->OutputError("message has no body parts")); - $line_break="\n"; - $headers=$this->headers; - if(strlen($this->mailer)) - $headers["X-Mailer"]=$this->mailer; - $headers["MIME-Version"]="1.0"; - if(strlen($error=$this->GetPartHeaders($headers,$this->body))) - return($error); - if(!($header_file=@fopen($base_path.".h","wb"))) - return($this->OutputPHPError("could not open mailing headers file ".$base_path.".h", error_get_last()['message'])); - for($header=0,Reset($headers);$headerOutputPHPError("could not write to the mailing headers file ".$base_path.".h", error_get_last()['message'])); - } - } - if(!@fflush($header_file)) - { - fclose($header_file); - @unlink($base_path.".h"); - return($this->OutputPHPError("could not write to the mailing headers file ".$base_path.".h", error_get_last()['message'])); - } - fclose($header_file); - if(strlen($error=$this->GetPartBody($body,$this->body))) - { - @unlink($base_path.".h"); - return($error); - } - if(!($body_file=@fopen($base_path.".b","wb"))) - { - @unlink($base_path.".h"); - return($this->OutputPHPError("could not open mailing body file ".$base_path.".b", error_get_last()['message'])); - } - if(!@fwrite($body_file,$body) - || !@fflush($body_file)) - { - fclose($body_file); - @unlink($base_path.".b"); - @unlink($base_path.".h"); - return($this->OutputPHPError("could not write to the mailing body file ".$base_path.".b", error_get_last()['message'])); - } - fclose($body_file); - if(!($envelope=@fopen($base_path.".e","wb"))) - { - @unlink($base_path.".b"); - @unlink($base_path.".h"); - return($this->OutputPHPError("could not open mailing envelope file ".$base_path.".e", error_get_last()['message'])); - } - if(!@fwrite($envelope,"F".$mailing_properties["Return-Path"].chr(0)) - || !@fflush($envelope)) - { - @fclose($envelope); - @unlink($base_path.".e"); - @unlink($base_path.".b"); - @unlink($base_path.".h"); - return($this->OutputPHPError("could not write to the return path to the mailing envelope file ".$base_path.".e", error_get_last()['message'])); - } - $mailing=++$this->last_mailing; - $this->mailings[$mailing]=array( - "Envelope"=>$envelope, - "BasePath"=>$base_path - ); - return(""); - } - - Function AddMailingRecipient($mailing,&$recipient_properties) - { - if(strlen($this->error)) - return($this->error); - if(!IsSet($this->mailings[$mailing])) - return($this->OutputError("it was not specified a valid mailing")); - if(!IsSet($recipient_properties["Address"]) - || strlen($recipient_properties["Address"])==0) - return($this->OutputError("it was not specified a valid mailing recipient Address")); - if(!@fwrite($this->mailings[$mailing]["Envelope"],"T".$recipient_properties["Address"].chr(0))) - return($this->OutputPHPError("could not write recipient address to the mailing envelope file", error_get_last()['message'])); - return(""); - } - - Function EndMailing($mailing) - { - if(strlen($this->error)) - return($this->error); - if(!IsSet($this->mailings[$mailing])) - return($this->OutputError("it was not specified a valid mailing")); - if(!IsSet($this->mailings[$mailing]["Envelope"])) - return($this->OutputError("the mailing was already ended")); - if(!@fwrite($this->mailings[$mailing]["Envelope"],chr(0)) - || !@fflush($this->mailings[$mailing]["Envelope"])) - return($this->OutputPHPError("could not end writing to the mailing envelope file", error_get_last()['message'])); - fclose($this->mailings[$mailing]["Envelope"]); - Unset($this->mailings[$mailing]["Envelope"]); - return(""); - } - - Function SendMailing($mailing) - { - if(strlen($this->error)) - return($this->error); - if(!IsSet($this->mailings[$mailing])) - return($this->OutputError("it was not specified a valid mailing")); - if(IsSet($this->mailings[$mailing]["Envelope"])) - return($this->OutputError("the mailing was not yet ended")); - $this->ResetMessage(); - $base_path=$this->mailings[$mailing]["BasePath"]; - if(GetType($header_lines=@File($base_path.".h"))!="array") - return($this->OutputPHPError("could not read the mailing headers file ".$base_path.".h", error_get_last()['message'])); - for($line=0;$lineTokenize($header_lines[$line],": "); - $this->headers[$header_name]=trim($this->Tokenize("\n")); - } - if(!($envelope_file=@fopen($base_path.".e","rb"))) - return($this->OutputPHPError("could not open the mailing envelope file ".$base_path.".e", error_get_last()['message'])); - for($bcc=$data="",$position=0;!feof($envelope_file) || strlen($data);) - { - if(GetType($break=strpos($data,chr(0),$position))!="integer") - { - if(GetType($chunk=@fread($envelope_file,$this->file_buffer_length))!="string") - { - fclose($envelope_file); - return($this->OutputPHPError("could not read the mailing envelop file ".$base_path.".e", error_get_last()['message'])); - } - $data=substr($data,$position).$chunk; - $position=0; - continue; - } - if($break==$position) - break; - switch($data[$position]) - { - case "F": - $this->headers["Return-Path"]=substr($data,$position+1,$break-$position-1); - break; - case "T": - $bcc.=(strlen($bcc)==0 ? "" : ", ").substr($data,$position+1,$break-$position-1); - break; - default: - return($this->OutputError("invalid mailing envelope file ".$base_path.".e")); - } - $position=$break+1; - } - fclose($envelope_file); - if(strlen($bcc)==0) - return($this->OutputError("the mailing envelop file ".$base_path.".e does not contain any recipients")); - $this->headers["Bcc"]=$bcc; - if(!($body_file=@fopen($base_path.".b","rb"))) - return($this->OutputPHPError("could not open the mailing body file ".$base_path.".b", error_get_last()['message'])); - for($data="";!feof($body_file);) - { - if(GetType($chunk=@fread($body_file,$this->file_buffer_length))!="string") - { - fclose($body_file); - return($this->OutputPHPError("could not read the mailing body file ".$base_path.".b", error_get_last()['message'])); - } - $data.=$chunk; - } - fclose($body_file); - if(strlen($error=$this->StartSendingMessage())) - return($error); - if(strlen($error=$this->SendMessageHeaders($this->headers))==0 - && strlen($error=$this->SendMessageBody($data))==0) - $error=$this->EndSendingMessage(); - $this->StopSendingMessage(); - return($error); - } -}; - -/* - -{metadocument} -
-{/metadocument} - -*/ - -?> diff --git a/vendor/email_message/php_message.php b/vendor/email_message/php_message.php deleted file mode 100644 index 7ffdad8..0000000 --- a/vendor/email_message/php_message.php +++ /dev/null @@ -1,13 +0,0 @@ - \ No newline at end of file diff --git a/vendor/email_message/pickup_message.php b/vendor/email_message/pickup_message.php deleted file mode 100644 index f690295..0000000 --- a/vendor/email_message/pickup_message.php +++ /dev/null @@ -1,275 +0,0 @@ - - - - net.manuellemos.mimemessage - - pickup_message_class - @(#) $Id: pickup_message.php,v 1.4 2006/05/04 01:24:35 mlemos Exp $ - Copyright � (C) Manuel Lemos 1999-2004 - MIME E-mail message composing and sending using a Windows mail - server pickup directory - Manuel Lemos - mlemos-at-acm.org - - - en - Implement an alternative message delivery method by dropping - messages in a Windows mail server pickup directory, thus overriding - the method of using the PHP mail() function implemented by - the base class. - It is meant to be used by on Windows 2000 or later with IIS or - Exchange mail servers because since this release the pickup directory - started being supported. - It is much faster than relaying messages to an SMTP server because - it works simply by storing messages in a special directory. This - delivery method does not have the overhead of the SMTP protocol. The - class does not need to wait for the mail server to pickup the - messages and deliver them to the destination recipients. Therefore, - it is recommended for bulk mailing. - This class should be used exactly the same way as the base - class for composing and sending messages. Just create a new object of - this class as follows and set only the necessary variables to - configure details of the message pickup. - require('email_message.php');
- require('pickup_message.php');
-
- $message_object = new pickup_message_class;
- - Requirements - You need to use at least Windows 2000 with IIS mail server or - Exchange 2000 or later. - The PHP script using this class must also run in the same Windows - machine on which the mail server is running. The current user must - have sufficient privileges to write to the mail server pickup - directory. - - Pickup directory - Before sending a message you need set the - mailroot_directory variable to specify - the path of the mail server directory, so the class knows where the - messages must be dropped for subsequent pickup and delivery by the - mail server.
-
- -{/metadocument} -*/ - -class pickup_message_class extends email_message_class -{ - /* Private variables */ - - var $line_break="\r\n"; - var $pickup_file=0; - var $pickup_file_name=""; - - /* Public variables */ - -/* -{metadocument} - - mailroot_directory - STRING - - - Specify the path of the directory where the Pickup - sub-directory is located. This sub-directory is used by the mail - server to pickup the messages to deliver. - If this variable is set to an empty string, the class attempts - to locate the directory automatically checking the registry. - If the class is not able to determine the mailroot directory path - and you are certain that IIS or Exchange programs are installed in - your Windows 2000 or later machine, set this variable to the - correct path of your mail server root directory. - Usually it is located inside the Inetpub directory of IIS - or Exchange installation path, but it may also be located in a - slightly different path. - C:\Inetpub\mailroot\ - - -{/metadocument} -*/ - var $mailroot_directory=""; - -/* -{metadocument} - - mailer_delivery - pickup $Revision: 1.4 $ - - Specify the text that is used to identify the mail - delivery class or sub-class. This text is appended to the - X-Mailer header text defined by the - mailer variable. - Do not change this variable. - - -{/metadocument} -*/ - var $mailer_delivery='pickup $Revision: 1.4 $'; - - Function CleanupMessageFile() - { - if($this->pickup_file) - { - fclose($this->pickup_file); - $this->pickup_file=0; - unlink($this->pickup_file_name); - } - } - - Function StartSendingMessage() - { - if(strlen($this->mailroot_directory)==0) - { - if(function_exists("class_exists") - && class_exists("COM")) - { - $shell=new COM("WScript.Shell"); - $wwwroot=$shell->RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\InetStp\\PathWWWRoot"); - if(is_dir($wwwroot)) - { - $mailroot=$wwwroot."\\..\\mailroot"; - if(is_dir($mailroot."\\Pickup")) - $this->mailroot_directory=$mailroot; - else - { - $mailroot=$wwwroot."\\mailroot"; - if(is_dir($mailroot."\\Pickup")) - $this->mailroot_directory=$mailroot; - } - } - } - } - if(strlen($this->mailroot_directory)==0) - return($this->OutputError("it was not specified the mailroot directory path")); - if(!is_dir($this->mailroot_directory."\\Pickup")) - return($this->OutputError("the specified mailroot path ".$this->mailroot_directory." does not contain a Pickup directory")); - $this->pickup_file_name=tempnam(GetEnv("TMP"),"eml"); - if(!($this->pickup_file=@fopen($this->pickup_file_name,"w"))) - return($this->OutputPHPError("could not create a pickup message file ".$this->pickup_file_name, error_get_last()['message'])); - return(""); - } - - Function SendMessageHeaders($headers) - { - for($error=$header_data="",$message_id_set=$date_set=0,$header=0,$return_path=$sender=$receivers=array(),Reset($headers);$headerGetRFC822Addresses($headers[$header_name],$sender); - break; - case "to": - case "cc": - case "bcc": - $this->GetRFC822Addresses($headers[$header_name],$receivers); - break; - case "date": - $date_set=1; - break; - case "message-id": - $message_id_set=1; - break; - } - if(strlen($error)) - { - $this->CleanupMessageFile(); - return($this->OutputError($error)); - } - switch(strtolower($header_name)) - { - case "x-sender": - case "x-receiver": - case "bcc": - break; - default: - $header_data.=$this->FormatHeader($header_name,$headers[$header_name])."\r\n"; - } - } - if(count($sender)==0) - { - $this->CleanupMessageFile(); - return($this->OutputError("it was not specified a valid From header")); - } - if(count($receivers)==0) - { - $this->CleanupMessageFile(); - return($this->OutputError("it was not specified a valid To header")); - } - Reset($return_path); - Reset($sender); - $envelop="x-sender: ".(count($return_path) ? Key($return_path) : Key($sender)).$this->line_break; - for($receiver=0,Reset($receivers);$receiverline_break; - if(!$date_set) - $header_data.="Date: ".date("D, d M Y H:i:s T").$this->line_break; - if(!$message_id_set - && $this->auto_message_id) - { - $sender=(count($return_path) ? Key($return_path) : Key($sender)); - $header_data.=$this->GenerateMessageID($sender).$this->line_break; - } - if(!@fputs($this->pickup_file, $envelop.$header_data.$this->line_break)) - { - $this->CleanupMessageFile(); - return($this->OutputPHPError("could not write the message headers to the pickup file", error_get_last()['message'])); - } - return(""); - } - - Function SendMessageBody($data) - { - if(!@fputs($this->pickup_file, $data)) - { - $this->CleanupMessageFile(); - return($this->OutputPHPError("could not write the message body to the pickup file", error_get_last()['message'])); - } - return(""); - } - - Function EndSendingMessage() - { - if(!@fflush($this->pickup_file)) - return($this->OutputPHPError("could not flush the message body to the pickup file", error_get_last()['message'])); - fclose($this->pickup_file); - $this->pickup_file=0; - $pickup_file_path=$this->mailroot_directory; - if(strcmp(substr($pickup_file_path,strlen($pickup_file_path)-1,1),"\\")) - $pickup_file_path.="\\"; - $pickup_file_path.="Pickup\\"; - if(!@copy($this->pickup_file_name,$pickup_file_path.basename($this->pickup_file_name))) - $error=$this->OutputPHPError("could not copy the message file to the pickup directory", error_get_last()['message']); - else - $error=""; - unlink($this->pickup_file_name); - return($error); - } - - Function StopSendingMessage() - { - return(""); - } - -}; - -/* - -{metadocument} -
-{/metadocument} - -*/ - -?> diff --git a/vendor/email_message/qmail_message.php b/vendor/email_message/qmail_message.php deleted file mode 100644 index edc1ad2..0000000 --- a/vendor/email_message/qmail_message.php +++ /dev/null @@ -1,207 +0,0 @@ - - - - net.manuellemos.mimemessage - - qmail_message_class - @(#) $Id: qmail_message.php,v 1.11 2009/07/27 22:07:23 mlemos Exp $ - Copyright � (C) Manuel Lemos 2001-2004 - MIME E-mail message composing and sending using Qmail - Manuel Lemos - mlemos-at-acm.org - - - en - Implement an alternative message delivery method using - - Qmail - http://www.qmail.org/ - MTA (Mail Transfer Agent). - This class should be used exactly the same way as the base - class for composing and sending messages. Just create a new object of - this class as follows and set only the necessary variables to - configure details of delivery using Qmail. - require('email_message.php');
- require('qmail_message.php');
-
- $message_object = new qmail_message_class;
-
-
- -{/metadocument} -*/ - -class qmail_message_class extends email_message_class -{ - /* Private variables */ - - var $line_break="\n"; - - /* Public variables */ - -/* -{metadocument} - - qmail_path - STRING - /var/qmail/bin - - Specifying the path of the Qmail programs. - Usually the default is correct. - - -{/metadocument} -*/ - var $qmail_path="/var/qmail/bin"; - -/* -{metadocument} - - mailer_delivery - qmail $Revision: 1.11 $ - - Specify the text that is used to identify the mail - delivery class or sub-class. This text is appended to the - X-Mailer header text defined by the - mailer variable. - Do not change this variable. - - -{/metadocument} -*/ - var $mailer_delivery='qmail $Revision: 1.11 $'; - - Function SendMail($to,$subject,$body,$headers,$return_path) - { - $command=$this->qmail_path."/qmail-inject"; - if(strcmp($return_path,"")) - $command.=" '".preg_replace("/'/", "'\\''","-f$return_path")."'"; - if(!($pipe=@popen($command,"w"))) - return($this->OutputPHPError("it was not possible to open qmail-inject input pipe", error_get_last()['message'])); - if(strlen($headers)) - $headers.="\n"; - if(!@fputs($pipe,"To: ".$to."\nSubject: ".$subject."\n".$headers."\n") - || !@fputs($pipe,$body) - || !@fflush($pipe)) - return($this->OutputPHPError("it was not possible to write qmail-inject input pipe", error_get_last()['message'])); - return(($rc=(pclose($pipe)>>8)) ? "qmail-inject error ".$rc : ""); - } - - Function SendMailing($mailing) - { - if(strlen($this->error)) - return($this->error); - if(!IsSet($this->mailings[$mailing])) - return($this->OutputError("it was not specified a valid mailing")); - if(IsSet($this->mailings[$mailing]["Envelope"])) - return($this->OutputError("the mailing was not yet ended")); - $this->ResetMessage(); - $base_path=$this->mailings[$mailing]["BasePath"]; - if(GetType($header_lines=@File($base_path.".h"))!="array") - return($this->OutputPHPError("could not read the mailing headers file ".$base_path.".h", error_get_last()['message'])); - if(!($envelope_file=@fopen($base_path.".e","rb"))) - return($this->OutputPHPError("could not open the mailing envelope file ".$base_path.".e", error_get_last()['message'])); - for($return_path=$data="";!feof($envelope_file) || strlen($data);) - { - if(GetType($break=strpos($data,chr(0)))!="integer") - { - if(GetType($chunk=@fread($envelope_file,$this->file_buffer_length))!="string") - { - fclose($envelope_file); - return($this->OutputPHPError("could not read the mailing envelop file ".$base_path.".e", error_get_last()['message'])); - } - $data.=$chunk; - continue; - } - if($break==0) - break; - switch($data[0]) - { - case "F": - $return_path=substr($data,1,$break-1); - break; - default: - return($this->OutputError("invalid mailing envelope file ".$base_path.".e")); - } - break; - } - fclose($envelope_file); - if(strlen($return_path)==0) - return($this->OutputError("envelope file ".$base_path.".e does not contain a return path")); - $headers=$this->FormatHeader("Date",gmdate("D, d M Y H:i:s -0000"))."\n"; - for($has=array(),$line=0;$lineTokenize($header_lines[$line],":"); - switch(strtolower($header)) - { - case "return-path": - case "bcc": - case "date": - case "content-length": - break; - case "from": - case "to": - case "cc": - case "message-id": - $has[strtolower($header)]=1; - default: - $headers.=$this->FormatHeader($header,trim($this->Tokenize("\n")))."\n"; - break; - } - } - if(!IsSet($has["from"])) - $headers.=$this->FormatHeader("From","<".$return_path.">")."\n"; - if(!IsSet($has["to"]) - && !IsSet($has["cc"])) - $headers.=$this->FormatHeader("Cc","recipient list not shown: ;")."\n"; - if(!IsSet($has["message-id"])) - { - $micros=$this->Tokenize(microtime()," "); - $seconds=$this->Tokenize(""); - $this->Tokenize($return_path,"@"); - $host=$this->Tokenize("@"); - if($host[strlen($host)-1]=="-") - $host=substr($host,0,strlen($host)-1); - $headers.=$this->FormatHeader("Message-ID","<".strftime("%Y%m%d%H%M%S",$seconds).substr($micros,1,5).".qmail@".$host.">")."\n"; - } - if(!($body_file=@fopen($base_path.".b","rb"))) - return($this->OutputPHPError("could not open the mailing body file ".$base_path.".b", error_get_last()['message'])); - for($body="";!feof($body_file);) - { - if(GetType($chunk=@fread($body_file,$this->file_buffer_length))!="string") - { - fclose($body_file); - return($this->OutputPHPError("could not read the mailing body file ".$base_path.".b", error_get_last()['message'])); - } - $body.=$chunk; - } - fclose($body_file); - $command=$this->qmail_path."/qmail-queue 1<".$base_path.".e"; - if(!($pipe=@popen($command,"w"))) - return($this->OutputPHPError("it was not possible to open qmail-queue input pipe", error_get_last()['message'])); - if(!@fputs($pipe,$headers."\n".$body) - || !@fflush($pipe)) - return($this->OutputPHPError("it was not possible to write qmail-queue input pipe", error_get_last()['message'])); - return(($rc=(pclose($pipe)>>8)) ? "qmail-queue error ".$rc : ""); - } -}; - -/* - -{metadocument} -
-{/metadocument} - -*/ - -?> diff --git a/vendor/email_message/sendmail_message.php b/vendor/email_message/sendmail_message.php deleted file mode 100644 index 2ac2ce0..0000000 --- a/vendor/email_message/sendmail_message.php +++ /dev/null @@ -1,268 +0,0 @@ - - - - net.manuellemos.mimemessage - - sendmail_message_class - @(#) $Id: sendmail_message.php,v 1.19 2011/11/26 09:41:09 mlemos Exp $ - Copyright � (C) Manuel Lemos 1999-2004 - MIME E-mail message composing and sending using Sendmail - Manuel Lemos - mlemos-at-acm.org - - - en - Implement an alternative message delivery method using - - Sendmail - http://www.sendmail.org/ - MTA (Mail Transfer Agent). This class can also be used with - other MTAs like - Exim - http://www.exim.org/ - , - Postfix - http://www.postfix.org/ - and - Qmail - http://www.qmail.org/ - , as they provide a wrapper - commands that emulate the sendmail command. - This class should be used exactly the same way as the base - class for composing and sending messages. Just create a new object of - this class as follows and set only the necessary variables to - configure details of delivery using Sendmail. - require('email_message.php');
- require('sendmail_message.php');
-
- $message_object = new sendmail_message_class;
- - Tuning the delivery mode for mass mailing - Sendmail supports several message delivery modes. In many - installations the default is to attempt to deliver the message right - away when the message is handed by the applications to - Sendmail. - This may be an inconvenient because it makes PHP scripts wait for the - message to be delivered to the destination SMTP server. If the SMTP - connection with that server is slow, it may stall the delivery for a - long while. - Under Unix/Linux, PHP defaults to using Sendmail or equivalent to - deliver messages sent with the mail() function. Some people - assume that it is faster to queue messages by relaying to an - intermediate SMTP server than to use the mail() function - that uses Sendmail. This is not accurate. - Sendmail supports other message delivery modes that can be used for - much faster message queueing. These modes are more recommended for - mass mailing. Adjust the value of the - delivery_mode variable to improve the - message queueing rate if you want to use this class for mass - mailing. - Alternatively, you may also call the - SetBulkMail to hint this class to use - a delivery mode more suitable for bulk mailing. Currently, this makes - this class use the delivery mode specified by the - bulk_mail_delivery_mode variable, which - defaults to make the messages be queued for later delivery, thus - making the calling script execute much faster.
-
- -{/metadocument} -*/ - -define("SENDMAIL_DELIVERY_DEFAULT", ""); -define("SENDMAIL_DELIVERY_INTERACTIVE", "i"); -define("SENDMAIL_DELIVERY_BACKGROUND", "b"); -define("SENDMAIL_DELIVERY_QUEUE", "q"); -define("SENDMAIL_DELIVERY_DEFERRED", "d"); - -class sendmail_message_class extends email_message_class -{ - /* Private variables */ - - var $line_break="\n"; - - /* Public variables */ - -/* -{metadocument} - - sendmail_path - STRING - /usr/lib/sendmail - - Specifying the path of the sendmail executable - program. - The original default path of the sendmail used to be - /usr/lib/sendmail. However, currently it is usually - located in /usr/sbin/sendmail having a symbolic link - pointing to that path from - /usr/lib/sendmail. - If this symbolic link does not exist or the sendmail is - different in your installation, you need to change this - variable. - - -{/metadocument} -*/ - var $sendmail_path="/usr/lib/sendmail"; - -/* -{metadocument} - - delivery_mode - STRING - - - Specify the Sendmail message delivery mode. These delivery - modes are only supported by Sendmail and Exim MTAs. - Current versions of Qmail and Postfix do not support configurable - delivery modes. They always inject the messages in the local queue - and let their queue management system take care of the delivery as - soon as possible. Just leave this variable with the default value - when using this class with these MTAs. - Sendmail supports several different delivery - modes: - SENDMAIL_DELIVERY_DEFAULT - - - Does not override the default mode. - SENDMAIL_DELIVERY_INTERACTIVE - - i - Attempt to send the messages synchronously to the recipient's SMTP - server and only returns when it succeeds or fails. This is usually - the default mode. It stalls the delivery of messages but it may be - safer to preserve disk space because the successfully delivered - messages are not stored. - SENDMAIL_DELIVERY_BACKGROUND - - b - Creates a background process that attempts to deliver the message - and returns immediately. This mode is recommended when you want - to send a few messages as soon as possible. It is not recommended - for sending messages to many recipients as it may consume too much - memory and CPU that result from creating excessive background - processes. - SENDMAIL_DELIVERY_QUEUE - - q - Just drop the message in the queue and leave it there until next - time the queue is run. It is recommended for deliverying messages - to many recipients as long as there is enough disk space to store - all the messages in the queue. - SENDMAIL_DELIVERY_DEFERRED - - d - The same as the queue mode except for a few verifications that are - skipped. - - - -{/metadocument} -*/ - var $delivery_mode=SENDMAIL_DELIVERY_DEFAULT; - -/* -{metadocument} - - bulk_mail_delivery_mode - STRING - q - - Specify the Sendmail message delivery mode when the class is - in bulk mail mode that is set with the - SetBulkMail function. - The available delivery modes are the same as those used to set - the delivery_mode variable. The - default bulk mail delivery mode is to just queue the message - (SENDMAIL_DELIVERY_QUEUE) without waiting for sendmail to - deliver the message. - Note that some MTAs that emulate Sendmail return an error when set - to queue delivery mode. If this happens with the MTA that you are - using, change this variable to the - SENDMAIL_DELIVERY_DEFAULT. - - -{/metadocument} -*/ - var $bulk_mail_delivery_mode=SENDMAIL_DELIVERY_QUEUE; - -/* -{metadocument} - - sendmail_arguments - STRING - - - Specify additional sendmail program arguments. - Use this to to pass additional arguments that are not - supported by this class. - - -{/metadocument} -*/ - var $sendmail_arguments=""; - -/* -{metadocument} - - mailer_delivery - sendmail $Revision: 1.19 $ - - Specify the text that is used to identify the mail - delivery class or sub-class. This text is appended to the - X-Mailer header text defined by the - mailer variable. - Do not change this variable. - - -{/metadocument} -*/ - var $mailer_delivery='sendmail $Revision: 1.19 $'; - - Function SendMail($to, $subject, $body, $headers, $return_path) - { - $command=$this->sendmail_path." -t -i"; - switch($this->bulk_mail ? $this->bulk_mail_delivery_mode : $this->delivery_mode) - { - case SENDMAIL_DELIVERY_DEFAULT: - case SENDMAIL_DELIVERY_INTERACTIVE: - case SENDMAIL_DELIVERY_BACKGROUND: - case SENDMAIL_DELIVERY_QUEUE: - case SENDMAIL_DELIVERY_DEFERRED: - break; - default: - return($this->OutputError("it was specified an unknown sendmail delivery mode")); - } - if($this->delivery_mode!=SENDMAIL_DELIVERY_DEFAULT) - $command.=" -od".$this->delivery_mode; - if(strlen($return_path)) - $command.=" -f '".preg_replace("/'/", "'\\''",$return_path)."'"; - if(strlen($this->sendmail_arguments)) - $command.=" ".$this->sendmail_arguments; - if(!($pipe=@popen($command,"w"))) - return($this->OutputPHPError("it was not possible to open sendmail input pipe", error_get_last()['message'])); - if(strlen($headers)) - $headers.="\n"; - if(!@fputs($pipe,"To: ".$to."\nSubject: ".$subject."\n".$headers."\n") - || !@fputs($pipe,$body) - || !@fflush($pipe)) - return($this->OutputPHPError("it was not possible to write sendmail input pipe", error_get_last()['message'])); - pclose($pipe); - return(""); - } -}; - -/* - -{metadocument} -
-{/metadocument} - -*/ - -?> diff --git a/vendor/email_message/smtp.php b/vendor/email_message/smtp.php deleted file mode 100644 index 93f9c23..0000000 --- a/vendor/email_message/smtp.php +++ /dev/null @@ -1,1912 +0,0 @@ - - - - net.manuellemos.smtp - - @(#) $Id: smtp.php,v 1.51 2016/08/23 04:55:14 mlemos Exp $ - Copyright (C) Manuel Lemos 1999-2011 - Sending e-mail messages via SMTP protocol - Manuel Lemos - mlemos-at-acm.org - - - en - Sending e-mail messages via SMTP protocol - If you are interested in translating the documentation of - this class to your own idiom, please - contact the author - mailto:authoraddress - . - Technical support for using this class may be obtained in the - smtpclass support forum. Just go to the support forum pages - page to browse the forum archives and post support request - messages: - - http://www.phpclasses.org/discuss/package/14/ - http://www.phpclasses.org/discuss/package/14/ - - To use this class just create a new object, set any variables - to configure its options and call the - SendMessage function to send a - message.It is not recommended that you use this - class alone unless you have deep understanding of Internet mail - standards on how to compose compliant e-mail messages. Instead, use - the - MIME message composing and sending class - http://www.phpclasses.org/mimemessage - and its sub-class SMTP message together with this SMTP class - to properly compose e-mail messages, so your messages are not - discarded for not being correctly composed. - - -{/metadocument} -*/ - -class smtp_class -{ -/* -{metadocument} - - user - STRING - - - Define the authorized user when sending messages to a SMTP - server. - Set this variable to the user name when the SMTP server - requires authentication. - - -{/metadocument} -*/ - var $user=""; - -/* -{metadocument} - - realm - STRING - - - Define the authentication realm when sending messages to a - SMTP server. - Set this variable when the SMTP server requires - authentication and if more than one authentication realm is - supported. - - -{/metadocument} -*/ - var $realm=""; - -/* -{metadocument} - - password - STRING - - - Define the authorized user password when sending messages - to a SMTP server. - Set this variable to the user password when the SMTP server - requires authentication. - - -{/metadocument} -*/ - var $password=""; - -/* -{metadocument} - - workstation - STRING - - - Define the client workstation name when sending messages - to a SMTP server. - Set this variable to the client workstation when the SMTP - server requires authentication identifiying the origin workstation - name. - - -{/metadocument} -*/ - var $workstation=""; - -/* -{metadocument} - - authentication_mechanism - STRING - - - Force the use of a specific authentication mechanism. - Set it to an empty string to let the class determine the - authentication mechanism to use automatically based on the - supported mechanisms by the server and by the SASL client library - classes. - Set this variable to a specific mechanism name if you want to - override the automatic authentication mechanism selection. - - -{/metadocument} -*/ - var $authentication_mechanism=""; - -/* -{metadocument} - - sasl_autoload - BOOLEAN - 0 - - Specify whether the class should check if the SASL classes - exists or should they be loaded with an autoloader. - Set this variable to - 1 if you are using an - autoloader to load the SASL classes. - - -{/metadocument} -*/ - var $sasl_autoload=0; - - -/* -{metadocument} - - host_name - STRING - - - Define the SMTP server host name. - Set to the host name of the SMTP server to which you want to - relay the messages. - - -{/metadocument} -*/ - var $host_name=""; - -/* -{metadocument} - - host_port - INTEGER - 25 - - Define the SMTP server host port. - Set to the TCP port of the SMTP server host to connect. - - -{/metadocument} -*/ - var $host_port=25; - -/* -{metadocument} - - socks_host_name - STRING - - - Define the SOCKS server host name. - Set to the SOCKS server host name through which the SMTP - connection should be routed. Leave it empty if you do not want the - connections to be established through a SOCKS server. - - -{/metadocument} -*/ - var $socks_host_name = ''; - -/* -{metadocument} - - socks_host_port - INTEGER - 1080 - - Define the SOCKS server host port. - Set to the port of the SOCKS server host through which the - the SMTP connection should be routed. - - -{/metadocument} -*/ - var $socks_host_port=1080; - -/* -{metadocument} - - socks_version - STRING - 5 - - Set the SOCKS protocol version. - Change this value if SOCKS server you want to use is - listening to a different port. - - -{/metadocument} -*/ - var $socks_version='5'; - -/* -{metadocument} - - http_proxy_host_name - STRING - - - Define the HTTP proxy server host name. - Set to the HTTP proxy server host name through which the - SMTP connection should be routed. Leave it empty if you do not - want the connections to be established through an HTTP proxy. - - -{/metadocument} -*/ - var $http_proxy_host_name = ''; - -/* -{metadocument} - - http_proxy_host_port - INTEGER - 80 - - Define the HTTP proxy server host port. - Set to the port of the HTTP proxy server host through which - the SMTP connection should be routed. - - -{/metadocument} -*/ - var $http_proxy_host_port=80; - -/* -{metadocument} - - user_agent - STRING - SMTP Class (http://www.phpclasses.org/smtpclass $Revision: 1.51 $) - - Set the user agent used when connecting via an HTTP proxy. - Change this value only if for some reason you want emulate a - certain e-mail client. - - -{/metadocument} -*/ - var $user_agent='SMTP Class (http://www.phpclasses.org/smtpclass $Revision: 1.51 $)'; - -/* -{metadocument} - - ssl - BOOLEAN - 0 - - Define whether the connection to the SMTP server should be - established securely using SSL protocol. - Set to 1 if the SMTP server - requires secure connections using SSL protocol. - - -{/metadocument} -*/ - var $ssl=0; - -/* -{metadocument} - - start_tls - BOOLEAN - 0 - - Define whether the connection to the SMTP server should use - encryption after the connection is established using TLS - protocol. - Set to 1 if the SMTP server - requires that authentication be done securely starting the TLS - protocol after the connection is established. - - -{/metadocument} -*/ - var $start_tls = 0; - -/* -{metadocument} - - localhost - STRING - - - Name of the local host computer - Set to the name of the computer connecting to the SMTP - server from the local network. - - -{/metadocument} -*/ - var $localhost=""; - -/* -{metadocument} - - timeout - INTEGER - 0 - - Specify the connection timeout period in seconds. - Leave it set to 0 if you want - the connection attempts to wait forever. Change this value if for - some reason the timeout period seems insufficient or otherwise it - seems too long. - - -{/metadocument} -*/ - var $timeout=0; - -/* -{metadocument} - - data_timeout - INTEGER - 0 - - Specify the timeout period in seconds to wait for data from - the server. - Leave it set to 0 if you want - to use the same value defined in the - timeout variable. Change this value - if for some reason the default data timeout period seems - insufficient or otherwise it seems too long. - - -{/metadocument} -*/ - var $data_timeout=0; - -/* -{metadocument} - - direct_delivery - BOOLEAN - 0 - - Boolean flag that indicates whether the message should be - sent in direct delivery mode, i.e. the message is sent to the SMTP - server associated to the domain of the recipient instead of - relaying to the server specified by the - host_name variable. - Set this to 1 if you - want to send urgent messages directly to the recipient domain SMTP - server. - - -{/metadocument} -*/ - var $direct_delivery=0; - -/* -{metadocument} - - error - STRING - - - Message that describes the error when a call to a class - function fails. - Check this variable when an error occurs to understand what - happened. - - -{/metadocument} -*/ - var $error=""; - -/* -{metadocument} - - debug - BOOLEAN - 0 - - Specify whether it is necessary to output SMTP connection - debug information. - Set this variable to - 1 if you need to see - the progress of the SMTP connection and protocol dialog when you - need to understand the reason for delivery problems. - - -{/metadocument} -*/ - var $debug=0; - -/* -{metadocument} - - html_debug - BOOLEAN - 0 - - Specify whether the debug information should be outputted in - HTML format. - Set this variable to - 1 if you need to see - the debug output in a Web page. - - -{/metadocument} -*/ - var $html_debug=0; - -/* -{metadocument} - - esmtp - BOOLEAN - 1 - - Specify whether the class should attempt to use ESMTP - extensions supported by the server. - Set this variable to - 0 if for some reason you - want to avoid benefitting from ESMTP extensions. - - -{/metadocument} -*/ - var $esmtp=1; - -/* -{metadocument} - - esmtp_extensions - HASH - - - Associative array with the list of ESMTP extensions - supported by the SMTP server. - Check this variable after connecting to the SMTP server to - determine which ESMTP extensions are supported. - - -{/metadocument} -*/ - var $esmtp_extensions=array(); - -/* -{metadocument} - - exclude_address - STRING - - - Specify an address that should be considered invalid - when resolving host name addresses. - In some networks any domain name that does not exist is - resolved as a sub-domain of the default local domain. If the DNS is - configured in such way that it always resolves any sub-domain of - the default local domain to a given address, it is hard to - determine whether a given domain does not exist. - If your network is configured this way, you may set this variable - to the address that all sub-domains of the default local domain - resolves, so the class can assume that such address is invalid. - - -{/metadocument} -*/ - var $exclude_address=""; - -/* -{metadocument} - - getmxrr - STRING - getmxrr - - Specify the name of the function that is called to determine - the SMTP server address of a given domain. - Change this to a working replacement of the PHP - getmxrr() function if this is not working in your system - and you want to send messages in direct delivery mode. - - -{/metadocument} -*/ - var $getmxrr="GetMXRR"; - -/* -{metadocument} - - pop3_auth_host - STRING - - - Specify the server address for POP3 based authentication. - Set this variable to the address of the POP3 server if the - SMTP server requires POP3 based authentication. - - -{/metadocument} -*/ - var $pop3_auth_host=""; - -/* -{metadocument} - - pop3_auth_port - INTEGER - 110 - - Specify the server port for POP3 based authentication. - Set this variable to the port of the POP3 server if the - SMTP server requires POP3 based authentication. - - -{/metadocument} -*/ - var $pop3_auth_port=110; - - /* private variables - DO NOT ACCESS */ - - var $state="Disconnected"; - var $connection=0; - var $pending_recipients=0; - var $next_token=""; - var $direct_sender=""; - var $connected_domain=""; - var $result_code; - var $disconnected_error=0; - var $esmtp_host=""; - var $maximum_piped_recipients=100; - - /* Private methods - DO NOT CALL */ - - Function Tokenize($string,$separator="") - { - if(!strcmp($separator,"")) - { - $separator=$string; - $string=$this->next_token; - } - for($character=0;$characternext_token=substr($string,$found+1); - return(substr($string,0,$found)); - } - else - { - $this->next_token=""; - return($string); - } - } - - Function OutputDebug($message) - { - $message.="\n"; - if($this->html_debug) - $message=str_replace("\n","
\n",HtmlEntities($message)); - echo $message; - flush(); - } - - Function SetDataAccessError($error) - { - $this->error=$error; - if(function_exists("socket_get_status")) - { - $status=socket_get_status($this->connection); - if($status["timed_out"]) - $this->error.=": data access time out"; - elseif($status["eof"]) - { - $this->error.=": the server disconnected"; - $this->disconnected_error=1; - } - } - return($this->error); - } - - Function SetError($error) - { - return($this->error=$error); - } - - Function GetLine() - { - for($line="";;) - { - if(feof($this->connection)) - { - $this->error="reached the end of data while reading from the SMTP server conection"; - return(""); - } - if(GetType($data=@fgets($this->connection,100))!="string" - || strlen($data)==0) - { - $this->SetDataAccessError("it was not possible to read line from the SMTP server"); - return(""); - } - $line.=$data; - $length=strlen($line); - if($length>=2 - && substr($line,$length-2,2)=="\r\n") - { - $line=substr($line,0,$length-2); - if($this->debug) - $this->OutputDebug("S $line"); - return($line); - } - } - } - - Function PutLine($line) - { - if($this->debug) - $this->OutputDebug("C $line"); - if(!@fputs($this->connection,"$line\r\n")) - { - $this->SetDataAccessError("it was not possible to send a line to the SMTP server"); - return(0); - } - return(1); - } - - Function PutData(&$data) - { - if(strlen($data)) - { - if($this->debug) - $this->OutputDebug("C $data"); - if(!@fputs($this->connection,$data)) - { - $this->SetDataAccessError("it was not possible to send data to the SMTP server"); - return(0); - } - } - return(1); - } - - Function VerifyResultLines($code,&$responses) - { - $responses=array(); - Unset($this->result_code); - while(strlen($line=$this->GetLine($this->connection))) - { - if(IsSet($this->result_code)) - { - if(strcmp($this->Tokenize($line," -"),$this->result_code)) - { - $this->error=$line; - return(0); - } - } - else - { - $this->result_code=$this->Tokenize($line," -"); - if(GetType($code)=="array") - { - for($codes=0;$codesresult_code,$code[$codes]);$codes++); - if($codes>=count($code)) - { - $this->error=$line; - return(0); - } - } - else - { - if(strcmp($this->result_code,$code)) - { - $this->error=$line; - return(0); - } - } - } - $responses[]=$this->Tokenize(""); - if(!strcmp($this->result_code,$this->Tokenize($line," "))) - return(1); - } - return(-1); - } - - Function FlushRecipients() - { - if($this->pending_sender) - { - if($this->VerifyResultLines("250",$responses)<=0) - return(0); - $this->pending_sender=0; - } - for(;$this->pending_recipients;$this->pending_recipients--) - { - if($this->VerifyResultLines(array("250","251"),$responses)<=0) - return(0); - } - return(1); - } - - Function Resolve($domain, &$ip, $server_type) - { - if(preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/',$domain)) - $ip=$domain; - else - { - if($this->debug) - $this->OutputDebug('Resolving '.$server_type.' server domain "'.$domain.'"...'); - if(!strcmp($ip=@gethostbyname($domain),$domain)) - $ip=""; - } - if(strlen($ip)==0 - || (strlen($this->exclude_address) - && !strcmp(@gethostbyname($this->exclude_address),$ip))) - return($this->SetError("could not resolve the host domain \"".$domain."\"")); - return(''); - } - - Function ConnectToHost($domain, $port, $resolve_message) - { - if($this->ssl) - { - $version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7"); - $php_version=intval($version[0])*1000000+intval($version[1])*1000+intval($version[2]); - if($php_version<4003000) - return("establishing SSL connections requires at least PHP version 4.3.0"); - if(!function_exists("extension_loaded") - || !extension_loaded("openssl")) - return("establishing SSL connections requires the OpenSSL extension enabled"); - } - if(strlen($this->Resolve($domain, $ip, 'SMTP'))) - return($this->error); - if(strlen($this->socks_host_name)) - { - switch($this->socks_version) - { - case '4': - $version = 4; - break; - case '5': - $version = 5; - break; - default: - return('it was not specified a supported SOCKS protocol version'); - break; - } - $host_ip = $ip; - $host_port = $port; - if(strlen($this->error = $this->Resolve($this->socks_host_name, $ip, 'SOCKS'))) - return($this->error); - if($this->ssl) - $ip="ssl://".($socks_host = $this->socks_host_name); - else - $socks_host = $ip; - if($this->debug) - $this->OutputDebug("Connecting to SOCKS server \"".$socks_host."\" port ".$this->http_proxy_host_port."..."); - if(($this->connection=($this->timeout ? fsockopen($ip, $this->socks_host_port, $errno, $error, $this->timeout) : fsockopen($ip, $this->socks_host_port, $errno, $error)))) - { - $timeout=($this->data_timeout ? $this->data_timeout : $this->timeout); - if($timeout - && function_exists("socket_set_timeout")) - socket_set_timeout($this->connection,$timeout,0); - if(strlen($this->socks_host_name)) - { - if($this->debug) - $this->OutputDebug('Connected to the SOCKS server '.$this->socks_host_name); - $send_error = 'it was not possible to send data to the SOCKS server'; - $receive_error = 'it was not possible to receive data from the SOCKS server'; - switch($version) - { - case 4: - $command = 1; - $user = ''; - if(!fputs($this->connection, chr($version).chr($command).pack('nN', $host_port, ip2long($host_ip)).$user.Chr(0))) - $error = $this->SetDataAccessError($send_error); - else - { - $response = fgets($this->connection, 9); - if(strlen($response) != 8) - $error = $this->SetDataAccessError($receive_error); - else - { - $socks_errors = array( - "\x5a"=>'', - "\x5b"=>'request rejected', - "\x5c"=>'request failed because client is not running identd (or not reachable from the server)', - "\x5d"=>'request failed because client\'s identd could not confirm the user ID string in the request', - ); - $error_code = $response[1]; - $error = (IsSet($socks_errors[$error_code]) ? $socks_errors[$error_code] : 'unknown'); - if(strlen($error)) - $error = 'SOCKS error: '.$error; - } - } - break; - case 5: - if($this->debug) - $this->OutputDebug('Negotiating the authentication method ...'); - $methods = 1; - $method = 0; - if(!fputs($this->connection, chr($version).chr($methods).chr($method))) - $error = $this->SetDataAccessError($send_error); - else - { - $response = fgets($this->connection, 3); - if(strlen($response) != 2) - $error = $this->SetDataAccessError($receive_error); - elseif(Ord($response[1]) != $method) - $error = 'the SOCKS server requires an authentication method that is not yet supported'; - else - { - if($this->debug) - $this->OutputDebug('Connecting to SMTP server IP '.$host_ip.' port '.$host_port.'...'); - $command = 1; - $address_type = 1; - if(!fputs($this->connection, chr($version).chr($command)."\x00".chr($address_type).pack('Nn', ip2long($host_ip), $host_port))) - $error = $this->SetDataAccessError($send_error); - else - { - $response = fgets($this->connection, 11); - if(strlen($response) != 10) - $error = $this->SetDataAccessError($receive_error); - else - { - $socks_errors = array( - "\x00"=>'', - "\x01"=>'general SOCKS server failure', - "\x02"=>'connection not allowed by ruleset', - "\x03"=>'Network unreachable', - "\x04"=>'Host unreachable', - "\x05"=>'Connection refused', - "\x06"=>'TTL expired', - "\x07"=>'Command not supported', - "\x08"=>'Address type not supported' - ); - $error_code = $response[1]; - $error = (IsSet($socks_errors[$error_code]) ? $socks_errors[$error_code] : 'unknown'); - if(strlen($error)) - $error = 'SOCKS error: '.$error; - } - } - } - } - break; - default: - $error = 'support for SOCKS protocol version '.$this->socks_version.' is not yet implemented'; - break; - } - if(strlen($this->error = $error)) - { - fclose($this->connection); - return($error); - } - } - return(''); - } - } - elseif(strlen($this->http_proxy_host_name)) - { - if(strlen($error = $this->Resolve($this->http_proxy_host_name, $ip, 'SMTP'))) - return($error); - if($this->ssl) - $ip = 'ssl://'.($proxy_host = $this->http_proxy_host_name); - else - $proxy_host = $ip; - if($this->debug) - $this->OutputDebug("Connecting to HTTP proxy server \"".$ip."\" port ".$this->http_proxy_host_port."..."); - if(($this->connection=($this->timeout ? @fsockopen($ip, $this->http_proxy_host_port, $errno, $error, $this->timeout) : @fsockopen($ip, $this->http_proxy_host_port, $errno, $error)))) - { - if($this->debug) - $this->OutputDebug('Connected to HTTP proxy host "'.$this->http_proxy_host_name.'".'); - $timeout=($this->data_timeout ? $this->data_timeout : $this->timeout); - if($timeout - && function_exists("socket_set_timeout")) - socket_set_timeout($this->connection,$timeout,0); - if($this->PutLine('CONNECT '.$domain.':'.$port.' HTTP/1.0') - && $this->PutLine('User-Agent: '.$this->user_agent) - && $this->PutLine('')) - { - if(GetType($response = $this->GetLine()) == 'string') - { - if(!preg_match('/^http\\/[0-9]+\\.[0-9]+[ \t]+([0-9]+)[ \t]*(.*)$/i', $response,$matches)) - return($this->SetError("3 it was received an unexpected HTTP response status")); - $error = $matches[1]; - switch($error) - { - case '200': - for(;;) - { - if(GetType($response = $this->GetLine()) != 'string') - break; - if(strlen($response) == 0) - return(''); - } - break; - default: - $this->error = 'the HTTP proxy returned error '.$error.' '.$matches[2]; - break; - } - } - } - if($this->debug) - $this->OutputDebug("Disconnected."); - fclose($this->connection); - $this->connection = 0; - return($this->error); - } - } - else - { - if($this->ssl) - $ip = 'ssl://'.($host = $domain); - elseif($this->start_tls) - $ip = $host = $domain; - else - $host = $ip; - if($this->debug) - $this->OutputDebug("Connecting to SMTP server \"".$host."\" port ".$port."..."); - if(($this->connection=($this->timeout ? @fsockopen($ip, $port, $errno, $error, $this->timeout) : @fsockopen($ip, $port, $errno, $error)))) - return(""); - } - $error=($this->timeout ? strval($error) : "??"); - switch($error) - { - case "-3": - return("-3 socket could not be created"); - case "-4": - return("-4 dns lookup on hostname \"".$domain."\" failed"); - case "-5": - return("-5 connection refused or timed out"); - case "-6": - return("-6 fdopen() call failed"); - case "-7": - return("-7 setvbuf() call failed"); - } - return("could not connect to the host \"".$domain."\": ".$error); - } - - Function SASLAuthenticate($mechanisms, $credentials, &$authenticated, &$mechanism) - { - $authenticated=0; - if(!$this->sasl_autoload - && (!function_exists("class_exists") - || !class_exists("sasl_client_class"))) - { - $this->error="it is not possible to authenticate using the specified mechanism because the SASL library class is not loaded"; - return(0); - } - $sasl=new sasl_client_class; - $sasl->SetCredential("user",$credentials["user"]); - $sasl->SetCredential("password",$credentials["password"]); - if(IsSet($credentials["realm"])) - $sasl->SetCredential("realm",$credentials["realm"]); - if(IsSet($credentials["workstation"])) - $sasl->SetCredential("workstation",$credentials["workstation"]); - if(IsSet($credentials["mode"])) - $sasl->SetCredential("mode",$credentials["mode"]); - do - { - $status=$sasl->Start($mechanisms,$message,$interactions); - } - while($status==SASL_INTERACT); - switch($status) - { - case SASL_CONTINUE: - break; - case SASL_NOMECH: - if(strlen($this->authentication_mechanism)) - { - $this->error="authenticated mechanism ".$this->authentication_mechanism." may not be used: ".$sasl->error; - return(0); - } - break; - default: - $this->error="Could not start the SASL authentication client: ".$sasl->error; - return(0); - } - if(strlen($mechanism=$sasl->mechanism)) - { - if($this->PutLine("AUTH ".$sasl->mechanism.(IsSet($message) ? " ".base64_encode($message) : ""))==0) - { - $this->error="Could not send the AUTH command"; - return(0); - } - if(!$this->VerifyResultLines(array("235","334"),$responses)) - return(0); - switch($this->result_code) - { - case "235": - $response=""; - $authenticated=1; - break; - case "334": - $response=base64_decode($responses[0]); - break; - default: - $this->error="Authentication error: ".$responses[0]; - return(0); - } - for(;!$authenticated;) - { - do - { - $status=$sasl->Step($response,$message,$interactions); - } - while($status==SASL_INTERACT); - switch($status) - { - case SASL_CONTINUE: - if($this->PutLine(base64_encode($message))==0) - { - $this->error="Could not send the authentication step message"; - return(0); - } - if(!$this->VerifyResultLines(array("235","334"),$responses)) - return(0); - switch($this->result_code) - { - case "235": - $response=""; - $authenticated=1; - break; - case "334": - $response=base64_decode($responses[0]); - break; - default: - $this->error="Authentication error: ".$responses[0]; - return(0); - } - break; - default: - $this->error="Could not process the SASL authentication step: ".$sasl->error; - return(0); - } - } - } - return(1); - } - - Function StartSMTP($localhost) - { - $success = 1; - $this->esmtp_extensions = array(); - $fallback=1; - if($this->esmtp - || strlen($this->user)) - { - if($this->PutLine('EHLO '.$localhost)) - { - if(($success_code=$this->VerifyResultLines('250',$responses))>0) - { - $this->esmtp_host=$this->Tokenize($responses[0]," "); - for($response=1;$responseTokenize($responses[$response]," ")); - $this->esmtp_extensions[$extension]=$this->Tokenize(""); - } - $success=1; - $fallback=0; - } - else - { - if($success_code==0) - { - $code=$this->Tokenize($this->error," -"); - switch($code) - { - case "421": - $fallback=0; - break; - } - } - } - } - else - $fallback=0; - } - if($fallback) - { - if($this->PutLine("HELO $localhost") - && $this->VerifyResultLines("250",$responses)>0) - $success=1; - } - return($success); - } - - /* Public methods */ - -/* -{metadocument} - - Connect - BOOLEAN - - Connect to an SMTP server. - Call this function as first step to send e-mail messages. - The function returns - 1 if the connection is - successfully established. - - - domain - STRING - - - Specify the domain of the recipient when using the direct - delivery mode. - - - -{/metadocument} -*/ - Function Connect($domain="") - { - if(strcmp($this->state,"Disconnected")) - { - $this->error="connection is already established"; - return(0); - } - $this->disconnected_error=0; - $this->error=$error=""; - $this->esmtp_host=""; - $this->esmtp_extensions=array(); - $hosts=array(); - if($this->direct_delivery) - { - if(strlen($domain)==0) - return(1); - $hosts=$weights=$mxhosts=array(); - $getmxrr=$this->getmxrr; - if(function_exists($getmxrr) - && $getmxrr($domain,$hosts,$weights)) - { - for($host=0;$hosthost_name)) - $hosts[]=$this->host_name; - if(strlen($this->pop3_auth_host)) - { - $user=$this->user; - if(strlen($user)==0) - { - $this->error="it was not specified the POP3 authentication user"; - return(0); - } - $password=$this->password; - if(strlen($password)==0) - { - $this->error="it was not specified the POP3 authentication password"; - return(0); - } - $domain=$this->pop3_auth_host; - $this->error=$this->ConnectToHost($domain, $this->pop3_auth_port, "Resolving POP3 authentication host \"".$domain."\"..."); - if(strlen($this->error)) - return(0); - if(strlen($response=$this->GetLine())==0) - return(0); - if(strcmp($this->Tokenize($response," "),"+OK")) - { - $this->error="POP3 authentication server greeting was not found"; - return(0); - } - if(!$this->PutLine("USER ".$this->user) - || strlen($response=$this->GetLine())==0) - return(0); - if(strcmp($this->Tokenize($response," "),"+OK")) - { - $this->error="POP3 authentication user was not accepted: ".$this->Tokenize("\r\n"); - return(0); - } - if(!$this->PutLine("PASS ".$password) - || strlen($response=$this->GetLine())==0) - return(0); - if(strcmp($this->Tokenize($response," "),"+OK")) - { - $this->error="POP3 authentication password was not accepted: ".$this->Tokenize("\r\n"); - return(0); - } - fclose($this->connection); - $this->connection=0; - } - } - if(count($hosts)==0) - { - $this->error="could not determine the SMTP to connect"; - return(0); - } - for($host=0, $error="not connected";strlen($error) && $hostConnectToHost($domain, $this->host_port, "Resolving SMTP server domain \"$domain\"..."); - } - if(strlen($error)) - { - $this->error=$error; - return(0); - } - $timeout=($this->data_timeout ? $this->data_timeout : $this->timeout); - if($timeout - && function_exists("socket_set_timeout")) - socket_set_timeout($this->connection,$timeout,0); - if($this->debug) - $this->OutputDebug("Connected to SMTP server \"".$domain."\"."); - if(!strcmp($localhost=$this->localhost,"") - && !strcmp($localhost=getenv("SERVER_NAME"),"") - && !strcmp($localhost=getenv("HOST"),"")) - $localhost="localhost"; - $success=0; - if($this->VerifyResultLines("220",$responses)>0) - { - $success = $this->StartSMTP($localhost); - if($this->start_tls) - { - if(!IsSet($this->esmtp_extensions["STARTTLS"])) - { - $this->error="server does not support starting TLS"; - $success=0; - } - elseif(!function_exists('stream_socket_enable_crypto')) - { - $this->error="this PHP installation or version does not support starting TLS"; - $success=0; - } - elseif($success = ($this->PutLine('STARTTLS') - && $this->VerifyResultLines('220',$responses)>0)) - { - if($this->debug) - $this->OutputDebug('Starting TLS cryptograpic protocol'); - if(!($success = @stream_socket_enable_crypto($this->connection, 1, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT))) - $this->error = 'could not start TLS connection encryption protocol'; - else - { - if($this->debug) - $this->OutputDebug('TLS started'); - $success = $this->StartSMTP($localhost); - } - } - } - if($success - && strlen($this->user) - && strlen($this->pop3_auth_host)==0) - { - if(!IsSet($this->esmtp_extensions["AUTH"])) - { - $this->error="server does not require authentication"; - if(IsSet($this->esmtp_extensions["STARTTLS"])) - $this->error .= ', it probably requires starting TLS'; - $success=0; - } - else - { - if(strlen($this->authentication_mechanism)) - $mechanisms=array($this->authentication_mechanism); - else - { - $mechanisms=array(); - for($authentication=$this->Tokenize($this->esmtp_extensions["AUTH"]," ");strlen($authentication);$authentication=$this->Tokenize(" ")) - $mechanisms[]=$authentication; - } - $credentials=array( - "user"=>$this->user, - "password"=>$this->password - ); - if(strlen($this->realm)) - $credentials["realm"]=$this->realm; - if(strlen($this->workstation)) - $credentials["workstation"]=$this->workstation; - $success=$this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism); - if(!$success - && !strcmp($mechanism,"PLAIN")) - { - /* - * Author: Russell Robinson, 25 May 2003, http://www.tectite.com/ - * Purpose: Try various AUTH PLAIN authentication methods. - */ - $mechanisms=array("PLAIN"); - $credentials=array( - "user"=>$this->user, - "password"=>$this->password - ); - if(strlen($this->realm)) - { - /* - * According to: http://www.sendmail.org/~ca/email/authrealms.html#authpwcheck_method - * some sendmails won't accept the realm, so try again without it - */ - $success=$this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism); - } - if(!$success) - { - /* - * It was seen an EXIM configuration like this: - * user^password^unused - */ - $credentials["mode"]=SASL_PLAIN_EXIM_DOCUMENTATION_MODE; - $success=$this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism); - } - if(!$success) - { - /* - * ... though: http://exim.work.de/exim-html-3.20/doc/html/spec_36.html - * specifies: ^user^password - */ - $credentials["mode"]=SASL_PLAIN_EXIM_MODE; - $success=$this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism); - } - } - if($success - && strlen($mechanism)==0) - { - $this->error="it is not supported any of the authentication mechanisms required by the server"; - $success=0; - } - } - } - } - if($success) - { - $this->state="Connected"; - $this->connected_domain=$domain; - } - else - { - fclose($this->connection); - $this->connection=0; - } - return($success); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - MailFrom - BOOLEAN - - Set the address of the message sender. - Call this function right after establishing a connection with - the Connect function. - The function returns - 1 if the sender address is - successfully set. - - - sender - STRING - - E-mail address of the sender. - - - -{/metadocument} -*/ - Function MailFrom($sender) - { - if($this->direct_delivery) - { - switch($this->state) - { - case "Disconnected": - $this->direct_sender=$sender; - return(1); - case "Connected": - $sender=$this->direct_sender; - break; - default: - $this->error="direct delivery connection is already established and sender is already set"; - return(0); - } - } - else - { - if(strcmp($this->state,"Connected")) - { - $this->error="connection is not in the initial state"; - return(0); - } - } - $this->error=""; - if(!$this->PutLine("MAIL FROM:<$sender>")) - return(0); - if(!IsSet($this->esmtp_extensions["PIPELINING"]) - && $this->VerifyResultLines("250",$responses)<=0) - return(0); - $this->state="SenderSet"; - if(IsSet($this->esmtp_extensions["PIPELINING"])) - $this->pending_sender=1; - $this->pending_recipients=0; - return(1); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - SetRecipient - BOOLEAN - - Set the address of a message recipient. - Call this function repeatedly for each recipient right after - setting the message sender with the - MailFrom function. - The function returns - 1 if the recipient address is - successfully set. - - - recipient - STRING - - E-mail address of a recipient. - - - -{/metadocument} -*/ - Function SetRecipient($recipient) - { - if($this->direct_delivery) - { - if(GetType($at=strrpos($recipient,"@"))!="integer") - return("it was not specified a valid direct recipient"); - $domain=substr($recipient,$at+1); - switch($this->state) - { - case "Disconnected": - if(!$this->Connect($domain)) - return(0); - if(!$this->MailFrom("")) - { - $error=$this->error; - $this->Disconnect(); - $this->error=$error; - return(0); - } - break; - case "SenderSet": - case "RecipientSet": - if(strcmp($this->connected_domain,$domain)) - { - $this->error="it is not possible to deliver directly to recipients of different domains"; - return(0); - } - break; - default: - $this->error="connection is already established and the recipient is already set"; - return(0); - } - } - else - { - switch($this->state) - { - case "SenderSet": - case "RecipientSet": - break; - default: - $this->error="connection is not in the recipient setting state"; - return(0); - } - } - $this->error=""; - if(!$this->PutLine("RCPT TO:<$recipient>")) - return(0); - if(IsSet($this->esmtp_extensions["PIPELINING"])) - { - $this->pending_recipients++; - if($this->pending_recipients>=$this->maximum_piped_recipients) - { - if(!$this->FlushRecipients()) - return(0); - } - } - else - { - if($this->VerifyResultLines(array("250","251"),$responses)<=0) - return(0); - } - $this->state="RecipientSet"; - return(1); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - StartData - BOOLEAN - - Tell the SMTP server that the message data will start being - sent. - Call this function right after you are done setting all the - message recipients with the - SetRecipient function. - The function returns - 1 if the server is ready to - start receiving the message data. - - -{/metadocument} -*/ - Function StartData() - { - if(strcmp($this->state,"RecipientSet")) - { - $this->error="connection is not in the start sending data state"; - return(0); - } - $this->error=""; - if(!$this->PutLine("DATA")) - return(0); - if($this->pending_recipients) - { - if(!$this->FlushRecipients()) - return(0); - } - if($this->VerifyResultLines("354",$responses)<=0) - return(0); - $this->state="SendingData"; - return(1); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - PrepareData - STRING - - Prepare message data to normalize line breaks and escaping - lines that contain single dots. - Call this function if the message data you want to send may - contain line breaks that are not the - sequence or it may contain - lines that just have a single dot. - Resulting normalized messages data. - - - data - STRING - - Message data to be prepared. - - - -{/metadocument} -*/ - Function PrepareData($data) - { - return(preg_replace(array("/\n\n|\r\r/","/(^|[^\r])\n/","/\r([^\n]|\$)/D","/(^|\n)\\./"),array("\r\n\r\n","\\1\r\n","\r\n\\1","\\1.."),$data)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - SendData - BOOLEAN - - Send message data. - Call this function repeatedly for all message data blocks - to be sent right after start sending message data with the - StartData function. - The function returns - 1 if the message data was - sent to the SMTP server successfully. - - - data - STRING - - Message data to be sent. - - - -{/metadocument} -*/ - Function SendData($data) - { - if(strcmp($this->state,"SendingData")) - { - $this->error="connection is not in the sending data state"; - return(0); - } - $this->error=""; - return($this->PutData($data)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - EndSendingData - BOOLEAN - - Tell the server that all the message data was sent. - Call this function when you are done with sending the message - data with the SendData function. - The function returns - 1 if the server accepted the - message. - - -{/metadocument} -*/ - Function EndSendingData() - { - if(strcmp($this->state,"SendingData")) - { - $this->error="connection is not in the sending data state"; - return(0); - } - $this->error=""; - if(!$this->PutLine("\r\n.") - || $this->VerifyResultLines("250",$responses)<=0) - return(0); - $this->state="Connected"; - return(1); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - ResetConnection - BOOLEAN - - Reset an already established SMTP connection to the initial - state. - Call this function when there was an error sending a message - and you need to skip to sending another message without - disconnecting. - The function returns - 1 if the connection was - resetted successfully. - - -{/metadocument} -*/ - Function ResetConnection() - { - switch($this->state) - { - case "Connected": - return(1); - case "SendingData": - $this->error="can not reset the connection while sending data"; - return(0); - case "Disconnected": - $this->error="can not reset the connection before it is established"; - return(0); - } - $this->error=""; - if(!$this->PutLine("RSET") - || $this->VerifyResultLines("250",$responses)<=0) - return(0); - $this->state="Connected"; - return(1); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - Disconnect - BOOLEAN - - Terminate a previously opened connection. - Call this function after you are done sending your - messages. - The function returns - 1 if the connection was - successfully closed. - - - quit - BOOLEAN - 1 - - Boolean option that tells whether the class should - perform the final connection quit handshake, or just close the - connection without waiting. - - - -{/metadocument} -*/ - Function Disconnect($quit=1) - { - if(!strcmp($this->state,"Disconnected")) - { - $this->error="it was not previously established a SMTP connection"; - return(0); - } - $this->error=""; - if(!strcmp($this->state,"Connected") - && $quit - && (!$this->PutLine("QUIT") - || ($this->VerifyResultLines("221",$responses)<=0 - && !$this->disconnected_error))) - return(0); - if($this->disconnected_error) - $this->disconnected_error=0; - else - fclose($this->connection); - $this->connection=0; - $this->state="Disconnected"; - if($this->debug) - $this->OutputDebug("Disconnected."); - return(1); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - SendMessage - BOOLEAN - - Send a message in a single call. - Call this function if you want to send a single messages to a - small number of recipients in a single call. - The function returns - 1 if the message was sent - successfully. - - - sender - STRING - - E-mail address of the sender. - - - - recipients - STRING - - Array with a list of the e-mail addresses of the - recipients of the message. - - - - headers - ARRAY - - Array with a list of the header lines of the message. - - - - body - STRING - - Body data of the message. - - - -{/metadocument} -*/ - Function SendMessage($sender,$recipients,$headers,$body) - { - if(($success=$this->Connect())) - { - if(($success=$this->MailFrom($sender))) - { - for($recipient=0;$recipientSetRecipient($recipients[$recipient]))) - break; - } - if($success - && ($success=$this->StartData())) - { - for($header_data="",$header=0;$headerSendData($header_data."\r\n") - && $this->SendData($this->PrepareData($body)) - && $this->EndSendingData()); - } - } - $error=$this->error; - $disconnect_success=$this->Disconnect($success); - if($success) - $success=$disconnect_success; - else - $this->error=$error; - } - return($success); - } -/* -{metadocument} - - -{/metadocument} -*/ - -}; - -/* - -{metadocument} -
-{/metadocument} - -*/ - -?> diff --git a/vendor/email_message/smtp_message.php b/vendor/email_message/smtp_message.php deleted file mode 100644 index b043a4a..0000000 --- a/vendor/email_message/smtp_message.php +++ /dev/null @@ -1,782 +0,0 @@ - - - - net.manuellemos.mimemessage - - smtp_message_class - @(#) $Id: smtp_message.php,v 1.36 2011/03/09 07:48:52 mlemos Exp $ - Copyright © (C) Manuel Lemos 1999-2004 - MIME E-mail message composing and sending via SMTP - Manuel Lemos - mlemos-at-acm.org - - - en - Implement an alternative message delivery method via SMTP - protocol, overriding the method of using the PHP mail() - function implemented by the base class. - This class should be used exactly the same way as the base - class for composing and sending messages. Just create a new object of - this class as follows and set only the necessary variables to - configure details of the SMTP delivery. - require('email_message.php');
- require('smtp.php');
- require('smtp_message.php');
-
- $message_object = new smtp_message_class;
- - Requirements - You need the - SMTP E-mail sending class - http://freshmeat.net/projects/smtpclass/ - to perform the actual message delivery via the SMTP - protocol. - - SMTP connection - Before sending a message by relaying it to a given SMTP server you - need set the smtp_host variable to that - server address. The localhost variable - needs to be set to the sending computer address. - You may also adjust the time the class will wait for establishing - a connection by changing the timeout - variable. - - Secure SMTP connections with SSL - Some SMTP servers, like for instance Gmail, require secure - connections via SSL. In that case it is necessary to set the - smtp_ssl variable to - 1. In the case of Gmail, it is also - necessary to set the connection port changing the - smtp_port variable to - 465. - SSL support requires at least PHP 4.3.0 with OpenSSL extension - enabled. - - Secure SMTP connections starting TLS after connections is established - Some SMTP servers, like for instance Hotmail, require starting the - TLS protocol after the connection is already established to exchange - data securely. In that case it is necessary to set the - smtp_start_tls variable to - 1. - Starting TLS protocol on an already established connection requires - at least PHP 5.1.0 with OpenSSL extension enabled. - - Authentication - Most servers only allow relaying messages sent by authorized - users. If the SMTP server that you want to use requires - authentication, you need to set the variables - smtp_user, - smtp_realm and - smtp_password. - The way these values need to be set depends on the server. Usually - the realm value is empty and only the user and password need to be - set. If the server requires authentication via NTLM - mechanism (Windows or Samba), you need to set the - smtp_realm to the Windows domain name - and also set the variable - smtp_workstation to the user workstation - name. - Some servers require that the authentication be done on a separate - server using the POP3 protocol before connecting to the SMTP server. - In this case you need to specify the address of the POP3 server - setting the smtp_pop3_auth_host - variable. - - Sending urgent messages with direct delivery - If you need to send urgent messages or obtain immediate confirmation - that a message is accepted by the recipient SMTP server, you can use - the direct delivery mode setting the - direct_delivery variable to - 1. This mode can be used to - send a message to only one recipient. - To use this mode, it is necessary to have a way to determine the - recipient domain SMTP server address. The class uses the PHP - getmxrr() function, but on some systems like for instance - under Windows, this function does not work. In this case you may - specify an equivalent alternative by setting the - smtp_getmxrr variable. See the SMTP - class page for available alternatives. - - Troubleshooting and debugging - If for some reason the delivery via SMTP is not working and the error - messages are not self-explanatory, you may set the - smtp_debug to - 1 to make the class output the - SMTP protocol dialog with the server. If you want to display this - dialog properly formatted in an HTML page, also set the - smtp_debug to - 1. - - Optimizing the delivery of messages to many recipients - When sending messages to many recipients, this class can hinted to - optimize its behavior by using the - SetBulkMail function. After calling this - function passing 1 to the - SetBulkMail - on - argument, when the message is sent this class opens - a TCP connection to the SMTP server but will not close it. This - avoids the overhead of opening and closing connections. - When the delivery of the messages to all recipients is done, the - connection may be closed implicitly by calling the - SetBulkMail function again passing - 0 to the - SetBulkMail - on - argument.
-
- -{/metadocument} -*/ - -class smtp_message_class extends email_message_class -{ - /* Private variables */ - - var $smtp; - var $line_break="\r\n"; - var $delivered = 0; - - /* Public variables */ - -/* -{metadocument} - - localhost - - - Specify the domain name of the computer sending the - message. - This value is used to identify the sending machine to the - SMTP server. When using the direct delivery mode, if this variable - is set to a non-empty string it used to generate the - Recieved header to show that the message passed by the - specified host address. To prevent confusing directly delivered - messages with spam, it is strongly recommended that you set this - variable to you server host name. - - -{/metadocument} -*/ - var $localhost=""; - -/* -{metadocument} - - smtp_host - STRING - - - Specify the address of the SMTP server. - Set to the address of the SMTP server that will relay the - messages. This variable is not used in direct delivery mode. - - -{/metadocument} -*/ - var $smtp_host="localhost"; - -/* -{metadocument} - - smtp_port - INTEGER - 25 - - Specify the TCP/IP port of SMTP server to connect. - Most servers work on port 25 . Certain e-mail services use - alternative ports to avoid firewall blocking. Gmail uses port - 465. - - -{/metadocument} -*/ - var $smtp_port=25; - -/* -{metadocument} - - smtp_ssl - BOOLEAN - 0 - - Specify whether it should use secure connections with SSL - to connect to the SMTP server. - Certain e-mail services like Gmail require SSL connections. - - -{/metadocument} -*/ - var $smtp_ssl=0; - -/* -{metadocument} - - smtp_start_tls - BOOLEAN - 0 - - Specify whether it should use secure connections starting - TLS protocol after connecting to the SMTP server. - Certain e-mail services like Hotmail require starting TLS - protocol after the connection to the SMTP server is already - established. - - -{/metadocument} -*/ - var $smtp_start_tls=0; - -/* -{metadocument} - - smtp_http_proxy_host_name - STRING - - - Specify name of the host when the connection should be - routed via an HTTP proxy. - Leave empty if no proxy should be used. - - -{/metadocument} -*/ - var $smtp_http_proxy_host_name=''; - -/* -{metadocument} - - smtp_http_proxy_host_port - INTEGER - 3128 - - Specify proxy port when the connection should be routed via - an HTTP proxy. - Change this variable if you need to use a proxy with a - specific port. - - -{/metadocument} -*/ - var $smtp_http_proxy_host_port=3128; - -/* -{metadocument} - - smtp_socks_host_name - STRING - - - Specify name of the host when the connection should be - routed via a SOCKS protocol proxy. - Leave empty if no proxy should be used. - - -{/metadocument} -*/ - var $smtp_socks_host_name = ''; - -/* -{metadocument} - - smtp_socks_host_port - INTEGER - 1080 - - Specify proxy port when the connection should be routed via - a SOCKS protocol proxy. - Change this variable if you need to use a proxy with a - specific port. - - -{/metadocument} -*/ - var $smtp_socks_host_port = 1080; - -/* -{metadocument} - - smtp_socks_version - STRING - - - Specify protocol version when the connection should be - routed via a SOCKS protocol proxy. - Change this variable if you need to use a proxy with a - specific SOCKS protocol version. - - -{/metadocument} -*/ - var $smtp_socks_version = '5'; - -/* -{metadocument} - - smtp_direct_delivery - BOOLEAN - 0 - - Boolean flag that indicates whether the message should be - sent in direct delivery mode. - Set this to 1 if you - want to send urgent messages directly to the recipient domain SMTP - server. - - -{/metadocument} -*/ - var $smtp_direct_delivery=0; - -/* -{metadocument} - - smtp_getmxrr - STRING - getmxrr - - Specify the name of the function that is called to determine - the SMTP server address of a given domain. - Change this to a working replacement of the PHP - getmxrr() function if this is not working in your system - and you want to send messages in direct delivery mode. - - -{/metadocument} -*/ - var $smtp_getmxrr="getmxrr"; - -/* -{metadocument} - - smtp_exclude_address - STRING - - - Specify an address that should be considered invalid - when resolving host name addresses. - In some networks any domain name that does not exist is - resolved as a sub-domain of the default local domain. If the DNS is - configured in such way that it always resolves any sub-domain of - the default local domain to a given address, it is hard to - determine whether a given domain does not exist. - If your network is configured this way, you may set this variable - to the address that all sub-domains of the default local domain - resolves, so the class can assume that such address is invalid. - - -{/metadocument} -*/ - var $smtp_exclude_address=""; - -/* -{metadocument} - - smtp_user - STRING - - - Specify the user name for authentication. - Set this variable if you need to authenticate before sending - a message. - - -{/metadocument} -*/ - var $smtp_user=""; - -/* -{metadocument} - - smtp_realm - STRING - - - Specify the user authentication realm. - Set this variable if you need to authenticate before sending - a message. - - -{/metadocument} -*/ - var $smtp_realm=""; - -/* -{metadocument} - - smtp_workstation - STRING - - - Specify the user authentication workstation needed when - using the NTLM authentication (Windows or Samba). - Set this variable if you need to authenticate before sending - a message. - - -{/metadocument} -*/ - var $smtp_workstation=""; - -/* -{metadocument} - - smtp_authentication_mechanism - STRING - - - Specify the user authentication mechanism that should be - used when authenticating with the SMTP server. - Set this variable if you need to force the SMTP connection to - authenticate with a specific authentication mechanism. Leave this - variable with an empty string if you want the authentication - mechanism be determined automatically from the list of mechanisms - supported by the server. - - -{/metadocument} -*/ - var $smtp_authentication_mechanism=""; - -/* -{metadocument} - - smtp_password - STRING - - - Specify the user authentication password. - Set this variable if you need to authenticate before sending - a message. - - -{/metadocument} -*/ - var $smtp_password=""; - -/* -{metadocument} - - smtp_pop3_auth_host - STRING - - - Specify the server address for POP3 based authentication. - Set this variable to the address of the POP3 server if the - SMTP server requires POP3 based authentication. - - -{/metadocument} -*/ - var $smtp_pop3_auth_host=""; - -/* -{metadocument} - - smtp_debug - BOOLEAN - 0 - - Specify whether it is necessary to output SMTP connection - debug information. - Set this variable to - 1 if you need to see - the progress of the SMTP connection and protocol dialog when you - need to understand the reason for delivery problems. - - -{/metadocument} -*/ - var $smtp_debug=0; - -/* -{metadocument} - - smtp_html_debug - BOOLEAN - 0 - - Specify whether the debug information should be outputted in - HTML format. - Set this variable to - 1 if you need to see - the debug output in a Web page. - - -{/metadocument} -*/ - var $smtp_html_debug=0; - -/* -{metadocument} - - esmtp - BOOLEAN - 1 - - Specify whether the class should try to use Enhanced SMTP - protocol features. - It is recommended to leave this variable set to - 1 so the class can take - advantage of Enhanced SMTP protocol features. - - -{/metadocument} -*/ - var $esmtp=1; - -/* -{metadocument} - - timeout - INTEGER - 25 - - Specify the connection timeout period in seconds. - Change this value if for some reason the timeout period seems - insufficient or otherwise it seems too long. - - -{/metadocument} -*/ - var $timeout=25; - -/* -{metadocument} - - invalid_recipients - ARRAY - - - Return the list of recipient addresses that were not - accepted by the SMTP server. - Check this variable after attempting to send a message to - figure whether there were any recipients that were rejected by the - SMTP server. - - -{/metadocument} -*/ - var $invalid_recipients=array(); - -/* -{metadocument} - - mailer_delivery - smtp $Revision: 1.36 $ - - Specify the text that is used to identify the mail - delivery class or sub-class. This text is appended to the - X-Mailer header text defined by the - mailer variable. - Do not change this variable. - - -{/metadocument} -*/ - var $mailer_delivery='smtp $Revision: 1.36 $'; - -/* -{metadocument} - - maximum_bulk_deliveries - INTEGER - 100 - - Specify the number of consecutive bulk mail deliveries - without disconnecting. - Lower this value if you have enabled the bulk mail mode but - the SMTP server does not accept sending more than a number of - messages within the same SMTP connection. - Set this value to 0 to never - disconnect during bulk mail mode unless an error occurs. - - -{/metadocument} -*/ - var $maximum_bulk_deliveries=100; - - Function SetRecipients(&$recipients,&$valid_recipients) - { - for($valid_recipients=$recipient=0,Reset($recipients);$recipientsmtp->SetRecipient($address)) - $valid_recipients++; - else - $this->invalid_recipients[$address]=$this->smtp->error; - } - return(1); - } - - Function ResetConnection($error) - { - if(IsSet($this->smtp)) - { - if(!$this->smtp->Disconnect() - && strlen($error) == 0) - $error = $this->smtp->error; - UnSet($this->smtp); - } - if(strlen($error)) - $this->OutputError($error); - return($error); - } - - Function StartSendingMessage() - { - if(function_exists("class_exists") - && !class_exists("smtp_class")) - return("the smtp_class class was not included"); - if(IsSet($this->smtp)) - return(""); - $this->smtp=new smtp_class; - $this->smtp->localhost=$this->localhost; - $this->smtp->host_name=$this->smtp_host; - $this->smtp->host_port=$this->smtp_port; - $this->smtp->ssl=$this->smtp_ssl; - $this->smtp->start_tls=$this->smtp_start_tls; - $this->smtp->http_proxy_host_name=$this->smtp_http_proxy_host_name; - $this->smtp->http_proxy_host_port=$this->smtp_http_proxy_host_port; - $this->smtp->socks_host_name=$this->smtp_socks_host_name; - $this->smtp->socks_host_port=$this->smtp_socks_host_port; - $this->smtp->socks_version=$this->smtp_socks_version; - $this->smtp->timeout=$this->timeout; - $this->smtp->debug=$this->smtp_debug; - $this->smtp->html_debug=$this->smtp_html_debug; - $this->smtp->direct_delivery=$this->smtp_direct_delivery; - $this->smtp->getmxrr=$this->smtp_getmxrr; - $this->smtp->exclude_address=$this->smtp_exclude_address; - $this->smtp->pop3_auth_host=$this->smtp_pop3_auth_host; - $this->smtp->user=$this->smtp_user; - $this->smtp->realm=$this->smtp_realm; - $this->smtp->workstation=$this->smtp_workstation; - $this->smtp->authentication_mechanism=$this->smtp_authentication_mechanism; - $this->smtp->password=$this->smtp_password; - $this->smtp->esmtp=$this->esmtp; - if($this->smtp->Connect()) - { - $this->delivered = 0; - return(""); - } - return($this->ResetConnection($this->smtp->error)); - } - - Function SendMessageHeaders($headers) - { - $header_data=""; - $date=date("r"); - if($this->smtp_direct_delivery - && strlen($this->localhost)) - { - $local_ip=gethostbyname($this->localhost); - $header_data.=$this->FormatHeader("Received","FROM ".$this->localhost." ([".$local_ip."]) BY ".$this->localhost." ([".$local_ip."]) WITH SMTP; ".$date)."\r\n"; - } - for($message_id_set=$date_set=0,$header=0,$return_path=$from=$to=$recipients=array(),Reset($headers);$headerGetRFC822Addresses($headers[$header_name],$from); - break; - case "to": - $error=$this->GetRFC822Addresses($headers[$header_name],$to); - break; - case "cc": - case "bcc": - $this->GetRFC822Addresses($headers[$header_name],$recipients); - break; - case "date": - $date_set=1; - break; - case "message-id": - $message_id_set=1; - break; - } - if(strcmp($error ?? null,"")) - return($this->ResetConnection($error)); - if(strtolower($header_name)=="bcc") - continue; - $header_data.=$this->FormatHeader($header_name,$headers[$header_name])."\r\n"; - } - if(count($from)==0) - return($this->ResetConnection("it was not specified a valid From header")); - Reset($return_path); - Reset($from); - $this->invalid_recipients=array(); - if(!$this->smtp->MailFrom(count($return_path) ? Key($return_path) : Key($from))) - return($this->ResetConnection($this->smtp->error)); - $r = 0; - if(count($to)) - { - if(!$this->SetRecipients($to,$valid_recipients)) - return($this->ResetConnection($this->smtp->error)); - $r += $valid_recipients; - } - if(!$date_set) - $header_data.="Date: ".$date."\r\n"; - if(!$message_id_set - && $this->auto_message_id) - { - $sender=(count($return_path) ? Key($return_path) : Key($from)); - $header_data.=$this->GenerateMessageID($sender)."\r\n"; - } - if(count($recipients)) - { - if(!$this->SetRecipients($recipients,$valid_recipients)) - return($this->ResetConnection($this->smtp->error)); - $r += $valid_recipients; - } - if($r==0) - return($this->ResetConnection("it were not specified any valid recipients")); - if(!$this->smtp->StartData() - || !$this->smtp->SendData($header_data."\r\n")) - return($this->ResetConnection($this->smtp->error)); - return(""); - } - - Function SendMessageBody($data) - { - return($this->smtp->SendData($this->smtp->PrepareData($data)) ? "" : $this->ResetConnection($this->smtp->error)); - } - - Function EndSendingMessage() - { - return($this->smtp->EndSendingData() ? "" : $this->ResetConnection($this->smtp->error)); - } - - Function StopSendingMessage() - { - ++$this->delivered; - if($this->bulk_mail - && !$this->smtp_direct_delivery - && ($this->maximum_bulk_deliveries == 0 - || $this->delivered < $this->maximum_bulk_deliveries)) - return(""); - return($this->ResetConnection('')); - } - - Function ChangeBulkMail($on) - { - if($on - || !IsSet($this->smtp)) - return(1); - return($this->smtp->Disconnect() ? "" : $this->ResetConnection($this->smtp->error)); - } -}; - -/* - -{metadocument} -
-{/metadocument} - -*/ - -?> diff --git a/vendor/sasl/LICENSE b/vendor/sasl/LICENSE deleted file mode 100644 index f731633..0000000 --- a/vendor/sasl/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2001-2005, Manuel Lemos -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the Manuel Lemos nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/sasl/basic_sasl_client.php b/vendor/sasl/basic_sasl_client.php deleted file mode 100644 index b2972b5..0000000 --- a/vendor/sasl/basic_sasl_client.php +++ /dev/null @@ -1,61 +0,0 @@ -state!=SASL_BASIC_STATE_START) - { - $client->error="Basic authentication state is not at the start"; - return(SASL_FAIL); - } - $this->credentials=array( - "user"=>"", - "password"=>"" - ); - $defaults=array( - ); - $status=$client->GetCredentials($this->credentials,$defaults,$interactions); - if($status==SASL_CONTINUE) - { - $message=$this->credentials["user"].":".$this->credentials["password"]; - $this->state=SASL_BASIC_STATE_DONE; - } - else - Unset($message); - return($status); - } - - Function Step(&$client, $response, &$message, &$interactions) - { - switch($this->state) - { - case SASL_BASIC_STATE_DONE: - $client->error="Basic authentication was finished without success"; - return(SASL_FAIL); - default: - $client->error="invalid Basic authentication step state"; - return(SASL_FAIL); - } - return(SASL_CONTINUE); - } -}; - -?> \ No newline at end of file diff --git a/vendor/sasl/cram_md5_sasl_client.php b/vendor/sasl/cram_md5_sasl_client.php deleted file mode 100644 index 69bd625..0000000 --- a/vendor/sasl/cram_md5_sasl_client.php +++ /dev/null @@ -1,67 +0,0 @@ -state!=SASL_CRAM_MD5_STATE_START) - { - $client->error="CRAM-MD5 authentication state is not at the start"; - return(SASL_FAIL); - } - $this->credentials=array( - "user"=>"", - "password"=>"" - ); - $defaults=array(); - $status=$client->GetCredentials($this->credentials,$defaults,$interactions); - if($status==SASL_CONTINUE) - $this->state=SASL_CRAM_MD5_STATE_RESPOND_CHALLENGE; - Unset($message); - return($status); - } - - Function Step(&$client, $response, &$message, &$interactions) - { - switch($this->state) - { - case SASL_CRAM_MD5_STATE_RESPOND_CHALLENGE: - $message=$this->credentials["user"]." ".$this->HMACMD5($this->credentials["password"], $response); - $this->state=SASL_CRAM_MD5_STATE_DONE; - break; - case SASL_CRAM_MD5_STATE_DONE: - $client->error="CRAM-MD5 authentication was finished without success"; - return(SASL_FAIL); - default: - $client->error="invalid CRAM-MD5 authentication step state"; - return(SASL_FAIL); - } - return(SASL_CONTINUE); - } -}; - -?> \ No newline at end of file diff --git a/vendor/sasl/digest_sasl_client.php b/vendor/sasl/digest_sasl_client.php deleted file mode 100644 index 924887d..0000000 --- a/vendor/sasl/digest_sasl_client.php +++ /dev/null @@ -1,135 +0,0 @@ -H($secret.':'.$data); - } - - Function Initialize(&$client) - { - return(1); - } - - Function Start(&$client, &$message, &$interactions) - { - if($this->state!=SASL_DIGEST_STATE_START) - { - $client->error='Digest authentication state is not at the start'; - return(SASL_FAIL); - } - $this->credentials=array( - 'user'=>'', - 'password'=>'', - 'uri'=>'', - 'method'=>'', - 'session'=>'' - ); - $defaults=array(); - $status=$client->GetCredentials($this->credentials,$defaults,$interactions); - if($status==SASL_CONTINUE) - $this->state=SASL_DIGEST_STATE_RESPOND_CHALLENGE; - Unset($message); - return($status); - } - - Function Step(&$client, $response, &$message, &$interactions) - { - switch($this->state) - { - case SASL_DIGEST_STATE_RESPOND_CHALLENGE: - $values=explode(',',$response); - $parameters=array(); - for($v=0; $vcredentials['user'].'"'; - if(!IsSet($parameters[$p='realm']) - && !IsSet($parameters[$p='nonce'])) - { - $client->error='Digest authentication parameter '.$p.' is missing from the server response'; - return(SASL_FAIL); - } - $message.=', realm='.$parameters['realm']; - $message.=', nonce='.$parameters['nonce']; - $message.=', uri="'.$this->credentials['uri'].'"'; - if(IsSet($parameters['algorithm'])) - { - $algorithm=$this->unq($parameters['algorithm']); - $message.=', algorithm='.$parameters['algorithm']; - } - else - $algorithm=''; - - $realm=$this->unq($parameters['realm']); - $nonce=$this->unq($parameters['nonce']); - if(IsSet($parameters['qop'])) - { - switch($qop=$this->unq($parameters['qop'])) - { - case "auth": - $cnonce=$this->credentials['session']; - break; - default: - $client->error='Digest authentication quality of protection '.$qop.' is not yet supported'; - return(SASL_FAIL); - } - } - $nc_value='00000001'; - if(IsSet($parameters['qop']) - && !strcmp($algorithm, 'MD5-sess')) - $A1=$this->H($this->credentials['user'].':'. $realm.':'. $this->credentials['password']).':'.$nonce.':'.$cnonce; - else - $A1=$this->credentials['user'].':'. $realm.':'. $this->credentials['password']; - $A2=$this->credentials['method'].':'.$this->credentials['uri']; - if(IsSet($parameters['qop'])) - $response=$this->KD($this->H($A1), $nonce.':'. $nc_value.':'. $cnonce.':'. $qop.':'. $this->H($A2)); - else - $response=$this->KD($this->H($A1), $nonce.':'. $this->H($A2)); - $message.=', response="'.$response.'"'; - if(IsSet($parameters['opaque'])) - $message.=', opaque='.$parameters['opaque']; - if(IsSet($parameters['qop'])) - $message.=', qop="'.$qop.'"'; - $message.=', nc='.$nc_value; - if(IsSet($parameters['qop'])) - $message.=', cnonce="'.$cnonce.'"'; - $client->encode_response=0; - $this->state=SASL_DIGEST_STATE_DONE; - break; - case SASL_DIGEST_STATE_DONE: - $client->error='Digest authentication was finished without success'; - return(SASL_FAIL); - default: - $client->error='invalid Digest authentication step state'; - return(SASL_FAIL); - } - return(SASL_CONTINUE); - } -}; - -?> \ No newline at end of file diff --git a/vendor/sasl/documentation/sasl_class.html b/vendor/sasl/documentation/sasl_class.html deleted file mode 100644 index 6948ab8..0000000 --- a/vendor/sasl/documentation/sasl_class.html +++ /dev/null @@ -1,193 +0,0 @@ - - - -Class: Simple Authentication and Security Layer client - - -

Class: Simple Authentication and Security Layer client

-
- -
- -
- -
- - -
-
Manuel Lemos (mlemos-at-acm.org)
- - diff --git a/vendor/sasl/login_sasl_client.php b/vendor/sasl/login_sasl_client.php deleted file mode 100644 index 923d16e..0000000 --- a/vendor/sasl/login_sasl_client.php +++ /dev/null @@ -1,69 +0,0 @@ -state!=SASL_LOGIN_STATE_START) - { - $client->error="LOGIN authentication state is not at the start"; - return(SASL_FAIL); - } - $this->credentials=array( - "user"=>"", - "password"=>"", - "realm"=>"" - ); - $defaults=array( - "realm"=>"" - ); - $status=$client->GetCredentials($this->credentials,$defaults,$interactions); - if($status==SASL_CONTINUE) - $this->state=SASL_LOGIN_STATE_IDENTIFY_USER; - Unset($message); - return($status); - } - - Function Step(&$client, $response, &$message, &$interactions) - { - switch($this->state) - { - case SASL_LOGIN_STATE_IDENTIFY_USER: - $message=$this->credentials["user"].(strlen($this->credentials["realm"]) ? "@".$this->credentials["realm"] : ""); - $this->state=SASL_LOGIN_STATE_IDENTIFY_PASSWORD; - break; - case SASL_LOGIN_STATE_IDENTIFY_PASSWORD: - $message=$this->credentials["password"]; - $this->state=SASL_LOGIN_STATE_DONE; - break; - case SASL_LOGIN_STATE_DONE: - $client->error="LOGIN authentication was finished without success"; - break; - default: - $client->error="invalid LOGIN authentication step state"; - return(SASL_FAIL); - } - return(SASL_CONTINUE); - } -}; - -?> \ No newline at end of file diff --git a/vendor/sasl/ntlm_sasl_client.php b/vendor/sasl/ntlm_sasl_client.php deleted file mode 100644 index 406edf2..0000000 --- a/vendor/sasl/ntlm_sasl_client.php +++ /dev/null @@ -1,180 +0,0 @@ -"mcrypt", - "mhash"=>"mhash" - ); - $client->error="the extension ".$extensions[$function]." required by the NTLM SASL client class is not available in this PHP configuration"; - return(0); - } - return(1); - } - - Function ASCIIToUnicode($ascii) - { - for($unicode="",$a=0;$aASCIIToUnicode($password); - $md4=mhash(MHASH_MD4,$unicode); - $padded=$md4.str_repeat(chr(0),21-strlen($md4)); - $iv_size=mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB); - $iv=mcrypt_create_iv($iv_size,MCRYPT_RAND); - for($response="",$third=0;$third<21;$third+=7) - { - for($packed="",$p=$third;$p<$third+7;$p++) - $packed.=str_pad(decbin(ord(substr($padded,$p,1))),8,"0",STR_PAD_LEFT); - for($key="",$p=0;$pASCIIToUnicode($domain); - $domain_length=strlen($domain_unicode); - $domain_offset=64; - $user_unicode=$this->ASCIIToUnicode($user); - $user_length=strlen($user_unicode); - $user_offset=$domain_offset+$domain_length; - $workstation_unicode=$this->ASCIIToUnicode($workstation); - $workstation_length=strlen($workstation_unicode); - $workstation_offset=$user_offset+$user_length; - $lm=""; - $lm_length=strlen($lm); - $lm_offset=$workstation_offset+$workstation_length; - $ntlm=$ntlm_response; - $ntlm_length=strlen($ntlm); - $ntlm_offset=$lm_offset+$lm_length; - $session=""; - $session_length=strlen($session); - $session_offset=$ntlm_offset+$ntlm_length; - return( - "NTLMSSP\0". - "\x03\x00\x00\x00". - pack("v",$lm_length). - pack("v",$lm_length). - pack("V",$lm_offset). - pack("v",$ntlm_length). - pack("v",$ntlm_length). - pack("V",$ntlm_offset). - pack("v",$domain_length). - pack("v",$domain_length). - pack("V",$domain_offset). - pack("v",$user_length). - pack("v",$user_length). - pack("V",$user_offset). - pack("v",$workstation_length). - pack("v",$workstation_length). - pack("V",$workstation_offset). - pack("v",$session_length). - pack("v",$session_length). - pack("V",$session_offset). - "\x01\x02\x00\x00". - $domain_unicode. - $user_unicode. - $workstation_unicode. - $lm. - $ntlm - ); - } - - Function Start(&$client, &$message, &$interactions) - { - if($this->state!=SASL_NTLM_STATE_START) - { - $client->error="NTLM authentication state is not at the start"; - return(SASL_FAIL); - } - $this->credentials=array( - "user"=>"", - "password"=>"", - "realm"=>"", - "workstation"=>"" - ); - $defaults=array(); - $status=$client->GetCredentials($this->credentials,$defaults,$interactions); - if($status==SASL_CONTINUE) - $this->state=SASL_NTLM_STATE_IDENTIFY_DOMAIN; - Unset($message); - return($status); - } - - Function Step(&$client, $response, &$message, &$interactions) - { - switch($this->state) - { - case SASL_NTLM_STATE_IDENTIFY_DOMAIN: - $message=$this->TypeMsg1($this->credentials["realm"],$this->credentials["workstation"]); - $this->state=SASL_NTLM_STATE_RESPOND_CHALLENGE; - break; - case SASL_NTLM_STATE_RESPOND_CHALLENGE: - $ntlm_response=$this->NTLMResponse(substr($response,24,8),$this->credentials["password"]); - $message=$this->TypeMsg3($ntlm_response,$this->credentials["user"],$this->credentials["realm"],$this->credentials["workstation"]); - $this->state=SASL_NTLM_STATE_DONE; - break; - case SASL_NTLM_STATE_DONE: - $client->error="NTLM authentication was finished without success"; - return(SASL_FAIL); - default: - $client->error="invalid NTLM authentication step state"; - return(SASL_FAIL); - } - return(SASL_CONTINUE); - } -}; - -?> \ No newline at end of file diff --git a/vendor/sasl/plain_sasl_client.php b/vendor/sasl/plain_sasl_client.php deleted file mode 100644 index c7feed0..0000000 --- a/vendor/sasl/plain_sasl_client.php +++ /dev/null @@ -1,99 +0,0 @@ -state!=SASL_PLAIN_STATE_START) - { - $client->error="PLAIN authentication state is not at the start"; - return(SASL_FAIL); - } - $this->credentials=array( - "user"=>"", - "password"=>"", - "realm"=>"", - "mode"=>"" - ); - $defaults=array( - "realm"=>"", - "mode"=>"" - ); - $status=$client->GetCredentials($this->credentials,$defaults,$interactions); - if($status==SASL_CONTINUE) - { - switch($this->credentials["mode"]) - { - case SASL_PLAIN_EXIM_MODE: - $message=$this->credentials["user"]."\0".$this->credentials["password"]."\0"; - break; - case SASL_PLAIN_EXIM_DOCUMENTATION_MODE: - $message="\0".$this->credentials["user"]."\0".$this->credentials["password"]; - break; - default: - $message=$this->credentials["user"]."\0".$this->credentials["user"].(strlen($this->credentials["realm"]) ? "@".$this->credentials["realm"] : "")."\0".$this->credentials["password"]; - break; - } - $this->state=SASL_PLAIN_STATE_DONE; - } - else - Unset($message); - return($status); - } - - Function Step(&$client, $response, &$message, &$interactions) - { - switch($this->state) - { -/* - case SASL_PLAIN_STATE_IDENTIFY: - switch($this->credentials["mode"]) - { - case SASL_PLAIN_EXIM_MODE: - $message=$this->credentials["user"]."\0".$this->credentials["password"]."\0"; - break; - case SASL_PLAIN_EXIM_DOCUMENTATION_MODE: - $message="\0".$this->credentials["user"]."\0".$this->credentials["password"]; - break; - default: - $message=$this->credentials["user"]."\0".$this->credentials["user"].(strlen($this->credentials["realm"]) ? "@".$this->credentials["realm"] : "")."\0".$this->credentials["password"]; - break; - } - var_dump($message); - $this->state=SASL_PLAIN_STATE_DONE; - break; -*/ - case SASL_PLAIN_STATE_DONE: - $client->error="PLAIN authentication was finished without success"; - return(SASL_FAIL); - default: - $client->error="invalid PLAIN authentication step state"; - return(SASL_FAIL); - } - return(SASL_CONTINUE); - } -}; - -?> \ No newline at end of file diff --git a/vendor/sasl/sasl.php b/vendor/sasl/sasl.php deleted file mode 100644 index 7be020a..0000000 --- a/vendor/sasl/sasl.php +++ /dev/null @@ -1,422 +0,0 @@ - - - - net.manuellemos.sasl - - @(#) $Id: sasl.php,v 1.11 2005/10/31 18:43:27 mlemos Exp $ - Copyright © (C) Manuel Lemos 2004 - Simple Authentication and Security Layer client - Manuel Lemos - mlemos-at-acm.org - - - en - Provide a common interface to plug-in driver classes that - implement different mechanisms for authentication used by clients of - standard protocols like SMTP, POP3, IMAP, HTTP, etc.. Currently the - supported authentication mechanisms are: PLAIN, - LOGIN, CRAM-MD5, Digest and NTML - (Windows or Samba). - . - - -{/metadocument} -*/ - -class sasl_client_class -{ - /* Public variables */ - -/* -{metadocument} - - error - STRING - - - Store the message that is returned when an error - occurs. - Check this variable to understand what happened when a call to - any of the class functions has failed. - This class uses cumulative error handling. This means that if one - class functions that may fail is called and this variable was - already set to an error message due to a failure in a previous call - to the same or other function, the function will also fail and does - not do anything. - This allows programs using this class to safely call several - functions that may fail and only check the failure condition after - the last function call. - Just set this variable to an empty string to clear the error - condition. - - -{/metadocument} -*/ - var $error=''; - -/* -{metadocument} - - mechanism - STRING - - - Store the name of the mechanism that was selected during the - call to the Start function. - You can access this variable but do not change it. - - -{/metadocument} -*/ - var $mechanism=''; - -/* -{metadocument} - - encode_response - BOOLEAN - 1 - - Let the drivers inform the applications whether responses - need to be encoded. - Applications should check this variable before sending - authentication responses to the server to determine if the - responses need to be encoded, eventually with base64 algorithm. - - -{/metadocument} -*/ - var $encode_response=1; - - /* Private variables */ - - var $driver; - var $drivers=array( - "Digest" => array("digest_sasl_client_class", "digest_sasl_client.php" ), - "CRAM-MD5" => array("cram_md5_sasl_client_class", "cram_md5_sasl_client.php" ), - "LOGIN" => array("login_sasl_client_class", "login_sasl_client.php" ), - "NTLM" => array("ntlm_sasl_client_class", "ntlm_sasl_client.php" ), - "PLAIN" => array("plain_sasl_client_class", "plain_sasl_client.php" ), - "Basic" => array("basic_sasl_client_class", "basic_sasl_client.php" ) - ); - var $credentials=array(); - - /* Public functions */ - -/* -{metadocument} - - SetCredential - VOID - - Store the value of a credential that may be used by any of - the supported mechanisms to process the authentication messages and - responses. - Call this function before starting the authentication dialog - to pass all the credential values that be needed to use the type - of authentication that the applications may need. - . - - - key - STRING - - Specify the name of the credential key. - - - - value - STRING - - Specify the value for the credential. - - - -{/metadocument} -*/ - Function SetCredential($key,$value) - { - $this->credentials[$key]=$value; - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - GetCredentials - INTEGER - - Retrieve the values of one or more credentials to be used by - the authentication mechanism classes. - This is meant to be used by authentication mechanism driver - classes to retrieve the credentials that may be neede. - The function may return SASL_CONTINUE if it - succeeded, or SASL_NOMECH if it was not possible to - retrieve one of the requested credentials. - - - credentials - HASH - - Reference to an associative array variable with all the - credentials that are being requested. The function initializes - this associative array values. - - - - defaults - HASH - - Associative arrays with default values for credentials - that may have not been defined. - - - - interactions - ARRAY - - Not yet in use. It is meant to provide context - information to retrieve credentials that may be obtained - interacting with the user. - - - -{/metadocument} -*/ - Function GetCredentials(&$credentials,$defaults,&$interactions) - { - Reset($credentials); - $end=(GetType($key=Key($credentials))!="string"); - for(;!$end;) - { - if(!IsSet($this->credentials[$key])) - { - if(IsSet($defaults[$key])) - $credentials[$key]=$defaults[$key]; - else - { - $this->error="the requested credential ".$key." is not defined"; - return(SASL_NOMECH); - } - } - else - $credentials[$key]=$this->credentials[$key]; - Next($credentials); - $end=(GetType($key=Key($credentials))!="string"); - } - return(SASL_CONTINUE); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - Start - INTEGER - - Process the initial authentication step initializing the - driver class that implements the first of the list of requested - mechanisms that is supported by this SASL client library - implementation. - Call this function specifying a list of mechanisms that the - server supports. If the - message - Start - argument returns a string, it should be sent to - the server as initial message. Check the - encode_response variable to determine - whether the initial message needs to be encoded, eventually with - base64 algorithm, before it is sent to the server. - The function may return SASL_CONTINUE if it - could start one of the requested authentication mechanisms. It - may return SASL_NOMECH if it was not possible to start - any of the requested mechanisms. It returns SASL_FAIL or - other value in case of error. - - - mechanisms - ARRAY - - - Define the list of names of authentication mechanisms - supported by the that should be tried. - - - - message - STRING - - - Return the initial message that should be sent to the - server to start the authentication dialog. If this value is - undefined, no message should be sent to the server. - - - - interactions - ARRAY - - Not yet in use. It is meant to provide context - information to interact with the end user. - - - -{/metadocument} -*/ - Function Start($mechanisms, &$message, &$interactions) - { - if(strlen($this->error)) - return(SASL_FAIL); - if(IsSet($this->driver)) - return($this->driver->Start($this,$message,$interactions)); - $no_mechanism_error=""; - for($m=0;$mdrivers[$mechanism])) - { - if(!class_exists($this->drivers[$mechanism][0])) - require(dirname(__FILE__)."/".$this->drivers[$mechanism][1]); - $this->driver=new $this->drivers[$mechanism][0]; - if($this->driver->Initialize($this)) - { - $this->encode_response=1; - $status=$this->driver->Start($this,$message,$interactions); - switch($status) - { - case SASL_NOMECH: - Unset($this->driver); - if(strlen($no_mechanism_error)==0) - $no_mechanism_error=$this->error; - $this->error=""; - break; - case SASL_CONTINUE: - $this->mechanism=$mechanism; - return($status); - default: - Unset($this->driver); - $this->error=""; - return($status); - } - } - else - { - Unset($this->driver); - if(strlen($no_mechanism_error)==0) - $no_mechanism_error=$this->error; - $this->error=""; - } - } - } - $this->error=(strlen($no_mechanism_error) ? $no_mechanism_error : "it was not requested any of the authentication mechanisms that are supported"); - return(SASL_NOMECH); - } -/* -{metadocument} - - -{/metadocument} -*/ - -/* -{metadocument} - - Step - INTEGER - - Process the authentication steps after the initial step, - until the authetication iteration dialog is complete. - Call this function iteratively after a successful initial - step calling the Start function. - The function returns SASL_CONTINUE if step was - processed successfully, or returns SASL_FAIL in case of - error. - - - response - STRING - - - Pass the response returned by the server to the previous - step. - - - - message - STRING - - - Return the message that should be sent to the server to - continue the authentication dialog. If this value is undefined, - no message should be sent to the server. - - - - interactions - ARRAY - - Not yet in use. It is meant to provide context - information to interact with the end user. - - - -{/metadocument} -*/ - Function Step($response, &$message, &$interactions) - { - if(strlen($this->error)) - return(SASL_FAIL); - return($this->driver->Step($this,$response,$message,$interactions)); - } -/* -{metadocument} - - -{/metadocument} -*/ - -}; - -/* - -{metadocument} - -{/metadocument} - -*/ - -?> \ No newline at end of file -- cgit v1.0