From 02e5d57998c04a7baca0558babbcada23dc42325 Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 26 Jun 2014 12:07:35 +0000 Subject: [PATCH] #949 Upgraded SwiftMailer to the latest version (5.2.1) SVN:trunk[3225] --- lib/swiftmailer/CHANGES | 137 +- lib/swiftmailer/LICENSE | 178 +- lib/swiftmailer/README | 20 +- lib/swiftmailer/VERSION | 2 +- lib/swiftmailer/lib/classes/Swift.php | 98 +- .../lib/classes/Swift/Attachment.php | 107 +- .../AbstractFilterableInputStream.php | 300 ++-- .../Swift/ByteStream/ArrayByteStream.php | 314 ++-- .../Swift/ByteStream/FileByteStream.php | 384 ++-- .../ByteStream/TemporaryFileByteStream.php | 44 + .../lib/classes/Swift/CharacterReader.php | 91 +- .../GenericFixedWidthReader.php | 154 +- .../Swift/CharacterReader/UsAsciiReader.php | 123 +- .../Swift/CharacterReader/Utf8Reader.php | 321 ++-- .../classes/Swift/CharacterReaderFactory.php | 22 +- .../SimpleCharacterReaderFactory.php | 206 ++- .../lib/classes/Swift/CharacterStream.php | 135 +- .../CharacterStream/ArrayCharacterStream.php | 531 +++--- .../CharacterStream/NgCharacterStream.php | 533 +++--- .../lib/classes/Swift/ConfigurableSpool.php | 87 +- .../lib/classes/Swift/DependencyContainer.php | 631 +++---- .../lib/classes/Swift/DependencyException.php | 25 +- .../lib/classes/Swift/EmbeddedFile.php | 103 +- lib/swiftmailer/lib/classes/Swift/Encoder.php | 22 +- .../classes/Swift/Encoder/Base64Encoder.php | 80 +- .../lib/classes/Swift/Encoder/QpEncoder.php | 472 ++--- .../classes/Swift/Encoder/Rfc2231Encoder.php | 127 +- .../lib/classes/Swift/Encoding.php | 101 +- .../lib/classes/Swift/Events/CommandEvent.php | 100 +- .../classes/Swift/Events/CommandListener.php | 19 +- .../lib/classes/Swift/Events/Event.php | 45 +- .../classes/Swift/Events/EventDispatcher.php | 130 +- .../classes/Swift/Events/EventListener.php | 7 +- .../lib/classes/Swift/Events/EventObject.php | 95 +- .../classes/Swift/Events/ResponseEvent.php | 100 +- .../classes/Swift/Events/ResponseListener.php | 19 +- .../lib/classes/Swift/Events/SendEvent.php | 220 +-- .../lib/classes/Swift/Events/SendListener.php | 32 +- .../Swift/Events/SimpleEventDispatcher.php | 282 ++- .../Swift/Events/TransportChangeEvent.php | 27 +- .../Swift/Events/TransportChangeListener.php | 64 +- .../Swift/Events/TransportExceptionEvent.php | 62 +- .../Events/TransportExceptionListener.php | 22 +- .../lib/classes/Swift/FailoverTransport.php | 59 +- .../lib/classes/Swift/FileSpool.php | 363 ++-- .../lib/classes/Swift/FileStream.php | 19 +- .../lib/classes/Swift/Filterable.php | 32 +- lib/swiftmailer/lib/classes/Swift/Image.php | 89 +- .../lib/classes/Swift/InputByteStream.php | 111 +- .../lib/classes/Swift/IoException.php | 23 +- .../lib/classes/Swift/KeyCache.php | 170 +- .../classes/Swift/KeyCache/ArrayKeyCache.php | 354 ++-- .../classes/Swift/KeyCache/DiskKeyCache.php | 555 +++--- .../Swift/KeyCache/KeyCacheInputStream.php | 70 +- .../classes/Swift/KeyCache/NullKeyCache.php | 189 +- .../KeyCache/SimpleKeyCacheInputStream.php | 218 +-- .../classes/Swift/LoadBalancedTransport.php | 61 +- .../lib/classes/Swift/MailTransport.php | 59 +- lib/swiftmailer/lib/classes/Swift/Mailer.php | 181 +- .../Swift/Mailer/ArrayRecipientIterator.php | 85 +- .../Swift/Mailer/RecipientIterator.php | 34 +- .../lib/classes/Swift/MemorySpool.php | 84 + lib/swiftmailer/lib/classes/Swift/Message.php | 313 +++- .../lib/classes/Swift/Mime/Attachment.php | 252 +-- .../classes/Swift/Mime/CharsetObserver.php | 18 +- .../lib/classes/Swift/Mime/ContentEncoder.php | 40 +- .../ContentEncoder/Base64ContentEncoder.php | 108 +- .../ContentEncoder/NativeQpContentEncoder.php | 125 ++ .../ContentEncoder/PlainContentEncoder.php | 297 ++- .../Mime/ContentEncoder/QpContentEncoder.php | 188 +- .../ContentEncoder/QpContentEncoderProxy.php | 90 + .../Mime/ContentEncoder/RawContentEncoder.php | 65 + .../lib/classes/Swift/Mime/EmbeddedFile.php | 61 +- .../classes/Swift/Mime/EncodingObserver.php | 19 +- .../lib/classes/Swift/Mime/Grammar.php | 293 +-- .../lib/classes/Swift/Mime/Header.php | 144 +- .../lib/classes/Swift/Mime/HeaderEncoder.php | 19 +- .../HeaderEncoder/Base64HeaderEncoder.php | 61 +- .../Mime/HeaderEncoder/QpHeaderEncoder.php | 93 +- .../lib/classes/Swift/Mime/HeaderFactory.php | 117 +- .../lib/classes/Swift/Mime/HeaderSet.php | 306 ++-- .../Swift/Mime/Headers/AbstractHeader.php | 919 +++++----- .../classes/Swift/Mime/Headers/DateHeader.php | 204 ++- .../Mime/Headers/IdentificationHeader.php | 301 ++-- .../Swift/Mime/Headers/MailboxHeader.php | 619 ++++--- .../Swift/Mime/Headers/OpenDKIMHeader.php | 139 ++ .../Mime/Headers/ParameterizedHeader.php | 476 +++-- .../classes/Swift/Mime/Headers/PathHeader.php | 232 +-- .../Swift/Mime/Headers/UnstructuredHeader.php | 185 +- .../lib/classes/Swift/Mime/Message.php | 420 +++-- .../lib/classes/Swift/Mime/MimeEntity.php | 190 +- .../lib/classes/Swift/Mime/MimePart.php | 357 ++-- .../Swift/Mime/ParameterizedHeader.php | 36 +- .../Swift/Mime/SimpleHeaderFactory.php | 308 ++-- .../classes/Swift/Mime/SimpleHeaderSet.php | 693 ++++--- .../lib/classes/Swift/Mime/SimpleMessage.php | 1129 ++++++------ .../classes/Swift/Mime/SimpleMimeEntity.php | 1597 +++++++++-------- .../lib/classes/Swift/MimePart.php | 82 +- .../lib/classes/Swift/NullTransport.php | 42 +- .../lib/classes/Swift/OutputByteStream.php | 51 +- .../classes/Swift/Plugins/AntiFloodPlugin.php | 243 ++- .../Swift/Plugins/BandwidthMonitorPlugin.php | 288 +-- .../Swift/Plugins/Decorator/Replacements.php | 35 +- .../classes/Swift/Plugins/DecoratorPlugin.php | 370 ++-- .../Swift/Plugins/ImpersonatePlugin.php | 30 +- .../lib/classes/Swift/Plugins/Logger.php | 41 +- .../classes/Swift/Plugins/LoggerPlugin.php | 261 ++- .../Swift/Plugins/Loggers/ArrayLogger.php | 109 +- .../Swift/Plugins/Loggers/EchoLogger.php | 82 +- .../classes/Swift/Plugins/MessageLogger.php | 77 + .../Swift/Plugins/Pop/Pop3Connection.php | 35 +- .../Swift/Plugins/Pop/Pop3Exception.php | 28 +- .../Swift/Plugins/PopBeforeSmtpPlugin.php | 494 +++-- .../Swift/Plugins/RedirectingPlugin.php | 266 ++- .../lib/classes/Swift/Plugins/Reporter.php | 35 +- .../classes/Swift/Plugins/ReporterPlugin.php | 110 +- .../Swift/Plugins/Reporters/HitReporter.php | 84 +- .../Swift/Plugins/Reporters/HtmlReporter.php | 48 +- .../lib/classes/Swift/Plugins/Sleeper.php | 18 +- .../classes/Swift/Plugins/ThrottlerPlugin.php | 324 ++-- .../lib/classes/Swift/Plugins/Timer.php | 18 +- .../lib/classes/Swift/Preferences.php | 156 +- .../Swift/ReplacementFilterFactory.php | 21 +- .../classes/Swift/RfcComplianceException.php | 23 +- .../lib/classes/Swift/SendmailTransport.php | 61 +- .../lib/classes/Swift/SignedMessage.php | 25 + lib/swiftmailer/lib/classes/Swift/Signer.php | 22 + .../lib/classes/Swift/Signers/BodySigner.php | 35 + .../lib/classes/Swift/Signers/DKIMSigner.php | 690 +++++++ .../classes/Swift/Signers/DomainKeySigner.php | 520 ++++++ .../classes/Swift/Signers/HeaderSigner.php | 67 + .../classes/Swift/Signers/OpenDKIMSigner.php | 184 ++ .../lib/classes/Swift/Signers/SMimeSigner.php | 430 +++++ .../lib/classes/Swift/SmtpTransport.php | 79 +- lib/swiftmailer/lib/classes/Swift/Spool.php | 60 +- .../lib/classes/Swift/SpoolTransport.php | 52 +- .../lib/classes/Swift/StreamFilter.php | 35 +- .../ByteArrayReplacementFilter.php | 298 ++- .../StreamFilters/StringReplacementFilter.php | 94 +- .../StringReplacementFilterFactory.php | 61 +- .../lib/classes/Swift/SwiftException.php | 22 +- .../lib/classes/Swift/Transport.php | 78 +- .../Swift/Transport/AbstractSmtpTransport.php | 921 +++++----- .../Esmtp/Auth/CramMd5Authenticator.php | 128 +- .../Esmtp/Auth/LoginAuthenticator.php | 68 +- .../Esmtp/Auth/NTLMAuthenticator.php | 701 ++++++++ .../Esmtp/Auth/PlainAuthenticator.php | 66 +- .../Esmtp/Auth/XOAuth2Authenticator.php | 71 + .../Swift/Transport/Esmtp/AuthHandler.php | 479 ++--- .../Swift/Transport/Esmtp/Authenticator.php | 40 +- .../classes/Swift/Transport/EsmtpHandler.php | 135 +- .../Swift/Transport/EsmtpTransport.php | 680 +++---- .../Swift/Transport/FailoverTransport.php | 137 +- .../lib/classes/Swift/Transport/IoBuffer.php | 100 +- .../Swift/Transport/LoadBalancedTransport.php | 298 ++- .../classes/Swift/Transport/MailInvoker.php | 36 +- .../classes/Swift/Transport/MailTransport.php | 406 ++--- .../classes/Swift/Transport/NullTransport.php | 138 +- .../Swift/Transport/SendmailTransport.php | 278 ++- .../Swift/Transport/SimpleMailInvoker.php | 70 +- .../lib/classes/Swift/Transport/SmtpAgent.php | 40 +- .../Swift/Transport/SpoolTransport.php | 185 +- .../classes/Swift/Transport/StreamBuffer.php | 581 +++--- .../lib/classes/Swift/TransportException.php | 25 +- .../lib/classes/Swift/Validate.php | 51 +- .../lib/dependency_maps/cache_deps.php | 42 +- .../lib/dependency_maps/message_deps.php | 10 +- .../lib/dependency_maps/mime_deps.php | 214 ++- .../lib/dependency_maps/transport_deps.php | 140 +- lib/swiftmailer/lib/mime_types.php | 1051 ++++++++++- lib/swiftmailer/lib/preferences.php | 35 +- lib/swiftmailer/lib/swift_init.php | 9 +- lib/swiftmailer/lib/swift_required.php | 21 +- lib/swiftmailer/lib/swift_required_pear.php | 21 +- 174 files changed, 18988 insertions(+), 14115 deletions(-) create mode 100644 lib/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php create mode 100644 lib/swiftmailer/lib/classes/Swift/MemorySpool.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Mime/Headers/OpenDKIMHeader.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php create mode 100644 lib/swiftmailer/lib/classes/Swift/SignedMessage.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Signer.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Signers/BodySigner.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php create mode 100644 lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php diff --git a/lib/swiftmailer/CHANGES b/lib/swiftmailer/CHANGES index 67e625783..c78c46326 100644 --- a/lib/swiftmailer/CHANGES +++ b/lib/swiftmailer/CHANGES @@ -1,5 +1,138 @@ -Changelog since Version 4.1.x -============================= +Changelog +========= + +5.2.1 (2014-06-13) +------------------ + + * SECURITY FIX: fixed CLI escaping when using sendmail as a transport + + Prior to 5.2.1, the sendmail transport (Swift_Transport_SendmailTransport) + was vulnerable to an arbitrary shell execution if the "From" header came + from a non-trusted source and no "Return-Path" is configured. + + * fixed parameter in DKIMSigner + * fixed compatibility with PHP < 5.4 + +5.2.0 (2014-05-08) +------------------ + + * fixed Swift_ByteStream_FileByteStream::read() to match to the specification + * fixed from-charset and to-charset arguments in mbstring_convert_encoding() usages + * fixed infinite loop in StreamBuffer + * fixed NullTransport to return the number of ignored emails instead of 0 + * Use phpunit and mockery for unit testing (realityking) + +5.1.0 (2014-03-18) +------------------ + + * fixed data writing to stream when sending large messages + * added support for libopendkim (https://github.com/xdecock/php-opendkim) + * merged SignedMessage and Message + * added Gmail XOAuth2 authentication + * updated the list of known mime types + * added NTLM authentication + +5.0.3 (2013-12-03) +------------------ + + * fixed double-dot bug + * fixed DKIM signer + +5.0.2 (2013-08-30) +------------------ + + * handled correct exception type while reading IoBuffer output + +5.0.1 (2013-06-17) +------------------ + + * changed the spool to only start the transport when a mail has to be sent + * fixed compatibility with PHP 5.2 + * fixed LICENSE file + +5.0.0 (2013-04-30) +------------------ + + * changed the license from LGPL to MIT + +4.3.1 (2013-04-11) +------------------ + + * removed usage of the native QP encoder when the charset is not UTF-8 + * fixed usage of uniqid to avoid collisions + * made a performance improvement when tokenizing large headers + * fixed usage of the PHP native QP encoder on PHP 5.4.7+ + +4.3.0 (2013-01-08) +------------------ + + * made the temporary directory configurable via the TMPDIR env variable + * added S/MIME signer and encryption support + +4.2.2 (2012-10-25) +------------------ + + * added the possibility to throttle messages per second in ThrottlerPlugin (mostly for Amazon SES) + * switched mime.qpcontentencoder to automatically use the PHP native encoder on PHP 5.4.7+ + * allowed specifying a whitelist with regular expressions in RedirectingPlugin + +4.2.1 (2012-07-13) +------------------ + + * changed the coding standards to PSR-1/2 + * fixed issue with autoloading + * added NativeQpContentEncoder to enhance performance (for PHP 5.3+) + +4.2.0 (2012-06-29) +------------------ + + * added documentation about how to use the Japanese support introduced in 4.1.8 + * added a way to override the default configuration in a lazy way + * changed the PEAR init script to lazy-load the initialization + * fixed a bug when calling Swift_Preferences before anything else (regression introduced in 4.1.8) + +4.1.8 (2012-06-17) +------------------ + + * added Japanese iso-2022-jp support + * changed the init script to lazy-load the initialization + * fixed docblocks (@id) which caused some problems with libraries parsing the dobclocks + * fixed Swift_Mime_Headers_IdentificationHeader::setId() when passed an array of ids + * fixed encoding of email addresses in headers + * added replacements setter to the Decorator plugin + +4.1.7 (2012-04-26) +------------------ + + * fixed QpEncoder safeMapShareId property + +4.1.6 (2012-03-23) +------------------ + + * reduced the size of serialized Messages + +4.1.5 (2012-01-04) +------------------ + + * enforced Swift_Spool::queueMessage() to return a Boolean + * made an optimization to the memory spool: start the transport only when required + * prevented stream_socket_client() from generating an error and throw a Swift_TransportException instead + * fixed a PHP warning when calling to mail() when safe_mode is off + * many doc tweaks + +4.1.4 (2011-12-16) +------------------ + + * added a memory spool (Swift_MemorySpool) + * fixed too many opened files when sending emails with attachments + +4.1.3 (2011-10-27) +------------------ + + * added STARTTLS support + * added missing @return tags on fluent methods + * added a MessageLogger plugin that logs all sent messages + * added composer.json 4.1.2 (2011-09-13) ------------------ diff --git a/lib/swiftmailer/LICENSE b/lib/swiftmailer/LICENSE index fc8a5de7e..674bb2a6e 100644 --- a/lib/swiftmailer/LICENSE +++ b/lib/swiftmailer/LICENSE @@ -1,165 +1,19 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 +Copyright (c) 2013 Fabien Potencier - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/swiftmailer/README b/lib/swiftmailer/README index 3ba719b48..eb5f8bcfa 100644 --- a/lib/swiftmailer/README +++ b/lib/swiftmailer/README @@ -1,8 +1,8 @@ -Swift Mailer, by Chris Corbyn ------------------------------ +Swift Mailer +------------ Swift Mailer is a component based mailing solution for PHP 5. -It is released under the LGPL license. +It is released under the MIT license. Homepage: http://swiftmailer.org Documentation: http://swiftmailer.org/docs @@ -14,17 +14,3 @@ Swift Mailer is highly object-oriented by design and lends itself to use in complex web application with a great deal of flexibility. For full details on usage, see the documentation. - -IMPORTANT: Users upgrading from version 3.x or earlier absolutely - MUST read the documentation. In short, the API is considerably - different so your old code won't "just work". - -If you'd like to make a donation, we are working on a system where -donations are taken on a per-feature-request basis via the website -with target amounts for each feature. In the meantime however you -may donate directly to the author via PayPal: - - PayPal: chris@w3style.co.uk - -Donations are certainly voluntary, but seriously, you donors are -complete legends and drive this project! :) diff --git a/lib/swiftmailer/VERSION b/lib/swiftmailer/VERSION index f632b38e6..064e3a3be 100644 --- a/lib/swiftmailer/VERSION +++ b/lib/swiftmailer/VERSION @@ -1 +1 @@ -Swift-4.1.2 +Swift-5.2.1 diff --git a/lib/swiftmailer/lib/classes/Swift.php b/lib/swiftmailer/lib/classes/Swift.php index bdb8d99fb..1d1f8215e 100644 --- a/lib/swiftmailer/lib/classes/Swift.php +++ b/lib/swiftmailer/lib/classes/Swift.php @@ -10,60 +10,72 @@ /** * General utility class in Swift Mailer, not to be instantiated. - * + * * @package Swift - * + * * @author Chris Corbyn */ abstract class Swift { - - static $initialized = false; - static $initPath; - - /** Swift Mailer Version number generated during dist release process */ - const VERSION = '@SWIFT_VERSION_NUMBER@'; - - /** - * Internal autoloader for spl_autoload_register(). - * - * @param string $class - */ - public static function autoload($class) - { - //Don't interfere with other autoloaders - if (0 !== strpos($class, 'Swift_')) + public static $initialized = false; + public static $inits = array(); + + /** Swift Mailer Version number generated during dist release process */ + const VERSION = '@SWIFT_VERSION_NUMBER@'; + + /** + * Registers an initializer callable that will be called the first time + * a SwiftMailer class is autoloaded. + * + * This enables you to tweak the default configuration in a lazy way. + * + * @param mixed $callable A valid PHP callable that will be called when autoloading the first Swift class + */ + public static function init($callable) { - return; + self::$inits[] = $callable; } - $path = dirname(__FILE__).'/'.str_replace('_', '/', $class).'.php'; - - if (!file_exists($path)) + /** + * Internal autoloader for spl_autoload_register(). + * + * @param string $class + */ + public static function autoload($class) { - return; + // Don't interfere with other autoloaders + if (0 !== strpos($class, 'Swift_')) { + return; + } + + $path = dirname(__FILE__).'/'.str_replace('_', '/', $class).'.php'; + + if (!file_exists($path)) { + return; + } + + require $path; + + if (self::$inits && !self::$initialized) { + self::$initialized = true; + foreach (self::$inits as $init) { + call_user_func($init); + } + } } - if (self::$initPath && !self::$initialized) + /** + * Configure autoloading using Swift Mailer. + * + * This is designed to play nicely with other autoloaders. + * + * @param mixed $callable A valid PHP callable that will be called when autoloading the first Swift class + */ + public static function registerAutoload($callable = null) { - self::$initialized = true; - require self::$initPath; + if (null !== $callable) { + self::$inits[] = $callable; + } + spl_autoload_register(array('Swift', 'autoload')); } - - require $path; - } - - /** - * Configure autoloading using Swift Mailer. - * - * This is designed to play nicely with other autoloaders. - * - * @param string $initPath The init script to load when autoloading the first Swift class - */ - public static function registerAutoload($initPath = null) - { - self::$initPath = $initPath; - spl_autoload_register(array('Swift', 'autoload')); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Attachment.php b/lib/swiftmailer/lib/classes/Swift/Attachment.php index 9362b8469..7fdbcb999 100644 --- a/lib/swiftmailer/lib/classes/Swift/Attachment.php +++ b/lib/swiftmailer/lib/classes/Swift/Attachment.php @@ -8,65 +8,66 @@ * file that was distributed with this source code. */ - /** * Attachment class for attaching files to a {@link Swift_Mime_Message}. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Attachment extends Swift_Mime_Attachment { - - /** - * Create a new Attachment. - * Details may be optionally provided to the constructor. - * @param string|Swift_OutputByteStream $data - * @param string $filename - * @param string $contentType - */ - public function __construct($data = null, $filename = null, - $contentType = null) - { - call_user_func_array( - array($this, 'Swift_Mime_Attachment::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('mime.attachment') - ); - - $this->setBody($data); - $this->setFilename($filename); - if ($contentType) + /** + * Create a new Attachment. + * + * Details may be optionally provided to the constructor. + * + * @param string|Swift_OutputByteStream $data + * @param string $filename + * @param string $contentType + */ + public function __construct($data = null, $filename = null, $contentType = null) { - $this->setContentType($contentType); + call_user_func_array( + array($this, 'Swift_Mime_Attachment::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('mime.attachment') + ); + + $this->setBody($data); + $this->setFilename($filename); + if ($contentType) { + $this->setContentType($contentType); + } + } + + /** + * Create a new Attachment. + * + * @param string|Swift_OutputByteStream $data + * @param string $filename + * @param string $contentType + * + * @return Swift_Mime_Attachment + */ + public static function newInstance($data = null, $filename = null, $contentType = null) + { + return new self($data, $filename, $contentType); + } + + /** + * Create a new Attachment from a filesystem path. + * + * @param string $path + * @param string $contentType optional + * + * @return Swift_Mime_Attachment + */ + public static function fromPath($path, $contentType = null) + { + return self::newInstance()->setFile( + new Swift_ByteStream_FileByteStream($path), + $contentType + ); } - } - - /** - * Create a new Attachment. - * @param string|Swift_OutputByteStream $data - * @param string $filename - * @param string $contentType - * @return Swift_Mime_Attachment - */ - public static function newInstance($data = null, $filename = null, - $contentType = null) - { - return new self($data, $filename, $contentType); - } - - /** - * Create a new Attachment from a filesystem path. - * @param string $path - * @param string $contentType optional - * @return Swift_Mime_Attachment - */ - public static function fromPath($path, $contentType = null) - { - return self::newInstance()->setFile( - new Swift_ByteStream_FileByteStream($path), - $contentType - ); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php b/lib/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php index 7a71c519f..e12c0dd5d 100644 --- a/lib/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php +++ b/lib/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php @@ -8,168 +8,176 @@ * file that was distributed with this source code. */ - /** * Provides the base functionality for an InputStream supporting filters. - * @package Swift + * + * @package Swift * @subpackage ByteStream - * @author Chris Corbyn + * @author Chris Corbyn */ -abstract class Swift_ByteStream_AbstractFilterableInputStream - implements Swift_InputByteStream, Swift_Filterable +abstract class Swift_ByteStream_AbstractFilterableInputStream implements Swift_InputByteStream, Swift_Filterable { - - /** Write sequence */ - private $_sequence = 0; - - /** StreamFilters */ - private $_filters = array(); - - /** A buffer for writing */ - private $_writeBuffer = ''; - - /** Bound streams */ - private $_mirrors = array(); - - /** - * Commit the given bytes to the storage medium immediately. - * @param string $bytes - * @access protected - */ - abstract protected function _commit($bytes); - - /** - * Flush any buffers/content with immediate effect. - * @access protected - */ - abstract protected function _flush(); - - /** - * Add a StreamFilter to this InputByteStream. - * @param Swift_StreamFilter $filter - * @param string $key - */ - public function addFilter(Swift_StreamFilter $filter, $key) - { - $this->_filters[$key] = $filter; - } - - /** - * Remove an already present StreamFilter based on its $key. - * @param string $key - */ - public function removeFilter($key) - { - unset($this->_filters[$key]); - } - - /** - * Writes $bytes to the end of the stream. - * @param string $bytes - * @throws Swift_IoException - */ - public function write($bytes) - { - $this->_writeBuffer .= $bytes; - foreach ($this->_filters as $filter) + /** + * Write sequence. + */ + protected $_sequence = 0; + + /** + * StreamFilters. + */ + private $_filters = array(); + + /** + * A buffer for writing. + */ + private $_writeBuffer = ''; + + /** + * Bound streams. + * + * @var Swift_InputByteStream[] + */ + private $_mirrors = array(); + + /** + * Commit the given bytes to the storage medium immediately. + * + * @param string $bytes + */ + abstract protected function _commit($bytes); + + /** + * Flush any buffers/content with immediate effect. + */ + abstract protected function _flush(); + + /** + * Add a StreamFilter to this InputByteStream. + * + * @param Swift_StreamFilter $filter + * @param string $key + */ + public function addFilter(Swift_StreamFilter $filter, $key) { - if ($filter->shouldBuffer($this->_writeBuffer)) - { - return; - } + $this->_filters[$key] = $filter; } - $this->_doWrite($this->_writeBuffer); - return ++$this->_sequence; - } - - /** - * For any bytes that are currently buffered inside the stream, force them - * off the buffer. - * - * @throws Swift_IoException - */ - public function commit() - { - $this->_doWrite($this->_writeBuffer); - } - - /** - * Attach $is to this stream. - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - */ - public function bind(Swift_InputByteStream $is) - { - $this->_mirrors[] = $is; - } - - /** - * Remove an already bound stream. - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - */ - public function unbind(Swift_InputByteStream $is) - { - foreach ($this->_mirrors as $k => $stream) + + /** + * Remove an already present StreamFilter based on its $key. + * + * @param string $key + */ + public function removeFilter($key) { - if ($is === $stream) - { - if ($this->_writeBuffer !== '') - { - $stream->write($this->_filter($this->_writeBuffer)); + unset($this->_filters[$key]); + } + + /** + * Writes $bytes to the end of the stream. + * + * @param string $bytes + * + * @return int + * + * @throws Swift_IoException + */ + public function write($bytes) + { + $this->_writeBuffer .= $bytes; + foreach ($this->_filters as $filter) { + if ($filter->shouldBuffer($this->_writeBuffer)) { + return; + } } - unset($this->_mirrors[$k]); - } + $this->_doWrite($this->_writeBuffer); + + return ++$this->_sequence; } - } - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - * @throws Swift_IoException - */ - public function flushBuffers() - { - if ($this->_writeBuffer !== '') + + /** + * For any bytes that are currently buffered inside the stream, force them + * off the buffer. + * + * @throws Swift_IoException + */ + public function commit() { - $this->_doWrite($this->_writeBuffer); + $this->_doWrite($this->_writeBuffer); } - $this->_flush(); - - foreach ($this->_mirrors as $stream) + + /** + * Attach $is to this stream. + * + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + */ + public function bind(Swift_InputByteStream $is) { - $stream->flushBuffers(); + $this->_mirrors[] = $is; } - } - - // -- Private methods - - /** Run $bytes through all filters */ - private function _filter($bytes) - { - foreach ($this->_filters as $filter) + + /** + * Remove an already bound stream. + * + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + */ + public function unbind(Swift_InputByteStream $is) { - $bytes = $filter->filter($bytes); + foreach ($this->_mirrors as $k => $stream) { + if ($is === $stream) { + if ($this->_writeBuffer !== '') { + $stream->write($this->_writeBuffer); + } + unset($this->_mirrors[$k]); + } + } } - return $bytes; - } - - /** Just write the bytes to the stream */ - private function _doWrite($bytes) - { - $this->_commit($this->_filter($bytes)); - - foreach ($this->_mirrors as $stream) + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + * + * @throws Swift_IoException + */ + public function flushBuffers() { - $stream->write($bytes); + if ($this->_writeBuffer !== '') { + $this->_doWrite($this->_writeBuffer); + } + $this->_flush(); + + foreach ($this->_mirrors as $stream) { + $stream->flushBuffers(); + } + } + + // -- Private methods + + /** Run $bytes through all filters */ + private function _filter($bytes) + { + foreach ($this->_filters as $filter) { + $bytes = $filter->filter($bytes); + } + + return $bytes; + } + + /** Just write the bytes to the stream */ + private function _doWrite($bytes) + { + $this->_commit($this->_filter($bytes)); + + foreach ($this->_mirrors as $stream) { + $stream->write($bytes); + } + + $this->_writeBuffer = ''; } - - $this->_writeBuffer = ''; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php b/lib/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php index c1cd01ae0..aa2959736 100644 --- a/lib/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php +++ b/lib/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php @@ -8,181 +8,179 @@ * file that was distributed with this source code. */ - /** * Allows reading and writing of bytes to and from an array. - * @package Swift + * + * @package Swift * @subpackage ByteStream - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_ByteStream_ArrayByteStream - implements Swift_InputByteStream, Swift_OutputByteStream +class Swift_ByteStream_ArrayByteStream implements Swift_InputByteStream, Swift_OutputByteStream { + /** + * The internal stack of bytes. + * + * @var string[] + */ + private $_array = array(); - /** - * The internal stack of bytes. - * @var string[] - * @access private - */ - private $_array = array(); + /** + * The size of the stack + * + * @var int + */ + private $_arraySize = 0; - /** - * The size of the stack - * @var int - * @access private - */ - private $_arraySize = 0; + /** + * The internal pointer offset. + * + * @var int + */ + private $_offset = 0; - /** - * The internal pointer offset. - * @var int - * @access private - */ - private $_offset = 0; - - /** Bound streams */ - private $_mirrors = array(); - - /** - * Create a new ArrayByteStream. - * If $stack is given the stream will be populated with the bytes it contains. - * @param mixed $stack of bytes in string or array form, optional - */ - public function __construct($stack = null) - { - if (is_array($stack)) - { - $this->_array = $stack; - $this->_arraySize = count($stack); - } - elseif (is_string($stack)) - { - $this->write($stack); - } - else - { - $this->_array = array(); - } - } + /** + * Bound streams. + * + * @var Swift_InputByteStream[] + */ + private $_mirrors = array(); - /** - * Reads $length bytes from the stream into a string and moves the pointer - * through the stream by $length. If less bytes exist than are requested the - * remaining bytes are given instead. If no bytes are remaining at all, boolean - * false is returned. - * @param int $length - * @return string - */ - public function read($length) - { - if ($this->_offset == $this->_arraySize) + /** + * Create a new ArrayByteStream. + * + * If $stack is given the stream will be populated with the bytes it contains. + * + * @param mixed $stack of bytes in string or array form, optional + */ + public function __construct($stack = null) { - return false; + if (is_array($stack)) { + $this->_array = $stack; + $this->_arraySize = count($stack); + } elseif (is_string($stack)) { + $this->write($stack); + } else { + $this->_array = array(); + } } - // Don't use array slice - $end = $length + $this->_offset; - $end = $this->_arraySize<$end - ?$this->_arraySize - :$end; - $ret = ''; - for (; $this->_offset < $end; ++$this->_offset) + /** + * Reads $length bytes from the stream into a string and moves the pointer + * through the stream by $length. + * + * If less bytes exist than are requested the + * remaining bytes are given instead. If no bytes are remaining at all, boolean + * false is returned. + * + * @param int $length + * + * @return string + */ + public function read($length) { - $ret .= $this->_array[$this->_offset]; - } - return $ret; - } + if ($this->_offset == $this->_arraySize) { + return false; + } - /** - * Writes $bytes to the end of the stream. - * @param string $bytes - */ - public function write($bytes) - { - $to_add = str_split($bytes); - foreach ($to_add as $value) - { - $this->_array[] = $value; - } - $this->_arraySize = count($this->_array); - - foreach ($this->_mirrors as $stream) - { - $stream->write($bytes); - } - } - - /** - * Not used. - */ - public function commit() - { - } - - /** - * Attach $is to this stream. - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - */ - public function bind(Swift_InputByteStream $is) - { - $this->_mirrors[] = $is; - } - - /** - * Remove an already bound stream. - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - */ - public function unbind(Swift_InputByteStream $is) - { - foreach ($this->_mirrors as $k => $stream) - { - if ($is === $stream) - { - unset($this->_mirrors[$k]); - } - } - } + // Don't use array slice + $end = $length + $this->_offset; + $end = $this->_arraySize<$end + ?$this->_arraySize + :$end; + $ret = ''; + for (; $this->_offset < $end; ++$this->_offset) { + $ret .= $this->_array[$this->_offset]; + } - /** - * Move the internal read pointer to $byteOffset in the stream. - * @param int $byteOffset - * @return boolean - */ - public function setReadPointer($byteOffset) - { - if ($byteOffset > $this->_arraySize) - { - $byteOffset = $this->_arraySize; - } - elseif ($byteOffset < 0) - { - $byteOffset = 0; + return $ret; } - $this->_offset = $byteOffset; - } - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - */ - public function flushBuffers() - { - $this->_offset = 0; - $this->_array = array(); - $this->_arraySize = 0; - - foreach ($this->_mirrors as $stream) + /** + * Writes $bytes to the end of the stream. + * + * @param string $bytes + */ + public function write($bytes) { - $stream->flushBuffers(); - } - } + $to_add = str_split($bytes); + foreach ($to_add as $value) { + $this->_array[] = $value; + } + $this->_arraySize = count($this->_array); + foreach ($this->_mirrors as $stream) { + $stream->write($bytes); + } + } + + /** + * Not used. + */ + public function commit() + { + } + + /** + * Attach $is to this stream. + * + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + */ + public function bind(Swift_InputByteStream $is) + { + $this->_mirrors[] = $is; + } + + /** + * Remove an already bound stream. + * + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + */ + public function unbind(Swift_InputByteStream $is) + { + foreach ($this->_mirrors as $k => $stream) { + if ($is === $stream) { + unset($this->_mirrors[$k]); + } + } + } + + /** + * Move the internal read pointer to $byteOffset in the stream. + * + * @param int $byteOffset + * + * @return bool + */ + public function setReadPointer($byteOffset) + { + if ($byteOffset > $this->_arraySize) { + $byteOffset = $this->_arraySize; + } elseif ($byteOffset < 0) { + $byteOffset = 0; + } + + $this->_offset = $byteOffset; + } + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + */ + public function flushBuffers() + { + $this->_offset = 0; + $this->_array = array(); + $this->_arraySize = 0; + + foreach ($this->_mirrors as $stream) { + $stream->flushBuffers(); + } + } } diff --git a/lib/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php b/lib/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php index 89a9c8107..6f1d87e0f 100644 --- a/lib/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php +++ b/lib/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php @@ -8,226 +8,226 @@ * file that was distributed with this source code. */ - /** * Allows reading and writing of bytes to and from a file. - * @package Swift + * + * @package Swift * @subpackage ByteStream - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_ByteStream_FileByteStream - extends Swift_ByteStream_AbstractFilterableInputStream - implements Swift_FileStream +class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterableInputStream implements Swift_FileStream { - - /** The internal pointer offset */ - private $_offset = 0; - - /** The path to the file */ - private $_path; - - /** The mode this file is opened in for writing */ - private $_mode; - - /** A lazy-loaded resource handle for reading the file */ - private $_reader; - - /** A lazy-loaded resource handle for writing the file */ - private $_writer; - - /** If magic_quotes_runtime is on, this will be true */ - private $_quotes = false; + /** The internal pointer offset */ + private $_offset = 0; - /** If stream is seekable true/false, or null if not known */ - private $_seekable = null; - - /** - * Create a new FileByteStream for $path. - * @param string $path - * @param string $writable if true - */ - public function __construct($path, $writable = false) - { - $this->_path = $path; - $this->_mode = $writable ? 'w+b' : 'rb'; - - if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) + /** The path to the file */ + private $_path; + + /** The mode this file is opened in for writing */ + private $_mode; + + /** A lazy-loaded resource handle for reading the file */ + private $_reader; + + /** A lazy-loaded resource handle for writing the file */ + private $_writer; + + /** If magic_quotes_runtime is on, this will be true */ + private $_quotes = false; + + /** If stream is seekable true/false, or null if not known */ + private $_seekable = null; + + /** + * Create a new FileByteStream for $path. + * + * @param string $path + * @param bool $writable if true + */ + public function __construct($path, $writable = false) { - $this->_quotes = true; + if (empty($path)) { + throw new Swift_IoException('The path cannot be empty'); + } + $this->_path = $path; + $this->_mode = $writable ? 'w+b' : 'rb'; + + if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) { + $this->_quotes = true; + } } - } - - /** - * Get the complete path to the file. - * @return string - */ - public function getPath() - { - return $this->_path; - } - - /** - * Reads $length bytes from the stream into a string and moves the pointer - * through the stream by $length. If less bytes exist than are requested the - * remaining bytes are given instead. If no bytes are remaining at all, boolean - * false is returned. - * @param int $length - * @return string - * @throws Swift_IoException - */ - public function read($length) - { - $fp = $this->_getReadHandle(); - if (!feof($fp)) + + /** + * Get the complete path to the file. + * + * @return string + */ + public function getPath() { - if ($this->_quotes) - { - ini_set('magic_quotes_runtime', 0); - } - $bytes = fread($fp, $length); - if ($this->_quotes) - { - ini_set('magic_quotes_runtime', 1); - } - $this->_offset = ftell($fp); - return $bytes; + return $this->_path; } - else + + /** + * Reads $length bytes from the stream into a string and moves the pointer + * through the stream by $length. + * + * If less bytes exist than are requested the + * remaining bytes are given instead. If no bytes are remaining at all, boolean + * false is returned. + * + * @param int $length + * + * @return string|bool + * + * @throws Swift_IoException + */ + public function read($length) { - return false; + $fp = $this->_getReadHandle(); + if (!feof($fp)) { + if ($this->_quotes) { + ini_set('magic_quotes_runtime', 0); + } + $bytes = fread($fp, $length); + if ($this->_quotes) { + ini_set('magic_quotes_runtime', 1); + } + $this->_offset = ftell($fp); + + // If we read one byte after reaching the end of the file + // feof() will return false and an empty string is returned + if ($bytes === '' && feof($fp)) { + $this->_resetReadHandle(); + + return false; + } + + return $bytes; + } + + $this->_resetReadHandle(); + + return false; } - } - - /** - * Move the internal read pointer to $byteOffset in the stream. - * @param int $byteOffset - * @return boolean - */ - public function setReadPointer($byteOffset) - { - if (isset($this->_reader)) + + /** + * Move the internal read pointer to $byteOffset in the stream. + * + * @param int $byteOffset + * + * @return bool + */ + public function setReadPointer($byteOffset) { - $this->_seekReadStreamToPosition($byteOffset); + if (isset($this->_reader)) { + $this->_seekReadStreamToPosition($byteOffset); + } + $this->_offset = $byteOffset; } - $this->_offset = $byteOffset; - } - - // -- Private methods - - /** Just write the bytes to the file */ - protected function _commit($bytes) - { - fwrite($this->_getWriteHandle(), $bytes); - $this->_resetReadHandle(); - } - - /** Not used */ - protected function _flush() - { - } - - /** Get the resource for reading */ - private function _getReadHandle() - { - if (!isset($this->_reader)) + + // -- Private methods + + /** Just write the bytes to the file */ + protected function _commit($bytes) { - if (!$this->_reader = fopen($this->_path, 'rb')) - { - throw new Swift_IoException( - 'Unable to open file for reading [' . $this->_path . ']' - ); - } - if ($this->_offset <> 0) - { - $this->_getReadStreamSeekableStatus(); - $this->_seekReadStreamToPosition($this->_offset); - } + fwrite($this->_getWriteHandle(), $bytes); + $this->_resetReadHandle(); } - return $this->_reader; - } - - /** Get the resource for writing */ - private function _getWriteHandle() - { - if (!isset($this->_writer)) + + /** Not used */ + protected function _flush() { - if (!$this->_writer = fopen($this->_path, $this->_mode)) - { - throw new Swift_IoException( - 'Unable to open file for writing [' . $this->_path . ']' - ); - } } - return $this->_writer; - } - - /** Force a reload of the resource for reading */ - private function _resetReadHandle() - { - if (isset($this->_reader)) + + /** Get the resource for reading */ + private function _getReadHandle() { - fclose($this->_reader); - $this->_reader = null; + if (!isset($this->_reader)) { + if (!$this->_reader = fopen($this->_path, 'rb')) { + throw new Swift_IoException( + 'Unable to open file for reading [' . $this->_path . ']' + ); + } + if ($this->_offset <> 0) { + $this->_getReadStreamSeekableStatus(); + $this->_seekReadStreamToPosition($this->_offset); + } + } + + return $this->_reader; } - } - - /** Check if ReadOnly Stream is seekable */ - private function _getReadStreamSeekableStatus() - { - $metas = stream_get_meta_data($this->_reader); - $this->_seekable = $metas['seekable']; - } - - /** Streams in a readOnly stream ensuring copy if needed */ - private function _seekReadStreamToPosition($offset) - { - if ($this->_seekable===null) + + /** Get the resource for writing */ + private function _getWriteHandle() { - $this->_getReadStreamSeekableStatus(); + if (!isset($this->_writer)) { + if (!$this->_writer = fopen($this->_path, $this->_mode)) { + throw new Swift_IoException( + 'Unable to open file for writing [' . $this->_path . ']' + ); + } + } + + return $this->_writer; } - if ($this->_seekable === false) + + /** Force a reload of the resource for reading */ + private function _resetReadHandle() { - $currentPos = ftell($this->_reader); - if ($currentPos<$offset) - { - $toDiscard = $offset-$currentPos; - fread($this->_reader, $toDiscard); - return; - } - $this->_copyReadStream(); + if (isset($this->_reader)) { + fclose($this->_reader); + $this->_reader = null; + } } - fseek($this->_reader, $offset, SEEK_SET); - } - - /** Copy a readOnly Stream to ensure seekability */ - private function _copyReadStream() - { - if ($tmpFile = fopen('php://temp/maxmemory:4096', 'w+b')) + + /** Check if ReadOnly Stream is seekable */ + private function _getReadStreamSeekableStatus() { - /* We have opened a php:// Stream Should work without problem */ - } - elseif (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) - { - /* We have opened a tmpfile */ - } - else - { - throw new Swift_IoException('Unable to copy the file to make it seekable, sys_temp_dir is not writable, php://memory not available'); + $metas = stream_get_meta_data($this->_reader); + $this->_seekable = $metas['seekable']; } - $currentPos = ftell($this->_reader); - fclose($this->_reader); - $source = fopen($this->_path, 'rb'); - if (!$source) + + /** Streams in a readOnly stream ensuring copy if needed */ + private function _seekReadStreamToPosition($offset) { - throw new Swift_IoException('Unable to open file for copying [' . $this->_path . ']'); + if ($this->_seekable===null) { + $this->_getReadStreamSeekableStatus(); + } + if ($this->_seekable === false) { + $currentPos = ftell($this->_reader); + if ($currentPos<$offset) { + $toDiscard = $offset-$currentPos; + fread($this->_reader, $toDiscard); + + return; + } + $this->_copyReadStream(); + } + fseek($this->_reader, $offset, SEEK_SET); } - fseek($tmpFile, 0, SEEK_SET); - while (!feof($source)) + + /** Copy a readOnly Stream to ensure seekability */ + private function _copyReadStream() { - fwrite($tmpFile, fread($source, 4096)); + if ($tmpFile = fopen('php://temp/maxmemory:4096', 'w+b')) { + /* We have opened a php:// Stream Should work without problem */ + } elseif (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) { + /* We have opened a tmpfile */ + } else { + throw new Swift_IoException('Unable to copy the file to make it seekable, sys_temp_dir is not writable, php://memory not available'); + } + $currentPos = ftell($this->_reader); + fclose($this->_reader); + $source = fopen($this->_path, 'rb'); + if (!$source) { + throw new Swift_IoException('Unable to open file for copying [' . $this->_path . ']'); + } + fseek($tmpFile, 0, SEEK_SET); + while (!feof($source)) { + fwrite($tmpFile, fread($source, 4096)); + } + fseek($tmpFile, $currentPos, SEEK_SET); + fclose($source); + $this->_reader = $tmpFile; } - fseek($tmpFile, $currentPos, SEEK_SET); - fclose($source); - $this->_reader = $tmpFile; - } } diff --git a/lib/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php b/lib/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php new file mode 100644 index 000000000..f35f885e3 --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php @@ -0,0 +1,44 @@ +getPath())) === false) { + throw new Swift_IoException('Failed to get temporary file content.'); + } + + return $content; + } + + public function __destruct() + { + if (file_exists($this->getPath())) { + @unlink($this->getPath()); + } + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterReader.php b/lib/swiftmailer/lib/classes/Swift/CharacterReader.php index 53d39ece9..91a9c9680 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterReader.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterReader.php @@ -10,51 +10,60 @@ /** * Analyzes characters for a specific character set. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn - * @author Xavier De Cock + * @author Chris Corbyn + * @author Xavier De Cock */ interface Swift_CharacterReader { - const MAP_TYPE_INVALID = 0x01; - const MAP_TYPE_FIXED_LEN = 0x02; - const MAP_TYPE_POSITIONS = 0x03; - - /** - * Returns the complete charactermap - * - * @param string $string - * @param int $startOffset - * @param array $currentMap - * @param mixed $ignoredChars - * @return int - */ - public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars); - - /** - * Returns mapType - * @int mapType - */ - public function getMapType(); - - /** - * Returns an integer which specifies how many more bytes to read. - * A positive integer indicates the number of more bytes to fetch before invoking - * this method again. - * A value of zero means this is already a valid character. - * A value of -1 means this cannot possibly be a valid character. - * @param int[] $bytes - * @return int - */ - public function validateByteSequence($bytes, $size); + const MAP_TYPE_INVALID = 0x01; + const MAP_TYPE_FIXED_LEN = 0x02; + const MAP_TYPE_POSITIONS = 0x03; - /** - * Returns the number of bytes which should be read to start each character. - * For fixed width character sets this should be the number of - * octets-per-character. For multibyte character sets this will probably be 1. - * @return int - */ - public function getInitialByteSize(); + /** + * Returns the complete character map + * + * @param string $string + * @param int $startOffset + * @param array $currentMap + * @param mixed $ignoredChars + * + * @return int + */ + public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars); + /** + * Returns the mapType, see constants. + * + * @return int + */ + public function getMapType(); + + /** + * Returns an integer which specifies how many more bytes to read. + * + * A positive integer indicates the number of more bytes to fetch before invoking + * this method again. + * + * A value of zero means this is already a valid character. + * A value of -1 means this cannot possibly be a valid character. + * + * @param integer[] $bytes + * @param int $size + * + * @return int + */ + public function validateByteSequence($bytes, $size); + + /** + * Returns the number of bytes which should be read to start each character. + * + * For fixed width character sets this should be the number of octets-per-character. + * For multibyte character sets this will probably be 1. + * + * @return int + */ + public function getInitialByteSize(); } diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php b/lib/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php index 9d09be27b..654761205 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php @@ -8,88 +8,92 @@ * file that was distributed with this source code. */ - /** * Provides fixed-width byte sizes for reading fixed-width character sets. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn - * @author Xavier De Cock + * @author Chris Corbyn + * @author Xavier De Cock */ -class Swift_CharacterReader_GenericFixedWidthReader - implements Swift_CharacterReader +class Swift_CharacterReader_GenericFixedWidthReader implements Swift_CharacterReader { - - /** - * The number of bytes in a single character. - * @var int - * @access private - */ - private $_width; - - /** - * Creates a new GenericFixedWidthReader using $width bytes per character. - * @param int $width - */ - public function __construct($width) - { - $this->_width = $width; - } + /** + * The number of bytes in a single character. + * + * @var int + */ + private $_width; - /** - * Returns the complete charactermap - * - * @param string $string - * @param int $startOffset - * @param array $currentMap - * @param mixed $ignoredChars - * @return $int - */ - public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) - { - $strlen = strlen($string); - // % and / are CPU intensive, so, maybe find a better way - $ignored = $strlen%$this->_width; - $ignoredChars = substr($string, - $ignored); - $currentMap = $this->_width; - return ($strlen - $ignored)/$this->_width; - - } - - /** - * Returns mapType - * @int mapType - */ - public function getMapType() - { - return self::MAP_TYPE_FIXED_LEN; - } + /** + * Creates a new GenericFixedWidthReader using $width bytes per character. + * + * @param int $width + */ + public function __construct($width) + { + $this->_width = $width; + } - /** - * Returns an integer which specifies how many more bytes to read. - * A positive integer indicates the number of more bytes to fetch before invoking - * this method again. - * A value of zero means this is already a valid character. - * A value of -1 means this cannot possibly be a valid character. - * @param string $bytes - * @return int - */ - public function validateByteSequence($bytes, $size) - { - $needed = $this->_width - $size; - return ($needed > -1) - ? $needed - : -1 - ; - } + /** + * Returns the complete character map. + * + * @param string $string + * @param int $startOffset + * @param array $currentMap + * @param mixed $ignoredChars + * + * @return int + */ + public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) + { + $strlen = strlen($string); + // % and / are CPU intensive, so, maybe find a better way + $ignored = $strlen % $this->_width; + $ignoredChars = substr($string, - $ignored); + $currentMap = $this->_width; - /** - * Returns the number of bytes which should be read to start each character. - * @return int - */ - public function getInitialByteSize() - { - return $this->_width; - } + return ($strlen - $ignored) / $this->_width; + } + /** + * Returns the mapType. + * + * @return int + */ + public function getMapType() + { + return self::MAP_TYPE_FIXED_LEN; + } + + /** + * Returns an integer which specifies how many more bytes to read. + * + * A positive integer indicates the number of more bytes to fetch before invoking + * this method again. + * + * A value of zero means this is already a valid character. + * A value of -1 means this cannot possibly be a valid character. + * + * @param string $bytes + * @param int $size + * + * @return int + */ + public function validateByteSequence($bytes, $size) + { + $needed = $this->_width - $size; + + return ($needed > -1) ? $needed : -1; + } + + /** + * Returns the number of bytes which should be read to start each character. + * + * @return int + */ + public function getInitialByteSize() + { + return $this->_width; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php b/lib/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php index 18a1bd8b6..8d03f316d 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php @@ -8,75 +8,78 @@ * file that was distributed with this source code. */ - /** * Analyzes US-ASCII characters. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_CharacterReader_UsAsciiReader - implements Swift_CharacterReader +class Swift_CharacterReader_UsAsciiReader implements Swift_CharacterReader { - /** - * Returns the complete charactermap - * - * @param string $string - * @param int $startOffset - * @param string $ignoredChars - */ - public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) - { - $strlen=strlen($string); - $ignoredChars=''; - for( $i = 0; $i < $strlen; ++$i) - { - if ($string[$i]>"\x07F") - { // Invalid char - $currentMap[$i+$startOffset]=$string[$i]; - } - } - return $strlen; - } - - /** - * Returns mapType - * @int mapType - */ - public function getMapType() - { - return self::MAP_TYPE_INVALID; - } - - /** - * Returns an integer which specifies how many more bytes to read. - * A positive integer indicates the number of more bytes to fetch before invoking - * this method again. - * A value of zero means this is already a valid character. - * A value of -1 means this cannot possibly be a valid character. - * @param string $bytes - * @return int - */ - public function validateByteSequence($bytes, $size) - { - $byte = reset($bytes); - if (1 == count($bytes) && $byte >= 0x00 && $byte <= 0x7F) + /** + * Returns the complete character map. + * + * @param string $string + * @param int $startOffset + * @param array $currentMap + * @param string $ignoredChars + * + * @return int + */ + public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) { - return 0; + $strlen=strlen($string); + $ignoredChars=''; + for ($i = 0; $i < $strlen; ++$i) { + if ($string[$i]>"\x07F") { // Invalid char + $currentMap[$i+$startOffset]=$string[$i]; + } + } + + return $strlen; } - else + + /** + * Returns mapType + * + * @return int mapType + */ + public function getMapType() { - return -1; + return self::MAP_TYPE_INVALID; } - } - /** - * Returns the number of bytes which should be read to start each character. - * @return int - */ - public function getInitialByteSize() - { - return 1; - } + /** + * Returns an integer which specifies how many more bytes to read. + * + * A positive integer indicates the number of more bytes to fetch before invoking + * this method again. + * A value of zero means this is already a valid character. + * A value of -1 means this cannot possibly be a valid character. + * + * @param string $bytes + * @param int $size + * + * @return int + */ + public function validateByteSequence($bytes, $size) + { + $byte = reset($bytes); + if (1 == count($bytes) && $byte >= 0x00 && $byte <= 0x7F) { + return 0; + } else { + return -1; + } + } + /** + * Returns the number of bytes which should be read to start each character. + * + * @return int + */ + public function getInitialByteSize() + { + return 1; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php b/lib/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php index f550c56a4..900bad557 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php @@ -8,175 +8,174 @@ * file that was distributed with this source code. */ - /** * Analyzes UTF-8 characters. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn - * @author Xavier De Cock + * @author Chris Corbyn + * @author Xavier De Cock */ -class Swift_CharacterReader_Utf8Reader - implements Swift_CharacterReader +class Swift_CharacterReader_Utf8Reader implements Swift_CharacterReader { + /** Pre-computed for optimization */ + private static $length_map=array( + // N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x0N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x2N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x4N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x6N + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7N + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x8N + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9N + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xAN + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBN + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xCN + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDN + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEN + 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0 // 0xFN + ); - /** Pre-computed for optimization */ - private static $length_map=array( -//N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x0N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x1N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x2N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x3N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x4N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x5N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x6N - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, //0x7N - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0x8N - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0x9N - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0xAN - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //0xBN - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, //0xCN - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, //0xDN - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, //0xEN - 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0 //0xFN - ); - private static $s_length_map=array( - "\x00"=>1, "\x01"=>1, "\x02"=>1, "\x03"=>1, "\x04"=>1, "\x05"=>1, "\x06"=>1, "\x07"=>1, - "\x08"=>1, "\x09"=>1, "\x0a"=>1, "\x0b"=>1, "\x0c"=>1, "\x0d"=>1, "\x0e"=>1, "\x0f"=>1, - "\x10"=>1, "\x11"=>1, "\x12"=>1, "\x13"=>1, "\x14"=>1, "\x15"=>1, "\x16"=>1, "\x17"=>1, - "\x18"=>1, "\x19"=>1, "\x1a"=>1, "\x1b"=>1, "\x1c"=>1, "\x1d"=>1, "\x1e"=>1, "\x1f"=>1, - "\x20"=>1, "\x21"=>1, "\x22"=>1, "\x23"=>1, "\x24"=>1, "\x25"=>1, "\x26"=>1, "\x27"=>1, - "\x28"=>1, "\x29"=>1, "\x2a"=>1, "\x2b"=>1, "\x2c"=>1, "\x2d"=>1, "\x2e"=>1, "\x2f"=>1, - "\x30"=>1, "\x31"=>1, "\x32"=>1, "\x33"=>1, "\x34"=>1, "\x35"=>1, "\x36"=>1, "\x37"=>1, - "\x38"=>1, "\x39"=>1, "\x3a"=>1, "\x3b"=>1, "\x3c"=>1, "\x3d"=>1, "\x3e"=>1, "\x3f"=>1, - "\x40"=>1, "\x41"=>1, "\x42"=>1, "\x43"=>1, "\x44"=>1, "\x45"=>1, "\x46"=>1, "\x47"=>1, - "\x48"=>1, "\x49"=>1, "\x4a"=>1, "\x4b"=>1, "\x4c"=>1, "\x4d"=>1, "\x4e"=>1, "\x4f"=>1, - "\x50"=>1, "\x51"=>1, "\x52"=>1, "\x53"=>1, "\x54"=>1, "\x55"=>1, "\x56"=>1, "\x57"=>1, - "\x58"=>1, "\x59"=>1, "\x5a"=>1, "\x5b"=>1, "\x5c"=>1, "\x5d"=>1, "\x5e"=>1, "\x5f"=>1, - "\x60"=>1, "\x61"=>1, "\x62"=>1, "\x63"=>1, "\x64"=>1, "\x65"=>1, "\x66"=>1, "\x67"=>1, - "\x68"=>1, "\x69"=>1, "\x6a"=>1, "\x6b"=>1, "\x6c"=>1, "\x6d"=>1, "\x6e"=>1, "\x6f"=>1, - "\x70"=>1, "\x71"=>1, "\x72"=>1, "\x73"=>1, "\x74"=>1, "\x75"=>1, "\x76"=>1, "\x77"=>1, - "\x78"=>1, "\x79"=>1, "\x7a"=>1, "\x7b"=>1, "\x7c"=>1, "\x7d"=>1, "\x7e"=>1, "\x7f"=>1, - "\x80"=>0, "\x81"=>0, "\x82"=>0, "\x83"=>0, "\x84"=>0, "\x85"=>0, "\x86"=>0, "\x87"=>0, - "\x88"=>0, "\x89"=>0, "\x8a"=>0, "\x8b"=>0, "\x8c"=>0, "\x8d"=>0, "\x8e"=>0, "\x8f"=>0, - "\x90"=>0, "\x91"=>0, "\x92"=>0, "\x93"=>0, "\x94"=>0, "\x95"=>0, "\x96"=>0, "\x97"=>0, - "\x98"=>0, "\x99"=>0, "\x9a"=>0, "\x9b"=>0, "\x9c"=>0, "\x9d"=>0, "\x9e"=>0, "\x9f"=>0, - "\xa0"=>0, "\xa1"=>0, "\xa2"=>0, "\xa3"=>0, "\xa4"=>0, "\xa5"=>0, "\xa6"=>0, "\xa7"=>0, - "\xa8"=>0, "\xa9"=>0, "\xaa"=>0, "\xab"=>0, "\xac"=>0, "\xad"=>0, "\xae"=>0, "\xaf"=>0, - "\xb0"=>0, "\xb1"=>0, "\xb2"=>0, "\xb3"=>0, "\xb4"=>0, "\xb5"=>0, "\xb6"=>0, "\xb7"=>0, - "\xb8"=>0, "\xb9"=>0, "\xba"=>0, "\xbb"=>0, "\xbc"=>0, "\xbd"=>0, "\xbe"=>0, "\xbf"=>0, - "\xc0"=>2, "\xc1"=>2, "\xc2"=>2, "\xc3"=>2, "\xc4"=>2, "\xc5"=>2, "\xc6"=>2, "\xc7"=>2, - "\xc8"=>2, "\xc9"=>2, "\xca"=>2, "\xcb"=>2, "\xcc"=>2, "\xcd"=>2, "\xce"=>2, "\xcf"=>2, - "\xd0"=>2, "\xd1"=>2, "\xd2"=>2, "\xd3"=>2, "\xd4"=>2, "\xd5"=>2, "\xd6"=>2, "\xd7"=>2, - "\xd8"=>2, "\xd9"=>2, "\xda"=>2, "\xdb"=>2, "\xdc"=>2, "\xdd"=>2, "\xde"=>2, "\xdf"=>2, - "\xe0"=>3, "\xe1"=>3, "\xe2"=>3, "\xe3"=>3, "\xe4"=>3, "\xe5"=>3, "\xe6"=>3, "\xe7"=>3, - "\xe8"=>3, "\xe9"=>3, "\xea"=>3, "\xeb"=>3, "\xec"=>3, "\xed"=>3, "\xee"=>3, "\xef"=>3, - "\xf0"=>4, "\xf1"=>4, "\xf2"=>4, "\xf3"=>4, "\xf4"=>4, "\xf5"=>4, "\xf6"=>4, "\xf7"=>4, - "\xf8"=>5, "\xf9"=>5, "\xfa"=>5, "\xfb"=>5, "\xfc"=>6, "\xfd"=>6, "\xfe"=>0, "\xff"=>0, - ); + private static $s_length_map=array( + "\x00"=>1, "\x01"=>1, "\x02"=>1, "\x03"=>1, "\x04"=>1, "\x05"=>1, "\x06"=>1, "\x07"=>1, + "\x08"=>1, "\x09"=>1, "\x0a"=>1, "\x0b"=>1, "\x0c"=>1, "\x0d"=>1, "\x0e"=>1, "\x0f"=>1, + "\x10"=>1, "\x11"=>1, "\x12"=>1, "\x13"=>1, "\x14"=>1, "\x15"=>1, "\x16"=>1, "\x17"=>1, + "\x18"=>1, "\x19"=>1, "\x1a"=>1, "\x1b"=>1, "\x1c"=>1, "\x1d"=>1, "\x1e"=>1, "\x1f"=>1, + "\x20"=>1, "\x21"=>1, "\x22"=>1, "\x23"=>1, "\x24"=>1, "\x25"=>1, "\x26"=>1, "\x27"=>1, + "\x28"=>1, "\x29"=>1, "\x2a"=>1, "\x2b"=>1, "\x2c"=>1, "\x2d"=>1, "\x2e"=>1, "\x2f"=>1, + "\x30"=>1, "\x31"=>1, "\x32"=>1, "\x33"=>1, "\x34"=>1, "\x35"=>1, "\x36"=>1, "\x37"=>1, + "\x38"=>1, "\x39"=>1, "\x3a"=>1, "\x3b"=>1, "\x3c"=>1, "\x3d"=>1, "\x3e"=>1, "\x3f"=>1, + "\x40"=>1, "\x41"=>1, "\x42"=>1, "\x43"=>1, "\x44"=>1, "\x45"=>1, "\x46"=>1, "\x47"=>1, + "\x48"=>1, "\x49"=>1, "\x4a"=>1, "\x4b"=>1, "\x4c"=>1, "\x4d"=>1, "\x4e"=>1, "\x4f"=>1, + "\x50"=>1, "\x51"=>1, "\x52"=>1, "\x53"=>1, "\x54"=>1, "\x55"=>1, "\x56"=>1, "\x57"=>1, + "\x58"=>1, "\x59"=>1, "\x5a"=>1, "\x5b"=>1, "\x5c"=>1, "\x5d"=>1, "\x5e"=>1, "\x5f"=>1, + "\x60"=>1, "\x61"=>1, "\x62"=>1, "\x63"=>1, "\x64"=>1, "\x65"=>1, "\x66"=>1, "\x67"=>1, + "\x68"=>1, "\x69"=>1, "\x6a"=>1, "\x6b"=>1, "\x6c"=>1, "\x6d"=>1, "\x6e"=>1, "\x6f"=>1, + "\x70"=>1, "\x71"=>1, "\x72"=>1, "\x73"=>1, "\x74"=>1, "\x75"=>1, "\x76"=>1, "\x77"=>1, + "\x78"=>1, "\x79"=>1, "\x7a"=>1, "\x7b"=>1, "\x7c"=>1, "\x7d"=>1, "\x7e"=>1, "\x7f"=>1, + "\x80"=>0, "\x81"=>0, "\x82"=>0, "\x83"=>0, "\x84"=>0, "\x85"=>0, "\x86"=>0, "\x87"=>0, + "\x88"=>0, "\x89"=>0, "\x8a"=>0, "\x8b"=>0, "\x8c"=>0, "\x8d"=>0, "\x8e"=>0, "\x8f"=>0, + "\x90"=>0, "\x91"=>0, "\x92"=>0, "\x93"=>0, "\x94"=>0, "\x95"=>0, "\x96"=>0, "\x97"=>0, + "\x98"=>0, "\x99"=>0, "\x9a"=>0, "\x9b"=>0, "\x9c"=>0, "\x9d"=>0, "\x9e"=>0, "\x9f"=>0, + "\xa0"=>0, "\xa1"=>0, "\xa2"=>0, "\xa3"=>0, "\xa4"=>0, "\xa5"=>0, "\xa6"=>0, "\xa7"=>0, + "\xa8"=>0, "\xa9"=>0, "\xaa"=>0, "\xab"=>0, "\xac"=>0, "\xad"=>0, "\xae"=>0, "\xaf"=>0, + "\xb0"=>0, "\xb1"=>0, "\xb2"=>0, "\xb3"=>0, "\xb4"=>0, "\xb5"=>0, "\xb6"=>0, "\xb7"=>0, + "\xb8"=>0, "\xb9"=>0, "\xba"=>0, "\xbb"=>0, "\xbc"=>0, "\xbd"=>0, "\xbe"=>0, "\xbf"=>0, + "\xc0"=>2, "\xc1"=>2, "\xc2"=>2, "\xc3"=>2, "\xc4"=>2, "\xc5"=>2, "\xc6"=>2, "\xc7"=>2, + "\xc8"=>2, "\xc9"=>2, "\xca"=>2, "\xcb"=>2, "\xcc"=>2, "\xcd"=>2, "\xce"=>2, "\xcf"=>2, + "\xd0"=>2, "\xd1"=>2, "\xd2"=>2, "\xd3"=>2, "\xd4"=>2, "\xd5"=>2, "\xd6"=>2, "\xd7"=>2, + "\xd8"=>2, "\xd9"=>2, "\xda"=>2, "\xdb"=>2, "\xdc"=>2, "\xdd"=>2, "\xde"=>2, "\xdf"=>2, + "\xe0"=>3, "\xe1"=>3, "\xe2"=>3, "\xe3"=>3, "\xe4"=>3, "\xe5"=>3, "\xe6"=>3, "\xe7"=>3, + "\xe8"=>3, "\xe9"=>3, "\xea"=>3, "\xeb"=>3, "\xec"=>3, "\xed"=>3, "\xee"=>3, "\xef"=>3, + "\xf0"=>4, "\xf1"=>4, "\xf2"=>4, "\xf3"=>4, "\xf4"=>4, "\xf5"=>4, "\xf6"=>4, "\xf7"=>4, + "\xf8"=>5, "\xf9"=>5, "\xfa"=>5, "\xfb"=>5, "\xfc"=>6, "\xfd"=>6, "\xfe"=>0, "\xff"=>0, + ); - /** - * Returns the complete charactermap - * - * @param string $string - * @param int $startOffset - * @param array $currentMap - * @param mixed $ignoredChars - */ - public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) - { - if (!isset($currentMap['i']) || !isset($currentMap['p'])) - { - $currentMap['p'] = $currentMap['i'] = array(); - } - $strlen=strlen($string); - $charPos=count($currentMap['p']); - $foundChars=0; - $invalid=false; - for ($i=0; $i<$strlen; ++$i) - { - $char=$string[$i]; - $size=self::$s_length_map[$char]; - if ($size==0) - { - /* char is invalid, we must wait for a resync */ - $invalid=true; - continue; - } - else - { - if ($invalid==true) - { - /* We mark the chars as invalid and start a new char */ - $currentMap['p'][$charPos+$foundChars]=$startOffset+$i; - $currentMap['i'][$charPos+$foundChars]=true; - ++$foundChars; - $invalid=false; - } - if (($i+$size) > $strlen){ - $ignoredChars=substr($string, $i); - break; - } - for ($j=1; $j<$size; ++$j) - { - $char=$string[$i+$j]; - if ($char>"\x7F" && $char<"\xC0") - { - // Valid - continue parsing - } - else - { - /* char is invalid, we must wait for a resync */ - $invalid=true; - continue 2; - } - } - /* Ok we got a complete char here */ - $lastChar=$currentMap['p'][$charPos+$foundChars]=$startOffset+$i+$size; - $i+=$j-1; - ++$foundChars; - } - } - return $foundChars; - } - - /** - * Returns mapType - * @int mapType - */ - public function getMapType() - { - return self::MAP_TYPE_POSITIONS; - } - - /** - * Returns an integer which specifies how many more bytes to read. - * A positive integer indicates the number of more bytes to fetch before invoking - * this method again. - * A value of zero means this is already a valid character. - * A value of -1 means this cannot possibly be a valid character. - * @param string $bytes - * @return int - */ - public function validateByteSequence($bytes, $size) - { - if ($size<1){ - return -1; + /** + * Returns the complete character map. + * + * @param string $string + * @param int $startOffset + * @param array $currentMap + * @param mixed $ignoredChars + * + * @return int + */ + public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) + { + if (!isset($currentMap['i']) || ! isset($currentMap['p'])) { + $currentMap['p'] = $currentMap['i'] = array(); + } + + $strlen=strlen($string); + $charPos=count($currentMap['p']); + $foundChars=0; + $invalid=false; + for ($i = 0; $i < $strlen; ++$i) { + $char = $string[$i]; + $size = self::$s_length_map[$char]; + if ($size == 0) { + /* char is invalid, we must wait for a resync */ + $invalid = true; + continue; + } else { + if ($invalid == true) { + /* We mark the chars as invalid and start a new char */ + $currentMap['p'][$charPos + $foundChars] = $startOffset + $i; + $currentMap['i'][$charPos + $foundChars] = true; + ++$foundChars; + $invalid = false; + } + if (($i + $size) > $strlen) { + $ignoredChars = substr($string, $i); + break; + } + for ($j = 1; $j < $size; ++$j) { + $char = $string[$i + $j]; + if ($char > "\x7F" && $char < "\xC0") { + // Valid - continue parsing + } else { + /* char is invalid, we must wait for a resync */ + $invalid = true; + continue 2; + } + } + /* Ok we got a complete char here */ + $currentMap['p'][$charPos + $foundChars] = $startOffset + $i + $size; + $i += $j - 1; + ++$foundChars; + } + } + + return $foundChars; } - $needed = self::$length_map[$bytes[0]] - $size; - return ($needed > -1) - ? $needed - : -1 - ; - } - /** - * Returns the number of bytes which should be read to start each character. - * @return int - */ - public function getInitialByteSize() - { - return 1; - } + /** + * Returns mapType. + * + * @return int mapType + */ + public function getMapType() + { + return self::MAP_TYPE_POSITIONS; + } + /** + * Returns an integer which specifies how many more bytes to read. + * + * A positive integer indicates the number of more bytes to fetch before invoking + * this method again. + * A value of zero means this is already a valid character. + * A value of -1 means this cannot possibly be a valid character. + * + * @param string $bytes + * @param int $size + * + * @return int + */ + public function validateByteSequence($bytes, $size) + { + if ($size<1) { + return -1; + } + $needed = self::$length_map[$bytes[0]] - $size; + + return ($needed > -1) + ? $needed + : -1 + ; + } + + /** + * Returns the number of bytes which should be read to start each character. + * + * @return int + */ + public function getInitialByteSize() + { + return 1; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php b/lib/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php index 55ce880b1..d653b8131 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php @@ -8,21 +8,21 @@ * file that was distributed with this source code. */ - /** * A factory for creating CharacterReaders. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_CharacterReaderFactory { - - /** - * Returns a CharacterReader suitable for the charset applied. - * @param string $charset - * @return Swift_CharacterReader - */ - public function getReaderFor($charset); - + /** + * Returns a CharacterReader suitable for the charset applied. + * + * @param string $charset + * + * @return Swift_CharacterReader + */ + public function getReaderFor($charset); } diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php b/lib/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php index eb5df3fef..d74b2c539 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php @@ -8,111 +8,119 @@ * file that was distributed with this source code. */ - /** * Standard factory for creating CharacterReaders. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_CharacterReaderFactory_SimpleCharacterReaderFactory - implements Swift_CharacterReaderFactory +class Swift_CharacterReaderFactory_SimpleCharacterReaderFactory implements Swift_CharacterReaderFactory { + /** + * A map of charset patterns to their implementation classes. + * + * @var array + */ + private static $_map = array(); - /** - * A map of charset patterns to their implementation classes. - * @var array - * @access private - */ - private $_map = array(); - - /** - * Factories which have already been loaded. - * @var Swift_CharacterReaderFactory[] - * @access private - */ - private $_loaded = array(); - - /** - * Creates a new CharacterReaderFactory. - */ - public function __construct() - { - $prefix = 'Swift_CharacterReader_'; - - $singleByte = array( - 'class' => $prefix . 'GenericFixedWidthReader', - 'constructor' => array(1) - ); - - $doubleByte = array( - 'class' => $prefix . 'GenericFixedWidthReader', - 'constructor' => array(2) - ); - - $fourBytes = array( - 'class' => $prefix . 'GenericFixedWidthReader', - 'constructor' => array(4) - ); - - //Utf-8 - $this->_map['utf-?8'] = array( - 'class' => $prefix . 'Utf8Reader', - 'constructor' => array() - ); - - //7-8 bit charsets - $this->_map['(us-)?ascii'] = $singleByte; - $this->_map['(iso|iec)-?8859-?[0-9]+'] = $singleByte; - $this->_map['windows-?125[0-9]'] = $singleByte; - $this->_map['cp-?[0-9]+'] = $singleByte; - $this->_map['ansi'] = $singleByte; - $this->_map['macintosh'] = $singleByte; - $this->_map['koi-?7'] = $singleByte; - $this->_map['koi-?8-?.+'] = $singleByte; - $this->_map['mik'] = $singleByte; - $this->_map['(cork|t1)'] = $singleByte; - $this->_map['v?iscii'] = $singleByte; - - //16 bits - $this->_map['(ucs-?2|utf-?16)'] = $doubleByte; - - //32 bits - $this->_map['(ucs-?4|utf-?32)'] = $fourBytes; - - //Fallback - $this->_map['.*'] = $singleByte; - } - - /** - * Returns a CharacterReader suitable for the charset applied. - * @param string $charset - * @return Swift_CharacterReader - */ - public function getReaderFor($charset) - { - $charset = trim(strtolower($charset)); - foreach ($this->_map as $pattern => $spec) + /** + * Factories which have already been loaded. + * + * @var Swift_CharacterReaderFactory[] + */ + private static $_loaded = array(); + + /** + * Creates a new CharacterReaderFactory. + */ + public function __construct() { - $re = '/^' . $pattern . '$/D'; - if (preg_match($re, $charset)) - { - if (!array_key_exists($pattern, $this->_loaded)) - { - $reflector = new ReflectionClass($spec['class']); - if ($reflector->getConstructor()) - { - $reader = $reflector->newInstanceArgs($spec['constructor']); - } - else - { - $reader = $reflector->newInstance(); - } - $this->_loaded[$pattern] = $reader; - } - return $this->_loaded[$pattern]; - } + $this->init(); + } + + public function __wakeup() + { + $this->init(); + } + + public function init() + { + if (count(self::$_map) > 0) { + return; + } + + $prefix = 'Swift_CharacterReader_'; + + $singleByte = array( + 'class' => $prefix . 'GenericFixedWidthReader', + 'constructor' => array(1) + ); + + $doubleByte = array( + 'class' => $prefix . 'GenericFixedWidthReader', + 'constructor' => array(2) + ); + + $fourBytes = array( + 'class' => $prefix . 'GenericFixedWidthReader', + 'constructor' => array(4) + ); + + // Utf-8 + self::$_map['utf-?8'] = array( + 'class' => $prefix . 'Utf8Reader', + 'constructor' => array() + ); + + //7-8 bit charsets + self::$_map['(us-)?ascii'] = $singleByte; + self::$_map['(iso|iec)-?8859-?[0-9]+'] = $singleByte; + self::$_map['windows-?125[0-9]'] = $singleByte; + self::$_map['cp-?[0-9]+'] = $singleByte; + self::$_map['ansi'] = $singleByte; + self::$_map['macintosh'] = $singleByte; + self::$_map['koi-?7'] = $singleByte; + self::$_map['koi-?8-?.+'] = $singleByte; + self::$_map['mik'] = $singleByte; + self::$_map['(cork|t1)'] = $singleByte; + self::$_map['v?iscii'] = $singleByte; + + //16 bits + self::$_map['(ucs-?2|utf-?16)'] = $doubleByte; + + //32 bits + self::$_map['(ucs-?4|utf-?32)'] = $fourBytes; + + // Fallback + self::$_map['.*'] = $singleByte; + } + + /** + * Returns a CharacterReader suitable for the charset applied. + * + * @param string $charset + * + * @return Swift_CharacterReader + */ + public function getReaderFor($charset) + { + $charset = trim(strtolower($charset)); + foreach (self::$_map as $pattern => $spec) { + $re = '/^' . $pattern . '$/D'; + if (preg_match($re, $charset)) { + if (!array_key_exists($pattern, self::$_loaded)) { + $reflector = new ReflectionClass($spec['class']); + if ($reflector->getConstructor()) { + $reader = $reflector->newInstanceArgs($spec['constructor']); + } else { + $reader = $reflector->newInstance(); + } + self::$_loaded[$pattern] = $reader; + } + + return self::$_loaded[$pattern]; + } + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterStream.php b/lib/swiftmailer/lib/classes/Swift/CharacterStream.php index bf9152822..a0f0721c2 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterStream.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterStream.php @@ -8,79 +8,84 @@ * file that was distributed with this source code. */ -require_once dirname(__FILE__) . '/OutputByteStream.php'; -require_once dirname(__FILE__) . '/CharacterReaderFactory.php'; - - /** * An abstract means of reading and writing data in terms of characters as opposed * to bytes. + * * Classes implementing this interface may use a subsystem which requires less * memory than working with large strings of data. - * @package Swift + * + * @package Swift * @subpackage CharacterStream - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_CharacterStream { + /** + * Set the character set used in this CharacterStream. + * + * @param string $charset + */ + public function setCharacterSet($charset); - /** - * Set the character set used in this CharacterStream. - * @param string $charset - */ - public function setCharacterSet($charset); - - /** - * Set the CharacterReaderFactory for multi charset support. - * @param Swift_CharacterReaderFactory $factory - */ - public function setCharacterReaderFactory( - Swift_CharacterReaderFactory $factory); - - /** - * Overwrite this character stream using the byte sequence in the byte stream. - * @param Swift_OutputByteStream $os output stream to read from - */ - public function importByteStream(Swift_OutputByteStream $os); - - /** - * Import a string a bytes into this CharacterStream, overwriting any existing - * data in the stream. - * @param string $string - */ - public function importString($string); - - /** - * Read $length characters from the stream and move the internal pointer - * $length further into the stream. - * @param int $length - * @return string - */ - public function read($length); - - /** - * Read $length characters from the stream and return a 1-dimensional array - * containing there octet values. - * @param int $length - * @return int[] - */ - public function readBytes($length); - - /** - * Write $chars to the end of the stream. - * @param string $chars - */ - public function write($chars); - - /** - * Move the internal pointer to $charOffset in the stream. - * @param int $charOffset - */ - public function setPointer($charOffset); - - /** - * Empty the stream and reset the internal pointer. - */ - public function flushContents(); - + /** + * Set the CharacterReaderFactory for multi charset support. + * + * @param Swift_CharacterReaderFactory $factory + */ + public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory); + + /** + * Overwrite this character stream using the byte sequence in the byte stream. + * + * @param Swift_OutputByteStream $os output stream to read from + */ + public function importByteStream(Swift_OutputByteStream $os); + + /** + * Import a string a bytes into this CharacterStream, overwriting any existing + * data in the stream. + * + * @param string $string + */ + public function importString($string); + + /** + * Read $length characters from the stream and move the internal pointer + * $length further into the stream. + * + * @param int $length + * + * @return string + */ + public function read($length); + + /** + * Read $length characters from the stream and return a 1-dimensional array + * containing there octet values. + * + * @param int $length + * + * @return int[] + */ + public function readBytes($length); + + /** + * Write $chars to the end of the stream. + * + * @param string $chars + */ + public function write($chars); + + /** + * Move the internal pointer to $charOffset in the stream. + * + * @param int $charOffset + */ + public function setPointer($charOffset); + + /** + * Empty the stream and reset the internal pointer. + */ + public function flushContents(); } diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php b/lib/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php index b74b08f0d..17f32c0cf 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php @@ -8,310 +8,289 @@ * file that was distributed with this source code. */ - - /** * A CharacterStream implementation which stores characters in an internal array. - * @package Swift + * + * @package Swift * @subpackage CharacterStream - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_CharacterStream_ArrayCharacterStream - implements Swift_CharacterStream +class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStream { - - /** A map of byte values and their respective characters */ - private static $_charMap; - - /** A map of characters and their derivative byte values */ - private static $_byteMap; - - /** The char reader (lazy-loaded) for the current charset */ - private $_charReader; + /** A map of byte values and their respective characters */ + private static $_charMap; - /** A factory for creatiing CharacterReader instances */ - private $_charReaderFactory; + /** A map of characters and their derivative byte values */ + private static $_byteMap; - /** The character set this stream is using */ - private $_charset; + /** The char reader (lazy-loaded) for the current charset */ + private $_charReader; - /** Array of characters */ - private $_array = array(); + /** A factory for creating CharacterReader instances */ + private $_charReaderFactory; - /** Size of the array of character */ - private $_array_size = array(); + /** The character set this stream is using */ + private $_charset; - /** The current character offset in the stream */ - private $_offset = 0; + /** Array of characters */ + private $_array = array(); - /** - * Create a new CharacterStream with the given $chars, if set. - * @param Swift_CharacterReaderFactory $factory for loading validators - * @param string $charset used in the stream - */ - public function __construct(Swift_CharacterReaderFactory $factory, - $charset) - { - self::_initializeMaps(); - $this->setCharacterReaderFactory($factory); - $this->setCharacterSet($charset); - } + /** Size of the array of character */ + private $_array_size = array(); - /** - * Set the character set used in this CharacterStream. - * @param string $charset - */ - public function setCharacterSet($charset) - { - $this->_charset = $charset; - $this->_charReader = null; - } + /** The current character offset in the stream */ + private $_offset = 0; - /** - * Set the CharacterReaderFactory for multi charset support. - * @param Swift_CharacterReaderFactory $factory - */ - public function setCharacterReaderFactory( - Swift_CharacterReaderFactory $factory) - { - $this->_charReaderFactory = $factory; - } - - /** - * Overwrite this character stream using the byte sequence in the byte stream. - * @param Swift_OutputByteStream $os output stream to read from - */ - public function importByteStream(Swift_OutputByteStream $os) - { - if (!isset($this->_charReader)) + /** + * Create a new CharacterStream with the given $chars, if set. + * + * @param Swift_CharacterReaderFactory $factory for loading validators + * @param string $charset used in the stream + */ + public function __construct(Swift_CharacterReaderFactory $factory, $charset) { - $this->_charReader = $this->_charReaderFactory - ->getReaderFor($this->_charset); + self::_initializeMaps(); + $this->setCharacterReaderFactory($factory); + $this->setCharacterSet($charset); } - $startLength = $this->_charReader->getInitialByteSize(); - while (false !== $bytes = $os->read($startLength)) + /** + * Set the character set used in this CharacterStream. + * + * @param string $charset + */ + public function setCharacterSet($charset) { - $c = array(); - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) - { - $c[] = self::$_byteMap[$bytes[$i]]; - } - $size = count($c); - $need = $this->_charReader - ->validateByteSequence($c, $size); - if ($need > 0 && - false !== $bytes = $os->read($need)) - { - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) - { - $c[] = self::$_byteMap[$bytes[$i]]; + $this->_charset = $charset; + $this->_charReader = null; + } + + /** + * Set the CharacterReaderFactory for multi charset support. + * + * @param Swift_CharacterReaderFactory $factory + */ + public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory) + { + $this->_charReaderFactory = $factory; + } + + /** + * Overwrite this character stream using the byte sequence in the byte stream. + * + * @param Swift_OutputByteStream $os output stream to read from + */ + public function importByteStream(Swift_OutputByteStream $os) + { + if (!isset($this->_charReader)) { + $this->_charReader = $this->_charReaderFactory + ->getReaderFor($this->_charset); } - } - $this->_array[] = $c; - ++$this->_array_size; - } - } - /** - * Import a string a bytes into this CharacterStream, overwriting any existing - * data in the stream. - * @param string $string - */ - public function importString($string) - { - $this->flushContents(); - $this->write($string); - } - - /** - * Read $length characters from the stream and move the internal pointer - * $length further into the stream. - * @param int $length - * @return string - */ - public function read($length) - { - if ($this->_offset == $this->_array_size) - { - return false; - } - - // Don't use array slice - $arrays = array(); - $end = $length + $this->_offset; - for ($i = $this->_offset; $i < $end; ++$i) - { - if (!isset($this->_array[$i])) - { - break; - } - $arrays[] = $this->_array[$i]; - } - $this->_offset += $i - $this->_offset; // Limit function calls - $chars = false; - foreach ($arrays as $array) - { - $chars .= implode('', array_map('chr', $array)); - } - return $chars; - } - - /** - * Read $length characters from the stream and return a 1-dimensional array - * containing there octet values. - * @param int $length - * @return int[] - */ - public function readBytes($length) - { - if ($this->_offset == $this->_array_size) - { - return false; - } - $arrays = array(); - $end = $length + $this->_offset; - for ($i = $this->_offset; $i < $end; ++$i) - { - if (!isset($this->_array[$i])) - { - break; - } - $arrays[] = $this->_array[$i]; - } - $this->_offset += ($i - $this->_offset); // Limit function calls - return call_user_func_array('array_merge', $arrays); - } - - /** - * Write $chars to the end of the stream. - * @param string $chars - */ - public function write($chars) - { - if (!isset($this->_charReader)) - { - $this->_charReader = $this->_charReaderFactory->getReaderFor( - $this->_charset); - } - - $startLength = $this->_charReader->getInitialByteSize(); - - $fp = fopen('php://memory', 'w+b'); - fwrite($fp, $chars); - unset($chars); - fseek($fp, 0, SEEK_SET); - - $buffer = array(0); - $buf_pos = 1; - $buf_len = 1; - $has_datas = true; - do - { - $bytes = array(); - // Buffer Filing - if ($buf_len - $buf_pos < $startLength) - { - $buf = array_splice($buffer, $buf_pos); - $new = $this->_reloadBuffer($fp, 100); - if ($new) - { - $buffer = array_merge($buf, $new); - $buf_len = count($buffer); - $buf_pos = 0; - } - else - { - $has_datas = false; - } - } - if ($buf_len - $buf_pos > 0) - { - $size = 0; - for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i) - { - ++$size; - $bytes[] = $buffer[$buf_pos++]; - } - $need = $this->_charReader->validateByteSequence( - $bytes, $size); - if ($need > 0) - { - if ($buf_len - $buf_pos < $need) - { - $new = $this->_reloadBuffer($fp, $need); - - if ($new) - { - $buffer = array_merge($buffer, $new); - $buf_len = count($buffer); + $startLength = $this->_charReader->getInitialByteSize(); + while (false !== $bytes = $os->read($startLength)) { + $c = array(); + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { + $c[] = self::$_byteMap[$bytes[$i]]; } - } - for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) - { - $bytes[] = $buffer[$buf_pos++]; - } + $size = count($c); + $need = $this->_charReader + ->validateByteSequence($c, $size); + if ($need > 0 && + false !== $bytes = $os->read($need)) + { + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { + $c[] = self::$_byteMap[$bytes[$i]]; + } + } + $this->_array[] = $c; + ++$this->_array_size; } - $this->_array[] = $bytes; - ++$this->_array_size; - } } - while ($has_datas); - - fclose($fp); - } - /** - * Move the internal pointer to $charOffset in the stream. - * @param int $charOffset - */ - public function setPointer($charOffset) - { - if ($charOffset > $this->_array_size) + /** + * Import a string a bytes into this CharacterStream, overwriting any existing + * data in the stream. + * + * @param string $string + */ + public function importString($string) { - $charOffset = $this->_array_size; + $this->flushContents(); + $this->write($string); } - elseif ($charOffset < 0) - { - $charOffset = 0; - } - $this->_offset = $charOffset; - } - /** - * Empty the stream and reset the internal pointer. - */ - public function flushContents() - { - $this->_offset = 0; - $this->_array = array(); - $this->_array_size = 0; - } - - private function _reloadBuffer($fp, $len) - { - if (!feof($fp) && ($bytes = fread($fp, $len)) !== false) + /** + * Read $length characters from the stream and move the internal pointer + * $length further into the stream. + * + * @param int $length + * + * @return string + */ + public function read($length) { - $buf = array(); - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) - { - $buf[] = self::$_byteMap[$bytes[$i]]; - } - return $buf; + if ($this->_offset == $this->_array_size) { + return false; + } + + // Don't use array slice + $arrays = array(); + $end = $length + $this->_offset; + for ($i = $this->_offset; $i < $end; ++$i) { + if (!isset($this->_array[$i])) { + break; + } + $arrays[] = $this->_array[$i]; + } + $this->_offset += $i - $this->_offset; // Limit function calls + $chars = false; + foreach ($arrays as $array) { + $chars .= implode('', array_map('chr', $array)); + } + + return $chars; } - return false; - } - - private static function _initializeMaps() - { - if (!isset(self::$_charMap)) + + /** + * Read $length characters from the stream and return a 1-dimensional array + * containing there octet values. + * + * @param int $length + * + * @return integer[] + */ + public function readBytes($length) { - self::$_charMap = array(); - for ($byte = 0; $byte < 256; ++$byte) - { - self::$_charMap[$byte] = chr($byte); - } - self::$_byteMap = array_flip(self::$_charMap); + if ($this->_offset == $this->_array_size) { + return false; + } + $arrays = array(); + $end = $length + $this->_offset; + for ($i = $this->_offset; $i < $end; ++$i) { + if (!isset($this->_array[$i])) { + break; + } + $arrays[] = $this->_array[$i]; + } + $this->_offset += ($i - $this->_offset); // Limit function calls + + return call_user_func_array('array_merge', $arrays); + } + + /** + * Write $chars to the end of the stream. + * + * @param string $chars + */ + public function write($chars) + { + if (!isset($this->_charReader)) { + $this->_charReader = $this->_charReaderFactory->getReaderFor( + $this->_charset); + } + + $startLength = $this->_charReader->getInitialByteSize(); + + $fp = fopen('php://memory', 'w+b'); + fwrite($fp, $chars); + unset($chars); + fseek($fp, 0, SEEK_SET); + + $buffer = array(0); + $buf_pos = 1; + $buf_len = 1; + $has_datas = true; + do { + $bytes = array(); + // Buffer Filing + if ($buf_len - $buf_pos < $startLength) { + $buf = array_splice($buffer, $buf_pos); + $new = $this->_reloadBuffer($fp, 100); + if ($new) { + $buffer = array_merge($buf, $new); + $buf_len = count($buffer); + $buf_pos = 0; + } else { + $has_datas = false; + } + } + if ($buf_len - $buf_pos > 0) { + $size = 0; + for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i) { + ++$size; + $bytes[] = $buffer[$buf_pos++]; + } + $need = $this->_charReader->validateByteSequence( + $bytes, $size); + if ($need > 0) { + if ($buf_len - $buf_pos < $need) { + $new = $this->_reloadBuffer($fp, $need); + + if ($new) { + $buffer = array_merge($buffer, $new); + $buf_len = count($buffer); + } + } + for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) { + $bytes[] = $buffer[$buf_pos++]; + } + } + $this->_array[] = $bytes; + ++$this->_array_size; + } + } while ($has_datas); + + fclose($fp); + } + + /** + * Move the internal pointer to $charOffset in the stream. + * + * @param int $charOffset + */ + public function setPointer($charOffset) + { + if ($charOffset > $this->_array_size) { + $charOffset = $this->_array_size; + } elseif ($charOffset < 0) { + $charOffset = 0; + } + $this->_offset = $charOffset; + } + + /** + * Empty the stream and reset the internal pointer. + */ + public function flushContents() + { + $this->_offset = 0; + $this->_array = array(); + $this->_array_size = 0; + } + + private function _reloadBuffer($fp, $len) + { + if (!feof($fp) && ($bytes = fread($fp, $len)) !== false) { + $buf = array(); + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { + $buf[] = self::$_byteMap[$bytes[$i]]; + } + + return $buf; + } + + return false; + } + + private static function _initializeMaps() + { + if (!isset(self::$_charMap)) { + self::$_charMap = array(); + for ($byte = 0; $byte < 256; ++$byte) { + self::$_charMap[$byte] = chr($byte); + } + self::$_byteMap = array_flip(self::$_charMap); + } } - } } diff --git a/lib/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php b/lib/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php index 57c3fb778..d43c4e0ca 100644 --- a/lib/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php +++ b/lib/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php @@ -1,298 +1,277 @@ . - + * This file is part of SwiftMailer. + * (c) 2004-2009 Chris Corbyn + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ - - /** * A CharacterStream implementation which stores characters in an internal array. - * @package Swift + * + * @package Swift * @subpackage CharacterStream - * @author Xavier De Cock + * @author Xavier De Cock */ -Class Swift_CharacterStream_NgCharacterStream - implements Swift_CharacterStream +class Swift_CharacterStream_NgCharacterStream implements Swift_CharacterStream { + /** + * The char reader (lazy-loaded) for the current charset. + * + * @var Swift_CharacterReader + */ + private $_charReader; - /** - * The char reader (lazy-loaded) for the current charset. - * @var Swift_CharacterReader - * @access private - */ - private $_charReader; + /** + * A factory for creating CharacterReader instances. + * + * @var Swift_CharacterReaderFactory + */ + private $_charReaderFactory; - /** - * A factory for creatiing CharacterReader instances. - * @var Swift_CharacterReaderFactory - * @access private - */ - private $_charReaderFactory; + /** + * The character set this stream is using. + * + * @var string + */ + private $_charset; - /** - * The character set this stream is using. - * @var string - * @access private - */ - private $_charset; - - /** - * The datas stored as is - * - * @var string - */ - private $_datas = ""; - - /** - * Number of bytes in the stream - * - * @var int - */ - private $_datasSize = 0; - - /** - * Map - * - * @var mixed - */ - private $_map; - - /** - * Map Type - * - * @var int - */ - private $_mapType = 0; - - /** - * Number of characters in the stream - * - * @var int - */ - private $_charCount = 0; - - /** - * Position in the stream - * - * @var unknown_type - */ - private $_currentPos = 0; - - /** - * The constructor - * - * @param Swift_CharacterReaderFactory $factory - * @param unknown_type $charset - */ - public function __construct(Swift_CharacterReaderFactory $factory, - $charset) - { - $this->setCharacterReaderFactory($factory); - $this->setCharacterSet($charset); - } - - /* -- Changing parameters of the stream -- */ + /** + * The data's stored as-is. + * + * @var string + */ + private $_datas = ''; - /** - * Set the character set used in this CharacterStream. - * @param string $charset - */ - public function setCharacterSet($charset) - { - $this->_charset = $charset; - $this->_charReader = null; - $this->_mapType = 0; - } + /** + * Number of bytes in the stream + * + * @var int + */ + private $_datasSize = 0; - /** - * Set the CharacterReaderFactory for multi charset support. - * @param Swift_CharacterReaderFactory $factory - */ - public function setCharacterReaderFactory( - Swift_CharacterReaderFactory $factory) - { - $this->_charReaderFactory = $factory; - } + /** + * Map. + * + * @var mixed + */ + private $_map; - /** - * @see Swift_CharacterStream::flushContents() - * - */ - public function flushContents() - { - $this->_datas = null; - $this->_map = null; - $this->_charCount = 0; - $this->_currentPos = 0; - $this->_datasSize = 0; - } - - /** - * @see Swift_CharacterStream::importByteStream() - * - * @param Swift_OutputByteStream $os - */ - public function importByteStream(Swift_OutputByteStream $os) - { - $this->flushContents(); - $blocks=512; - $os->setReadPointer(0); - while(false!==($read = $os->read($blocks))) - $this->write($read); - } - - /** - * @see Swift_CharacterStream::importString() - * - * @param string $string - */ - public function importString($string) - { - $this->flushContents(); - $this->write($string); - } - - /** - * @see Swift_CharacterStream::read() - * - * @param int $length - * @return string - */ - public function read($length) - { - if ($this->_currentPos>=$this->_charCount) - { - return false; - } - $ret=false; - $length = ($this->_currentPos+$length > $this->_charCount) - ? $this->_charCount - $this->_currentPos - : $length; - switch ($this->_mapType) - { - case Swift_CharacterReader::MAP_TYPE_FIXED_LEN: - $len = $length*$this->_map; - $ret = substr($this->_datas, - $this->_currentPos * $this->_map, - $len); - $this->_currentPos += $length; - break; - - case Swift_CharacterReader::MAP_TYPE_INVALID: - $end = $this->_currentPos + $length; - $end = $end > $this->_charCount - ?$this->_charCount - :$end; - $ret = ''; - for (; $this->_currentPos < $length; ++$this->_currentPos) - { - if (isset ($this->_map[$this->_currentPos])) - { - $ret .= '?'; - } - else - { - $ret .= $this->_datas[$this->_currentPos]; - } - } - break; - - case Swift_CharacterReader::MAP_TYPE_POSITIONS: - $end = $this->_currentPos + $length; - $end = $end > $this->_charCount - ?$this->_charCount - :$end; - $ret = ''; - $start = 0; - if ($this->_currentPos>0) - { - $start = $this->_map['p'][$this->_currentPos-1]; - } - $to = $start; - for (; $this->_currentPos < $end; ++$this->_currentPos) - { - if (isset($this->_map['i'][$this->_currentPos])) { - $ret .= substr($this->_datas, $start, $to - $start).'?'; - $start = $this->_map['p'][$this->_currentPos]; - } else { - $to = $this->_map['p'][$this->_currentPos]; - } - } - $ret .= substr($this->_datas, $start, $to - $start); - break; - } - return $ret; - } - - /** - * @see Swift_CharacterStream::readBytes() - * - * @param int $length - * @return int[] - */ - public function readBytes($length) - { - $read=$this->read($length); - if ($read!==false) - { - $ret = array_map('ord', str_split($read, 1)); - return $ret; - } - return false; - } - - /** - * @see Swift_CharacterStream::setPointer() - * - * @param int $charOffset - */ - public function setPointer($charOffset) - { - if ($this->_charCount<$charOffset){ - $charOffset=$this->_charCount; - } - $this->_currentPos = $charOffset; - } - - /** - * @see Swift_CharacterStream::write() - * - * @param string $chars - */ - public function write($chars) - { - if (!isset($this->_charReader)) + /** + * Map Type. + * + * @var int + */ + private $_mapType = 0; + + /** + * Number of characters in the stream. + * + * @var int + */ + private $_charCount = 0; + + /** + * Position in the stream. + * + * @var int + */ + private $_currentPos = 0; + + /** + * Constructor. + * + * @param Swift_CharacterReaderFactory $factory + * @param string $charset + */ + public function __construct(Swift_CharacterReaderFactory $factory, $charset) { - $this->_charReader = $this->_charReaderFactory->getReaderFor( - $this->_charset); - $this->_map = array(); - $this->_mapType = $this->_charReader->getMapType(); + $this->setCharacterReaderFactory($factory); + $this->setCharacterSet($charset); } - $ignored=''; - $this->_datas .= $chars; - $this->_charCount += $this->_charReader->getCharPositions(substr($this->_datas, $this->_datasSize), $this->_datasSize, $this->_map, $ignored); - if ($ignored!==false) { - $this->_datasSize=strlen($this->_datas)-strlen($ignored); - } - else + + /* -- Changing parameters of the stream -- */ + + /** + * Set the character set used in this CharacterStream. + * + * @param string $charset + */ + public function setCharacterSet($charset) { - $this->_datasSize=strlen($this->_datas); + $this->_charset = $charset; + $this->_charReader = null; + $this->_mapType = 0; } - } -} \ No newline at end of file + + /** + * Set the CharacterReaderFactory for multi charset support. + * + * @param Swift_CharacterReaderFactory $factory + */ + public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory) + { + $this->_charReaderFactory = $factory; + } + + /** + * @see Swift_CharacterStream::flushContents() + */ + public function flushContents() + { + $this->_datas = null; + $this->_map = null; + $this->_charCount = 0; + $this->_currentPos = 0; + $this->_datasSize = 0; + } + + /** + * @see Swift_CharacterStream::importByteStream() + * + * @param Swift_OutputByteStream $os + */ + public function importByteStream(Swift_OutputByteStream $os) + { + $this->flushContents(); + $blocks=512; + $os->setReadPointer(0); + while(false!==($read = $os->read($blocks))) + $this->write($read); + } + + /** + * @see Swift_CharacterStream::importString() + * + * @param string $string + */ + public function importString($string) + { + $this->flushContents(); + $this->write($string); + } + + /** + * @see Swift_CharacterStream::read() + * + * @param int $length + * + * @return string + */ + public function read($length) + { + if ($this->_currentPos>=$this->_charCount) { + return false; + } + $ret=false; + $length = ($this->_currentPos+$length > $this->_charCount) + ? $this->_charCount - $this->_currentPos + : $length; + switch ($this->_mapType) { + case Swift_CharacterReader::MAP_TYPE_FIXED_LEN: + $len = $length*$this->_map; + $ret = substr($this->_datas, + $this->_currentPos * $this->_map, + $len); + $this->_currentPos += $length; + break; + + case Swift_CharacterReader::MAP_TYPE_INVALID: + $end = $this->_currentPos + $length; + $end = $end > $this->_charCount + ?$this->_charCount + :$end; + $ret = ''; + for (; $this->_currentPos < $length; ++$this->_currentPos) { + if (isset ($this->_map[$this->_currentPos])) { + $ret .= '?'; + } else { + $ret .= $this->_datas[$this->_currentPos]; + } + } + break; + + case Swift_CharacterReader::MAP_TYPE_POSITIONS: + $end = $this->_currentPos + $length; + $end = $end > $this->_charCount + ?$this->_charCount + :$end; + $ret = ''; + $start = 0; + if ($this->_currentPos>0) { + $start = $this->_map['p'][$this->_currentPos-1]; + } + $to = $start; + for (; $this->_currentPos < $end; ++$this->_currentPos) { + if (isset($this->_map['i'][$this->_currentPos])) { + $ret .= substr($this->_datas, $start, $to - $start).'?'; + $start = $this->_map['p'][$this->_currentPos]; + } else { + $to = $this->_map['p'][$this->_currentPos]; + } + } + $ret .= substr($this->_datas, $start, $to - $start); + break; + } + + return $ret; + } + + /** + * @see Swift_CharacterStream::readBytes() + * + * @param int $length + * + * @return integer[] + */ + public function readBytes($length) + { + $read=$this->read($length); + if ($read!==false) { + $ret = array_map('ord', str_split($read, 1)); + + return $ret; + } + + return false; + } + + /** + * @see Swift_CharacterStream::setPointer() + * + * @param int $charOffset + */ + public function setPointer($charOffset) + { + if ($this->_charCount<$charOffset) { + $charOffset=$this->_charCount; + } + $this->_currentPos = $charOffset; + } + + /** + * @see Swift_CharacterStream::write() + * + * @param string $chars + */ + public function write($chars) + { + if (!isset($this->_charReader)) { + $this->_charReader = $this->_charReaderFactory->getReaderFor( + $this->_charset); + $this->_map = array(); + $this->_mapType = $this->_charReader->getMapType(); + } + $ignored=''; + $this->_datas .= $chars; + $this->_charCount += $this->_charReader->getCharPositions(substr($this->_datas, $this->_datasSize), $this->_datasSize, $this->_map, $ignored); + if ($ignored!==false) { + $this->_datasSize=strlen($this->_datas)-strlen($ignored); + } else { + $this->_datasSize=strlen($this->_datas); + } + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/ConfigurableSpool.php b/lib/swiftmailer/lib/classes/Swift/ConfigurableSpool.php index 27a9b6c91..11179f8da 100644 --- a/lib/swiftmailer/lib/classes/Swift/ConfigurableSpool.php +++ b/lib/swiftmailer/lib/classes/Swift/ConfigurableSpool.php @@ -10,50 +10,55 @@ /** * Base class for Spools (implements time and message limits). + * * @package Swift * @author Fabien Potencier */ abstract class Swift_ConfigurableSpool implements Swift_Spool { - /** The maximum number of messages to send per flush */ - private $_message_limit; - - /** The time limit per flush */ - private $_time_limit; - - /** - * Sets the maximum number of messages to send per flush. - * @param int $limit The limit - */ - public function setMessageLimit($limit) - { - $this->_message_limit = (int) $limit; - } - - /** - * Gets the maximum number of messages to send per flush. - * @return int The limit - */ - public function getMessageLimit() - { - return $this->_message_limit; - } - - /** - * Sets the time limit (in seconds) per flush. - * @param int $limit The limit - */ - public function setTimeLimit($limit) - { - $this->_time_limit = (int) $limit; - } - - /** - * Gets the time limit (in seconds) per flush. - * @return int The limit - */ - public function getTimeLimit() - { - return $this->_time_limit; - } + /** The maximum number of messages to send per flush */ + private $_message_limit; + + /** The time limit per flush */ + private $_time_limit; + + /** + * Sets the maximum number of messages to send per flush. + * + * @param int $limit + */ + public function setMessageLimit($limit) + { + $this->_message_limit = (int) $limit; + } + + /** + * Gets the maximum number of messages to send per flush. + * + * @return int The limit + */ + public function getMessageLimit() + { + return $this->_message_limit; + } + + /** + * Sets the time limit (in seconds) per flush. + * + * @param int $limit The limit + */ + public function setTimeLimit($limit) + { + $this->_time_limit = (int) $limit; + } + + /** + * Gets the time limit (in seconds) per flush. + * + * @return int The limit + */ + public function getTimeLimit() + { + return $this->_time_limit; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/DependencyContainer.php b/lib/swiftmailer/lib/classes/Swift/DependencyContainer.php index 066811e87..2f9a77432 100644 --- a/lib/swiftmailer/lib/classes/Swift/DependencyContainer.php +++ b/lib/swiftmailer/lib/classes/Swift/DependencyContainer.php @@ -8,341 +8,366 @@ * file that was distributed with this source code. */ - /** * Dependency Injection container. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_DependencyContainer { - - /** Constant for literal value types */ - const TYPE_VALUE = 0x0001; - - /** Constant for new instance types */ - const TYPE_INSTANCE = 0x0010; - - /** Constant for shared instance types */ - const TYPE_SHARED = 0x0100; - - /** Constant for aliases */ - const TYPE_ALIAS = 0x1000; - - /** Singleton instance */ - private static $_instance = null; - - /** The data container */ - private $_store = array(); - - /** The current endpoint in the data container */ - private $_endPoint; - - /** - * Constructor should not be used. - * Use {@link getInstance()} instead. - */ - public function __construct() { } - - /** - * Returns a singleton of the DependencyContainer. - * @return Swift_DependencyContainer - */ - public static function getInstance() - { - if (!isset(self::$_instance)) + /** Constant for literal value types */ + const TYPE_VALUE = 0x0001; + + /** Constant for new instance types */ + const TYPE_INSTANCE = 0x0010; + + /** Constant for shared instance types */ + const TYPE_SHARED = 0x0100; + + /** Constant for aliases */ + const TYPE_ALIAS = 0x1000; + + /** Singleton instance */ + private static $_instance = null; + + /** The data container */ + private $_store = array(); + + /** The current endpoint in the data container */ + private $_endPoint; + + /** + * Constructor should not be used. + * + * Use {@link getInstance()} instead. + */ + public function __construct() { } + + /** + * Returns a singleton of the DependencyContainer. + * + * @return Swift_DependencyContainer + */ + public static function getInstance() { - self::$_instance = new self(); + if (!isset(self::$_instance)) { + self::$_instance = new self(); + } + + return self::$_instance; } - return self::$_instance; - } - - /** - * List the names of all items stored in the Container. - * @return array - */ - public function listItems() - { - return array_keys($this->_store); - } - - /** - * Test if an item is registered in this container with the given name. - * @param string $itemName - * @return boolean - * @see register() - */ - public function has($itemName) - { - return array_key_exists($itemName, $this->_store) - && isset($this->_store[$itemName]['lookupType']); - } - - /** - * Lookup the item with the given $itemName. - * @param string $itemName - * @return mixed - * @throws Swift_DependencyException If the dependency is not found - * @see register() - */ - public function lookup($itemName) - { - if (!$this->has($itemName)) + + /** + * List the names of all items stored in the Container. + * + * @return array + */ + public function listItems() { - throw new Swift_DependencyException( - 'Cannot lookup dependency "' . $itemName . '" since it is not registered.' - ); + return array_keys($this->_store); } - - switch ($this->_store[$itemName]['lookupType']) + + /** + * Test if an item is registered in this container with the given name. + * + * @see register() + * + * @param string $itemName + * + * @return bool + */ + public function has($itemName) { - case self::TYPE_ALIAS: - return $this->_createAlias($itemName); - case self::TYPE_VALUE: - return $this->_getValue($itemName); - case self::TYPE_INSTANCE: - return $this->_createNewInstance($itemName); - case self::TYPE_SHARED: - return $this->_createSharedInstance($itemName); + return array_key_exists($itemName, $this->_store) + && isset($this->_store[$itemName]['lookupType']); } - } - - /** - * Create an array of arguments passed to the constructor of $itemName. - * @param string $itemName - * @return array - */ - public function createDependenciesFor($itemName) - { - $args = array(); - if (isset($this->_store[$itemName]['args'])) + + /** + * Lookup the item with the given $itemName. + * + * @see register() + * + * @param string $itemName + * + * @return mixed + * + * @throws Swift_DependencyException If the dependency is not found + */ + public function lookup($itemName) { - $args = $this->_resolveArgs($this->_store[$itemName]['args']); + if (!$this->has($itemName)) { + throw new Swift_DependencyException( + 'Cannot lookup dependency "' . $itemName . '" since it is not registered.' + ); + } + + switch ($this->_store[$itemName]['lookupType']) { + case self::TYPE_ALIAS: + return $this->_createAlias($itemName); + case self::TYPE_VALUE: + return $this->_getValue($itemName); + case self::TYPE_INSTANCE: + return $this->_createNewInstance($itemName); + case self::TYPE_SHARED: + return $this->_createSharedInstance($itemName); + } } - return $args; - } - - /** - * Register a new dependency with $itemName. - * This method returns the current DependencyContainer instance because it - * requires the use of the fluid interface to set the specific details for the - * dependency. - * - * @param string $itemName - * @return Swift_DependencyContainer - * @see asNewInstanceOf(), asSharedInstanceOf(), asValue() - */ - public function register($itemName) - { - $this->_store[$itemName] = array(); - $this->_endPoint =& $this->_store[$itemName]; - return $this; - } - - /** - * Specify the previously registered item as a literal value. - * {@link register()} must be called before this will work. - * - * @param mixed $value - * @return Swift_DependencyContainer - */ - public function asValue($value) - { - $endPoint =& $this->_getEndPoint(); - $endPoint['lookupType'] = self::TYPE_VALUE; - $endPoint['value'] = $value; - return $this; - } - - /** - * Specify the previously registered item as an alias of another item. - * @param string $lookup - * @return Swift_DependencyContainer - */ - public function asAliasOf($lookup) - { - $endPoint =& $this->_getEndPoint(); - $endPoint['lookupType'] = self::TYPE_ALIAS; - $endPoint['ref'] = $lookup; - return $this; - } - - /** - * Specify the previously registered item as a new instance of $className. - * {@link register()} must be called before this will work. - * Any arguments can be set with {@link withDependencies()}, - * {@link addConstructorValue()} or {@link addConstructorLookup()}. - * - * @param string $className - * @return Swift_DependencyContainer - * @see withDependencies(), addConstructorValue(), addConstructorLookup() - */ - public function asNewInstanceOf($className) - { - $endPoint =& $this->_getEndPoint(); - $endPoint['lookupType'] = self::TYPE_INSTANCE; - $endPoint['className'] = $className; - return $this; - } - - /** - * Specify the previously registered item as a shared instance of $className. - * {@link register()} must be called before this will work. - * @param string $className - * @return Swift_DependencyContainer - */ - public function asSharedInstanceOf($className) - { - $endPoint =& $this->_getEndPoint(); - $endPoint['lookupType'] = self::TYPE_SHARED; - $endPoint['className'] = $className; - return $this; - } - - /** - * Specify a list of injected dependencies for the previously registered item. - * This method takes an array of lookup names. - * - * @param array $lookups - * @return Swift_DependencyContainer - * @see addConstructorValue(), addConstructorLookup() - */ - public function withDependencies(array $lookups) - { - $endPoint =& $this->_getEndPoint(); - $endPoint['args'] = array(); - foreach ($lookups as $lookup) + + /** + * Create an array of arguments passed to the constructor of $itemName. + * + * @param string $itemName + * + * @return array + */ + public function createDependenciesFor($itemName) { - $this->addConstructorLookup($lookup); + $args = array(); + if (isset($this->_store[$itemName]['args'])) { + $args = $this->_resolveArgs($this->_store[$itemName]['args']); + } + + return $args; } - return $this; - } - - /** - * Specify a literal (non looked up) value for the constructor of the - * previously registered item. - * - * @param mixed $value - * @return Swift_DependencyContainer - * @see withDependencies(), addConstructorLookup() - */ - public function addConstructorValue($value) - { - $endPoint =& $this->_getEndPoint(); - if (!isset($endPoint['args'])) + + /** + * Register a new dependency with $itemName. + * + * This method returns the current DependencyContainer instance because it + * requires the use of the fluid interface to set the specific details for the + * dependency. + * @see asNewInstanceOf(), asSharedInstanceOf(), asValue() + * + * @param string $itemName + * + * @return Swift_DependencyContainer + */ + public function register($itemName) { - $endPoint['args'] = array(); + $this->_store[$itemName] = array(); + $this->_endPoint =& $this->_store[$itemName]; + + return $this; } - $endPoint['args'][] = array('type' => 'value', 'item' => $value); - return $this; - } - - /** - * Specify a dependency lookup for the constructor of the previously - * registered item. - * - * @param string $lookup - * @return Swift_DependencyContainer - * @see withDependencies(), addConstructorValue() - */ - public function addConstructorLookup($lookup) - { - $endPoint =& $this->_getEndPoint(); - if (!isset($this->_endPoint['args'])) + + /** + * Specify the previously registered item as a literal value. + * + * {@link register()} must be called before this will work. + * + * @param mixed $value + * + * @return Swift_DependencyContainer + */ + public function asValue($value) { - $endPoint['args'] = array(); + $endPoint =& $this->_getEndPoint(); + $endPoint['lookupType'] = self::TYPE_VALUE; + $endPoint['value'] = $value; + + return $this; } - $endPoint['args'][] = array('type' => 'lookup', 'item' => $lookup); - return $this; - } - - // -- Private methods - - /** Get the literal value with $itemName */ - private function _getValue($itemName) - { - return $this->_store[$itemName]['value']; - } - - /** Resolve an alias to another item */ - private function _createAlias($itemName) - { - return $this->lookup($this->_store[$itemName]['ref']); - } - - /** Create a fresh instance of $itemName */ - private function _createNewInstance($itemName) - { - $reflector = new ReflectionClass($this->_store[$itemName]['className']); - if ($reflector->getConstructor()) + + /** + * Specify the previously registered item as an alias of another item. + * + * @param string $lookup + * + * @return Swift_DependencyContainer + */ + public function asAliasOf($lookup) { - return $reflector->newInstanceArgs( - $this->createDependenciesFor($itemName) - ); + $endPoint =& $this->_getEndPoint(); + $endPoint['lookupType'] = self::TYPE_ALIAS; + $endPoint['ref'] = $lookup; + + return $this; } - else + + /** + * Specify the previously registered item as a new instance of $className. + * + * {@link register()} must be called before this will work. + * Any arguments can be set with {@link withDependencies()}, + * {@link addConstructorValue()} or {@link addConstructorLookup()}. + * + * @see withDependencies(), addConstructorValue(), addConstructorLookup() + * + * @param string $className + * + * @return Swift_DependencyContainer + */ + public function asNewInstanceOf($className) { - return $reflector->newInstance(); + $endPoint =& $this->_getEndPoint(); + $endPoint['lookupType'] = self::TYPE_INSTANCE; + $endPoint['className'] = $className; + + return $this; } - } - - /** Create and register a shared instance of $itemName */ - private function _createSharedInstance($itemName) - { - if (!isset($this->_store[$itemName]['instance'])) + + /** + * Specify the previously registered item as a shared instance of $className. + * + * {@link register()} must be called before this will work. + * + * @param string $className + * + * @return Swift_DependencyContainer + */ + public function asSharedInstanceOf($className) { - $this->_store[$itemName]['instance'] = $this->_createNewInstance($itemName); + $endPoint =& $this->_getEndPoint(); + $endPoint['lookupType'] = self::TYPE_SHARED; + $endPoint['className'] = $className; + + return $this; } - return $this->_store[$itemName]['instance']; - } - - /** Get the current endpoint in the store */ - private function &_getEndPoint() - { - if (!isset($this->_endPoint)) + + /** + * Specify a list of injected dependencies for the previously registered item. + * + * This method takes an array of lookup names. + * + * @see addConstructorValue(), addConstructorLookup() + * + * @param array $lookups + * + * @return Swift_DependencyContainer + */ + public function withDependencies(array $lookups) { - throw new BadMethodCallException( - 'Component must first be registered by calling register()' - ); + $endPoint =& $this->_getEndPoint(); + $endPoint['args'] = array(); + foreach ($lookups as $lookup) { + $this->addConstructorLookup($lookup); + } + + return $this; } - return $this->_endPoint; - } - - /** Get an argument list with dependencies resolved */ - private function _resolveArgs(array $args) - { - $resolved = array(); - foreach ($args as $argDefinition) + + /** + * Specify a literal (non looked up) value for the constructor of the + * previously registered item. + * + * @see withDependencies(), addConstructorLookup() + * + * @param mixed $value + * + * @return Swift_DependencyContainer + */ + public function addConstructorValue($value) { - switch ($argDefinition['type']) - { - case 'lookup': - $resolved[] = $this->_lookupRecursive($argDefinition['item']); - break; - case 'value': - $resolved[] = $argDefinition['item']; - break; - } + $endPoint =& $this->_getEndPoint(); + if (!isset($endPoint['args'])) { + $endPoint['args'] = array(); + } + $endPoint['args'][] = array('type' => 'value', 'item' => $value); + + return $this; } - return $resolved; - } - - /** Resolve a single dependency with an collections */ - private function _lookupRecursive($item) - { - if (is_array($item)) + + /** + * Specify a dependency lookup for the constructor of the previously + * registered item. + * + * @see withDependencies(), addConstructorValue() + * + * @param string $lookup + * + * @return Swift_DependencyContainer + */ + public function addConstructorLookup($lookup) { - $collection = array(); - foreach ($item as $k => $v) - { - $collection[$k] = $this->_lookupRecursive($v); - } - return $collection; + $endPoint =& $this->_getEndPoint(); + if (!isset($this->_endPoint['args'])) { + $endPoint['args'] = array(); + } + $endPoint['args'][] = array('type' => 'lookup', 'item' => $lookup); + + return $this; } - else + + // -- Private methods + + /** Get the literal value with $itemName */ + private function _getValue($itemName) { - return $this->lookup($item); + return $this->_store[$itemName]['value']; + } + + /** Resolve an alias to another item */ + private function _createAlias($itemName) + { + return $this->lookup($this->_store[$itemName]['ref']); + } + + /** Create a fresh instance of $itemName */ + private function _createNewInstance($itemName) + { + $reflector = new ReflectionClass($this->_store[$itemName]['className']); + if ($reflector->getConstructor()) { + return $reflector->newInstanceArgs( + $this->createDependenciesFor($itemName) + ); + } else { + return $reflector->newInstance(); + } + } + + /** Create and register a shared instance of $itemName */ + private function _createSharedInstance($itemName) + { + if (!isset($this->_store[$itemName]['instance'])) { + $this->_store[$itemName]['instance'] = $this->_createNewInstance($itemName); + } + + return $this->_store[$itemName]['instance']; + } + + /** Get the current endpoint in the store */ + private function &_getEndPoint() + { + if (!isset($this->_endPoint)) { + throw new BadMethodCallException( + 'Component must first be registered by calling register()' + ); + } + + return $this->_endPoint; + } + + /** Get an argument list with dependencies resolved */ + private function _resolveArgs(array $args) + { + $resolved = array(); + foreach ($args as $argDefinition) { + switch ($argDefinition['type']) { + case 'lookup': + $resolved[] = $this->_lookupRecursive($argDefinition['item']); + break; + case 'value': + $resolved[] = $argDefinition['item']; + break; + } + } + + return $resolved; + } + + /** Resolve a single dependency with an collections */ + private function _lookupRecursive($item) + { + if (is_array($item)) { + $collection = array(); + foreach ($item as $k => $v) { + $collection[$k] = $this->_lookupRecursive($v); + } + + return $collection; + } else { + return $this->lookup($item); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/DependencyException.php b/lib/swiftmailer/lib/classes/Swift/DependencyException.php index 7622aac80..b3f017094 100644 --- a/lib/swiftmailer/lib/classes/Swift/DependencyException.php +++ b/lib/swiftmailer/lib/classes/Swift/DependencyException.php @@ -8,22 +8,21 @@ * file that was distributed with this source code. */ - /** - * DependencyException thrown when a requested dependeny is missing. + * DependencyException gets thrown when a requested dependency is missing. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_DependencyException extends Swift_SwiftException { - - /** - * Create a new DependencyException with $message. - * @param string $message - */ - public function __construct($message) - { - parent::__construct($message); - } - + /** + * Create a new DependencyException with $message. + * + * @param string $message + */ + public function __construct($message) + { + parent::__construct($message); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/EmbeddedFile.php b/lib/swiftmailer/lib/classes/Swift/EmbeddedFile.php index 122a62584..a39a3478a 100644 --- a/lib/swiftmailer/lib/classes/Swift/EmbeddedFile.php +++ b/lib/swiftmailer/lib/classes/Swift/EmbeddedFile.php @@ -8,63 +8,64 @@ * file that was distributed with this source code. */ - /** * An embedded file, in a multipart message. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_EmbeddedFile extends Swift_Mime_EmbeddedFile { - - /** - * Create a new EmbeddedFile. - * Details may be optionally provided to the constructor. - * @param string|Swift_OutputByteStream $data - * @param string $filename - * @param string $contentType - */ - public function __construct($data = null, $filename = null, - $contentType = null) - { - call_user_func_array( - array($this, 'Swift_Mime_EmbeddedFile::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('mime.embeddedfile') - ); - - $this->setBody($data); - $this->setFilename($filename); - if ($contentType) + /** + * Create a new EmbeddedFile. + * + * Details may be optionally provided to the constructor. + * + * @param string|Swift_OutputByteStream $data + * @param string $filename + * @param string $contentType + */ + public function __construct($data = null, $filename = null, $contentType = null) { - $this->setContentType($contentType); + call_user_func_array( + array($this, 'Swift_Mime_EmbeddedFile::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('mime.embeddedfile') + ); + + $this->setBody($data); + $this->setFilename($filename); + if ($contentType) { + $this->setContentType($contentType); + } + } + + /** + * Create a new EmbeddedFile. + * + * @param string|Swift_OutputByteStream $data + * @param string $filename + * @param string $contentType + * + * @return Swift_Mime_EmbeddedFile + */ + public static function newInstance($data = null, $filename = null, $contentType = null) + { + return new self($data, $filename, $contentType); + } + + /** + * Create a new EmbeddedFile from a filesystem path. + * + * @param string $path + * + * @return Swift_Mime_EmbeddedFile + */ + public static function fromPath($path) + { + return self::newInstance()->setFile( + new Swift_ByteStream_FileByteStream($path) + ); } - } - - /** - * Create a new EmbeddedFile. - * @param string|Swift_OutputByteStream $data - * @param string $filename - * @param string $contentType - * @return Swift_Mime_EmbeddedFile - */ - public static function newInstance($data = null, $filename = null, - $contentType = null) - { - return new self($data, $filename, $contentType); - } - - /** - * Create a new EmbeddedFile from a filesystem path. - * @param string $path - * @return Swift_Mime_EmbeddedFile - */ - public static function fromPath($path) - { - return self::newInstance()->setFile( - new Swift_ByteStream_FileByteStream($path) - ); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Encoder.php b/lib/swiftmailer/lib/classes/Swift/Encoder.php index 3db403f13..2ad62e6cb 100644 --- a/lib/swiftmailer/lib/classes/Swift/Encoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Encoder.php @@ -8,7 +8,6 @@ * file that was distributed with this source code. */ - /** * Interface for all Encoder schemes. * @package Swift @@ -17,15 +16,14 @@ */ interface Swift_Encoder extends Swift_Mime_CharsetObserver { - - /** - * Encode a given string to produce an encoded string. - * @param string $string - * @param int $firstLineOffset if first line needs to be shorter - * @param int $maxLineLength - 0 indicates the default length for this encoding - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, - $maxLineLength = 0); - + /** + * Encode a given string to produce an encoded string. + * + * @param string $string + * @param int $firstLineOffset if first line needs to be shorter + * @param int $maxLineLength - 0 indicates the default length for this encoding + * + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0); } diff --git a/lib/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php b/lib/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php index ba62c8d2f..63e473136 100644 --- a/lib/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Encoder/Base64Encoder.php @@ -8,55 +8,53 @@ * file that was distributed with this source code. */ - /** * Handles Base 64 Encoding in Swift Mailer. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Encoder_Base64Encoder implements Swift_Encoder { - - /** - * Takes an unencoded string and produces a Base64 encoded string from it. - * Base64 encoded strings have a maximum line length of 76 characters. - * If the first line needs to be shorter, indicate the difference with - * $firstLineOffset. - * @param string $string to encode - * @param int $firstLineOffset - * @param int $maxLineLength, optional, 0 indicates the default of 76 bytes - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, - $maxLineLength = 0) - { - if (0 >= $maxLineLength || 76 < $maxLineLength) + /** + * Takes an unencoded string and produces a Base64 encoded string from it. + * + * Base64 encoded strings have a maximum line length of 76 characters. + * If the first line needs to be shorter, indicate the difference with + * $firstLineOffset. + * + * @param string $string to encode + * @param int $firstLineOffset + * @param int $maxLineLength optional, 0 indicates the default of 76 bytes + * + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) { - $maxLineLength = 76; + if (0 >= $maxLineLength || 76 < $maxLineLength) { + $maxLineLength = 76; + } + + $encodedString = base64_encode($string); + $firstLine = ''; + + if (0 != $firstLineOffset) { + $firstLine = substr( + $encodedString, 0, $maxLineLength - $firstLineOffset + ) . "\r\n"; + $encodedString = substr( + $encodedString, $maxLineLength - $firstLineOffset + ); + } + + return $firstLine . trim(chunk_split($encodedString, $maxLineLength, "\r\n")); } - - $encodedString = base64_encode($string); - $firstLine = ''; - - if (0 != $firstLineOffset) + + /** + * Does nothing. + */ + public function charsetChanged($charset) { - $firstLine = substr( - $encodedString, 0, $maxLineLength - $firstLineOffset - ) . "\r\n"; - $encodedString = substr( - $encodedString, $maxLineLength - $firstLineOffset - ); } - - return $firstLine . trim(chunk_split($encodedString, $maxLineLength, "\r\n")); - } - - /** - * Does nothing. - */ - public function charsetChanged($charset) - { - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php b/lib/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php index ab113039f..3c362ed57 100644 --- a/lib/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php @@ -8,251 +8,279 @@ * file that was distributed with this source code. */ - /** * Handles Quoted Printable (QP) Encoding in Swift Mailer. + * * Possibly the most accurate RFC 2045 QP implementation found in PHP. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Encoder_QpEncoder implements Swift_Encoder { + /** + * The CharacterStream used for reading characters (as opposed to bytes). + * + * @var Swift_CharacterStream + */ + protected $_charStream; - /** - * The CharacterStream used for reading characters (as opposed to bytes). - * @var Swift_CharacterStream - * @access protected - */ - protected $_charStream; + /** + * A filter used if input should be canonicalized. + * + * @var Swift_StreamFilter + */ + protected $_filter; - /** - * A filter used if input should be canonicalized. - * @var Swift_StreamFilter - * @access protected - */ - protected $_filter; + /** + * Pre-computed QP for HUGE optimization. + * + * @var string[] + */ + protected static $_qpMap = array( + 0 => '=00', 1 => '=01', 2 => '=02', 3 => '=03', 4 => '=04', + 5 => '=05', 6 => '=06', 7 => '=07', 8 => '=08', 9 => '=09', + 10 => '=0A', 11 => '=0B', 12 => '=0C', 13 => '=0D', 14 => '=0E', + 15 => '=0F', 16 => '=10', 17 => '=11', 18 => '=12', 19 => '=13', + 20 => '=14', 21 => '=15', 22 => '=16', 23 => '=17', 24 => '=18', + 25 => '=19', 26 => '=1A', 27 => '=1B', 28 => '=1C', 29 => '=1D', + 30 => '=1E', 31 => '=1F', 32 => '=20', 33 => '=21', 34 => '=22', + 35 => '=23', 36 => '=24', 37 => '=25', 38 => '=26', 39 => '=27', + 40 => '=28', 41 => '=29', 42 => '=2A', 43 => '=2B', 44 => '=2C', + 45 => '=2D', 46 => '=2E', 47 => '=2F', 48 => '=30', 49 => '=31', + 50 => '=32', 51 => '=33', 52 => '=34', 53 => '=35', 54 => '=36', + 55 => '=37', 56 => '=38', 57 => '=39', 58 => '=3A', 59 => '=3B', + 60 => '=3C', 61 => '=3D', 62 => '=3E', 63 => '=3F', 64 => '=40', + 65 => '=41', 66 => '=42', 67 => '=43', 68 => '=44', 69 => '=45', + 70 => '=46', 71 => '=47', 72 => '=48', 73 => '=49', 74 => '=4A', + 75 => '=4B', 76 => '=4C', 77 => '=4D', 78 => '=4E', 79 => '=4F', + 80 => '=50', 81 => '=51', 82 => '=52', 83 => '=53', 84 => '=54', + 85 => '=55', 86 => '=56', 87 => '=57', 88 => '=58', 89 => '=59', + 90 => '=5A', 91 => '=5B', 92 => '=5C', 93 => '=5D', 94 => '=5E', + 95 => '=5F', 96 => '=60', 97 => '=61', 98 => '=62', 99 => '=63', + 100 => '=64', 101 => '=65', 102 => '=66', 103 => '=67', 104 => '=68', + 105 => '=69', 106 => '=6A', 107 => '=6B', 108 => '=6C', 109 => '=6D', + 110 => '=6E', 111 => '=6F', 112 => '=70', 113 => '=71', 114 => '=72', + 115 => '=73', 116 => '=74', 117 => '=75', 118 => '=76', 119 => '=77', + 120 => '=78', 121 => '=79', 122 => '=7A', 123 => '=7B', 124 => '=7C', + 125 => '=7D', 126 => '=7E', 127 => '=7F', 128 => '=80', 129 => '=81', + 130 => '=82', 131 => '=83', 132 => '=84', 133 => '=85', 134 => '=86', + 135 => '=87', 136 => '=88', 137 => '=89', 138 => '=8A', 139 => '=8B', + 140 => '=8C', 141 => '=8D', 142 => '=8E', 143 => '=8F', 144 => '=90', + 145 => '=91', 146 => '=92', 147 => '=93', 148 => '=94', 149 => '=95', + 150 => '=96', 151 => '=97', 152 => '=98', 153 => '=99', 154 => '=9A', + 155 => '=9B', 156 => '=9C', 157 => '=9D', 158 => '=9E', 159 => '=9F', + 160 => '=A0', 161 => '=A1', 162 => '=A2', 163 => '=A3', 164 => '=A4', + 165 => '=A5', 166 => '=A6', 167 => '=A7', 168 => '=A8', 169 => '=A9', + 170 => '=AA', 171 => '=AB', 172 => '=AC', 173 => '=AD', 174 => '=AE', + 175 => '=AF', 176 => '=B0', 177 => '=B1', 178 => '=B2', 179 => '=B3', + 180 => '=B4', 181 => '=B5', 182 => '=B6', 183 => '=B7', 184 => '=B8', + 185 => '=B9', 186 => '=BA', 187 => '=BB', 188 => '=BC', 189 => '=BD', + 190 => '=BE', 191 => '=BF', 192 => '=C0', 193 => '=C1', 194 => '=C2', + 195 => '=C3', 196 => '=C4', 197 => '=C5', 198 => '=C6', 199 => '=C7', + 200 => '=C8', 201 => '=C9', 202 => '=CA', 203 => '=CB', 204 => '=CC', + 205 => '=CD', 206 => '=CE', 207 => '=CF', 208 => '=D0', 209 => '=D1', + 210 => '=D2', 211 => '=D3', 212 => '=D4', 213 => '=D5', 214 => '=D6', + 215 => '=D7', 216 => '=D8', 217 => '=D9', 218 => '=DA', 219 => '=DB', + 220 => '=DC', 221 => '=DD', 222 => '=DE', 223 => '=DF', 224 => '=E0', + 225 => '=E1', 226 => '=E2', 227 => '=E3', 228 => '=E4', 229 => '=E5', + 230 => '=E6', 231 => '=E7', 232 => '=E8', 233 => '=E9', 234 => '=EA', + 235 => '=EB', 236 => '=EC', 237 => '=ED', 238 => '=EE', 239 => '=EF', + 240 => '=F0', 241 => '=F1', 242 => '=F2', 243 => '=F3', 244 => '=F4', + 245 => '=F5', 246 => '=F6', 247 => '=F7', 248 => '=F8', 249 => '=F9', + 250 => '=FA', 251 => '=FB', 252 => '=FC', 253 => '=FD', 254 => '=FE', + 255 => '=FF' + ); - /** - * Pre-computed QP for HUGE optmization. - * @var string[] - * @access protected - */ - protected $_qpMap = array( - 0 => '=00', 1 => '=01', 2 => '=02', 3 => '=03', 4 => '=04', - 5 => '=05', 6 => '=06', 7 => '=07', 8 => '=08', 9 => '=09', - 10 => '=0A', 11 => '=0B', 12 => '=0C', 13 => '=0D', 14 => '=0E', - 15 => '=0F', 16 => '=10', 17 => '=11', 18 => '=12', 19 => '=13', - 20 => '=14', 21 => '=15', 22 => '=16', 23 => '=17', 24 => '=18', - 25 => '=19', 26 => '=1A', 27 => '=1B', 28 => '=1C', 29 => '=1D', - 30 => '=1E', 31 => '=1F', 32 => '=20', 33 => '=21', 34 => '=22', - 35 => '=23', 36 => '=24', 37 => '=25', 38 => '=26', 39 => '=27', - 40 => '=28', 41 => '=29', 42 => '=2A', 43 => '=2B', 44 => '=2C', - 45 => '=2D', 46 => '=2E', 47 => '=2F', 48 => '=30', 49 => '=31', - 50 => '=32', 51 => '=33', 52 => '=34', 53 => '=35', 54 => '=36', - 55 => '=37', 56 => '=38', 57 => '=39', 58 => '=3A', 59 => '=3B', - 60 => '=3C', 61 => '=3D', 62 => '=3E', 63 => '=3F', 64 => '=40', - 65 => '=41', 66 => '=42', 67 => '=43', 68 => '=44', 69 => '=45', - 70 => '=46', 71 => '=47', 72 => '=48', 73 => '=49', 74 => '=4A', - 75 => '=4B', 76 => '=4C', 77 => '=4D', 78 => '=4E', 79 => '=4F', - 80 => '=50', 81 => '=51', 82 => '=52', 83 => '=53', 84 => '=54', - 85 => '=55', 86 => '=56', 87 => '=57', 88 => '=58', 89 => '=59', - 90 => '=5A', 91 => '=5B', 92 => '=5C', 93 => '=5D', 94 => '=5E', - 95 => '=5F', 96 => '=60', 97 => '=61', 98 => '=62', 99 => '=63', - 100 => '=64', 101 => '=65', 102 => '=66', 103 => '=67', 104 => '=68', - 105 => '=69', 106 => '=6A', 107 => '=6B', 108 => '=6C', 109 => '=6D', - 110 => '=6E', 111 => '=6F', 112 => '=70', 113 => '=71', 114 => '=72', - 115 => '=73', 116 => '=74', 117 => '=75', 118 => '=76', 119 => '=77', - 120 => '=78', 121 => '=79', 122 => '=7A', 123 => '=7B', 124 => '=7C', - 125 => '=7D', 126 => '=7E', 127 => '=7F', 128 => '=80', 129 => '=81', - 130 => '=82', 131 => '=83', 132 => '=84', 133 => '=85', 134 => '=86', - 135 => '=87', 136 => '=88', 137 => '=89', 138 => '=8A', 139 => '=8B', - 140 => '=8C', 141 => '=8D', 142 => '=8E', 143 => '=8F', 144 => '=90', - 145 => '=91', 146 => '=92', 147 => '=93', 148 => '=94', 149 => '=95', - 150 => '=96', 151 => '=97', 152 => '=98', 153 => '=99', 154 => '=9A', - 155 => '=9B', 156 => '=9C', 157 => '=9D', 158 => '=9E', 159 => '=9F', - 160 => '=A0', 161 => '=A1', 162 => '=A2', 163 => '=A3', 164 => '=A4', - 165 => '=A5', 166 => '=A6', 167 => '=A7', 168 => '=A8', 169 => '=A9', - 170 => '=AA', 171 => '=AB', 172 => '=AC', 173 => '=AD', 174 => '=AE', - 175 => '=AF', 176 => '=B0', 177 => '=B1', 178 => '=B2', 179 => '=B3', - 180 => '=B4', 181 => '=B5', 182 => '=B6', 183 => '=B7', 184 => '=B8', - 185 => '=B9', 186 => '=BA', 187 => '=BB', 188 => '=BC', 189 => '=BD', - 190 => '=BE', 191 => '=BF', 192 => '=C0', 193 => '=C1', 194 => '=C2', - 195 => '=C3', 196 => '=C4', 197 => '=C5', 198 => '=C6', 199 => '=C7', - 200 => '=C8', 201 => '=C9', 202 => '=CA', 203 => '=CB', 204 => '=CC', - 205 => '=CD', 206 => '=CE', 207 => '=CF', 208 => '=D0', 209 => '=D1', - 210 => '=D2', 211 => '=D3', 212 => '=D4', 213 => '=D5', 214 => '=D6', - 215 => '=D7', 216 => '=D8', 217 => '=D9', 218 => '=DA', 219 => '=DB', - 220 => '=DC', 221 => '=DD', 222 => '=DE', 223 => '=DF', 224 => '=E0', - 225 => '=E1', 226 => '=E2', 227 => '=E3', 228 => '=E4', 229 => '=E5', - 230 => '=E6', 231 => '=E7', 232 => '=E8', 233 => '=E9', 234 => '=EA', - 235 => '=EB', 236 => '=EC', 237 => '=ED', 238 => '=EE', 239 => '=EF', - 240 => '=F0', 241 => '=F1', 242 => '=F2', 243 => '=F3', 244 => '=F4', - 245 => '=F5', 246 => '=F6', 247 => '=F7', 248 => '=F8', 249 => '=F9', - 250 => '=FA', 251 => '=FB', 252 => '=FC', 253 => '=FD', 254 => '=FE', - 255 => '=FF' - ); + protected static $_safeMapShare = array(); - /** - * A map of non-encoded ascii characters. - * @var string[] - * @access protected - */ - protected $_safeMap = array(); + /** + * A map of non-encoded ascii characters. + * + * @var string[] + */ + protected $_safeMap = array(); - /** - * Creates a new QpEncoder for the given CharacterStream. - * @param Swift_CharacterStream $charStream to use for reading characters - * @param Swift_StreamFilter $filter if input should be canonicalized - */ - public function __construct(Swift_CharacterStream $charStream, - Swift_StreamFilter $filter = null) - { - $this->_charStream = $charStream; - foreach (array_merge( - array(0x09, 0x20), range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte) + /** + * Creates a new QpEncoder for the given CharacterStream. + * + * @param Swift_CharacterStream $charStream to use for reading characters + * @param Swift_StreamFilter $filter if input should be canonicalized + */ + public function __construct(Swift_CharacterStream $charStream, Swift_StreamFilter $filter = null) { - $this->_safeMap[$byte] = chr($byte); - } - $this->_filter = $filter; - } - - /** - * Takes an unencoded string and produces a QP encoded string from it. - * QP encoded strings have a maximum line length of 76 characters. - * If the first line needs to be shorter, indicate the difference with - * $firstLineOffset. - * @param string $string to encode - * @param int $firstLineOffset, optional - * @param int $maxLineLength, optional, 0 indicates the default of 76 chars - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, - $maxLineLength = 0) - { - if ($maxLineLength > 76 || $maxLineLength <= 0) - { - $maxLineLength = 76; - } - - $thisLineLength = $maxLineLength - $firstLineOffset; - - $lines = array(); - $lNo = 0; - $lines[$lNo] = ''; - $currentLine =& $lines[$lNo++]; - $size=$lineLen=0; - - $this->_charStream->flushContents(); - $this->_charStream->importString($string); - - //Fetching more than 4 chars at one is slower, as is fetching fewer bytes - // Conveniently 4 chars is the UTF-8 safe number since UTF-8 has up to 6 - // bytes per char and (6 * 4 * 3 = 72 chars per line) * =NN is 3 bytes - while (false !== $bytes = $this->_nextSequence()) - { - //If we're filtering the input - if (isset($this->_filter)) - { - //If we can't filter because we need more bytes - while ($this->_filter->shouldBuffer($bytes)) - { - //Then collect bytes into the buffer - if (false === $moreBytes = $this->_nextSequence(1)) - { - break; - } - - foreach ($moreBytes as $b) - { - $bytes[] = $b; - } + $this->_charStream = $charStream; + if (!isset(self::$_safeMapShare[$this->getSafeMapShareId()])) { + $this->initSafeMap(); + self::$_safeMapShare[$this->getSafeMapShareId()] = $this->_safeMap; + } else { + $this->_safeMap = self::$_safeMapShare[$this->getSafeMapShareId()]; } - //And filter them - $bytes = $this->_filter->filter($bytes); - } + $this->_filter = $filter; + } - $enc = $this->_encodeByteSequence($bytes, $size); - if ($currentLine && $lineLen+$size >= $thisLineLength) - { + public function __sleep() + { + return array('_charStream', '_filter'); + } + + public function __wakeup() + { + if (!isset(self::$_safeMapShare[$this->getSafeMapShareId()])) { + $this->initSafeMap(); + self::$_safeMapShare[$this->getSafeMapShareId()] = $this->_safeMap; + } else { + $this->_safeMap = self::$_safeMapShare[$this->getSafeMapShareId()]; + } + } + + protected function getSafeMapShareId() + { + return get_class($this); + } + + protected function initSafeMap() + { + foreach (array_merge( + array(0x09, 0x20), range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte) + { + $this->_safeMap[$byte] = chr($byte); + } + } + + /** + * Takes an unencoded string and produces a QP encoded string from it. + * + * QP encoded strings have a maximum line length of 76 characters. + * If the first line needs to be shorter, indicate the difference with + * $firstLineOffset. + * + * @param string $string to encode + * @param int $firstLineOffset, optional + * @param int $maxLineLength, optional 0 indicates the default of 76 chars + * + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) + { + if ($maxLineLength > 76 || $maxLineLength <= 0) { + $maxLineLength = 76; + } + + $thisLineLength = $maxLineLength - $firstLineOffset; + + $lines = array(); + $lNo = 0; $lines[$lNo] = ''; $currentLine =& $lines[$lNo++]; - $thisLineLength = $maxLineLength; - $lineLen=0; - } - $lineLen+=$size; - $currentLine .= $enc; + $size=$lineLen=0; + + $this->_charStream->flushContents(); + $this->_charStream->importString($string); + + // Fetching more than 4 chars at one is slower, as is fetching fewer bytes + // Conveniently 4 chars is the UTF-8 safe number since UTF-8 has up to 6 + // bytes per char and (6 * 4 * 3 = 72 chars per line) * =NN is 3 bytes + while (false !== $bytes = $this->_nextSequence()) { + // If we're filtering the input + if (isset($this->_filter)) { + // If we can't filter because we need more bytes + while ($this->_filter->shouldBuffer($bytes)) { + // Then collect bytes into the buffer + if (false === $moreBytes = $this->_nextSequence(1)) { + break; + } + + foreach ($moreBytes as $b) { + $bytes[] = $b; + } + } + // And filter them + $bytes = $this->_filter->filter($bytes); + } + + $enc = $this->_encodeByteSequence($bytes, $size); + if ($currentLine && $lineLen+$size >= $thisLineLength) { + $lines[$lNo] = ''; + $currentLine =& $lines[$lNo++]; + $thisLineLength = $maxLineLength; + $lineLen=0; + } + $lineLen+=$size; + $currentLine .= $enc; + } + + return $this->_standardize(implode("=\r\n", $lines)); } - return $this->_standardize(implode("=\r\n", $lines)); - } - - /** - * Updates the charset used. - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->_charStream->setCharacterSet($charset); - } - - // -- Protected methods - - /** - * Encode the given byte array into a verbatim QP form. - * @param int[] $bytes - * @return string - * @access protected - */ - protected function _encodeByteSequence(array $bytes, &$size) - { - $ret = ''; - $size=0; - foreach ($bytes as $b) + /** + * Updates the charset used. + * + * @param string $charset + */ + public function charsetChanged($charset) { - if (isset($this->_safeMap[$b])) - { - $ret .= $this->_safeMap[$b]; - ++$size; - } - else - { - $ret .= $this->_qpMap[$b]; - $size+=3; - } + $this->_charStream->setCharacterSet($charset); } - return $ret; - } - /** - * Get the next sequence of bytes to read from the char stream. - * @param int $size number of bytes to read - * @return int[] - * @access protected - */ - protected function _nextSequence($size = 4) - { - return $this->_charStream->readBytes($size); - } + // -- Protected methods - /** - * Make sure CRLF is correct and HT/SPACE are in valid places. - * @param string $string - * @return string - * @access protected - */ - protected function _standardize($string) - { - $string = str_replace(array("\t=0D=0A", " =0D=0A", "=0D=0A"), - array("=09\r\n", "=20\r\n", "\r\n"), $string - ); - switch ($end = ord(substr($string, -1))) + /** + * Encode the given byte array into a verbatim QP form. + * + * @param integer[] $bytes + * @param int $size + * + * @return string + */ + protected function _encodeByteSequence(array $bytes, &$size) { - case 0x09: - case 0x20: - $string = substr_replace($string, $this->_qpMap[$end], -1); - } - return $string; - } + $ret = ''; + $size=0; + foreach ($bytes as $b) { + if (isset($this->_safeMap[$b])) { + $ret .= $this->_safeMap[$b]; + ++$size; + } else { + $ret .= self::$_qpMap[$b]; + $size+=3; + } + } + return $ret; + } + + /** + * Get the next sequence of bytes to read from the char stream. + * + * @param int $size number of bytes to read + * + * @return integer[] + */ + protected function _nextSequence($size = 4) + { + return $this->_charStream->readBytes($size); + } + + /** + * Make sure CRLF is correct and HT/SPACE are in valid places. + * + * @param string $string + * + * @return string + */ + protected function _standardize($string) + { + $string = str_replace(array("\t=0D=0A", " =0D=0A", "=0D=0A"), + array("=09\r\n", "=20\r\n", "\r\n"), $string + ); + switch ($end = ord(substr($string, -1))) { + case 0x09: + case 0x20: + $string = substr_replace($string, self::$_qpMap[$end], -1); + } + + return $string; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php b/lib/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php index c4c572571..aa914a89d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php @@ -8,80 +8,79 @@ * file that was distributed with this source code. */ - /** * Handles RFC 2231 specified Encoding in Swift Mailer. - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Encoder_Rfc2231Encoder implements Swift_Encoder { - - /** - * A character stream to use when reading a string as characters instead of bytes. - * @var Swift_CharacterStream - * @access private - */ - private $_charStream; - - /** - * Creates a new Rfc2231Encoder using the given character stream instance. - * @param Swift_CharacterStream - */ - public function __construct(Swift_CharacterStream $charStream) - { - $this->_charStream = $charStream; - } - - /** - * Takes an unencoded string and produces a string encoded according to - * RFC 2231 from it. - * @param string $string to encode - * @param int $firstLineOffset - * @param int $maxLineLength, optional, 0 indicates the default of 75 bytes - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, - $maxLineLength = 0) - { - $lines = array(); $lineCount = 0; - $lines[] = ''; - $currentLine =& $lines[$lineCount++]; - - if (0 >= $maxLineLength) + /** + * A character stream to use when reading a string as characters instead of bytes. + * + * @var Swift_CharacterStream + */ + private $_charStream; + + /** + * Creates a new Rfc2231Encoder using the given character stream instance. + * + * @param Swift_CharacterStream + */ + public function __construct(Swift_CharacterStream $charStream) { - $maxLineLength = 75; + $this->_charStream = $charStream; } - - $this->_charStream->flushContents(); - $this->_charStream->importString($string); - - $thisLineLength = $maxLineLength - $firstLineOffset; - - while (false !== $char = $this->_charStream->read(4)) + + /** + * Takes an unencoded string and produces a string encoded according to + * RFC 2231 from it. + * + * @param string $string + * @param int $firstLineOffset + * @param int $maxLineLength optional, 0 indicates the default of 75 bytes + * + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) { - $encodedChar = rawurlencode($char); - if (0 != strlen($currentLine) - && strlen($currentLine . $encodedChar) > $thisLineLength) - { + $lines = array(); $lineCount = 0; $lines[] = ''; $currentLine =& $lines[$lineCount++]; - $thisLineLength = $maxLineLength; - } - $currentLine .= $encodedChar; + + if (0 >= $maxLineLength) { + $maxLineLength = 75; + } + + $this->_charStream->flushContents(); + $this->_charStream->importString($string); + + $thisLineLength = $maxLineLength - $firstLineOffset; + + while (false !== $char = $this->_charStream->read(4)) { + $encodedChar = rawurlencode($char); + if (0 != strlen($currentLine) + && strlen($currentLine . $encodedChar) > $thisLineLength) + { + $lines[] = ''; + $currentLine =& $lines[$lineCount++]; + $thisLineLength = $maxLineLength; + } + $currentLine .= $encodedChar; + } + + return implode("\r\n", $lines); + } + + /** + * Updates the charset used. + * + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->_charStream->setCharacterSet($charset); } - - return implode("\r\n", $lines); - } - - /** - * Updates the charset used. - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->_charStream->setCharacterSet($charset); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Encoding.php b/lib/swiftmailer/lib/classes/Swift/Encoding.php index 369b9a5db..96391949c 100644 --- a/lib/swiftmailer/lib/classes/Swift/Encoding.php +++ b/lib/swiftmailer/lib/classes/Swift/Encoding.php @@ -8,62 +8,59 @@ * file that was distributed with this source code. */ - /** * Provides quick access to each encoding type. - * - * @package Swift + * + * @package Swift * @subpackage Encoder - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Encoding { - - /** - * Get the Encoder that provides 7-bit encoding. - * - * @return Swift_Mime_ContentEncoder - */ - public static function get7BitEncoding() - { - return self::_lookup('mime.7bitcontentencoder'); - } - - /** - * Get the Encoder that provides 8-bit encoding. - * - * @return Swift_Mime_ContentEncoder - */ - public static function get8BitEncoding() - { - return self::_lookup('mime.8bitcontentencoder'); - } - - /** - * Get the Encoder that provides Quoted-Printable (QP) encoding. - * - * @return Swift_Mime_ContentEncoder - */ - public static function getQpEncoding() - { - return self::_lookup('mime.qpcontentencoder'); - } - - /** - * Get the Encoder that provides Base64 encoding. - * - * @return Swift_Mime_ContentEncoder - */ - public static function getBase64Encoding() - { - return self::_lookup('mime.base64contentencoder'); - } - - // -- Private Static Methods - - private static function _lookup($key) - { - return Swift_DependencyContainer::getInstance()->lookup($key); - } - + /** + * Get the Encoder that provides 7-bit encoding. + * + * @return Swift_Mime_ContentEncoder + */ + public static function get7BitEncoding() + { + return self::_lookup('mime.7bitcontentencoder'); + } + + /** + * Get the Encoder that provides 8-bit encoding. + * + * @return Swift_Mime_ContentEncoder + */ + public static function get8BitEncoding() + { + return self::_lookup('mime.8bitcontentencoder'); + } + + /** + * Get the Encoder that provides Quoted-Printable (QP) encoding. + * + * @return Swift_Mime_ContentEncoder + */ + public static function getQpEncoding() + { + return self::_lookup('mime.qpcontentencoder'); + } + + /** + * Get the Encoder that provides Base64 encoding. + * + * @return Swift_Mime_ContentEncoder + */ + public static function getBase64Encoding() + { + return self::_lookup('mime.base64contentencoder'); + } + + // -- Private Static Methods + + private static function _lookup($key) + { + return Swift_DependencyContainer::getInstance()->lookup($key); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/CommandEvent.php b/lib/swiftmailer/lib/classes/Swift/Events/CommandEvent.php index 11b808c01..fa4f44470 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/CommandEvent.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/CommandEvent.php @@ -8,58 +8,60 @@ * file that was distributed with this source code. */ - /** * Generated when a command is sent over an SMTP connection. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Events_CommandEvent extends Swift_Events_EventObject { - - /** - * The command sent to the server. - * @var string - */ - private $_command; - - /** - * An array of codes which a successful response will contain. - * @var int[] - */ - private $_successCodes = array(); - - /** - * Create a new CommandEvent for $source with $command. - * @param Swift_Transport $source - * @param string $command - * @param array $successCodes - */ - public function __construct(Swift_Transport $source, - $command, $successCodes = array()) - { - parent::__construct($source); - $this->_command = $command; - $this->_successCodes = $successCodes; - } - - /** - * Get the command which was sent to the server. - * @return string - */ - public function getCommand() - { - return $this->_command; - } - - /** - * Get the numeric response codes which indicate success for this command. - * @return int[] - */ - public function getSuccessCodes() - { - return $this->_successCodes; - } - -} \ No newline at end of file + /** + * The command sent to the server. + * + * @var string + */ + private $_command; + + /** + * An array of codes which a successful response will contain. + * + * @var integer[] + */ + private $_successCodes = array(); + + /** + * Create a new CommandEvent for $source with $command. + * + * @param Swift_Transport $source + * @param string $command + * @param array $successCodes + */ + public function __construct(Swift_Transport $source, $command, $successCodes = array()) + { + parent::__construct($source); + $this->_command = $command; + $this->_successCodes = $successCodes; + } + + /** + * Get the command which was sent to the server. + * + * @return string + */ + public function getCommand() + { + return $this->_command; + } + + /** + * Get the numeric response codes which indicate success for this command. + * + * @return integer[] + */ + public function getSuccessCodes() + { + return $this->_successCodes; + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Events/CommandListener.php b/lib/swiftmailer/lib/classes/Swift/Events/CommandListener.php index 0964577aa..68009047f 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/CommandListener.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/CommandListener.php @@ -8,20 +8,19 @@ * file that was distributed with this source code. */ - /** * Listens for Transports to send commands to the server. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Events_CommandListener extends Swift_Events_EventListener { - - /** - * Invoked immediately following a command being sent. - * @param Swift_Events_ResponseEvent $evt - */ - public function commandSent(Swift_Events_CommandEvent $evt); - + /** + * Invoked immediately following a command being sent. + * + * @param Swift_Events_CommandEvent $evt + */ + public function commandSent(Swift_Events_CommandEvent $evt); } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/Event.php b/lib/swiftmailer/lib/classes/Swift/Events/Event.php index c6726a75f..c93bd9936 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/Event.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/Event.php @@ -10,30 +10,31 @@ /** * The minimum interface for an Event. - * - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Events_Event { - - /** - * Get the source object of this event. - * @return object - */ - public function getSource(); - - /** - * Prevent this Event from bubbling any further up the stack. - * @param boolean $cancel, optional - */ - public function cancelBubble($cancel = true); - - /** - * Returns true if this Event will not bubble any further up the stack. - * @return boolean - */ - public function bubbleCancelled(); - + /** + * Get the source object of this event. + * + * @return object + */ + public function getSource(); + + /** + * Prevent this Event from bubbling any further up the stack. + * + * @param bool $cancel, optional + */ + public function cancelBubble($cancel = true); + + /** + * Returns true if this Event will not bubble any further up the stack. + * + * @return bool + */ + public function bubbleCancelled(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php b/lib/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php index a0e5e601d..59aeac855 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php @@ -8,72 +8,78 @@ * file that was distributed with this source code. */ - /** * Interface for the EventDispatcher which handles the event dispatching layer. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Events_EventDispatcher { - - /** - * Create a new SendEvent for $source and $message. - * @param Swift_Transport $source - * @param Swift_Mime_Message - * @return Swift_Events_SendEvent - */ - public function createSendEvent(Swift_Transport $source, - Swift_Mime_Message $message); - - /** - * Create a new CommandEvent for $source and $command. - * @param Swift_Transport $source - * @param string $command That will be executed - * @param array $successCodes That are needed - * @return Swift_Events_CommandEvent - */ - public function createCommandEvent(Swift_Transport $source, - $command, $successCodes = array()); - - /** - * Create a new ResponseEvent for $source and $response. - * @param Swift_Transport $source - * @param string $response - * @param boolean $valid If the response is valid - * @return Swift_Events_ResponseEvent - */ - public function createResponseEvent(Swift_Transport $source, - $response, $valid); - - /** - * Create a new TransportChangeEvent for $source. - * @param Swift_Transport $source - * @return Swift_Events_TransportChangeEvent - */ - public function createTransportChangeEvent(Swift_Transport $source); - - /** - * Create a new TransportExceptionEvent for $source. - * @param Swift_Transport $source - * @param Swift_TransportException $ex - * @return Swift_Events_TransportExceptionEvent - */ - public function createTransportExceptionEvent(Swift_Transport $source, - Swift_TransportException $ex); - - /** - * Bind an event listener to this dispatcher. - * @param Swift_Events_EventListener $listener - */ - public function bindEventListener(Swift_Events_EventListener $listener); - - /** - * Dispatch the given Event to all suitable listeners. - * @param Swift_Events_EventObject $evt - * @param string $target method - */ - public function dispatchEvent(Swift_Events_EventObject $evt, $target); - + /** + * Create a new SendEvent for $source and $message. + * + * @param Swift_Transport $source + * @param Swift_Mime_Message + * + * @return Swift_Events_SendEvent + */ + public function createSendEvent(Swift_Transport $source, Swift_Mime_Message $message); + + /** + * Create a new CommandEvent for $source and $command. + * + * @param Swift_Transport $source + * @param string $command That will be executed + * @param array $successCodes That are needed + * + * @return Swift_Events_CommandEvent + */ + public function createCommandEvent(Swift_Transport $source, $command, $successCodes = array()); + + /** + * Create a new ResponseEvent for $source and $response. + * + * @param Swift_Transport $source + * @param string $response + * @param bool $valid If the response is valid + * + * @return Swift_Events_ResponseEvent + */ + public function createResponseEvent(Swift_Transport $source, $response, $valid); + + /** + * Create a new TransportChangeEvent for $source. + * + * @param Swift_Transport $source + * + * @return Swift_Events_TransportChangeEvent + */ + public function createTransportChangeEvent(Swift_Transport $source); + + /** + * Create a new TransportExceptionEvent for $source. + * + * @param Swift_Transport $source + * @param Swift_TransportException $ex + * + * @return Swift_Events_TransportExceptionEvent + */ + public function createTransportExceptionEvent(Swift_Transport $source, Swift_TransportException $ex); + + /** + * Bind an event listener to this dispatcher. + * + * @param Swift_Events_EventListener $listener + */ + public function bindEventListener(Swift_Events_EventListener $listener); + + /** + * Dispatch the given Event to all suitable listeners. + * + * @param Swift_Events_EventObject $evt + * @param string $target method + */ + public function dispatchEvent(Swift_Events_EventObject $evt, $target); } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/EventListener.php b/lib/swiftmailer/lib/classes/Swift/Events/EventListener.php index 00fb799dc..bb2133145 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/EventListener.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/EventListener.php @@ -10,10 +10,11 @@ /** * An identity interface which all EventListeners must extend. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Events_EventListener -{ +{ } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/EventObject.php b/lib/swiftmailer/lib/classes/Swift/Events/EventObject.php index ba6aac0b7..30526ce2d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/EventObject.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/EventObject.php @@ -8,57 +8,58 @@ * file that was distributed with this source code. */ - /** * A base Event which all Event classes inherit from. - * - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Events_EventObject implements Swift_Events_Event { - - /** The source of this Event */ - private $_source; - - /** The state of this Event (should it bubble up the stack?) */ - private $_bubbleCancelled = false; - - /** - * Create a new EventObject originating at $source. - * @param object $source - */ - public function __construct($source) - { - $this->_source = $source; - } - - /** - * Get the source object of this event. - * @return object - */ - public function getSource() - { - return $this->_source; - } - - /** - * Prevent this Event from bubbling any further up the stack. - * @param boolean $cancel, optional - */ - public function cancelBubble($cancel = true) - { - $this->_bubbleCancelled = $cancel; - } - - /** - * Returns true if this Event will not bubble any further up the stack. - * @return boolean - */ - public function bubbleCancelled() - { - return $this->_bubbleCancelled; - } - + /** The source of this Event */ + private $_source; + + /** The state of this Event (should it bubble up the stack?) */ + private $_bubbleCancelled = false; + + /** + * Create a new EventObject originating at $source. + * + * @param object $source + */ + public function __construct($source) + { + $this->_source = $source; + } + + /** + * Get the source object of this event. + * + * @return object + */ + public function getSource() + { + return $this->_source; + } + + /** + * Prevent this Event from bubbling any further up the stack. + * + * @param bool $cancel, optional + */ + public function cancelBubble($cancel = true) + { + $this->_bubbleCancelled = $cancel; + } + + /** + * Returns true if this Event will not bubble any further up the stack. + * + * @return bool + */ + public function bubbleCancelled() + { + return $this->_bubbleCancelled; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php b/lib/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php index 7ce0ad68d..6d7eb2710 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/ResponseEvent.php @@ -8,57 +8,61 @@ * file that was distributed with this source code. */ - /** * Generated when a response is received on a SMTP connection. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Events_ResponseEvent extends Swift_Events_EventObject { - - /** - * The overall result. - * @var boolean - */ - private $_valid; - - /** - * The response received from the server. - * @var string - */ - private $_response; - - /** - * Create a new ResponseEvent for $source and $response. - * @param Swift_Transport $source - * @param string $response - * @param boolean $valid - */ - public function __construct(Swift_Transport $source, $response, $valid = false) - { - parent::__construct($source); - $this->_response = $response; - $this->_valid = $valid; - } - - /** - * Get the response which was received from the server. - * @return string - */ - public function getResponse() - { - return $this->_response; - } - - /** - * Get the success status of this Event. - * @return boolean - */ - public function isValid() - { - return $this->_valid; - } - -} \ No newline at end of file + /** + * The overall result. + * + * @var bool + */ + private $_valid; + + /** + * The response received from the server. + * + * @var string + */ + private $_response; + + /** + * Create a new ResponseEvent for $source and $response. + * + * @param Swift_Transport $source + * @param string $response + * @param bool $valid + */ + public function __construct(Swift_Transport $source, $response, $valid = false) + { + parent::__construct($source); + $this->_response = $response; + $this->_valid = $valid; + } + + /** + * Get the response which was received from the server. + * + * @return string + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Get the success status of this Event. + * + * @return bool + */ + public function isValid() + { + return $this->_valid; + } + +} diff --git a/lib/swiftmailer/lib/classes/Swift/Events/ResponseListener.php b/lib/swiftmailer/lib/classes/Swift/Events/ResponseListener.php index d2fc8e484..a39ba435c 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/ResponseListener.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/ResponseListener.php @@ -8,20 +8,19 @@ * file that was distributed with this source code. */ - /** * Listens for responses from a remote SMTP server. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Events_ResponseListener extends Swift_Events_EventListener { - - /** - * Invoked immediately following a response coming back. - * @param Swift_Events_ResponseEvent $evt - */ - public function responseReceived(Swift_Events_ResponseEvent $evt); - + /** + * Invoked immediately following a response coming back. + * + * @param Swift_Events_ResponseEvent $evt + */ + public function responseReceived(Swift_Events_ResponseEvent $evt); } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/SendEvent.php b/lib/swiftmailer/lib/classes/Swift/Events/SendEvent.php index c2b5ca4ff..0e055405d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/SendEvent.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/SendEvent.php @@ -8,119 +8,121 @@ * file that was distributed with this source code. */ - /** * Generated when a message is being sent. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Events_SendEvent extends Swift_Events_EventObject { - - /** Sending has yet to occur */ - const RESULT_PENDING = 0x0001; - - /** Sending was successful */ - const RESULT_SUCCESS = 0x0010; - - /** Sending worked, but there were some failures */ - const RESULT_TENTATIVE = 0x0100; - - /** Sending failed */ - const RESULT_FAILED = 0x1000; - - /** - * The Message being sent. - * @var Swift_Mime_Message - */ - private $_message; - - /** - * The Transport used in sending. - * @var Swift_Transport - */ - private $_transport; - - /** - * Any recipients which failed after sending. - * @var string[] - */ - private $_failedRecipients = array(); - - /** - * The overall result as a bitmask from the class constants. - * @var int - */ - private $result; - - /** - * Create a new SendEvent for $source and $message. - * @param Swift_Transport $source - * @param Swift_Mime_Message $message - */ - public function __construct(Swift_Transport $source, - Swift_Mime_Message $message) - { - parent::__construct($source); - $this->_message = $message; - $this->_result = self::RESULT_PENDING; - } - - /** - * Get the Transport used to send the Message. - * @return Swift_Transport - */ - public function getTransport() - { - return $this->getSource(); - } - - /** - * Get the Message being sent. - * @return Swift_Mime_Message - */ - public function getMessage() - { - return $this->_message; - } - - /** - * Set the array of addresses that failed in sending. - * @param array $recipients - */ - public function setFailedRecipients($recipients) - { - $this->_failedRecipients = $recipients; - } - - /** - * Get an recipient addresses which were not accepted for delivery. - * @return string[] - */ - public function getFailedRecipients() - { - return $this->_failedRecipients; - } - - /** - * Set the result of sending. - * @return int - */ - public function setResult($result) - { - $this->_result = $result; - } - - /** - * Get the result of this Event. - * The return value is a bitmask from - * {@link RESULT_PENDING, RESULT_SUCCESS, RESULT_TENTATIVE, RESULT_FAILED} - * @return int - */ - public function getResult() - { - return $this->_result; - } - + /** Sending has yet to occur */ + const RESULT_PENDING = 0x0001; + + /** Sending was successful */ + const RESULT_SUCCESS = 0x0010; + + /** Sending worked, but there were some failures */ + const RESULT_TENTATIVE = 0x0100; + + /** Sending failed */ + const RESULT_FAILED = 0x1000; + + /** + * The Message being sent. + * + * @var Swift_Mime_Message + */ + private $_message; + + /** + * Any recipients which failed after sending. + * + * @var string[] + */ + private $_failedRecipients = array(); + + /** + * The overall result as a bitmask from the class constants. + * + * @var int + */ + private $_result; + + /** + * Create a new SendEvent for $source and $message. + * + * @param Swift_Transport $source + * @param Swift_Mime_Message $message + */ + public function __construct(Swift_Transport $source, Swift_Mime_Message $message) + { + parent::__construct($source); + $this->_message = $message; + $this->_result = self::RESULT_PENDING; + } + + /** + * Get the Transport used to send the Message. + * + * @return Swift_Transport + */ + public function getTransport() + { + return $this->getSource(); + } + + /** + * Get the Message being sent. + * + * @return Swift_Mime_Message + */ + public function getMessage() + { + return $this->_message; + } + + /** + * Set the array of addresses that failed in sending. + * + * @param array $recipients + */ + public function setFailedRecipients($recipients) + { + $this->_failedRecipients = $recipients; + } + + /** + * Get an recipient addresses which were not accepted for delivery. + * + * @return string[] + */ + public function getFailedRecipients() + { + return $this->_failedRecipients; + } + + /** + * Set the result of sending. + * + * @param int $result + */ + public function setResult($result) + { + $this->_result = $result; + } + + /** + * Get the result of this Event. + * + * The return value is a bitmask from + * {@see RESULT_PENDING, RESULT_SUCCESS, RESULT_TENTATIVE, RESULT_FAILED} + * + * @return int + */ + public function getResult() + { + return $this->_result; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/SendListener.php b/lib/swiftmailer/lib/classes/Swift/Events/SendListener.php index 1ce187c9c..bc914f542 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/SendListener.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/SendListener.php @@ -8,26 +8,26 @@ * file that was distributed with this source code. */ - /** * Listens for Messages being sent from within the Transport system. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Events_SendListener extends Swift_Events_EventListener { - - /** - * Invoked immediately before the Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt); - - /** - * Invoked immediately after the Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt); - + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt); + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt); } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php b/lib/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php index 1d9237cfd..b869481ef 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php @@ -8,160 +8,154 @@ * file that was distributed with this source code. */ - /** * The EventDispatcher which handles the event dispatching layer. - * - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Events_SimpleEventDispatcher implements Swift_Events_EventDispatcher { - - /** A map of event types to their associated listener types */ - private $_eventMap = array(); - - /** Event listeners bound to this dispatcher */ - private $_listeners = array(); - - /** Listeners queued to have an Event bubbled up the stack to them */ - private $_bubbleQueue = array(); - - /** - * Create a new EventDispatcher. - */ - public function __construct() - { - $this->_eventMap = array( - 'Swift_Events_CommandEvent' => 'Swift_Events_CommandListener', - 'Swift_Events_ResponseEvent' => 'Swift_Events_ResponseListener', - 'Swift_Events_SendEvent' => 'Swift_Events_SendListener', - 'Swift_Events_TransportChangeEvent' => 'Swift_Events_TransportChangeListener', - 'Swift_Events_TransportExceptionEvent' => 'Swift_Events_TransportExceptionListener' - ); - } - - /** - * Create a new SendEvent for $source and $message. - * - * @param Swift_Transport $source - * @param Swift_Mime_Message - * @return Swift_Events_SendEvent - */ - public function createSendEvent(Swift_Transport $source, - Swift_Mime_Message $message) - { - return new Swift_Events_SendEvent($source, $message); - } - - /** - * Create a new CommandEvent for $source and $command. - * - * @param Swift_Transport $source - * @param string $command That will be executed - * @param array $successCodes That are needed - * @return Swift_Events_CommandEvent - */ - public function createCommandEvent(Swift_Transport $source, - $command, $successCodes = array()) - { - return new Swift_Events_CommandEvent($source, $command, $successCodes); - } - - /** - * Create a new ResponseEvent for $source and $response. - * - * @param Swift_Transport $source - * @param string $response - * @param boolean $valid If the response is valid - * @return Swift_Events_ResponseEvent - */ - public function createResponseEvent(Swift_Transport $source, - $response, $valid) - { - return new Swift_Events_ResponseEvent($source, $response, $valid); - } - - /** - * Create a new TransportChangeEvent for $source. - * - * @param Swift_Transport $source - * @return Swift_Events_TransportChangeEvent - */ - public function createTransportChangeEvent(Swift_Transport $source) - { - return new Swift_Events_TransportChangeEvent($source); - } - - /** - * Create a new TransportExceptionEvent for $source. - * - * @param Swift_Transport $source - * @param Swift_TransportException $ex - * @return Swift_Events_TransportExceptionEvent - */ - public function createTransportExceptionEvent(Swift_Transport $source, - Swift_TransportException $ex) - { - return new Swift_Events_TransportExceptionEvent($source, $ex); - } - - /** - * Bind an event listener to this dispatcher. - * - * @param Swift_Events_EventListener $listener - */ - public function bindEventListener(Swift_Events_EventListener $listener) - { - foreach ($this->_listeners as $l) + /** A map of event types to their associated listener types */ + private $_eventMap = array(); + + /** Event listeners bound to this dispatcher */ + private $_listeners = array(); + + /** Listeners queued to have an Event bubbled up the stack to them */ + private $_bubbleQueue = array(); + + /** + * Create a new EventDispatcher. + */ + public function __construct() { - //Already loaded - if ($l === $listener) - { - return; - } + $this->_eventMap = array( + 'Swift_Events_CommandEvent' => 'Swift_Events_CommandListener', + 'Swift_Events_ResponseEvent' => 'Swift_Events_ResponseListener', + 'Swift_Events_SendEvent' => 'Swift_Events_SendListener', + 'Swift_Events_TransportChangeEvent' => 'Swift_Events_TransportChangeListener', + 'Swift_Events_TransportExceptionEvent' => 'Swift_Events_TransportExceptionListener' + ); } - $this->_listeners[] = $listener; - } - - /** - * Dispatch the given Event to all suitable listeners. - * - * @param Swift_Events_EventObject $evt - * @param string $target method - */ - public function dispatchEvent(Swift_Events_EventObject $evt, $target) - { - $this->_prepareBubbleQueue($evt); - $this->_bubble($evt, $target); - } - - // -- Private methods - - /** Queue listeners on a stack ready for $evt to be bubbled up it */ - private function _prepareBubbleQueue(Swift_Events_EventObject $evt) - { - $this->_bubbleQueue = array(); - $evtClass = get_class($evt); - foreach ($this->_listeners as $listener) + + /** + * Create a new SendEvent for $source and $message. + * + * @param Swift_Transport $source + * @param Swift_Mime_Message + * + * @return Swift_Events_SendEvent + */ + public function createSendEvent(Swift_Transport $source, Swift_Mime_Message $message) { - if (array_key_exists($evtClass, $this->_eventMap) - && ($listener instanceof $this->_eventMap[$evtClass])) - { - $this->_bubbleQueue[] = $listener; - } + return new Swift_Events_SendEvent($source, $message); } - } - - /** Bubble $evt up the stack calling $target() on each listener */ - private function _bubble(Swift_Events_EventObject $evt, $target) - { - if (!$evt->bubbleCancelled() && $listener = array_shift($this->_bubbleQueue)) + + /** + * Create a new CommandEvent for $source and $command. + * + * @param Swift_Transport $source + * @param string $command That will be executed + * @param array $successCodes That are needed + * + * @return Swift_Events_CommandEvent + */ + public function createCommandEvent(Swift_Transport $source, $command, $successCodes = array()) { - $listener->$target($evt); - $this->_bubble($evt, $target); + return new Swift_Events_CommandEvent($source, $command, $successCodes); + } + + /** + * Create a new ResponseEvent for $source and $response. + * + * @param Swift_Transport $source + * @param string $response + * @param bool $valid If the response is valid + * + * @return Swift_Events_ResponseEvent + */ + public function createResponseEvent(Swift_Transport $source, $response, $valid) + { + return new Swift_Events_ResponseEvent($source, $response, $valid); + } + + /** + * Create a new TransportChangeEvent for $source. + * + * @param Swift_Transport $source + * + * @return Swift_Events_TransportChangeEvent + */ + public function createTransportChangeEvent(Swift_Transport $source) + { + return new Swift_Events_TransportChangeEvent($source); + } + + /** + * Create a new TransportExceptionEvent for $source. + * + * @param Swift_Transport $source + * @param Swift_TransportException $ex + * + * @return Swift_Events_TransportExceptionEvent + */ + public function createTransportExceptionEvent(Swift_Transport $source, Swift_TransportException $ex) + { + return new Swift_Events_TransportExceptionEvent($source, $ex); + } + + /** + * Bind an event listener to this dispatcher. + * + * @param Swift_Events_EventListener $listener + */ + public function bindEventListener(Swift_Events_EventListener $listener) + { + foreach ($this->_listeners as $l) { + // Already loaded + if ($l === $listener) { + return; + } + } + $this->_listeners[] = $listener; + } + + /** + * Dispatch the given Event to all suitable listeners. + * + * @param Swift_Events_EventObject $evt + * @param string $target method + */ + public function dispatchEvent(Swift_Events_EventObject $evt, $target) + { + $this->_prepareBubbleQueue($evt); + $this->_bubble($evt, $target); + } + + // -- Private methods + + /** Queue listeners on a stack ready for $evt to be bubbled up it */ + private function _prepareBubbleQueue(Swift_Events_EventObject $evt) + { + $this->_bubbleQueue = array(); + $evtClass = get_class($evt); + foreach ($this->_listeners as $listener) { + if (array_key_exists($evtClass, $this->_eventMap) + && ($listener instanceof $this->_eventMap[$evtClass])) + { + $this->_bubbleQueue[] = $listener; + } + } + } + + /** Bubble $evt up the stack calling $target() on each listener */ + private function _bubble(Swift_Events_EventObject $evt, $target) + { + if (!$evt->bubbleCancelled() && $listener = array_shift($this->_bubbleQueue)) { + $listener->$target($evt); + $this->_bubble($evt, $target); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php b/lib/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php index e57176a9b..d8b5316bf 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php @@ -8,23 +8,22 @@ * file that was distributed with this source code. */ - /** * Generated when the state of a Transport is changed (i.e. stopped/started). - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Events_TransportChangeEvent extends Swift_Events_EventObject { - - /** - * Get the Transport. - * @return Swift_Transport - */ - public function getTransport() - { - return $this->getSource(); - } - -} \ No newline at end of file + /** + * Get the Transport. + * + * @return Swift_Transport + */ + public function getTransport() + { + return $this->getSource(); + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php b/lib/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php index 9c028f0d2..15550370e 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php @@ -8,44 +8,40 @@ * file that was distributed with this source code. */ - /** * Listens for changes within the Transport system. - * - * @package Swift + * + * @package Swift * @subpackage Events - * - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Events_TransportChangeListener extends Swift_Events_EventListener { - - /** - * Invoked just before a Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt); - - /** - * Invoked immediately after the Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function transportStarted(Swift_Events_TransportChangeEvent $evt); - - /** - * Invoked just before a Transport is stopped. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt); - - /** - * Invoked immediately after the Transport is stopped. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function transportStopped(Swift_Events_TransportChangeEvent $evt); - + /** + * Invoked just before a Transport is started. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt); + + /** + * Invoked immediately after the Transport is started. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function transportStarted(Swift_Events_TransportChangeEvent $evt); + + /** + * Invoked just before a Transport is stopped. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt); + + /** + * Invoked immediately after the Transport is stopped. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function transportStopped(Swift_Events_TransportChangeEvent $evt); } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php b/lib/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php index 154432864..88cf4746d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php @@ -8,41 +8,41 @@ * file that was distributed with this source code. */ - /** * Generated when a TransportException is thrown from the Transport system. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Events_TransportExceptionEvent extends Swift_Events_EventObject { - - /** - * The Exception thrown. - * @var Swift_TransportException - */ - private $_exception; - - /** - * Create a new TransportExceptionEvent for $transport. - * @param Swift_Transport $transport - * @param Swift_TransportException $ex - */ - public function __construct(Swift_Transport $transport, - Swift_TransportException $ex) - { - parent::__construct($transport); - $this->_exception = $ex; - } - - /** - * Get the TransportException thrown. - * @return Swift_TransportException - */ - public function getException() - { - return $this->_exception; - } - + /** + * The Exception thrown. + * + * @var Swift_TransportException + */ + private $_exception; + + /** + * Create a new TransportExceptionEvent for $transport. + * + * @param Swift_Transport $transport + * @param Swift_TransportException $ex + */ + public function __construct(Swift_Transport $transport, Swift_TransportException $ex) + { + parent::__construct($transport); + $this->_exception = $ex; + } + + /** + * Get the TransportException thrown. + * + * @return Swift_TransportException + */ + public function getException() + { + return $this->_exception; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php b/lib/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php index 92266afbe..709abda33 100644 --- a/lib/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php +++ b/lib/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php @@ -8,21 +8,19 @@ * file that was distributed with this source code. */ - /** * Listens for Exceptions thrown from within the Transport system. - * @package Swift + * + * @package Swift * @subpackage Events - * @author Chris Corbyn + * @author Chris Corbyn */ -interface Swift_Events_TransportExceptionListener - extends Swift_Events_EventListener +interface Swift_Events_TransportExceptionListener extends Swift_Events_EventListener { - - /** - * Invoked as a TransportException is thrown in the Transport system. - * @param Swift_Events_TransportExceptionEvent $evt - */ - public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt); - + /** + * Invoked as a TransportException is thrown in the Transport system. + * + * @param Swift_Events_TransportExceptionEvent $evt + */ + public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt); } diff --git a/lib/swiftmailer/lib/classes/Swift/FailoverTransport.php b/lib/swiftmailer/lib/classes/Swift/FailoverTransport.php index 5767119cf..22a82c690 100644 --- a/lib/swiftmailer/lib/classes/Swift/FailoverTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/FailoverTransport.php @@ -8,39 +8,40 @@ * file that was distributed with this source code. */ - /** * Contains a list of redundant Transports so when one fails, the next is used. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_FailoverTransport extends Swift_Transport_FailoverTransport { - - /** - * Creates a new FailoverTransport with $transports. - * @param array $transports - */ - public function __construct($transports = array()) - { - call_user_func_array( - array($this, 'Swift_Transport_FailoverTransport::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.failover') - ); - - $this->setTransports($transports); - } - - /** - * Create a new FailoverTransport instance. - * @param string $transports - * @return Swift_FailoverTransport - */ - public static function newInstance($transports = array()) - { - return new self($transports); - } - + /** + * Creates a new FailoverTransport with $transports. + * + * @param Swift_Transport[] $transports + */ + public function __construct($transports = array()) + { + call_user_func_array( + array($this, 'Swift_Transport_FailoverTransport::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.failover') + ); + + $this->setTransports($transports); + } + + /** + * Create a new FailoverTransport instance. + * + * @param Swift_Transport[] $transports + * + * @return Swift_FailoverTransport + */ + public static function newInstance($transports = array()) + { + return new self($transports); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/FileSpool.php b/lib/swiftmailer/lib/classes/Swift/FileSpool.php index 76c144ea5..c2f8d7cff 100644 --- a/lib/swiftmailer/lib/classes/Swift/FileSpool.php +++ b/lib/swiftmailer/lib/classes/Swift/FileSpool.php @@ -10,199 +10,200 @@ /** * Stores Messages on the filesystem. + * * @package Swift * @author Fabien Potencier - * @author Xavier De Cock + * @author Xavier De Cock */ class Swift_FileSpool extends Swift_ConfigurableSpool { - /** The spool directory */ - private $_path; - - /** - * File WriteRetry Limit - * @var int - */ - private $_retryLimit=10; - - /** - * Create a new FileSpool. - * @param string $path - * @throws Swift_IoException - */ - public function __construct($path) - { - $this->_path = $path; - - if (!file_exists($this->_path)) - { - if (!mkdir($this->_path, 0777, true)) - { - throw new Swift_IoException('Unable to create Path ['.$this->_path.']'); - } - } - } - - /** - * Tests if this Spool mechanism has started. - * - * @return boolean - */ - public function isStarted() - { - return true; - } - - /** - * Starts this Spool mechanism. - */ - public function start() - { - } - - /** - * Stops this Spool mechanism. - */ - public function stop() - { - } - - /** - * Allow to manage the enqueuing retry limit. - * Default, is ten and allows over 64^20 different fileNames - * - * @param integer $limit - */ - public function setRetryLimit($limit) - { - $this->_retryLimit=$limit; - } - - /** - * Queues a message. - * @param Swift_Mime_Message $message The message to store - * @return boolean - * @throws Swift_IoException - */ - public function queueMessage(Swift_Mime_Message $message) - { - $ser = serialize($message); - $fileName=$this->_path.'/'.$this->getRandomString(10); - for ($i = 0; $i < $this->_retryLimit; ++$i) - { - /* We try an exclusive creation of the file - * This is an atomic operation, it avoid locking mechanism - */ - $fp=fopen($fileName.'.message', 'x'); - if ($fp) - { - fwrite($fp, $ser); - fclose($fp); - - return; - } - else - { - /* The file allready exists, we try a longer fileName - */ - $fileName.=$this->getRandomString(1); - } - } - - throw new Swift_IoException('Unable to create a file for enqueuing Message'); - } - - /** - * Execute a recovery if for anyreason a process is sending for too long - * - * @param int $timeout in second Defaults is for very slow smtp responses - */ - public function recover($timeout=900) - { - foreach (new DirectoryIterator($this->_path) as $file) - { - $file = $file->getRealPath(); + /** The spool directory */ + private $_path; - if (substr($file, -16)=='.message.sending') - { - $lockedtime=filectime($file); - if ((time()-$lockedtime)>$timeout) - { - rename($file, substr($file, 0, -8)); + /** + * File WriteRetry Limit + * + * @var int + */ + private $_retryLimit=10; + + /** + * Create a new FileSpool. + * + * @param string $path + * + * @throws Swift_IoException + */ + public function __construct($path) + { + $this->_path = $path; + + if (!file_exists($this->_path)) { + if (!mkdir($this->_path, 0777, true)) { + throw new Swift_IoException('Unable to create Path ['.$this->_path.']'); + } } - } - } - } - - /** - * Sends messages using the given transport instance. - * - * @param Swift_Transport $transport A transport instance - * @param string[] &$failedRecipients An array of failures by-reference - * - * @return int The number of sent emails - */ - public function flushQueue(Swift_Transport $transport, &$failedRecipients = null) - { - if (!$transport->isStarted()) - { - $transport->start(); } - $failedRecipients = (array) $failedRecipients; - $count = 0; - $time = time(); - foreach (new DirectoryIterator($this->_path) as $file) + /** + * Tests if this Spool mechanism has started. + * + * @return bool + */ + public function isStarted() { - $file = $file->getRealPath(); - - if (substr($file, -8) != '.message') - { - continue; - } - - /* We try a rename, it's an atomic operation, and avoid locking the file */ - if (rename($file, $file.'.sending')) - { - $message = unserialize(file_get_contents($file.'.sending')); - - $count += $transport->send($message, $failedRecipients); - - unlink($file.'.sending'); - } - else - { - /* This message has just been catched by another process */ - continue; - } - - if ($this->getMessageLimit() && $count >= $this->getMessageLimit()) - { - break; - } - - if ($this->getTimeLimit() && (time() - $time) >= $this->getTimeLimit()) - { - break; - } + return true; } - return $count; - } - - /** - * Returns a random string needed to generate a fileName for the queue. - * @param int $count - */ - protected function getRandomString($count) { - // This string MUST stay FS safe, avoid special chars - $base="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-."; - $ret=''; - $strlen=strlen($base); - for ($i=0; $i<$count; ++$i) + /** + * Starts this Spool mechanism. + */ + public function start() { - $ret.=$base[((int)rand(0,$strlen-1))]; } - return $ret; - } + + /** + * Stops this Spool mechanism. + */ + public function stop() + { + } + + /** + * Allow to manage the enqueuing retry limit. + * + * Default, is ten and allows over 64^20 different fileNames + * + * @param int $limit + */ + public function setRetryLimit($limit) + { + $this->_retryLimit=$limit; + } + + /** + * Queues a message. + * + * @param Swift_Mime_Message $message The message to store + * + * @return bool + * + * @throws Swift_IoException + */ + public function queueMessage(Swift_Mime_Message $message) + { + $ser = serialize($message); + $fileName = $this->_path . '/' . $this->getRandomString(10); + for ($i = 0; $i < $this->_retryLimit; ++$i) { + /* We try an exclusive creation of the file. This is an atomic operation, it avoid locking mechanism */ + $fp = @fopen($fileName . '.message', 'x'); + if (false !== $fp) { + if (false === fwrite($fp, $ser)) { + return false; + } + + return fclose($fp); + } else { + /* The file already exists, we try a longer fileName */ + $fileName .= $this->getRandomString(1); + } + } + + throw new Swift_IoException('Unable to create a file for enqueuing Message'); + } + + /** + * Execute a recovery if for any reason a process is sending for too long. + * + * @param int $timeout in second Defaults is for very slow smtp responses + */ + public function recover($timeout = 900) + { + foreach (new DirectoryIterator($this->_path) as $file) { + $file = $file->getRealPath(); + + if (substr($file, - 16) == '.message.sending') { + $lockedtime = filectime($file); + if ((time() - $lockedtime) > $timeout) { + rename($file, substr($file, 0, - 8)); + } + } + } + } + + /** + * Sends messages using the given transport instance. + * + * @param Swift_Transport $transport A transport instance + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int The number of sent e-mail's + */ + public function flushQueue(Swift_Transport $transport, &$failedRecipients = null) + { + $directoryIterator = new DirectoryIterator($this->_path); + + /* Start the transport only if there are queued files to send */ + if (!$transport->isStarted()) { + foreach ($directoryIterator as $file) { + if (substr($file->getRealPath(), -8) == '.message') { + $transport->start(); + break; + } + } + } + + $failedRecipients = (array) $failedRecipients; + $count = 0; + $time = time(); + foreach ($directoryIterator as $file) { + $file = $file->getRealPath(); + + if (substr($file, -8) != '.message') { + continue; + } + + /* We try a rename, it's an atomic operation, and avoid locking the file */ + if (rename($file, $file.'.sending')) { + $message = unserialize(file_get_contents($file.'.sending')); + + $count += $transport->send($message, $failedRecipients); + + unlink($file.'.sending'); + } else { + /* This message has just been catched by another process */ + continue; + } + + if ($this->getMessageLimit() && $count >= $this->getMessageLimit()) { + break; + } + + if ($this->getTimeLimit() && (time() - $time) >= $this->getTimeLimit()) { + break; + } + } + + return $count; + } + + /** + * Returns a random string needed to generate a fileName for the queue. + * + * @param int $count + * + * @return string + */ + protected function getRandomString($count) + { + // This string MUST stay FS safe, avoid special chars + $base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-."; + $ret = ''; + $strlen = strlen($base); + for ($i = 0; $i < $count; ++$i) { + $ret .= $base[((int) rand(0, $strlen - 1))]; + } + + return $ret; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/FileStream.php b/lib/swiftmailer/lib/classes/Swift/FileStream.php index 56bf36ee4..567633ecd 100644 --- a/lib/swiftmailer/lib/classes/Swift/FileStream.php +++ b/lib/swiftmailer/lib/classes/Swift/FileStream.php @@ -8,20 +8,19 @@ * file that was distributed with this source code. */ - /** * An OutputByteStream which specifically reads from a file. - * @package Swift + * + * @package Swift * @subpackage ByteStream - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_FileStream extends Swift_OutputByteStream { - - /** - * Get the complete path to the file. - * @return string - */ - public function getPath(); - + /** + * Get the complete path to the file. + * + * @return string + */ + public function getPath(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Filterable.php b/lib/swiftmailer/lib/classes/Swift/Filterable.php index 4ca5f4022..64ad3b56c 100644 --- a/lib/swiftmailer/lib/classes/Swift/Filterable.php +++ b/lib/swiftmailer/lib/classes/Swift/Filterable.php @@ -8,26 +8,26 @@ * file that was distributed with this source code. */ - /** * Allows StreamFilters to operate on a stream. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Filterable { - - /** - * Add a new StreamFilter, referenced by $key. - * @param Swift_StreamFilter $filter - * @param string $key - */ - public function addFilter(Swift_StreamFilter $filter, $key); - - /** - * Remove an existing filter using $key. - * @param string $key - */ - public function removeFilter($key); - + /** + * Add a new StreamFilter, referenced by $key. + * + * @param Swift_StreamFilter $filter + * @param string $key + */ + public function addFilter(Swift_StreamFilter $filter, $key); + + /** + * Remove an existing filter using $key. + * + * @param string $key + */ + public function removeFilter($key); } diff --git a/lib/swiftmailer/lib/classes/Swift/Image.php b/lib/swiftmailer/lib/classes/Swift/Image.php index 3baa79ea2..ccc485ddd 100644 --- a/lib/swiftmailer/lib/classes/Swift/Image.php +++ b/lib/swiftmailer/lib/classes/Swift/Image.php @@ -8,53 +8,56 @@ * file that was distributed with this source code. */ - /** * An image, embedded in a multipart message. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Image extends Swift_EmbeddedFile { - - /** - * Create a new EmbeddedFile. - * Details may be optionally provided to the constructor. - * @param string|Swift_OutputByteStream $data - * @param string $filename - * @param string $contentType - */ - public function __construct($data = null, $filename = null, - $contentType = null) - { - parent::__construct($data, $filename, $contentType); - } - - /** - * Create a new Image. - * @param string|Swift_OutputByteStream $data - * @param string $filename - * @param string $contentType - * @return Swift_Mime_EmbeddedFile - */ - public static function newInstance($data = null, $filename = null, - $contentType = null) - { - return new self($data, $filename, $contentType); - } - - /** - * Create a new Image from a filesystem path. - * @param string $path - * @return Swift_Mime_EmbeddedFile - */ - public static function fromPath($path) - { - $image = self::newInstance()->setFile( - new Swift_ByteStream_FileByteStream($path) - ); - return $image; - } - + /** + * Create a new EmbeddedFile. + * + * Details may be optionally provided to the constructor. + * + * @param string|Swift_OutputByteStream $data + * @param string $filename + * @param string $contentType + */ + public function __construct($data = null, $filename = null, $contentType = null) + { + parent::__construct($data, $filename, $contentType); + } + + /** + * Create a new Image. + * + * @param string|Swift_OutputByteStream $data + * @param string $filename + * @param string $contentType + * + * @return Swift_Image + */ + public static function newInstance($data = null, $filename = null, $contentType = null) + { + return new self($data, $filename, $contentType); + } + + /** + * Create a new Image from a filesystem path. + * + * @param string $path + * + * @return Swift_Image + */ + public static function fromPath($path) + { + $image = self::newInstance()->setFile( + new Swift_ByteStream_FileByteStream($path) + ); + + return $image; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/InputByteStream.php b/lib/swiftmailer/lib/classes/Swift/InputByteStream.php index e8f45f4a3..3506aca2e 100644 --- a/lib/swiftmailer/lib/classes/Swift/InputByteStream.php +++ b/lib/swiftmailer/lib/classes/Swift/InputByteStream.php @@ -10,63 +10,68 @@ /** * An abstract means of writing data. + * * Classes implementing this interface may use a subsystem which requires less * memory than working with large strings of data. - * @package Swift + * + * @package Swift * @subpackage ByteStream - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_InputByteStream { - - /** - * Writes $bytes to the end of the stream. - * - * Writing may not happen immediately if the stream chooses to buffer. If - * you want to write these bytes with immediate effect, call {@link commit()} - * after calling write(). - * - * This method returns the sequence ID of the write (i.e. 1 for first, 2 for - * second, etc etc). - * - * @param string $bytes - * @return int - * @throws Swift_IoException - */ - public function write($bytes); - - /** - * For any bytes that are currently buffered inside the stream, force them - * off the buffer. - * - * @throws Swift_IoException - */ - public function commit(); - - /** - * Attach $is to this stream. - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - */ - public function bind(Swift_InputByteStream $is); - - /** - * Remove an already bound stream. - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - */ - public function unbind(Swift_InputByteStream $is); - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - * @throws Swift_IoException - */ - public function flushBuffers(); - + /** + * Writes $bytes to the end of the stream. + * + * Writing may not happen immediately if the stream chooses to buffer. If + * you want to write these bytes with immediate effect, call {@link commit()} + * after calling write(). + * + * This method returns the sequence ID of the write (i.e. 1 for first, 2 for + * second, etc etc). + * + * @param string $bytes + * + * @return int + * + * @throws Swift_IoException + */ + public function write($bytes); + + /** + * For any bytes that are currently buffered inside the stream, force them + * off the buffer. + * + * @throws Swift_IoException + */ + public function commit(); + + /** + * Attach $is to this stream. + * + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + */ + public function bind(Swift_InputByteStream $is); + + /** + * Remove an already bound stream. + * + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + */ + public function unbind(Swift_InputByteStream $is); + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + * + * @throws Swift_IoException + */ + public function flushBuffers(); } diff --git a/lib/swiftmailer/lib/classes/Swift/IoException.php b/lib/swiftmailer/lib/classes/Swift/IoException.php index 7c2a9bbfb..dca105743 100644 --- a/lib/swiftmailer/lib/classes/Swift/IoException.php +++ b/lib/swiftmailer/lib/classes/Swift/IoException.php @@ -8,22 +8,21 @@ * file that was distributed with this source code. */ - /** * I/O Exception class. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_IoException extends Swift_SwiftException { - - /** - * Create a new IoException with $message. - * @param string $message - */ - public function __construct($message) - { - parent::__construct($message); - } - + /** + * Create a new IoException with $message. + * + * @param string $message + */ + public function __construct($message) + { + parent::__construct($message); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/KeyCache.php b/lib/swiftmailer/lib/classes/Swift/KeyCache.php index e3e8f0c14..606f55ee7 100644 --- a/lib/swiftmailer/lib/classes/Swift/KeyCache.php +++ b/lib/swiftmailer/lib/classes/Swift/KeyCache.php @@ -8,90 +8,100 @@ * file that was distributed with this source code. */ - /** * Provides a mechanism for storing data using two keys. - * @package Swift + * + * @package Swift * @subpackage KeyCache - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_KeyCache { - - /** Mode for replacing existing cached data */ - const MODE_WRITE = 1; - - /** Mode for appending data to the end of existing cached data */ - const MODE_APPEND = 2; - - /** - * Set a string into the cache under $itemKey for the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @param string $string - * @param int $mode - * @see MODE_WRITE, MODE_APPEND - */ - public function setString($nsKey, $itemKey, $string, $mode); - - /** - * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @param Swift_OutputByteStream $os - * @param int $mode - * @see MODE_WRITE, MODE_APPEND - */ - public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, - $mode); - - /** - * Provides a ByteStream which when written to, writes data to $itemKey. - * NOTE: The stream will always write in append mode. - * If the optional third parameter is passed all writes will go through $is. - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $is, optional - * @return Swift_InputByteStream - */ - public function getInputByteStream($nsKey, $itemKey, - Swift_InputByteStream $is = null); - - /** - * Get data back out of the cache as a string. - * @param string $nsKey - * @param string $itemKey - * @return string - */ - public function getString($nsKey, $itemKey); - - /** - * Get data back out of the cache as a ByteStream. - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $is to write the data to - */ - public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is); - - /** - * Check if the given $itemKey exists in the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @return boolean - */ - public function hasKey($nsKey, $itemKey); - - /** - * Clear data for $itemKey in the namespace $nsKey if it exists. - * @param string $nsKey - * @param string $itemKey - */ - public function clearKey($nsKey, $itemKey); - - /** - * Clear all data in the namespace $nsKey if it exists. - * @param string $nsKey - */ - public function clearAll($nsKey); - + /** Mode for replacing existing cached data */ + const MODE_WRITE = 1; + + /** Mode for appending data to the end of existing cached data */ + const MODE_APPEND = 2; + + /** + * Set a string into the cache under $itemKey for the namespace $nsKey. + * + * @see MODE_WRITE, MODE_APPEND + * + * @param string $nsKey + * @param string $itemKey + * @param string $string + * @param int $mode + */ + public function setString($nsKey, $itemKey, $string, $mode); + + /** + * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. + * + * @see MODE_WRITE, MODE_APPEND + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_OutputByteStream $os + * @param int $mode + */ + public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode); + + /** + * Provides a ByteStream which when written to, writes data to $itemKey. + * + * NOTE: The stream will always write in append mode. + * If the optional third parameter is passed all writes will go through $is. + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $is optional input stream + * + * @return Swift_InputByteStream + */ + public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $is = null); + + /** + * Get data back out of the cache as a string. + * + * @param string $nsKey + * @param string $itemKey + * + * @return string + */ + public function getString($nsKey, $itemKey); + + /** + * Get data back out of the cache as a ByteStream. + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $is stream to write the data to + */ + public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is); + + /** + * Check if the given $itemKey exists in the namespace $nsKey. + * + * @param string $nsKey + * @param string $itemKey + * + * @return bool + */ + public function hasKey($nsKey, $itemKey); + + /** + * Clear data for $itemKey in the namespace $nsKey if it exists. + * + * @param string $nsKey + * @param string $itemKey + */ + public function clearKey($nsKey, $itemKey); + + /** + * Clear all data in the namespace $nsKey if it exists. + * + * @param string $nsKey + */ + public function clearAll($nsKey); } diff --git a/lib/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php b/lib/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php index 72d784226..8ef3dcc99 100644 --- a/lib/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php +++ b/lib/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php @@ -8,197 +8,203 @@ * file that was distributed with this source code. */ - /** * A basic KeyCache backed by an array. - * @package Swift + * + * @package Swift * @subpackage KeyCache - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_KeyCache_ArrayKeyCache implements Swift_KeyCache { - - /** - * Cache contents. - * @var array - * @access private - */ - private $_contents = array(); - - /** - * An InputStream for cloning. - * @var Swift_KeyCache_KeyCacheInputStream - * @access private - */ - private $_stream; - - /** - * Create a new ArrayKeyCache with the given $stream for cloning to make - * InputByteStreams. - * @param Swift_KeyCache_KeyCacheInputStream $stream - */ - public function __construct(Swift_KeyCache_KeyCacheInputStream $stream) - { - $this->_stream = $stream; - } - - /** - * Set a string into the cache under $itemKey for the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @param string $string - * @param int $mode - * @see MODE_WRITE, MODE_APPEND - */ - public function setString($nsKey, $itemKey, $string, $mode) - { - $this->_prepareCache($nsKey); - switch ($mode) + /** + * Cache contents. + * + * @var array + */ + private $_contents = array(); + + /** + * An InputStream for cloning. + * + * @var Swift_KeyCache_KeyCacheInputStream + */ + private $_stream; + + /** + * Create a new ArrayKeyCache with the given $stream for cloning to make + * InputByteStreams. + * + * @param Swift_KeyCache_KeyCacheInputStream $stream + */ + public function __construct(Swift_KeyCache_KeyCacheInputStream $stream) { - case self::MODE_WRITE: - $this->_contents[$nsKey][$itemKey] = $string; - break; - case self::MODE_APPEND: - if (!$this->hasKey($nsKey, $itemKey)) - { - $this->_contents[$nsKey][$itemKey] = ''; + $this->_stream = $stream; + } + + /** + * Set a string into the cache under $itemKey for the namespace $nsKey. + * + * @see MODE_WRITE, MODE_APPEND + * + * @param string $nsKey + * @param string $itemKey + * @param string $string + * @param int $mode + */ + public function setString($nsKey, $itemKey, $string, $mode) + { + $this->_prepareCache($nsKey); + switch ($mode) { + case self::MODE_WRITE: + $this->_contents[$nsKey][$itemKey] = $string; + break; + case self::MODE_APPEND: + if (!$this->hasKey($nsKey, $itemKey)) { + $this->_contents[$nsKey][$itemKey] = ''; + } + $this->_contents[$nsKey][$itemKey] .= $string; + break; + default: + throw new Swift_SwiftException( + 'Invalid mode [' . $mode . '] used to set nsKey='. + $nsKey . ', itemKey=' . $itemKey + ); } - $this->_contents[$nsKey][$itemKey] .= $string; - break; - default: - throw new Swift_SwiftException( - 'Invalid mode [' . $mode . '] used to set nsKey='. - $nsKey . ', itemKey=' . $itemKey - ); } - } - - /** - * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @param Swift_OutputByteStream $os - * @param int $mode - * @see MODE_WRITE, MODE_APPEND - */ - public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, - $mode) - { - $this->_prepareCache($nsKey); - switch ($mode) + + /** + * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. + * + * @see MODE_WRITE, MODE_APPEND + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_OutputByteStream $os + * @param int $mode + */ + public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode) { - case self::MODE_WRITE: - $this->clearKey($nsKey, $itemKey); - case self::MODE_APPEND: - if (!$this->hasKey($nsKey, $itemKey)) - { - $this->_contents[$nsKey][$itemKey] = ''; + $this->_prepareCache($nsKey); + switch ($mode) { + case self::MODE_WRITE: + $this->clearKey($nsKey, $itemKey); + case self::MODE_APPEND: + if (!$this->hasKey($nsKey, $itemKey)) { + $this->_contents[$nsKey][$itemKey] = ''; + } + while (false !== $bytes = $os->read(8192)) { + $this->_contents[$nsKey][$itemKey] .= $bytes; + } + break; + default: + throw new Swift_SwiftException( + 'Invalid mode [' . $mode . '] used to set nsKey='. + $nsKey . ', itemKey=' . $itemKey + ); } - while (false !== $bytes = $os->read(8192)) - { - $this->_contents[$nsKey][$itemKey] .= $bytes; + } + + /** + * Provides a ByteStream which when written to, writes data to $itemKey. + * + * NOTE: The stream will always write in append mode. + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $writeThrough + * + * @return Swift_InputByteStream + */ + public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $writeThrough = null) + { + $is = clone $this->_stream; + $is->setKeyCache($this); + $is->setNsKey($nsKey); + $is->setItemKey($itemKey); + if (isset($writeThrough)) { + $is->setWriteThroughStream($writeThrough); } - break; - default: - throw new Swift_SwiftException( - 'Invalid mode [' . $mode . '] used to set nsKey='. - $nsKey . ', itemKey=' . $itemKey - ); + + return $is; } - } - - /** - * Provides a ByteStream which when written to, writes data to $itemKey. - * NOTE: The stream will always write in append mode. - * @param string $nsKey - * @param string $itemKey - * @return Swift_InputByteStream - */ - public function getInputByteStream($nsKey, $itemKey, - Swift_InputByteStream $writeThrough = null) - { - $is = clone $this->_stream; - $is->setKeyCache($this); - $is->setNsKey($nsKey); - $is->setItemKey($itemKey); - if (isset($writeThrough)) + + /** + * Get data back out of the cache as a string. + * + * @param string $nsKey + * @param string $itemKey + * + * @return string + */ + public function getString($nsKey, $itemKey) { - $is->setWriteThroughStream($writeThrough); + $this->_prepareCache($nsKey); + if ($this->hasKey($nsKey, $itemKey)) { + return $this->_contents[$nsKey][$itemKey]; + } } - return $is; - } - - /** - * Get data back out of the cache as a string. - * @param string $nsKey - * @param string $itemKey - * @return string - */ - public function getString($nsKey, $itemKey) - { - $this->_prepareCache($nsKey); - if ($this->hasKey($nsKey, $itemKey)) + + /** + * Get data back out of the cache as a ByteStream. + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $is to write the data to + */ + public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) { - return $this->_contents[$nsKey][$itemKey]; + $this->_prepareCache($nsKey); + $is->write($this->getString($nsKey, $itemKey)); } - } - - /** - * Get data back out of the cache as a ByteStream. - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $is to write the data to - */ - public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) - { - $this->_prepareCache($nsKey); - $is->write($this->getString($nsKey, $itemKey)); - } - - /** - * Check if the given $itemKey exists in the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @return boolean - */ - public function hasKey($nsKey, $itemKey) - { - $this->_prepareCache($nsKey); - return array_key_exists($itemKey, $this->_contents[$nsKey]); - } - - /** - * Clear data for $itemKey in the namespace $nsKey if it exists. - * @param string $nsKey - * @param string $itemKey - */ - public function clearKey($nsKey, $itemKey) - { - unset($this->_contents[$nsKey][$itemKey]); - } - - /** - * Clear all data in the namespace $nsKey if it exists. - * @param string $nsKey - */ - public function clearAll($nsKey) - { - unset($this->_contents[$nsKey]); - } - - // -- Private methods - - /** - * Initialize the namespace of $nsKey if needed. - * @param string $nsKey - * @access private - */ - private function _prepareCache($nsKey) - { - if (!array_key_exists($nsKey, $this->_contents)) + + /** + * Check if the given $itemKey exists in the namespace $nsKey. + * + * @param string $nsKey + * @param string $itemKey + * + * @return bool + */ + public function hasKey($nsKey, $itemKey) { - $this->_contents[$nsKey] = array(); + $this->_prepareCache($nsKey); + + return array_key_exists($itemKey, $this->_contents[$nsKey]); + } + + /** + * Clear data for $itemKey in the namespace $nsKey if it exists. + * + * @param string $nsKey + * @param string $itemKey + */ + public function clearKey($nsKey, $itemKey) + { + unset($this->_contents[$nsKey][$itemKey]); + } + + /** + * Clear all data in the namespace $nsKey if it exists. + * + * @param string $nsKey + */ + public function clearAll($nsKey) + { + unset($this->_contents[$nsKey]); + } + + // -- Private methods + + /** + * Initialize the namespace of $nsKey if needed. + * + * @param string $nsKey + */ + private function _prepareCache($nsKey) + { + if (!array_key_exists($nsKey, $this->_contents)) { + $this->_contents[$nsKey] = array(); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php b/lib/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php index 7835079e8..abd8611f2 100644 --- a/lib/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php +++ b/lib/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php @@ -8,326 +8,321 @@ * file that was distributed with this source code. */ - /** * A KeyCache which streams to and from disk. - * @package Swift + * + * @package Swift * @subpackage KeyCache - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache { + /** Signal to place pointer at start of file */ + const POSITION_START = 0; - /** Signal to place pointer at start of file */ - const POSITION_START = 0; + /** Signal to place pointer at end of file */ + const POSITION_END = 1; - /** Signal to place pointer at end of file */ - const POSITION_END = 1; - - /** Signal to leave pointer in whatever position it currently is */ - const POSITION_CURRENT = 2; + /** Signal to leave pointer in whatever position it currently is */ + const POSITION_CURRENT = 2; - /** - * An InputStream for cloning. - * @var Swift_KeyCache_KeyCacheInputStream - * @access private - */ - private $_stream; + /** + * An InputStream for cloning. + * + * @var Swift_KeyCache_KeyCacheInputStream + */ + private $_stream; - /** - * A path to write to. - * @var string - * @access private - */ - private $_path; + /** + * A path to write to. + * + * @var string + */ + private $_path; - /** - * Stored keys. - * @var array - * @access private - */ - private $_keys = array(); + /** + * Stored keys. + * + * @var array + */ + private $_keys = array(); - /** - * Will be true if magic_quotes_runtime is turned on. - * @var boolean - * @access private - */ - private $_quotes = false; + /** + * Will be true if magic_quotes_runtime is turned on. + * + * @var bool + */ + private $_quotes = false; - /** - * Create a new DiskKeyCache with the given $stream for cloning to make - * InputByteStreams, and the given $path to save to. - * @param Swift_KeyCache_KeyCacheInputStream $stream - * @param string $path to save to - */ - public function __construct(Swift_KeyCache_KeyCacheInputStream $stream, $path) - { - $this->_stream = $stream; - $this->_path = $path; - - if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) + /** + * Create a new DiskKeyCache with the given $stream for cloning to make + * InputByteStreams, and the given $path to save to. + * + * @param Swift_KeyCache_KeyCacheInputStream $stream + * @param string $path to save to + */ + public function __construct(Swift_KeyCache_KeyCacheInputStream $stream, $path) { - $this->_quotes = true; - } - } + $this->_stream = $stream; + $this->_path = $path; - /** - * Set a string into the cache under $itemKey for the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @param string $string - * @param int $mode - * @throws Swift_IoException - * @see MODE_WRITE, MODE_APPEND - */ - public function setString($nsKey, $itemKey, $string, $mode) - { - $this->_prepareCache($nsKey); - switch ($mode) - { - case self::MODE_WRITE: - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); - break; - case self::MODE_APPEND: - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END); - break; - default: - throw new Swift_SwiftException( - 'Invalid mode [' . $mode . '] used to set nsKey='. - $nsKey . ', itemKey=' . $itemKey - ); - break; + if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) { + $this->_quotes = true; + } } - fwrite($fp, $string); - $this->_freeHandle($nsKey, $itemKey); - } - /** - * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @param Swift_OutputByteStream $os - * @param int $mode - * @see MODE_WRITE, MODE_APPEND - * @throws Swift_IoException - */ - public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, - $mode) - { - $this->_prepareCache($nsKey); - switch ($mode) + /** + * Set a string into the cache under $itemKey for the namespace $nsKey. + * + * @see MODE_WRITE, MODE_APPEND + * + * @param string $nsKey + * @param string $itemKey + * @param string $string + * @param int $mode + * + * @throws Swift_IoException + */ + public function setString($nsKey, $itemKey, $string, $mode) { - case self::MODE_WRITE: - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); - break; - case self::MODE_APPEND: - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END); - break; - default: - throw new Swift_SwiftException( - 'Invalid mode [' . $mode . '] used to set nsKey='. - $nsKey . ', itemKey=' . $itemKey - ); - break; + $this->_prepareCache($nsKey); + switch ($mode) { + case self::MODE_WRITE: + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); + break; + case self::MODE_APPEND: + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END); + break; + default: + throw new Swift_SwiftException( + 'Invalid mode [' . $mode . '] used to set nsKey='. + $nsKey . ', itemKey=' . $itemKey + ); + break; + } + fwrite($fp, $string); + $this->_freeHandle($nsKey, $itemKey); } - while (false !== $bytes = $os->read(8192)) - { - fwrite($fp, $bytes); - } - $this->_freeHandle($nsKey, $itemKey); - } - /** - * Provides a ByteStream which when written to, writes data to $itemKey. - * NOTE: The stream will always write in append mode. - * @param string $nsKey - * @param string $itemKey - * @return Swift_InputByteStream - */ - public function getInputByteStream($nsKey, $itemKey, - Swift_InputByteStream $writeThrough = null) - { - $is = clone $this->_stream; - $is->setKeyCache($this); - $is->setNsKey($nsKey); - $is->setItemKey($itemKey); - if (isset($writeThrough)) + /** + * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. + * + * @see MODE_WRITE, MODE_APPEND + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_OutputByteStream $os + * @param int $mode + * + * @throws Swift_IoException + */ + public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode) { - $is->setWriteThroughStream($writeThrough); + $this->_prepareCache($nsKey); + switch ($mode) { + case self::MODE_WRITE: + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); + break; + case self::MODE_APPEND: + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END); + break; + default: + throw new Swift_SwiftException( + 'Invalid mode [' . $mode . '] used to set nsKey='. + $nsKey . ', itemKey=' . $itemKey + ); + break; + } + while (false !== $bytes = $os->read(8192)) { + fwrite($fp, $bytes); + } + $this->_freeHandle($nsKey, $itemKey); } - return $is; - } - /** - * Get data back out of the cache as a string. - * @param string $nsKey - * @param string $itemKey - * @return string - * @throws Swift_IoException - */ - public function getString($nsKey, $itemKey) - { - $this->_prepareCache($nsKey); - if ($this->hasKey($nsKey, $itemKey)) + /** + * Provides a ByteStream which when written to, writes data to $itemKey. + * + * NOTE: The stream will always write in append mode. + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $writeThrough + * + * @return Swift_InputByteStream + */ + public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $writeThrough = null) { - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); - if ($this->_quotes) - { - ini_set('magic_quotes_runtime', 0); - } - $str = ''; - while (!feof($fp) && false !== $bytes = fread($fp, 8192)) - { - $str .= $bytes; - } - if ($this->_quotes) - { - ini_set('magic_quotes_runtime', 1); - } - $this->_freeHandle($nsKey, $itemKey); - return $str; - } - } + $is = clone $this->_stream; + $is->setKeyCache($this); + $is->setNsKey($nsKey); + $is->setItemKey($itemKey); + if (isset($writeThrough)) { + $is->setWriteThroughStream($writeThrough); + } - /** - * Get data back out of the cache as a ByteStream. - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $is to write the data to - */ - public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) - { - if ($this->hasKey($nsKey, $itemKey)) + return $is; + } + + /** + * Get data back out of the cache as a string. + * + * @param string $nsKey + * @param string $itemKey + * + * @return string + * + * @throws Swift_IoException + */ + public function getString($nsKey, $itemKey) { - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); - if ($this->_quotes) - { - ini_set('magic_quotes_runtime', 0); - } - while (!feof($fp) && false !== $bytes = fread($fp, 8192)) - { - $is->write($bytes); - } - if ($this->_quotes) - { - ini_set('magic_quotes_runtime', 1); - } - $this->_freeHandle($nsKey, $itemKey); + $this->_prepareCache($nsKey); + if ($this->hasKey($nsKey, $itemKey)) { + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); + if ($this->_quotes) { + ini_set('magic_quotes_runtime', 0); + } + $str = ''; + while (!feof($fp) && false !== $bytes = fread($fp, 8192)) { + $str .= $bytes; + } + if ($this->_quotes) { + ini_set('magic_quotes_runtime', 1); + } + $this->_freeHandle($nsKey, $itemKey); + + return $str; + } } - } - /** - * Check if the given $itemKey exists in the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @return boolean - */ - public function hasKey($nsKey, $itemKey) - { - return is_file($this->_path . '/' . $nsKey . '/' . $itemKey); - } - - /** - * Clear data for $itemKey in the namespace $nsKey if it exists. - * @param string $nsKey - * @param string $itemKey - */ - public function clearKey($nsKey, $itemKey) - { - if ($this->hasKey($nsKey, $itemKey)) + /** + * Get data back out of the cache as a ByteStream. + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $is to write the data to + */ + public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) { - $this->_freeHandle($nsKey, $itemKey); - unlink($this->_path . '/' . $nsKey . '/' . $itemKey); + if ($this->hasKey($nsKey, $itemKey)) { + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START); + if ($this->_quotes) { + ini_set('magic_quotes_runtime', 0); + } + while (!feof($fp) && false !== $bytes = fread($fp, 8192)) { + $is->write($bytes); + } + if ($this->_quotes) { + ini_set('magic_quotes_runtime', 1); + } + $this->_freeHandle($nsKey, $itemKey); + } } - } - /** - * Clear all data in the namespace $nsKey if it exists. - * @param string $nsKey - */ - public function clearAll($nsKey) - { - if (array_key_exists($nsKey, $this->_keys)) + /** + * Check if the given $itemKey exists in the namespace $nsKey. + * + * @param string $nsKey + * @param string $itemKey + * + * @return bool + */ + public function hasKey($nsKey, $itemKey) { - foreach ($this->_keys[$nsKey] as $itemKey=>$null) - { - $this->clearKey($nsKey, $itemKey); - } - if (is_dir($this->_path . '/' . $nsKey)) - { - rmdir($this->_path . '/' . $nsKey); - } - unset($this->_keys[$nsKey]); + return is_file($this->_path . '/' . $nsKey . '/' . $itemKey); } - } - // -- Private methods + /** + * Clear data for $itemKey in the namespace $nsKey if it exists. + * + * @param string $nsKey + * @param string $itemKey + */ + public function clearKey($nsKey, $itemKey) + { + if ($this->hasKey($nsKey, $itemKey)) { + $this->_freeHandle($nsKey, $itemKey); + unlink($this->_path . '/' . $nsKey . '/' . $itemKey); + } + } - /** - * Initialize the namespace of $nsKey if needed. - * @param string $nsKey - * @access private - */ - private function _prepareCache($nsKey) - { - $cacheDir = $this->_path . '/' . $nsKey; - if (!is_dir($cacheDir)) + /** + * Clear all data in the namespace $nsKey if it exists. + * + * @param string $nsKey + */ + public function clearAll($nsKey) { - if (!mkdir($cacheDir)) - { - throw new Swift_IoException('Failed to create cache directory ' . $cacheDir); - } - $this->_keys[$nsKey] = array(); + if (array_key_exists($nsKey, $this->_keys)) { + foreach ($this->_keys[$nsKey] as $itemKey=>$null) { + $this->clearKey($nsKey, $itemKey); + } + if (is_dir($this->_path . '/' . $nsKey)) { + rmdir($this->_path . '/' . $nsKey); + } + unset($this->_keys[$nsKey]); + } } - } - /** - * Get a file handle on the cache item. - * @param string $nsKey - * @param string $itemKey - * @param int $position - * @return resource - * @access private - */ - private function _getHandle($nsKey, $itemKey, $position) - { - if (!isset($this->_keys[$nsKey][$itemKey])) - { - $openMode = $this->hasKey($nsKey, $itemKey) - ? 'r+b' - : 'w+b' - ; - $fp = fopen($this->_path . '/' . $nsKey . '/' . $itemKey, $openMode); - $this->_keys[$nsKey][$itemKey] = $fp; - } - if (self::POSITION_START == $position) - { - fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_SET); - } - elseif (self::POSITION_END == $position) - { - fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_END); - } - return $this->_keys[$nsKey][$itemKey]; - } - - private function _freeHandle($nsKey, $itemKey) - { - $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_CURRENT); - fclose($fp); - $this->_keys[$nsKey][$itemKey] = null; - } + // -- Private methods - /** - * Destructor. - */ - public function __destruct() - { - foreach ($this->_keys as $nsKey=>$null) + /** + * Initialize the namespace of $nsKey if needed. + * + * @param string $nsKey + */ + private function _prepareCache($nsKey) { - $this->clearAll($nsKey); + $cacheDir = $this->_path . '/' . $nsKey; + if (!is_dir($cacheDir)) { + if (!mkdir($cacheDir)) { + throw new Swift_IoException('Failed to create cache directory ' . $cacheDir); + } + $this->_keys[$nsKey] = array(); + } } - } + /** + * Get a file handle on the cache item. + * + * @param string $nsKey + * @param string $itemKey + * @param int $position + * + * @return resource + */ + private function _getHandle($nsKey, $itemKey, $position) + { + if (!isset($this->_keys[$nsKey][$itemKey])) { + $openMode = $this->hasKey($nsKey, $itemKey) + ? 'r+b' + : 'w+b' + ; + $fp = fopen($this->_path . '/' . $nsKey . '/' . $itemKey, $openMode); + $this->_keys[$nsKey][$itemKey] = $fp; + } + if (self::POSITION_START == $position) { + fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_SET); + } elseif (self::POSITION_END == $position) { + fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_END); + } + + return $this->_keys[$nsKey][$itemKey]; + } + + private function _freeHandle($nsKey, $itemKey) + { + $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_CURRENT); + fclose($fp); + $this->_keys[$nsKey][$itemKey] = null; + } + + /** + * Destructor. + */ + public function __destruct() + { + foreach ($this->_keys as $nsKey=>$null) { + $this->clearAll($nsKey); + } + } } diff --git a/lib/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php b/lib/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php index f4a3f4761..f4f8adb96 100644 --- a/lib/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php +++ b/lib/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php @@ -8,44 +8,46 @@ * file that was distributed with this source code. */ - /** * Writes data to a KeyCache using a stream. - * @package Swift + * + * @package Swift * @subpackage KeyCache - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_KeyCache_KeyCacheInputStream extends Swift_InputByteStream { - - /** - * Set the KeyCache to wrap. - * @param Swift_KeyCache $keyCache - */ - public function setKeyCache(Swift_KeyCache $keyCache); - - /** - * Set the nsKey which will be written to. - * @param string $nsKey - */ - public function setNsKey($nsKey); - - /** - * Set the itemKey which will be written to. - * @param string $itemKey - */ - public function setItemKey($itemKey); - - /** - * Specify a stream to write through for each write(). - * @param Swift_InputByteStream $is - */ - public function setWriteThroughStream(Swift_InputByteStream $is); - - /** - * Any implementation should be cloneable, allowing the clone to access a - * separate $nsKey and $itemKey. - */ - public function __clone(); - + /** + * Set the KeyCache to wrap. + * + * @param Swift_KeyCache $keyCache + */ + public function setKeyCache(Swift_KeyCache $keyCache); + + /** + * Set the nsKey which will be written to. + * + * @param string $nsKey + */ + public function setNsKey($nsKey); + + /** + * Set the itemKey which will be written to. + * + * @param string $itemKey + */ + public function setItemKey($itemKey); + + /** + * Specify a stream to write through for each write(). + * + * @param Swift_InputByteStream $is + */ + public function setWriteThroughStream(Swift_InputByteStream $is); + + /** + * Any implementation should be cloneable, allowing the clone to access a + * separate $nsKey and $itemKey. + */ + public function __clone(); } diff --git a/lib/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php b/lib/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php index d75ab48a3..5c4e2cfd6 100644 --- a/lib/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php +++ b/lib/swiftmailer/lib/classes/Swift/KeyCache/NullKeyCache.php @@ -8,99 +8,110 @@ * file that was distributed with this source code. */ - /** * A null KeyCache that does not cache at all. - * @package Swift + * + * @package Swift * @subpackage KeyCache - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_KeyCache_NullKeyCache implements Swift_KeyCache { - - /** - * Set a string into the cache under $itemKey for the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @param string $string - * @param int $mode - * @see MODE_WRITE, MODE_APPEND - */ - public function setString($nsKey, $itemKey, $string, $mode) - { - } - - /** - * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @param Swift_OutputByteStream $os - * @param int $mode - * @see MODE_WRITE, MODE_APPEND - */ - public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, - $mode) - { - } - - /** - * Provides a ByteStream which when written to, writes data to $itemKey. - * NOTE: The stream will always write in append mode. - * @param string $nsKey - * @param string $itemKey - * @return Swift_InputByteStream - */ - public function getInputByteStream($nsKey, $itemKey, - Swift_InputByteStream $writeThrough = null) - { - } - - /** - * Get data back out of the cache as a string. - * @param string $nsKey - * @param string $itemKey - * @return string - */ - public function getString($nsKey, $itemKey) - { - } - - /** - * Get data back out of the cache as a ByteStream. - * @param string $nsKey - * @param string $itemKey - * @param Swift_InputByteStream $is to write the data to - */ - public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) - { - } - - /** - * Check if the given $itemKey exists in the namespace $nsKey. - * @param string $nsKey - * @param string $itemKey - * @return boolean - */ - public function hasKey($nsKey, $itemKey) - { - return false; - } - - /** - * Clear data for $itemKey in the namespace $nsKey if it exists. - * @param string $nsKey - * @param string $itemKey - */ - public function clearKey($nsKey, $itemKey) - { - } - - /** - * Clear all data in the namespace $nsKey if it exists. - * @param string $nsKey - */ - public function clearAll($nsKey) - { - } - + /** + * Set a string into the cache under $itemKey for the namespace $nsKey. + * + * @see MODE_WRITE, MODE_APPEND + * + * @param string $nsKey + * @param string $itemKey + * @param string $string + * @param int $mode + */ + public function setString($nsKey, $itemKey, $string, $mode) + { + } + + /** + * Set a ByteStream into the cache under $itemKey for the namespace $nsKey. + * + * @see MODE_WRITE, MODE_APPEND + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_OutputByteStream $os + * @param int $mode + */ + public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode) + { + } + + /** + * Provides a ByteStream which when written to, writes data to $itemKey. + * + * NOTE: The stream will always write in append mode. + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $writeThrough + * + * @return Swift_InputByteStream + */ + public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $writeThrough = null) + { + } + + /** + * Get data back out of the cache as a string. + * + * @param string $nsKey + * @param string $itemKey + * + * @return string + */ + public function getString($nsKey, $itemKey) + { + } + + /** + * Get data back out of the cache as a ByteStream. + * + * @param string $nsKey + * @param string $itemKey + * @param Swift_InputByteStream $is to write the data to + */ + public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is) + { + } + + /** + * Check if the given $itemKey exists in the namespace $nsKey. + * + * @param string $nsKey + * @param string $itemKey + * + * @return bool + */ + public function hasKey($nsKey, $itemKey) + { + return false; + } + + /** + * Clear data for $itemKey in the namespace $nsKey if it exists. + * + * @param string $nsKey + * @param string $itemKey + */ + public function clearKey($nsKey, $itemKey) + { + } + + /** + * Clear all data in the namespace $nsKey if it exists. + * + * @param string $nsKey + */ + public function clearAll($nsKey) + { + } } diff --git a/lib/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php b/lib/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php index e9c90bf56..aa7de04a7 100644 --- a/lib/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php +++ b/lib/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php @@ -8,122 +8,122 @@ * file that was distributed with this source code. */ - /** * Writes data to a KeyCache using a stream. - * @package Swift + * + * @package Swift * @subpackage KeyCache - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_KeyCache_SimpleKeyCacheInputStream - implements Swift_KeyCache_KeyCacheInputStream +class Swift_KeyCache_SimpleKeyCacheInputStream implements Swift_KeyCache_KeyCacheInputStream { - - /** The KeyCache being written to */ - private $_keyCache; - - /** The nsKey of the KeyCache being written to */ - private $_nsKey; - - /** The itemKey of the KeyCache being written to */ - private $_itemKey; - - /** A stream to write through on each write() */ - private $_writeThrough = null; - - /** - * Set the KeyCache to wrap. - * @param Swift_KeyCache $keyCache - */ - public function setKeyCache(Swift_KeyCache $keyCache) - { - $this->_keyCache = $keyCache; - } - - /** - * Specify a stream to write through for each write(). - * @param Swift_InputByteStream $is - */ - public function setWriteThroughStream(Swift_InputByteStream $is) - { - $this->_writeThrough = $is; - } - - /** - * Writes $bytes to the end of the stream. - * @param string $bytes - * @param Swift_InputByteStream $is, optional - */ - public function write($bytes, Swift_InputByteStream $is = null) - { - $this->_keyCache->setString( - $this->_nsKey, $this->_itemKey, $bytes, Swift_KeyCache::MODE_APPEND - ); - if (isset($is)) + /** The KeyCache being written to */ + private $_keyCache; + + /** The nsKey of the KeyCache being written to */ + private $_nsKey; + + /** The itemKey of the KeyCache being written to */ + private $_itemKey; + + /** A stream to write through on each write() */ + private $_writeThrough = null; + + /** + * Set the KeyCache to wrap. + * + * @param Swift_KeyCache $keyCache + */ + public function setKeyCache(Swift_KeyCache $keyCache) { - $is->write($bytes); + $this->_keyCache = $keyCache; } - if (isset($this->_writeThrough)) + + /** + * Specify a stream to write through for each write(). + * + * @param Swift_InputByteStream $is + */ + public function setWriteThroughStream(Swift_InputByteStream $is) { - $this->_writeThrough->write($bytes); + $this->_writeThrough = $is; + } + + /** + * Writes $bytes to the end of the stream. + * + * @param string $bytes + * @param Swift_InputByteStream $is optional + */ + public function write($bytes, Swift_InputByteStream $is = null) + { + $this->_keyCache->setString( + $this->_nsKey, $this->_itemKey, $bytes, Swift_KeyCache::MODE_APPEND + ); + if (isset($is)) { + $is->write($bytes); + } + if (isset($this->_writeThrough)) { + $this->_writeThrough->write($bytes); + } + } + + /** + * Not used. + */ + public function commit() + { + } + + /** + * Not used. + */ + public function bind(Swift_InputByteStream $is) + { + } + + /** + * Not used. + */ + public function unbind(Swift_InputByteStream $is) + { + } + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + */ + public function flushBuffers() + { + $this->_keyCache->clearKey($this->_nsKey, $this->_itemKey); + } + + /** + * Set the nsKey which will be written to. + * + * @param string $nsKey + */ + public function setNsKey($nsKey) + { + $this->_nsKey = $nsKey; + } + + /** + * Set the itemKey which will be written to. + * + * @param string $itemKey + */ + public function setItemKey($itemKey) + { + $this->_itemKey = $itemKey; + } + + /** + * Any implementation should be cloneable, allowing the clone to access a + * separate $nsKey and $itemKey. + */ + public function __clone() + { + $this->_writeThrough = null; } - } - - /** - * Not used. - */ - public function commit() - { - } - - /** - * Not used. - */ - public function bind(Swift_InputByteStream $is) - { - } - - /** - * Not used. - */ - public function unbind(Swift_InputByteStream $is) - { - } - - /** - * Flush the contents of the stream (empty it) and set the internal pointer - * to the beginning. - */ - public function flushBuffers() - { - $this->_keyCache->clearKey($this->_nsKey, $this->_itemKey); - } - - /** - * Set the nsKey which will be written to. - * @param string $nsKey - */ - public function setNsKey($nsKey) - { - $this->_nsKey = $nsKey; - } - - /** - * Set the itemKey which will be written to. - * @param string $itemKey - */ - public function setItemKey($itemKey) - { - $this->_itemKey = $itemKey; - } - - /** - * Any implementation should be cloneable, allowing the clone to access a - * separate $nsKey and $itemKey. - */ - public function __clone() - { - $this->_writeThrough = null; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php b/lib/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php index de3045ad6..6eb3db706 100644 --- a/lib/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php @@ -8,39 +8,40 @@ * file that was distributed with this source code. */ - /** - * Redudantly and rotationally uses several Transport implementations when sending. - * @package Swift + * Redundantly and rotationally uses several Transport implementations when sending. + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_LoadBalancedTransport extends Swift_Transport_LoadBalancedTransport { - - /** - * Creates a new LoadBalancedTransport with $transports. - * @param array $transports - */ - public function __construct($transports = array()) - { - call_user_func_array( - array($this, 'Swift_Transport_LoadBalancedTransport::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.loadbalanced') - ); - - $this->setTransports($transports); - } - - /** - * Create a new LoadBalancedTransport instance. - * @param string $transports - * @return Swift_LoadBalancedTransport - */ - public static function newInstance($transports = array()) - { - return new self($transports); - } - + /** + * Creates a new LoadBalancedTransport with $transports. + * + * @param array $transports + */ + public function __construct($transports = array()) + { + call_user_func_array( + array($this, 'Swift_Transport_LoadBalancedTransport::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.loadbalanced') + ); + + $this->setTransports($transports); + } + + /** + * Create a new LoadBalancedTransport instance. + * + * @param array $transports + * + * @return Swift_LoadBalancedTransport + */ + public static function newInstance($transports = array()) + { + return new self($transports); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/MailTransport.php b/lib/swiftmailer/lib/classes/Swift/MailTransport.php index dd8ccacc8..6c5793967 100644 --- a/lib/swiftmailer/lib/classes/Swift/MailTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/MailTransport.php @@ -8,39 +8,40 @@ * file that was distributed with this source code. */ - /** * Sends Messages using the mail() function. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_MailTransport extends Swift_Transport_MailTransport { - - /** - * Create a new MailTransport, optionally specifying $extraParams. - * @param string $extraParams - */ - public function __construct($extraParams = '-f%s') - { - call_user_func_array( - array($this, 'Swift_Transport_MailTransport::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.mail') - ); - - $this->setExtraParams($extraParams); - } - - /** - * Create a new MailTransport instance. - * @param string $extraParams To be passed to mail() - * @return Swift_MailTransport - */ - public static function newInstance($extraParams = '-f%s') - { - return new self($extraParams); - } - + /** + * Create a new MailTransport, optionally specifying $extraParams. + * + * @param string $extraParams + */ + public function __construct($extraParams = '-f%s') + { + call_user_func_array( + array($this, 'Swift_Transport_MailTransport::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.mail') + ); + + $this->setExtraParams($extraParams); + } + + /** + * Create a new MailTransport instance. + * + * @param string $extraParams To be passed to mail() + * + * @return Swift_MailTransport + */ + public static function newInstance($extraParams = '-f%s') + { + return new self($extraParams); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mailer.php b/lib/swiftmailer/lib/classes/Swift/Mailer.php index 802e46594..f4e051232 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mailer.php +++ b/lib/swiftmailer/lib/classes/Swift/Mailer.php @@ -8,111 +8,108 @@ * file that was distributed with this source code. */ - /** * Swift Mailer class. - * + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mailer { - - /** The Transport used to send messages */ - private $_transport; - - /** - * Create a new Mailer using $transport for delivery. - * - * @param Swift_Transport $transport - */ - public function __construct(Swift_Transport $transport) - { - $this->_transport = $transport; - } + /** The Transport used to send messages */ + private $_transport; - /** - * Create a new Mailer instance. - * - * @param Swift_Transport $transport - * @return Swift_Mailer - */ - public static function newInstance(Swift_Transport $transport) - { - return new self($transport); - } + /** + * Create a new Mailer using $transport for delivery. + * + * @param Swift_Transport $transport + */ + public function __construct(Swift_Transport $transport) + { + $this->_transport = $transport; + } - /** - * Create a new class instance of one if the message services - * For example 'mimepart' would create a 'message.mimepart' instance - * - * @param string $service - * @return object - */ - public function createMessage($service = 'message') - { - return Swift_DependencyContainer::getInstance() - ->lookup('message.'.$service); - } + /** + * Create a new Mailer instance. + * + * @param Swift_Transport $transport + * + * @return Swift_Mailer + */ + public static function newInstance(Swift_Transport $transport) + { + return new self($transport); + } - /** - * Send the given Message like it would be sent in a mail client. - * - * All recipients (with the exception of Bcc) will be able to see the other - * recipients this message was sent to. - * - * Recipient/sender data will be retreived from the Message object. - * - * The return value is the number of recipients who were accepted for - * delivery. - * - * @param Swift_Mime_Message $message - * @param array &$failedRecipients, optional - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $failedRecipients = (array) $failedRecipients; - - if (!$this->_transport->isStarted()) + /** + * Create a new class instance of one of the message services. + * + * For example 'mimepart' would create a 'message.mimepart' instance + * + * @param string $service + * + * @return object + */ + public function createMessage($service = 'message') { - $this->_transport->start(); + return Swift_DependencyContainer::getInstance() + ->lookup('message.'.$service); } - - $sent = 0; - - try + + /** + * Send the given Message like it would be sent in a mail client. + * + * All recipients (with the exception of Bcc) will be able to see the other + * recipients this message was sent to. + * + * Recipient/sender data will be retrieved from the Message object. + * + * The return value is the number of recipients who were accepted for + * delivery. + * + * @param Swift_Mime_Message $message + * @param array $failedRecipients An array of failures by-reference + * + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) { - $sent = $this->_transport->send($message, $failedRecipients); + $failedRecipients = (array) $failedRecipients; + + if (!$this->_transport->isStarted()) { + $this->_transport->start(); + } + + $sent = 0; + + try { + $sent = $this->_transport->send($message, $failedRecipients); + } catch (Swift_RfcComplianceException $e) { + foreach ($message->getTo() as $address => $name) { + $failedRecipients[] = $address; + } + } + + return $sent; } - catch (Swift_RfcComplianceException $e) + + /** + * Register a plugin using a known unique key (e.g. myPlugin). + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) { - foreach ($message->getTo() as $address => $name) - { - $failedRecipients[] = $address; - } + $this->_transport->registerPlugin($plugin); + } + + /** + * The Transport used to send messages. + * + * @return Swift_Transport + */ + public function getTransport() + { + return $this->_transport; } - - return $sent; - } - - /** - * Register a plugin using a known unique key (e.g. myPlugin). - * - * @param Swift_Events_EventListener $plugin - * @param string $key - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_transport->registerPlugin($plugin); - } - - /** - * The Transport used to send messages. - * @return Swift_Transport - */ - public function getTransport() - { - return $this->_transport; - } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php b/lib/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php index c732ebb91..1dd32415b 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php +++ b/lib/swiftmailer/lib/classes/Swift/Mailer/ArrayRecipientIterator.php @@ -8,51 +8,50 @@ * file that was distributed with this source code. */ - /** - * Wraps a standard PHP array in an interator. - * @package Swift + * Wraps a standard PHP array in an iterator. + * + * @package Swift * @subpackage Mailer - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mailer_ArrayRecipientIterator - implements Swift_Mailer_RecipientIterator +class Swift_Mailer_ArrayRecipientIterator implements Swift_Mailer_RecipientIterator { - - /** - * The list of recipients. - * @var array - * @access private - */ - private $_recipients = array(); - - /** - * Create a new ArrayRecipientIterator from $recipients. - * @param array $recipients - */ - public function __construct(array $recipients) - { - $this->_recipients = $recipients; - } - - /** - * Returns true only if there are more recipients to send to. - * @return boolean - */ - public function hasNext() - { - return !empty($this->_recipients); - } - - /** - * Returns an array where the keys are the addresses of recipients and the - * values are the names. - * e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL) - * @return array - */ - public function nextRecipient() - { - return array_splice($this->_recipients, 0, 1); - } - + /** + * The list of recipients. + * + * @var array + */ + private $_recipients = array(); + + /** + * Create a new ArrayRecipientIterator from $recipients. + * + * @param array $recipients + */ + public function __construct(array $recipients) + { + $this->_recipients = $recipients; + } + + /** + * Returns true only if there are more recipients to send to. + * + * @return bool + */ + public function hasNext() + { + return !empty($this->_recipients); + } + + /** + * Returns an array where the keys are the addresses of recipients and the + * values are the names. e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL) + * + * @return array + */ + public function nextRecipient() + { + return array_splice($this->_recipients, 0, 1); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php b/lib/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php index 271384166..8f109fa95 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php +++ b/lib/swiftmailer/lib/classes/Swift/Mailer/RecipientIterator.php @@ -10,25 +10,25 @@ /** * Provides an abstract way of specifying recipients for batch sending. - * @package Swift + * + * @package Swift * @subpackage Mailer - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mailer_RecipientIterator { - - /** - * Returns true only if there are more recipients to send to. - * @return boolean - */ - public function hasNext(); - - /** - * Returns an array where the keys are the addresses of recipients and the - * values are the names. - * e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL) - * @return array - */ - public function nextRecipient(); - + /** + * Returns true only if there are more recipients to send to. + * + * @return bool + */ + public function hasNext(); + + /** + * Returns an array where the keys are the addresses of recipients and the + * values are the names. e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL) + * + * @return array + */ + public function nextRecipient(); } diff --git a/lib/swiftmailer/lib/classes/Swift/MemorySpool.php b/lib/swiftmailer/lib/classes/Swift/MemorySpool.php new file mode 100644 index 000000000..6e042cd6a --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/MemorySpool.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Stores Messages in memory. + * + * @package Swift + * @author Fabien Potencier + */ +class Swift_MemorySpool implements Swift_Spool +{ + protected $messages = array(); + + /** + * Tests if this Transport mechanism has started. + * + * @return bool + */ + public function isStarted() + { + return true; + } + + /** + * Starts this Transport mechanism. + */ + public function start() + { + } + + /** + * Stops this Transport mechanism. + */ + public function stop() + { + } + + /** + * Stores a message in the queue. + * + * @param Swift_Mime_Message $message The message to store + * + * @return bool Whether the operation has succeeded + */ + public function queueMessage(Swift_Mime_Message $message) + { + $this->messages[] = $message; + + return true; + } + + /** + * Sends messages using the given transport instance. + * + * @param Swift_Transport $transport A transport instance + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int The number of sent emails + */ + public function flushQueue(Swift_Transport $transport, &$failedRecipients = null) + { + if (!$this->messages) { + return 0; + } + + if (!$transport->isStarted()) { + $transport->start(); + } + + $count = 0; + while ($message = array_pop($this->messages)) { + $count += $transport->send($message, $failedRecipients); + } + + return $count; + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Message.php b/lib/swiftmailer/lib/classes/Swift/Message.php index 2f12ede3f..a5aac9eaa 100644 --- a/lib/swiftmailer/lib/classes/Swift/Message.php +++ b/lib/swiftmailer/lib/classes/Swift/Message.php @@ -8,77 +8,266 @@ * file that was distributed with this source code. */ - /** * The Message class for building emails. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Message extends Swift_Mime_SimpleMessage { - - /** - * Create a new Message. - * Details may be optionally passed into the constructor. - * @param string $subject - * @param string $body - * @param string $contentType - * @param string $charset - */ - public function __construct($subject = null, $body = null, - $contentType = null, $charset = null) - { - call_user_func_array( - array($this, 'Swift_Mime_SimpleMessage::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('mime.message') - ); + /** + * @var Swift_Signers_HeaderSigner[] + */ + private $headerSigners = array(); + + /** + * @var Swift_Signers_BodySigner[] + */ + private $bodySigners = array(); + + /** + * @var array + */ + private $savedMessage = array(); + + /** + * Create a new Message. + * + * Details may be optionally passed into the constructor. + * + * @param string $subject + * @param string $body + * @param string $contentType + * @param string $charset + */ + public function __construct($subject = null, $body = null, $contentType = null, $charset = null) + { + call_user_func_array( + array($this, 'Swift_Mime_SimpleMessage::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('mime.message') + ); + + if (!isset($charset)) { + $charset = Swift_DependencyContainer::getInstance() + ->lookup('properties.charset'); + } + $this->setSubject($subject); + $this->setBody($body); + $this->setCharset($charset); + if ($contentType) { + $this->setContentType($contentType); + } + } + + /** + * Create a new Message. + * + * @param string $subject + * @param string $body + * @param string $contentType + * @param string $charset + * + * @return Swift_Message + */ + public static function newInstance($subject = null, $body = null, $contentType = null, $charset = null) + { + return new self($subject, $body, $contentType, $charset); + } + + /** + * Add a MimePart to this Message. + * + * @param string|Swift_OutputByteStream $body + * @param string $contentType + * @param string $charset + * + * @return Swift_Mime_SimpleMessage + */ + public function addPart($body, $contentType = null, $charset = null) + { + return $this->attach(Swift_MimePart::newInstance( + $body, $contentType, $charset + )); + } - if (!isset($charset)) + /** + * Attach a new signature handler to the message. + * + * @param Swift_Signer $signer + * @return Swift_Message + */ + public function attachSigner(Swift_Signer $signer) { - $charset = Swift_DependencyContainer::getInstance() - ->lookup('properties.charset'); + if ($signer instanceof Swift_Signers_HeaderSigner) { + $this->headerSigners[] = $signer; + } elseif ($signer instanceof Swift_Signers_BodySigner) { + $this->bodySigners[] = $signer; + } + + return $this; } - $this->setSubject($subject); - $this->setBody($body); - $this->setCharset($charset); - if ($contentType) + + /** + * Attach a new signature handler to the message. + * + * @param Swift_Signer $signer + * @return Swift_Message + */ + public function detachSigner(Swift_Signer $signer) { - $this->setContentType($contentType); + if ($signer instanceof Swift_Signers_HeaderSigner) { + foreach ($this->headerSigners as $k => $headerSigner) { + if ($headerSigner === $signer) { + unset($this->headerSigners[$k]); + return $this; + } + } + } elseif ($signer instanceof Swift_Signers_BodySigner) { + foreach ($this->bodySigners as $k => $bodySigner) { + if ($bodySigner === $signer) { + unset($this->bodySigners[$k]); + return $this; + } + } + } + + return $this; + } + + /** + * Get this message as a complete string. + * + * @return string + */ + public function toString() + { + if (empty($this->headerSigners) && empty($this->bodySigners)) { + return parent::toString(); + } + + $this->saveMessage(); + + $this->doSign(); + + $string = parent::toString(); + + $this->restoreMessage(); + + return $string; + } + + /** + * Write this message to a {@link Swift_InputByteStream}. + * + * @param Swift_InputByteStream $is + */ + public function toByteStream(Swift_InputByteStream $is) + { + if (empty($this->headerSigners) && empty($this->bodySigners)) { + parent::toByteStream($is); + return; + } + + $this->saveMessage(); + + $this->doSign(); + + parent::toByteStream($is); + + $this->restoreMessage(); + + } + + public function __wakeup() + { + Swift_DependencyContainer::getInstance()->createDependenciesFor('mime.message'); + } + + /* -- Protected Methods -- */ + + /** + * loops through signers and apply the signatures + */ + protected function doSign() + { + foreach ($this->bodySigners as $signer) { + $altered = $signer->getAlteredHeaders(); + $this->saveHeaders($altered); + $signer->signMessage($this); + } + + foreach ($this->headerSigners as $signer) { + $altered = $signer->getAlteredHeaders(); + $this->saveHeaders($altered); + $signer->reset(); + + $signer->setHeaders($this->getHeaders()); + + $signer->startBody(); + $this->_bodyToByteStream($signer); + $signer->endBody(); + + $signer->addSignature($this->getHeaders()); + } + } + + /** + * save the message before any signature is applied + */ + protected function saveMessage() + { + $this->savedMessage = array('headers'=> array()); + $this->savedMessage['body'] = $this->getBody(); + $this->savedMessage['children'] = $this->getChildren(); + if (count($this->savedMessage['children']) > 0 && $this->getBody() != '') { + $this->setChildren(array_merge(array($this->_becomeMimePart()), $this->savedMessage['children'])); + $this->setBody(''); + } + } + + /** + * save the original headers + * @param array $altered + */ + protected function saveHeaders(array $altered) + { + foreach ($altered as $head) { + $lc = strtolower($head); + + if (!isset($this->savedMessage['headers'][$lc])) { + $this->savedMessage['headers'][$lc] = $this->getHeaders()->getAll($head); + } + } + } + + /** + * Remove or restore altered headers + */ + protected function restoreHeaders() + { + foreach ($this->savedMessage['headers'] as $name => $savedValue) { + $headers = $this->getHeaders()->getAll($name); + + foreach ($headers as $key => $value) { + if (!isset($savedValue[$key])) { + $this->getHeaders()->remove($name, $key); + } + } + } + } + + /** + * Restore message body + */ + protected function restoreMessage() + { + $this->setBody($this->savedMessage['body']); + $this->setChildren($this->savedMessage['children']); + + $this->restoreHeaders(); + $this->savedMessage = array(); } - } - - /** - * Create a new Message. - * @param string $subject - * @param string $body - * @param string $contentType - * @param string $charset - * @return Swift_Mime_Message - */ - public static function newInstance($subject = null, $body = null, - $contentType = null, $charset = null) - { - return new self($subject, $body, $contentType, $charset); - } - - /** - * Add a MimePart to this Message. - * @param string|Swift_OutputByteStream $body - * @param string $contentType - * @param string $charset - */ - public function addPart($body, $contentType = null, $charset = null) - { - return $this->attach(Swift_MimePart::newInstance( - $body, $contentType, $charset - )); - } - - public function __wakeup() - { - Swift_DependencyContainer::getInstance()->createDependenciesFor('mime.message'); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Attachment.php b/lib/swiftmailer/lib/classes/Swift/Mime/Attachment.php index 230313de1..108a02adf 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Attachment.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Attachment.php @@ -8,132 +8,148 @@ * file that was distributed with this source code. */ - /** * An attachment, in a multipart message. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity { - - /** Recognized MIME types */ - private $_mimeTypes = array(); - - /** - * Create a new Attachment with $headers, $encoder and $cache. - * @param Swift_Mime_HeaderSet $headers - * @param Swift_Mime_ContentEncoder $encoder - * @param Swift_KeyCache $cache - * @param Swift_Mime_Grammar $grammar - * @param array $mimeTypes optional - */ - public function __construct(Swift_Mime_HeaderSet $headers, - Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, - Swift_Mime_Grammar $grammar, $mimeTypes = array()) - { - parent::__construct($headers, $encoder, $cache, $grammar); - $this->setDisposition('attachment'); - $this->setContentType('application/octet-stream'); - $this->_mimeTypes = $mimeTypes; - } - - /** - * Get the nesting level used for this attachment. - * Always returns {@link LEVEL_MIXED}. - * @return int - */ - public function getNestingLevel() - { - return self::LEVEL_MIXED; - } - - /** - * Get the Content-Disposition of this attachment. - * By default attachments have a disposition of "attachment". - * @return string - */ - public function getDisposition() - { - return $this->_getHeaderFieldModel('Content-Disposition'); - } - - /** - * Set the Content-Disposition of this attachment. - * @param string $disposition - */ - public function setDisposition($disposition) - { - if (!$this->_setHeaderFieldModel('Content-Disposition', $disposition)) + /** Recognized MIME types */ + private $_mimeTypes = array(); + + /** + * Create a new Attachment with $headers, $encoder and $cache. + * + * @param Swift_Mime_HeaderSet $headers + * @param Swift_Mime_ContentEncoder $encoder + * @param Swift_KeyCache $cache + * @param Swift_Mime_Grammar $grammar + * @param array $mimeTypes optional + */ + public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $mimeTypes = array()) { - $this->getHeaders()->addParameterizedHeader( - 'Content-Disposition', $disposition - ); + parent::__construct($headers, $encoder, $cache, $grammar); + $this->setDisposition('attachment'); + $this->setContentType('application/octet-stream'); + $this->_mimeTypes = $mimeTypes; } - return $this; - } - - /** - * Get the filename of this attachment when downloaded. - * @return string - */ - public function getFilename() - { - return $this->_getHeaderParameter('Content-Disposition', 'filename'); - } - - /** - * Set the filename of this attachment. - * @param string $filename - */ - public function setFilename($filename) - { - $this->_setHeaderParameter('Content-Disposition', 'filename', $filename); - $this->_setHeaderParameter('Content-Type', 'name', $filename); - return $this; - } - - /** - * Get the file size of this attachment. - * @return int - */ - public function getSize() - { - return $this->_getHeaderParameter('Content-Disposition', 'size'); - } - - /** - * Set the file size of this attachment. - * @param int $size - */ - public function setSize($size) - { - $this->_setHeaderParameter('Content-Disposition', 'size', $size); - return $this; - } - - /** - * Set the file that this attachment is for. - * @param Swift_FileStream $file - * @param string $contentType optional - */ - public function setFile(Swift_FileStream $file, $contentType = null) - { - $this->setFilename(basename($file->getPath())); - $this->setBody($file, $contentType); - if (!isset($contentType)) + + /** + * Get the nesting level used for this attachment. + * + * Always returns {@link LEVEL_MIXED}. + * + * @return int + */ + public function getNestingLevel() { - $extension = strtolower(substr( - $file->getPath(), strrpos($file->getPath(), '.') + 1 - )); - - if (array_key_exists($extension, $this->_mimeTypes)) - { - $this->setContentType($this->_mimeTypes[$extension]); - } + return self::LEVEL_MIXED; + } + + /** + * Get the Content-Disposition of this attachment. + * + * By default attachments have a disposition of "attachment". + * + * @return string + */ + public function getDisposition() + { + return $this->_getHeaderFieldModel('Content-Disposition'); + } + + /** + * Set the Content-Disposition of this attachment. + * + * @param string $disposition + * + * @return Swift_Mime_Attachment + */ + public function setDisposition($disposition) + { + if (!$this->_setHeaderFieldModel('Content-Disposition', $disposition)) { + $this->getHeaders()->addParameterizedHeader( + 'Content-Disposition', $disposition + ); + } + + return $this; + } + + /** + * Get the filename of this attachment when downloaded. + * + * @return string + */ + public function getFilename() + { + return $this->_getHeaderParameter('Content-Disposition', 'filename'); + } + + /** + * Set the filename of this attachment. + * + * @param string $filename + * + * @return Swift_Mime_Attachment + */ + public function setFilename($filename) + { + $this->_setHeaderParameter('Content-Disposition', 'filename', $filename); + $this->_setHeaderParameter('Content-Type', 'name', $filename); + + return $this; + } + + /** + * Get the file size of this attachment. + * + * @return int + */ + public function getSize() + { + return $this->_getHeaderParameter('Content-Disposition', 'size'); + } + + /** + * Set the file size of this attachment. + * + * @param int $size + * + * @return Swift_Mime_Attachment + */ + public function setSize($size) + { + $this->_setHeaderParameter('Content-Disposition', 'size', $size); + + return $this; + } + + /** + * Set the file that this attachment is for. + * + * @param Swift_FileStream $file + * @param string $contentType optional + * + * @return Swift_Mime_Attachment + */ + public function setFile(Swift_FileStream $file, $contentType = null) + { + $this->setFilename(basename($file->getPath())); + $this->setBody($file, $contentType); + if (!isset($contentType)) { + $extension = strtolower(substr( + $file->getPath(), strrpos($file->getPath(), '.') + 1 + )); + + if (array_key_exists($extension, $this->_mimeTypes)) { + $this->setContentType($this->_mimeTypes[$extension]); + } + } + + return $this; } - return $this; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php b/lib/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php index c26009f73..bfd41edfe 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php @@ -10,17 +10,17 @@ /** * Observes changes in an Mime entity's character set. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_CharsetObserver { - - /** - * Notify this observer that the entity's charset has changed. - * @param string $charset - */ - public function charsetChanged($charset); - + /** + * Notify this observer that the entity's charset has changed. + * + * @param string $charset + */ + public function charsetChanged($charset); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php index 6e02fec4d..67fbf94df 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php @@ -8,31 +8,29 @@ * file that was distributed with this source code. */ - /** * Interface for all Transfer Encoding schemes. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_ContentEncoder extends Swift_Encoder { - - /** - * Encode $in to $out. - * @param Swift_OutputByteStream $os to read from - * @param Swift_InputByteStream $is to write to - * @param int $firstLineOffset - * @param int $maxLineLength - 0 indicates the default length for this encoding - */ - public function encodeByteStream( - Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, - $maxLineLength = 0); - - /** - * Get the MIME name of this content encoding scheme. - * @return string - */ - public function getName(); - + /** + * Encode $in to $out. + * + * @param Swift_OutputByteStream $os to read from + * @param Swift_InputByteStream $is to write to + * @param int $firstLineOffset + * @param int $maxLineLength - 0 indicates the default length for this encoding + */ + public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0); + + /** + * Get the MIME name of this content encoding scheme. + * + * @return string + */ + public function getName(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php index 04e1155c5..ed9baf469 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php @@ -8,70 +8,62 @@ * file that was distributed with this source code. */ - /** * Handles Base 64 Transfer Encoding in Swift Mailer. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mime_ContentEncoder_Base64ContentEncoder - extends Swift_Encoder_Base64Encoder - implements Swift_Mime_ContentEncoder +class Swift_Mime_ContentEncoder_Base64ContentEncoder extends Swift_Encoder_Base64Encoder implements Swift_Mime_ContentEncoder { - - /** - * Encode stream $in to stream $out. - * @param Swift_OutputByteStream $in - * @param Swift_InputByteStream $out - * @param int $firstLineOffset - * @param int $maxLineLength, optional, 0 indicates the default of 76 bytes - */ - public function encodeByteStream( - Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, - $maxLineLength = 0) - { - if (0 >= $maxLineLength || 76 < $maxLineLength) + /** + * Encode stream $in to stream $out. + * + * @param Swift_OutputByteStream $os + * @param Swift_InputByteStream $is + * @param int $firstLineOffset + * @param int $maxLineLength, optional, 0 indicates the default of 76 bytes + */ + public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) { - $maxLineLength = 76; - } - - $remainder = 0; - - while (false !== $bytes = $os->read(8190)) - { - $encoded = base64_encode($bytes); - $encodedTransformed = ''; - $thisMaxLineLength = $maxLineLength - $remainder - $firstLineOffset; - - while ($thisMaxLineLength < strlen($encoded)) - { - $encodedTransformed .= substr($encoded, 0, $thisMaxLineLength) . "\r\n"; - $firstLineOffset = 0; - $encoded = substr($encoded, $thisMaxLineLength); - $thisMaxLineLength = $maxLineLength; + if (0 >= $maxLineLength || 76 < $maxLineLength) { + $maxLineLength = 76; + } + $remainder = 0; - } - - if (0 < $remainingLength = strlen($encoded)) - { - $remainder += $remainingLength; - $encodedTransformed .= $encoded; - $encoded = null; - } - - $is->write($encodedTransformed); + + while (false !== $bytes = $os->read(8190)) { + $encoded = base64_encode($bytes); + $encodedTransformed = ''; + $thisMaxLineLength = $maxLineLength - $remainder - $firstLineOffset; + + while ($thisMaxLineLength < strlen($encoded)) { + $encodedTransformed .= substr($encoded, 0, $thisMaxLineLength) . "\r\n"; + $firstLineOffset = 0; + $encoded = substr($encoded, $thisMaxLineLength); + $thisMaxLineLength = $maxLineLength; + $remainder = 0; + } + + if (0 < $remainingLength = strlen($encoded)) { + $remainder += $remainingLength; + $encodedTransformed .= $encoded; + $encoded = null; + } + + $is->write($encodedTransformed); + } + } + + /** + * Get the name of this encoding scheme. + * Returns the string 'base64'. + * + * @return string + */ + public function getName() + { + return 'base64'; } - } - - /** - * Get the name of this encoding scheme. - * Returns the string 'base64'. - * @return string - */ - public function getName() - { - return 'base64'; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php new file mode 100644 index 000000000..ce7c31ea8 --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php @@ -0,0 +1,125 @@ +charset = $charset ? $charset : 'utf-8'; + } + + /** + * Notify this observer that the entity's charset has changed. + * + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->charset = $charset; + } + + /** + * Encode $in to $out. + * + * @param Swift_OutputByteStream $os to read from + * @param Swift_InputByteStream $is to write to + * @param int $firstLineOffset + * @param int $maxLineLength 0 indicates the default length for this encoding + * + * @throws RuntimeException + */ + public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) + { + if ($this->charset !== 'utf-8') { + throw new RuntimeException( + sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset)); + } + + $string = ''; + + while (false !== $bytes = $os->read(8192)) { + $string .= $bytes; + } + + $is->write($this->encodeString($string)); + } + + /** + * Get the MIME name of this content encoding scheme. + * + * @return string + */ + public function getName() + { + return 'quoted-printable'; + } + + /** + * Encode a given string to produce an encoded string. + * + * @param string $string + * @param int $firstLineOffset if first line needs to be shorter + * @param int $maxLineLength 0 indicates the default length for this encoding + * + * @return string + * + * @throws RuntimeException + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) + { + if ($this->charset !== 'utf-8') { + throw new RuntimeException( + sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset)); + } + + return $this->_standardize(quoted_printable_encode($string)); + } + + /** + * Make sure CRLF is correct and HT/SPACE are in valid places. + * + * @param string $string + * + * @return string + */ + protected function _standardize($string) + { + // transform CR or LF to CRLF + $string = preg_replace('~=0D(?!=0A)|(?_name = $name; - $this->_canonical = $canonical; - } - - /** - * Encode a given string to produce an encoded string. - * @param string $string - * @param int $firstLineOffset, ignored - * @param int $maxLineLength - 0 means no wrapping will occur - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, - $maxLineLength = 0) - { - if ($this->_canonical) + /** + * The name of this encoding scheme (probably 7bit or 8bit). + * + * @var string + */ + private $_name; + + /** + * True if canonical transformations should be done. + * + * @var bool + */ + private $_canonical; + + /** + * Creates a new PlainContentEncoder with $name (probably 7bit or 8bit). + * + * @param string $name + * @param bool $canonical If canonicalization transformation should be done. + */ + public function __construct($name, $canonical = false) { - $string = $this->_canonicalize($string); + $this->_name = $name; + $this->_canonical = $canonical; } - return $this->_safeWordWrap($string, $maxLineLength, "\r\n"); - } - - /** - * Encode stream $in to stream $out. - * @param Swift_OutputByteStream $in - * @param Swift_InputByteStream $out - * @param int $firstLineOffset, ignored - * @param int $maxLineLength, optional, 0 means no wrapping will occur - */ - public function encodeByteStream( - Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, - $maxLineLength = 0) - { - $leftOver = ''; - while (false !== $bytes = $os->read(8192)) + + /** + * Encode a given string to produce an encoded string. + * + * @param string $string + * @param int $firstLineOffset ignored + * @param int $maxLineLength - 0 means no wrapping will occur + * + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) { - $toencode = $leftOver . $bytes; - if ($this->_canonical) - { - $toencode = $this->_canonicalize($toencode); - } - $wrapped = $this->_safeWordWrap($toencode, $maxLineLength, "\r\n"); - $lastLinePos = strrpos($wrapped, "\r\n"); - $leftOver = substr($wrapped, $lastLinePos); - $wrapped = substr($wrapped, 0, $lastLinePos); - - $is->write($wrapped); - } - if (strlen($leftOver)) - { - $is->write($leftOver); - } - } - - /** - * Get the name of this encoding scheme. - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * Not used. - */ - public function charsetChanged($charset) - { - } - - // -- Private methods - - /** - * A safer (but weaker) wordwrap for unicode. - * @param string $string - * @param int $length - * @param string $le - * @return string - * @access private - */ - private function _safeWordwrap($string, $length = 75, $le = "\r\n") - { - if (0 >= $length) - { - return $string; - } - - $originalLines = explode($le, $string); - - $lines = array(); - $lineCount = 0; - - foreach ($originalLines as $originalLine) - { - $lines[] = ''; - $currentLine =& $lines[$lineCount++]; - - //$chunks = preg_split('/(?<=[\ \t,\.!\?\-&\+\/])/', $originalLine); - $chunks = preg_split('/(?<=\s)/', $originalLine); - - foreach ($chunks as $chunk) - { - if (0 != strlen($currentLine) - && strlen($currentLine . $chunk) > $length) - { - $lines[] = ''; - $currentLine =& $lines[$lineCount++]; + if ($this->_canonical) { + $string = $this->_canonicalize($string); } - $currentLine .= $chunk; - } + + return $this->_safeWordWrap($string, $maxLineLength, "\r\n"); + } + + /** + * Encode stream $in to stream $out. + * + * @param Swift_OutputByteStream $os + * @param Swift_InputByteStream $is + * @param int $firstLineOffset ignored + * @param int $maxLineLength optional, 0 means no wrapping will occur + */ + public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) + { + $leftOver = ''; + while (false !== $bytes = $os->read(8192)) { + $toencode = $leftOver . $bytes; + if ($this->_canonical) { + $toencode = $this->_canonicalize($toencode); + } + $wrapped = $this->_safeWordWrap($toencode, $maxLineLength, "\r\n"); + $lastLinePos = strrpos($wrapped, "\r\n"); + $leftOver = substr($wrapped, $lastLinePos); + $wrapped = substr($wrapped, 0, $lastLinePos); + + $is->write($wrapped); + } + if (strlen($leftOver)) { + $is->write($leftOver); + } + } + + /** + * Get the name of this encoding scheme. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Not used. + */ + public function charsetChanged($charset) + { + } + + // -- Private methods + + /** + * A safer (but weaker) wordwrap for unicode. + * + * @param string $string + * @param int $length + * @param string $le + * + * @return string + */ + private function _safeWordwrap($string, $length = 75, $le = "\r\n") + { + if (0 >= $length) { + return $string; + } + + $originalLines = explode($le, $string); + + $lines = array(); + $lineCount = 0; + + foreach ($originalLines as $originalLine) { + $lines[] = ''; + $currentLine =& $lines[$lineCount++]; + + //$chunks = preg_split('/(?<=[\ \t,\.!\?\-&\+\/])/', $originalLine); + $chunks = preg_split('/(?<=\s)/', $originalLine); + + foreach ($chunks as $chunk) { + if (0 != strlen($currentLine) + && strlen($currentLine . $chunk) > $length) + { + $lines[] = ''; + $currentLine =& $lines[$lineCount++]; + } + $currentLine .= $chunk; + } + } + + return implode("\r\n", $lines); + } + + /** + * Canonicalize string input (fix CRLF). + * + * @param string $string + * + * @return string + */ + private function _canonicalize($string) + { + return str_replace( + array("\r\n", "\r", "\n"), + array("\n", "\n", "\r\n"), + $string + ); } - - return implode("\r\n", $lines); - } - - /** - * Canonicalize string input (fix CRLF). - * @param string $string - * @return string - * @access private - */ - private function _canonicalize($string) - { - return str_replace( - array("\r\n", "\r", "\n"), - array("\n", "\n", "\r\n"), - $string - ); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php index 87bcefc47..6df4a5f3f 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php @@ -8,110 +8,118 @@ * file that was distributed with this source code. */ - /** * Handles Quoted Printable (QP) Transfer Encoding in Swift Mailer. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mime_ContentEncoder_QpContentEncoder extends Swift_Encoder_QpEncoder - implements Swift_Mime_ContentEncoder +class Swift_Mime_ContentEncoder_QpContentEncoder extends Swift_Encoder_QpEncoder implements Swift_Mime_ContentEncoder { + protected $_dotEscape; - /** - * Creates a new QpContentEncoder for the given CharacterStream. - * @param Swift_CharacterStream $charStream to use for reading characters - * @param Swift_StreamFilter $filter if canonicalization should occur - * @param boolean $dotEscape if dot stuffing workaround must be enabled - */ - public function __construct(Swift_CharacterStream $charStream, - Swift_StreamFilter $filter = null, $dotEscape=false) - { - parent::__construct($charStream, $filter); - if ($dotEscape) { - /* Encode . as =2e for buggy remote servers */ - unset($this->_safeMap[0x2e]); - } - } - - /** - * Encode stream $in to stream $out. - * QP encoded strings have a maximum line length of 76 characters. - * If the first line needs to be shorter, indicate the difference with - * $firstLineOffset. - * @param Swift_OutputByteStream $os output stream - * @param Swift_InputByteStream $is input stream - * @param int $firstLineOffset - * @param int $maxLineLength - */ - public function encodeByteStream( - Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, - $maxLineLength = 0) - { - if ($maxLineLength > 76 || $maxLineLength <= 0) + /** + * Creates a new QpContentEncoder for the given CharacterStream. + * + * @param Swift_CharacterStream $charStream to use for reading characters + * @param Swift_StreamFilter $filter if canonicalization should occur + * @param bool $dotEscape if dot stuffing workaround must be enabled + */ + public function __construct(Swift_CharacterStream $charStream, Swift_StreamFilter $filter = null, $dotEscape = false) { - $maxLineLength = 76; + $this->_dotEscape = $dotEscape; + parent::__construct($charStream, $filter); } - $thisLineLength = $maxLineLength - $firstLineOffset; - - $this->_charStream->flushContents(); - $this->_charStream->importByteStream($os); - - $currentLine = ''; - $prepend = ''; - $size=$lineLen=0; - - while (false !== $bytes = $this->_nextSequence()) + public function __sleep() { - //If we're filtering the input - if (isset($this->_filter)) - { - //If we can't filter because we need more bytes - while ($this->_filter->shouldBuffer($bytes)) - { - //Then collect bytes into the buffer - if (false === $moreBytes = $this->_nextSequence(1)) - { - break; - } + return array('_charStream', '_filter', '_dotEscape'); + } - foreach ($moreBytes as $b) - { - $bytes[] = $b; - } + protected function getSafeMapShareId() + { + return get_class($this).($this->_dotEscape ? '.dotEscape' : ''); + } + + protected function initSafeMap() + { + parent::initSafeMap(); + if ($this->_dotEscape) { + /* Encode . as =2e for buggy remote servers */ + unset($this->_safeMap[0x2e]); } - //And filter them - $bytes = $this->_filter->filter($bytes); - } - - $enc = $this->_encodeByteSequence($bytes, $size); - if ($currentLine && $lineLen+$size >= $thisLineLength) - { - $is->write($prepend . $this->_standardize($currentLine)); - $currentLine = ''; - $prepend = "=\r\n"; - $thisLineLength = $maxLineLength; - $lineLen=0; - } - $lineLen+=$size; - $currentLine .= $enc; } - if (strlen($currentLine)) + + /** + * Encode stream $in to stream $out. + * + * QP encoded strings have a maximum line length of 76 characters. + * If the first line needs to be shorter, indicate the difference with + * $firstLineOffset. + * + * @param Swift_OutputByteStream $os output stream + * @param Swift_InputByteStream $is input stream + * @param int $firstLineOffset + * @param int $maxLineLength + */ + public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) { - $is->write($prepend . $this->_standardize($currentLine)); + if ($maxLineLength > 76 || $maxLineLength <= 0) { + $maxLineLength = 76; + } + + $thisLineLength = $maxLineLength - $firstLineOffset; + + $this->_charStream->flushContents(); + $this->_charStream->importByteStream($os); + + $currentLine = ''; + $prepend = ''; + $size=$lineLen=0; + + while (false !== $bytes = $this->_nextSequence()) { + // If we're filtering the input + if (isset($this->_filter)) { + // If we can't filter because we need more bytes + while ($this->_filter->shouldBuffer($bytes)) { + // Then collect bytes into the buffer + if (false === $moreBytes = $this->_nextSequence(1)) { + break; + } + + foreach ($moreBytes as $b) { + $bytes[] = $b; + } + } + // And filter them + $bytes = $this->_filter->filter($bytes); + } + + $enc = $this->_encodeByteSequence($bytes, $size); + if ($currentLine && $lineLen+$size >= $thisLineLength) { + $is->write($prepend . $this->_standardize($currentLine)); + $currentLine = ''; + $prepend = "=\r\n"; + $thisLineLength = $maxLineLength; + $lineLen=0; + } + $lineLen+=$size; + $currentLine .= $enc; + } + if (strlen($currentLine)) { + $is->write($prepend . $this->_standardize($currentLine)); + } } - } - - /** - * Get the name of this encoding scheme. - * Returns the string 'quoted-printable'. - * @return string - */ - public function getName() - { - return 'quoted-printable'; - } + /** + * Get the name of this encoding scheme. + * Returns the string 'quoted-printable'. + * + * @return string + */ + public function getName() + { + return 'quoted-printable'; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php new file mode 100644 index 000000000..491409acd --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php @@ -0,0 +1,90 @@ + + */ +class Swift_Mime_ContentEncoder_QpContentEncoderProxy implements Swift_Mime_ContentEncoder +{ + /** + * @var Swift_Mime_ContentEncoder_QpContentEncoder + */ + private $safeEncoder; + + /** + * @var Swift_Mime_ContentEncoder_NativeQpContentEncoder + */ + private $nativeEncoder; + + /** + * @var null|string + */ + private $charset; + + /** + * Constructor. + * + * @param Swift_Mime_ContentEncoder_QpContentEncoder $safeEncoder + * @param Swift_Mime_ContentEncoder_NativeQpContentEncoder $nativeEncoder + * @param string|null $charset + */ + public function __construct(Swift_Mime_ContentEncoder_QpContentEncoder $safeEncoder, Swift_Mime_ContentEncoder_NativeQpContentEncoder $nativeEncoder, $charset) + { + $this->safeEncoder = $safeEncoder; + $this->nativeEncoder = $nativeEncoder; + $this->charset = $charset; + } + + /** + * {@inheritdoc} + */ + public function charsetChanged($charset) + { + $this->charset = $charset; + } + + /** + * {@inheritdoc} + */ + public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) + { + $this->getEncoder()->encodeByteStream($os, $is, $firstLineOffset, $maxLineLength); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'quoted-printable'; + } + + /** + * {@inheritdoc} + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) + { + return $this->getEncoder()->encodeString($string, $firstLineOffset, $maxLineLength); + } + + /** + * @return Swift_Mime_ContentEncoder + */ + private function getEncoder() + { + return 'utf-8' === $this->charset ? $this->nativeEncoder : $this->safeEncoder; + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php new file mode 100644 index 000000000..8f1f9b575 --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/RawContentEncoder.php @@ -0,0 +1,65 @@ + + */ +class Swift_Mime_ContentEncoder_RawContentEncoder implements Swift_Mime_ContentEncoder +{ + /** + * Encode a given string to produce an encoded string. + * + * @param string $string + * @param int $firstLineOffset ignored + * @param int $maxLineLength ignored + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) + { + return $string; + } + + /** + * Encode stream $in to stream $out. + * + * @param Swift_OutputByteStream $in + * @param Swift_InputByteStream $out + * @param int $firstLineOffset ignored + * @param int $maxLineLength ignored + */ + public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) + { + while (false !== ($bytes = $os->read(8192))) { + $is->write($bytes); + } + } + + /** + * Get the name of this encoding scheme. + * + * @return string + */ + public function getName() + { + return 'raw'; + } + + /** + * Not used. + */ + public function charsetChanged($charset) + { + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php b/lib/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php index 529de7f91..9079fabf5 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/EmbeddedFile.php @@ -8,41 +8,40 @@ * file that was distributed with this source code. */ - /** * An embedded file, in a multipart message. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_EmbeddedFile extends Swift_Mime_Attachment { - - /** - * Creates a new Attachment with $headers and $encoder. - * @param Swift_Mime_HeaderSet $headers - * @param Swift_Mime_ContentEncoder $encoder - * @param Swift_KeyCache $cache - * @param Swift_Mime_Grammar $grammar - * @param array $mimeTypes optional - */ - public function __construct(Swift_Mime_HeaderSet $headers, - Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, - Swift_Mime_Grammar $grammar, $mimeTypes = array()) - { - parent::__construct($headers, $encoder, $cache, $grammar, $mimeTypes); - $this->setDisposition('inline'); - $this->setId($this->getId()); - } - - /** - * Get the nesting level of this EmbeddedFile. - * Returns {@link LEVEL_RELATED}. - * @return int - */ - public function getNestingLevel() - { - return self::LEVEL_RELATED; - } - + /** + * Creates a new Attachment with $headers and $encoder. + * + * @param Swift_Mime_HeaderSet $headers + * @param Swift_Mime_ContentEncoder $encoder + * @param Swift_KeyCache $cache + * @param Swift_Mime_Grammar $grammar + * @param array $mimeTypes optional + */ + public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $mimeTypes = array()) + { + parent::__construct($headers, $encoder, $cache, $grammar, $mimeTypes); + $this->setDisposition('inline'); + $this->setId($this->getId()); + } + + /** + * Get the nesting level of this EmbeddedFile. + * + * Returns {@see LEVEL_RELATED}. + * + * @return int + */ + public function getNestingLevel() + { + return self::LEVEL_RELATED; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php b/lib/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php index 021cabd0f..e7e6f20d6 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php @@ -8,20 +8,19 @@ * file that was distributed with this source code. */ - /** * Observes changes for a Mime entity's ContentEncoder. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_EncodingObserver { - - /** - * Notify this observer that the observed entity's ContentEncoder has changed. - * @param Swift_Mime_ContentEncoder $encoder - */ - public function encoderChanged(Swift_Mime_ContentEncoder $encoder); - + /** + * Notify this observer that the observed entity's ContentEncoder has changed. + * + * @param Swift_Mime_ContentEncoder $encoder + */ + public function encoderChanged(Swift_Mime_ContentEncoder $encoder); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Grammar.php b/lib/swiftmailer/lib/classes/Swift/Mime/Grammar.php index e3f7d301e..9b0670741 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Grammar.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Grammar.php @@ -10,154 +10,169 @@ /** * Defines the grammar to use for validation, implements the RFC 2822 (and friends) ABNF grammar definitions. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Fabien Potencier - * @author Chris Corbyn + * @author Fabien Potencier + * @author Chris Corbyn */ class Swift_Mime_Grammar { - /** - * Special characters used in the syntax which need to be escaped. - * @var string[] - * @access private - */ - private $_specials = array(); + /** + * Special characters used in the syntax which need to be escaped. + * + * @var string[] + */ + private static $_specials = array(); - /** - * Tokens defined in RFC 2822 (and some related RFCs). - * @var string[] - * @access private - */ - private $_grammar = array(); - - /** - * Initialize some RFC 2822 (and friends) ABNF grammar definitions. - * @access protected - */ - public function __construct() - { - $this->_specials = array( - '(', ')', '<', '>', '[', ']', - ':', ';', '@', ',', '.', '"' - ); - - /*** Refer to RFC 2822 for ABNF grammar ***/ - - //All basic building blocks - $this->_grammar['NO-WS-CTL'] = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]'; - $this->_grammar['WSP'] = '[ \t]'; - $this->_grammar['CRLF'] = '(?:\r\n)'; - $this->_grammar['FWS'] = '(?:(?:' . $this->_grammar['WSP'] . '*' . - $this->_grammar['CRLF'] . ')?' . $this->_grammar['WSP'] . ')'; - $this->_grammar['text'] = '[\x00-\x08\x0B\x0C\x0E-\x7F]'; - $this->_grammar['quoted-pair'] = '(?:\\\\' . $this->_grammar['text'] . ')'; - $this->_grammar['ctext'] = '(?:' . $this->_grammar['NO-WS-CTL'] . - '|[\x21-\x27\x2A-\x5B\x5D-\x7E])'; - //Uses recursive PCRE (?1) -- could be a weak point?? - $this->_grammar['ccontent'] = '(?:' . $this->_grammar['ctext'] . '|' . - $this->_grammar['quoted-pair'] . '|(?1))'; - $this->_grammar['comment'] = '(\((?:' . $this->_grammar['FWS'] . '|' . - $this->_grammar['ccontent']. ')*' . $this->_grammar['FWS'] . '?\))'; - $this->_grammar['CFWS'] = '(?:(?:' . $this->_grammar['FWS'] . '?' . - $this->_grammar['comment'] . ')*(?:(?:' . $this->_grammar['FWS'] . '?' . - $this->_grammar['comment'] . ')|' . $this->_grammar['FWS'] . '))'; - $this->_grammar['qtext'] = '(?:' . $this->_grammar['NO-WS-CTL'] . - '|[\x21\x23-\x5B\x5D-\x7E])'; - $this->_grammar['qcontent'] = '(?:' . $this->_grammar['qtext'] . '|' . - $this->_grammar['quoted-pair'] . ')'; - $this->_grammar['quoted-string'] = '(?:' . $this->_grammar['CFWS'] . '?"' . - '(' . $this->_grammar['FWS'] . '?' . $this->_grammar['qcontent'] . ')*' . - $this->_grammar['FWS'] . '?"' . $this->_grammar['CFWS'] . '?)'; - $this->_grammar['atext'] = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]'; - $this->_grammar['atom'] = '(?:' . $this->_grammar['CFWS'] . '?' . - $this->_grammar['atext'] . '+' . $this->_grammar['CFWS'] . '?)'; - $this->_grammar['dot-atom-text'] = '(?:' . $this->_grammar['atext'] . '+' . - '(\.' . $this->_grammar['atext'] . '+)*)'; - $this->_grammar['dot-atom'] = '(?:' . $this->_grammar['CFWS'] . '?' . - $this->_grammar['dot-atom-text'] . '+' . $this->_grammar['CFWS'] . '?)'; - $this->_grammar['word'] = '(?:' . $this->_grammar['atom'] . '|' . - $this->_grammar['quoted-string'] . ')'; - $this->_grammar['phrase'] = '(?:' . $this->_grammar['word'] . '+?)'; - $this->_grammar['no-fold-quote'] = '(?:"(?:' . $this->_grammar['qtext'] . - '|' . $this->_grammar['quoted-pair'] . ')*")'; - $this->_grammar['dtext'] = '(?:' . $this->_grammar['NO-WS-CTL'] . - '|[\x21-\x5A\x5E-\x7E])'; - $this->_grammar['no-fold-literal'] = '(?:\[(?:' . $this->_grammar['dtext'] . - '|' . $this->_grammar['quoted-pair'] . ')*\])'; - - //Message IDs - $this->_grammar['id-left'] = '(?:' . $this->_grammar['dot-atom-text'] . '|' . - $this->_grammar['no-fold-quote'] . ')'; - $this->_grammar['id-right'] = '(?:' . $this->_grammar['dot-atom-text'] . '|' . - $this->_grammar['no-fold-literal'] . ')'; - - //Addresses, mailboxes and paths - $this->_grammar['local-part'] = '(?:' . $this->_grammar['dot-atom'] . '|' . - $this->_grammar['quoted-string'] . ')'; - $this->_grammar['dcontent'] = '(?:' . $this->_grammar['dtext'] . '|' . - $this->_grammar['quoted-pair'] . ')'; - $this->_grammar['domain-literal'] = '(?:' . $this->_grammar['CFWS'] . '?\[(' . - $this->_grammar['FWS'] . '?' . $this->_grammar['dcontent'] . ')*?' . - $this->_grammar['FWS'] . '?\]' . $this->_grammar['CFWS'] . '?)'; - $this->_grammar['domain'] = '(?:' . $this->_grammar['dot-atom'] . '|' . - $this->_grammar['domain-literal'] . ')'; - $this->_grammar['addr-spec'] = '(?:' . $this->_grammar['local-part'] . '@' . - $this->_grammar['domain'] . ')'; - } - - /** - * Get the grammar defined for $name token. - * @param string $name execatly as written in the RFC - * @return string - */ - public function getDefinition($name) - { - if (array_key_exists($name, $this->_grammar)) + /** + * Tokens defined in RFC 2822 (and some related RFCs). + * + * @var string[] + */ + private static $_grammar = array(); + + /** + * Initialize some RFC 2822 (and friends) ABNF grammar definitions. + */ + public function __construct() { - return $this->_grammar[$name]; + $this->init(); } - else + + public function __wakeup() { - throw new Swift_RfcComplianceException( - "No such grammar '" . $name . "' defined." - ); + $this->init(); } - } - - /** - * Returns the tokens defined in RFC 2822 (and some related RFCs). - * @return array - */ - public function getGrammarDefinitions() - { - return $this->_grammar; - } - - /** - * Returns the current special characters used in the syntax which need to be escaped. - * @return array - */ - public function getSpecials() - { - return $this->_specials; - } - - /** - * Escape special characters in a string (convert to quoted-pairs). - * @param string $token - * @param string[] $include additonal chars to escape - * @param string[] $exclude chars from escaping - * @return string - */ - public function escapeSpecials($token, $include = array(), - $exclude = array()) - { - foreach ( - array_merge(array('\\'), array_diff($this->_specials, $exclude), $include) as $char) + + protected function init() { - $token = str_replace($char, '\\' . $char, $token); + if (count(self::$_specials) > 0) { + return; + } + + self::$_specials = array( + '(', ')', '<', '>', '[', ']', + ':', ';', '@', ',', '.', '"' + ); + + /*** Refer to RFC 2822 for ABNF grammar ***/ + + // All basic building blocks + self::$_grammar['NO-WS-CTL'] = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]'; + self::$_grammar['WSP'] = '[ \t]'; + self::$_grammar['CRLF'] = '(?:\r\n)'; + self::$_grammar['FWS'] = '(?:(?:' . self::$_grammar['WSP'] . '*' . + self::$_grammar['CRLF'] . ')?' . self::$_grammar['WSP'] . ')'; + self::$_grammar['text'] = '[\x00-\x08\x0B\x0C\x0E-\x7F]'; + self::$_grammar['quoted-pair'] = '(?:\\\\' . self::$_grammar['text'] . ')'; + self::$_grammar['ctext'] = '(?:' . self::$_grammar['NO-WS-CTL'] . + '|[\x21-\x27\x2A-\x5B\x5D-\x7E])'; + // Uses recursive PCRE (?1) -- could be a weak point?? + self::$_grammar['ccontent'] = '(?:' . self::$_grammar['ctext'] . '|' . + self::$_grammar['quoted-pair'] . '|(?1))'; + self::$_grammar['comment'] = '(\((?:' . self::$_grammar['FWS'] . '|' . + self::$_grammar['ccontent']. ')*' . self::$_grammar['FWS'] . '?\))'; + self::$_grammar['CFWS'] = '(?:(?:' . self::$_grammar['FWS'] . '?' . + self::$_grammar['comment'] . ')*(?:(?:' . self::$_grammar['FWS'] . '?' . + self::$_grammar['comment'] . ')|' . self::$_grammar['FWS'] . '))'; + self::$_grammar['qtext'] = '(?:' . self::$_grammar['NO-WS-CTL'] . + '|[\x21\x23-\x5B\x5D-\x7E])'; + self::$_grammar['qcontent'] = '(?:' . self::$_grammar['qtext'] . '|' . + self::$_grammar['quoted-pair'] . ')'; + self::$_grammar['quoted-string'] = '(?:' . self::$_grammar['CFWS'] . '?"' . + '(' . self::$_grammar['FWS'] . '?' . self::$_grammar['qcontent'] . ')*' . + self::$_grammar['FWS'] . '?"' . self::$_grammar['CFWS'] . '?)'; + self::$_grammar['atext'] = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]'; + self::$_grammar['atom'] = '(?:' . self::$_grammar['CFWS'] . '?' . + self::$_grammar['atext'] . '+' . self::$_grammar['CFWS'] . '?)'; + self::$_grammar['dot-atom-text'] = '(?:' . self::$_grammar['atext'] . '+' . + '(\.' . self::$_grammar['atext'] . '+)*)'; + self::$_grammar['dot-atom'] = '(?:' . self::$_grammar['CFWS'] . '?' . + self::$_grammar['dot-atom-text'] . '+' . self::$_grammar['CFWS'] . '?)'; + self::$_grammar['word'] = '(?:' . self::$_grammar['atom'] . '|' . + self::$_grammar['quoted-string'] . ')'; + self::$_grammar['phrase'] = '(?:' . self::$_grammar['word'] . '+?)'; + self::$_grammar['no-fold-quote'] = '(?:"(?:' . self::$_grammar['qtext'] . + '|' . self::$_grammar['quoted-pair'] . ')*")'; + self::$_grammar['dtext'] = '(?:' . self::$_grammar['NO-WS-CTL'] . + '|[\x21-\x5A\x5E-\x7E])'; + self::$_grammar['no-fold-literal'] = '(?:\[(?:' . self::$_grammar['dtext'] . + '|' . self::$_grammar['quoted-pair'] . ')*\])'; + + // Message IDs + self::$_grammar['id-left'] = '(?:' . self::$_grammar['dot-atom-text'] . '|' . + self::$_grammar['no-fold-quote'] . ')'; + self::$_grammar['id-right'] = '(?:' . self::$_grammar['dot-atom-text'] . '|' . + self::$_grammar['no-fold-literal'] . ')'; + + // Addresses, mailboxes and paths + self::$_grammar['local-part'] = '(?:' . self::$_grammar['dot-atom'] . '|' . + self::$_grammar['quoted-string'] . ')'; + self::$_grammar['dcontent'] = '(?:' . self::$_grammar['dtext'] . '|' . + self::$_grammar['quoted-pair'] . ')'; + self::$_grammar['domain-literal'] = '(?:' . self::$_grammar['CFWS'] . '?\[(' . + self::$_grammar['FWS'] . '?' . self::$_grammar['dcontent'] . ')*?' . + self::$_grammar['FWS'] . '?\]' . self::$_grammar['CFWS'] . '?)'; + self::$_grammar['domain'] = '(?:' . self::$_grammar['dot-atom'] . '|' . + self::$_grammar['domain-literal'] . ')'; + self::$_grammar['addr-spec'] = '(?:' . self::$_grammar['local-part'] . '@' . + self::$_grammar['domain'] . ')'; + } + + /** + * Get the grammar defined for $name token. + * + * @param string $name exactly as written in the RFC + * + * @return string + */ + public function getDefinition($name) + { + if (array_key_exists($name, self::$_grammar)) { + return self::$_grammar[$name]; + } else { + throw new Swift_RfcComplianceException( + "No such grammar '" . $name . "' defined." + ); + } + } + + /** + * Returns the tokens defined in RFC 2822 (and some related RFCs). + * + * @return array + */ + public function getGrammarDefinitions() + { + return self::$_grammar; + } + + /** + * Returns the current special characters used in the syntax which need to be escaped. + * + * @return array + */ + public function getSpecials() + { + return self::$_specials; + } + + /** + * Escape special characters in a string (convert to quoted-pairs). + * + * @param string $token + * @param string[] $include additional chars to escape + * @param string[] $exclude chars from escaping + * + * @return string + */ + public function escapeSpecials($token, $include = array(), $exclude = array()) + { + foreach (array_merge(array('\\'), array_diff(self::$_specials, $exclude), $include) as $char) { + $token = str_replace($char, '\\' . $char, $token); + } + + return $token; } - return $token; - } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Header.php b/lib/swiftmailer/lib/classes/Swift/Mime/Header.php index 38fc40cde..8a3d05f83 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Header.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Header.php @@ -10,76 +10,86 @@ /** * A MIME Header. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_Header { - - /** Text headers */ - const TYPE_TEXT = 2; - - /** Parameterized headers (text + params) */ - const TYPE_PARAMETERIZED = 6; + /** Text headers */ + const TYPE_TEXT = 2; - /** Mailbox and address headers */ - const TYPE_MAILBOX = 8; - - /** Date and time headers */ - const TYPE_DATE = 16; - - /** Identification headers */ - const TYPE_ID = 32; - - /** Address path headers */ - const TYPE_PATH = 64; - - /** - * Get the type of Header that this instance represents. - * @return int - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - */ - public function getFieldType(); - - /** - * Set the model for the field body. - * The actual types needed will vary depending upon the type of Header. - * @param mixed $model - */ - public function setFieldBodyModel($model); - - /** - * Set the charset used when rendering the Header. - * @param string $charset - */ - public function setCharset($charset); - - /** - * Get the model for the field body. - * The return type depends on the specifics of the Header. - * @return mixed - */ - public function getFieldBodyModel(); - - /** - * Get the name of this header (e.g. Subject). - * The name is an identifier and as such will be immutable. - * @return string - */ - public function getFieldName(); - - /** - * Get the field body, prepared for folding into a final header value. - * @return string - */ - public function getFieldBody(); - - /** - * Get this Header rendered as a compliant string. - * @return string - */ - public function toString(); - + /** headers (text + params) */ + const TYPE_PARAMETERIZED = 6; + + /** Mailbox and address headers */ + const TYPE_MAILBOX = 8; + + /** Date and time headers */ + const TYPE_DATE = 16; + + /** Identification headers */ + const TYPE_ID = 32; + + /** Address path headers */ + const TYPE_PATH = 64; + + /** + * Get the type of Header that this instance represents. + * + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + * + * @return int + */ + public function getFieldType(); + + /** + * Set the model for the field body. + * + * The actual types needed will vary depending upon the type of Header. + * + * @param mixed $model + */ + public function setFieldBodyModel($model); + + /** + * Set the charset used when rendering the Header. + * + * @param string $charset + */ + public function setCharset($charset); + + /** + * Get the model for the field body. + * + * The return type depends on the specifics of the Header. + * + * @return mixed + */ + public function getFieldBodyModel(); + + /** + * Get the name of this header (e.g. Subject). + * + * The name is an identifier and as such will be immutable. + * + * @return string + */ + public function getFieldName(); + + /** + * Get the field body, prepared for folding into a final header value. + * + * @return string + */ + public function getFieldBody(); + + /** + * Get this Header rendered as a compliant string. + * + * @return string + */ + public function toString(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php index 023f36779..4aff4dc95 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php @@ -8,20 +8,19 @@ * file that was distributed with this source code. */ - /** * Interface for all Header Encoding schemes. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_HeaderEncoder extends Swift_Encoder { - - /** - * Get the MIME name of this content encoding scheme. - * @return string - */ - public function getName(); - + /** + * Get the MIME name of this content encoding scheme. + * + * @return string + */ + public function getName(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php index feaba981c..7a57e3f74 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/Base64HeaderEncoder.php @@ -8,29 +8,50 @@ * file that was distributed with this source code. */ -require_once dirname(__FILE__) . '/../HeaderEncoder.php'; -require_once dirname(__FILE__) . '/../../Encoder/Base64Encoder.php'; - - /** * Handles Base64 (B) Header Encoding in Swift Mailer. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mime_HeaderEncoder_Base64HeaderEncoder - extends Swift_Encoder_Base64Encoder - implements Swift_Mime_HeaderEncoder +class Swift_Mime_HeaderEncoder_Base64HeaderEncoder extends Swift_Encoder_Base64Encoder implements Swift_Mime_HeaderEncoder { - - /** - * Get the name of this encoding scheme. - * Returns the string 'B'. - * @return string - */ - public function getName() - { - return 'B'; - } - + /** + * Get the name of this encoding scheme. + * Returns the string 'B'. + * + * @return string + */ + public function getName() + { + return 'B'; + } + + /** + * Takes an unencoded string and produces a Base64 encoded string from it. + * + * If the charset is iso-2022-jp, it uses mb_encode_mimeheader instead of + * default encodeString, otherwise pass to the parent method. + * + * @param string $string string to encode + * @param int $firstLineOffset + * @param int $maxLineLength optional, 0 indicates the default of 76 bytes + * @param string $charset + * + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0, $charset = 'utf-8') + { + if (strtolower($charset) === 'iso-2022-jp') { + $old = mb_internal_encoding(); + mb_internal_encoding('utf-8'); + $newstring = mb_encode_mimeheader($string, $charset, $this->getName(), "\r\n"); + mb_internal_encoding($old); + + return $newstring; + } + + return parent::encodeString($string, $firstLineOffset, $maxLineLength); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php index 9c4066d0b..1527f4ff9 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php @@ -8,61 +8,60 @@ * file that was distributed with this source code. */ -require_once dirname(__FILE__) . '/../HeaderEncoder.php'; -require_once dirname(__FILE__) . '/../../Encoder/QpEncoder.php'; -require_once dirname(__FILE__) . '/../../CharacterStream.php'; - /** * Handles Quoted Printable (Q) Header Encoding in Swift Mailer. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mime_HeaderEncoder_QpHeaderEncoder extends Swift_Encoder_QpEncoder - implements Swift_Mime_HeaderEncoder +class Swift_Mime_HeaderEncoder_QpHeaderEncoder extends Swift_Encoder_QpEncoder implements Swift_Mime_HeaderEncoder { - - /** - * Creates a new QpHeaderEncoder for the given CharacterStream. - * @param Swift_CharacterStream $charStream to use for reading characters - */ - public function __construct(Swift_CharacterStream $charStream) - { - parent::__construct($charStream); - // Reset the safeMap - $this->_safeMap=array(); - foreach (array_merge( - range(0x61, 0x7A), range(0x41, 0x5A), - range(0x30, 0x39), array(0x20, 0x21, 0x2A, 0x2B, 0x2D, 0x2F) - ) as $byte) + /** + * Creates a new QpHeaderEncoder for the given CharacterStream. + * + * @param Swift_CharacterStream $charStream to use for reading characters + */ + public function __construct(Swift_CharacterStream $charStream) { - $this->_safeMap[$byte] = chr($byte); + parent::__construct($charStream); } - } - /** - * Get the name of this encoding scheme. - * Returns the string 'Q'. - * @return string - */ - public function getName() - { - return 'Q'; - } + protected function initSafeMap() + { + foreach (array_merge( + range(0x61, 0x7A), range(0x41, 0x5A), + range(0x30, 0x39), array(0x20, 0x21, 0x2A, 0x2B, 0x2D, 0x2F) + ) as $byte) { + $this->_safeMap[$byte] = chr($byte); + } + } - /** - * Takes an unencoded string and produces a Q encoded string from it. - * @param string $string to encode - * @param int $firstLineOffset, optional - * @param int $maxLineLength, optional, 0 indicates the default of 76 chars - * @return string - */ - public function encodeString($string, $firstLineOffset = 0, - $maxLineLength = 0) - { - return str_replace(array(' ', '=20', "=\r\n"), array('_', '_', "\r\n"), - parent::encodeString($string, $firstLineOffset, $maxLineLength) - ); - } + /** + * Get the name of this encoding scheme. + * + * Returns the string 'Q'. + * + * @return string + */ + public function getName() + { + return 'Q'; + } + /** + * Takes an unencoded string and produces a QP encoded string from it. + * + * @param string $string string to encode + * @param int $firstLineOffset optional + * @param int $maxLineLength optional, 0 indicates the default of 76 chars + * + * @return string + */ + public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) + { + return str_replace(array(' ', '=20', "=\r\n"), array('_', '_', "\r\n"), + parent::encodeString($string, $firstLineOffset, $maxLineLength) + ); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php index 13083bb0a..40a1e1739 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php @@ -8,64 +8,73 @@ * file that was distributed with this source code. */ - /** * Creates MIME headers. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_HeaderFactory extends Swift_Mime_CharsetObserver { - - /** - * Create a new Mailbox Header with a list of $addresses. - * @param string $name - * @param array|string $addresses - * @return Swift_Mime_Header - */ - public function createMailboxHeader($name, $addresses = null); - - /** - * Create a new Date header using $timestamp (UNIX time). - * @param string $name - * @param int $timestamp - * @return Swift_Mime_Header - */ - public function createDateHeader($name, $timestamp = null); - - /** - * Create a new basic text header with $name and $value. - * @param string $name - * @param string $value - * @return Swift_Mime_Header - */ - public function createTextHeader($name, $value = null); - - /** - * Create a new ParameterizedHeader with $name, $value and $params. - * @param string $name - * @param string $value - * @param array $params - * @return Swift_Mime_ParameterizedHeader - */ - public function createParameterizedHeader($name, $value = null, - $params = array()); - - /** - * Create a new ID header for Message-ID or Content-ID. - * @param string $name - * @param string|array $ids - * @return Swift_Mime_Header - */ - public function createIdHeader($name, $ids = null); - - /** - * Create a new Path header with an address (path) in it. - * @param string $name - * @param string $path - * @return Swift_Mime_Header - */ - public function createPathHeader($name, $path = null); - + /** + * Create a new Mailbox Header with a list of $addresses. + * + * @param string $name + * @param array|string $addresses + * + * @return Swift_Mime_Header + */ + public function createMailboxHeader($name, $addresses = null); + + /** + * Create a new Date header using $timestamp (UNIX time). + * + * @param string $name + * @param int $timestamp + * + * @return Swift_Mime_Header + */ + public function createDateHeader($name, $timestamp = null); + + /** + * Create a new basic text header with $name and $value. + * + * @param string $name + * @param string $value + * + * @return Swift_Mime_Header + */ + public function createTextHeader($name, $value = null); + + /** + * Create a new ParameterizedHeader with $name, $value and $params. + * + * @param string $name + * @param string $value + * @param array $params + * + * @return Swift_Mime_ParameterizedHeader + */ + public function createParameterizedHeader($name, $value = null, $params = array()); + + /** + * Create a new ID header for Message-ID or Content-ID. + * + * @param string $name + * @param string|array $ids + * + * @return Swift_Mime_Header + */ + public function createIdHeader($name, $ids = null); + + /** + * Create a new Path header with an address (path) in it. + * + * @param string $name + * @param string $path + * + * @return Swift_Mime_Header + */ + public function createPathHeader($name, $path = null); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php index 65895091d..309bcd861 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php @@ -8,162 +8,164 @@ * file that was distributed with this source code. */ - /** * A collection of MIME headers. - * - * @package Swift + * + * @package Swift * @subpackage Mime - * - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_HeaderSet extends Swift_Mime_CharsetObserver { - - /** - * Add a new Mailbox Header with a list of $addresses. - * - * @param string $name - * @param array|string $addresses - */ - public function addMailboxHeader($name, $addresses = null); - - /** - * Add a new Date header using $timestamp (UNIX time). - * - * @param string $name - * @param int $timestamp - */ - public function addDateHeader($name, $timestamp = null); - - /** - * Add a new basic text header with $name and $value. - * - * @param string $name - * @param string $value - */ - public function addTextHeader($name, $value = null); - - /** - * Add a new ParameterizedHeader with $name, $value and $params. - * - * @param string $name - * @param string $value - * @param array $params - */ - public function addParameterizedHeader($name, $value = null, - $params = array()); - - /** - * Add a new ID header for Message-ID or Content-ID. - * - * @param string $name - * @param string|array $ids - */ - public function addIdHeader($name, $ids = null); - - /** - * Add a new Path header with an address (path) in it. - * - * @param string $name - * @param string $path - */ - public function addPathHeader($name, $path = null); - - /** - * Returns true if at least one header with the given $name exists. - * - * If multiple headers match, the actual one may be specified by $index. - * - * @param string $name - * @param int $index - * - * @return boolean - */ - public function has($name, $index = 0); - - /** - * Set a header in the HeaderSet. - * - * The header may be a previously fetched header via {@link get()} or it may - * be one that has been created separately. - * - * If $index is specified, the header will be inserted into the set at this - * offset. - * - * @param Swift_Mime_Header $header - * @param int $index - */ - public function set(Swift_Mime_Header $header, $index = 0); - - /** - * Get the header with the given $name. - * If multiple headers match, the actual one may be specified by $index. - * Returns NULL if none present. - * - * @param string $name - * @param int $index - * - * @return Swift_Mime_Header - */ - public function get($name, $index = 0); - - /** - * Get all headers with the given $name. - * - * @param string $name - * - * @return array - */ - public function getAll($name = null); - - /** - * Remove the header with the given $name if it's set. - * - * If multiple headers match, the actual one may be specified by $index. - * - * @param string $name - * @param int $index - */ - public function remove($name, $index = 0); - - /** - * Remove all headers with the given $name. - * - * @param string $name - */ - public function removeAll($name); - - /** - * Create a new instance of this HeaderSet. - * - * @return Swift_Mime_HeaderSet - */ - public function newInstance(); - - /** - * Define a list of Header names as an array in the correct order. - * - * These Headers will be output in the given order where present. - * - * @param array $sequence - */ - public function defineOrdering(array $sequence); - - /** - * Set a list of header names which must always be displayed when set. - * - * Usually headers without a field value won't be output unless set here. - * - * @param array $names - */ - public function setAlwaysDisplayed(array $names); - - /** - * Returns a string with a representation of all headers. - * - * @return string - */ - public function toString(); - + /** + * Add a new Mailbox Header with a list of $addresses. + * + * @param string $name + * @param array|string $addresses + */ + public function addMailboxHeader($name, $addresses = null); + + /** + * Add a new Date header using $timestamp (UNIX time). + * + * @param string $name + * @param int $timestamp + */ + public function addDateHeader($name, $timestamp = null); + + /** + * Add a new basic text header with $name and $value. + * + * @param string $name + * @param string $value + */ + public function addTextHeader($name, $value = null); + + /** + * Add a new ParameterizedHeader with $name, $value and $params. + * + * @param string $name + * @param string $value + * @param array $params + */ + public function addParameterizedHeader($name, $value = null, $params = array()); + + /** + * Add a new ID header for Message-ID or Content-ID. + * + * @param string $name + * @param string|array $ids + */ + public function addIdHeader($name, $ids = null); + + /** + * Add a new Path header with an address (path) in it. + * + * @param string $name + * @param string $path + */ + public function addPathHeader($name, $path = null); + + /** + * Returns true if at least one header with the given $name exists. + * + * If multiple headers match, the actual one may be specified by $index. + * + * @param string $name + * @param int $index + * + * @return bool + */ + public function has($name, $index = 0); + + /** + * Set a header in the HeaderSet. + * + * The header may be a previously fetched header via {@link get()} or it may + * be one that has been created separately. + * + * If $index is specified, the header will be inserted into the set at this + * offset. + * + * @param Swift_Mime_Header $header + * @param int $index + */ + public function set(Swift_Mime_Header $header, $index = 0); + + /** + * Get the header with the given $name. + * If multiple headers match, the actual one may be specified by $index. + * Returns NULL if none present. + * + * @param string $name + * @param int $index + * + * @return Swift_Mime_Header + */ + public function get($name, $index = 0); + + /** + * Get all headers with the given $name. + * + * @param string $name + * + * @return array + */ + public function getAll($name = null); + + /** + * Return the name of all Headers + * + * @return array + */ + public function listAll(); + + /** + * Remove the header with the given $name if it's set. + * + * If multiple headers match, the actual one may be specified by $index. + * + * @param string $name + * @param int $index + */ + public function remove($name, $index = 0); + + /** + * Remove all headers with the given $name. + * + * @param string $name + */ + public function removeAll($name); + + /** + * Create a new instance of this HeaderSet. + * + * @return Swift_Mime_HeaderSet + */ + public function newInstance(); + + /** + * Define a list of Header names as an array in the correct order. + * + * These Headers will be output in the given order where present. + * + * @param array $sequence + */ + public function defineOrdering(array $sequence); + + /** + * Set a list of header names which must always be displayed when set. + * + * Usually headers without a field value won't be output unless set here. + * + * @param array $names + */ + public function setAlwaysDisplayed(array $names); + + /** + * Returns a string with a representation of all headers. + * + * @return string + */ + public function toString(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php index 1304e5e3b..cdf79036a 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php @@ -10,492 +10,495 @@ /** * An abstract base MIME Header. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header { - - /** - * The name of this Header. - * @var string - * @access private - */ - private $_name; - - /** - * The Grammar used for this Header. - * @var Swift_Mime_Grammar - * @access private - */ - private $_grammar; - - /** - * The Encoder used to encode this Header. - * @var Swift_Encoder - * @access private - */ - private $_encoder; - - /** - * The maximum length of a line in the header. - * @var int - * @access private - */ - private $_lineLength = 78; - - /** - * The language used in this Header. - * @var string - */ - private $_lang; - - /** - * The character set of the text in this Header. - * @var string - * @access private - */ - private $_charset = 'utf-8'; - - /** - * The value of this Header, cached. - * @var string - * @access private - */ - private $_cachedValue = null; - - /** - * Creates a new Header. - * @param Swift_Mime_Grammar $grammar - */ - public function __construct(Swift_Mime_Grammar $grammar) - { - $this->setGrammar($grammar); - } - - /** - * Set the character set used in this Header. - * @param string $charset - */ - public function setCharset($charset) - { - $this->clearCachedValueIf($charset != $this->_charset); - $this->_charset = $charset; - if (isset($this->_encoder)) + /** + * The name of this Header. + * + * @var string + */ + private $_name; + + /** + * The Grammar used for this Header. + * + * @var Swift_Mime_Grammar + */ + private $_grammar; + + /** + * The Encoder used to encode this Header. + * + * @var Swift_Encoder + */ + private $_encoder; + + /** + * The maximum length of a line in the header. + * + * @var int + */ + private $_lineLength = 78; + + /** + * The language used in this Header. + * + * @var string + */ + private $_lang; + + /** + * The character set of the text in this Header. + * + * @var string + */ + private $_charset = 'utf-8'; + + /** + * The value of this Header, cached. + * + * @var string + */ + private $_cachedValue = null; + + /** + * Creates a new Header. + * + * @param Swift_Mime_Grammar $grammar + */ + public function __construct(Swift_Mime_Grammar $grammar) { - $this->_encoder->charsetChanged($charset); + $this->setGrammar($grammar); } - } - - /** - * Get the character set used in this Header. - * @return string - */ - public function getCharset() - { - return $this->_charset; - } - - /** - * Set the language used in this Header. - * For example, for US English, 'en-us'. - * This can be unspecified. - * @param string $lang - */ - public function setLanguage($lang) - { - $this->clearCachedValueIf($this->_lang != $lang); - $this->_lang = $lang; - } - - /** - * Get the language used in this Header. - * @return string - */ - public function getLanguage() - { - return $this->_lang; - } - - /** - * Set the encoder used for encoding the header. - * @param Swift_Mime_HeaderEncoder $encoder - */ - public function setEncoder(Swift_Mime_HeaderEncoder $encoder) - { - $this->_encoder = $encoder; - $this->setCachedValue(null); - } - - /** - * Get the encoder used for encoding this Header. - * @return Swift_Mime_HeaderEncoder - */ - public function getEncoder() - { - return $this->_encoder; - } - - /** - * Set the grammar used for the header. - * @param Swift_Mime_Grammar $grammar - */ - public function setGrammar(Swift_Mime_Grammar $grammar) - { - $this->_grammar = $grammar; - $this->setCachedValue(null); - } - - /** - * Get the grammar used for this Header. - * @return Swift_Mime_Grammar - */ - public function getGrammar() - { - return $this->_grammar; - } - - /** - * Get the name of this header (e.g. charset). - * @return string - */ - public function getFieldName() - { - return $this->_name; - } - - /** - * Set the maximum length of lines in the header (excluding EOL). - * @param int $lineLength - */ - public function setMaxLineLength($lineLength) - { - $this->clearCachedValueIf($this->_lineLength != $lineLength); - $this->_lineLength = $lineLength; - } - - /** - * Get the maximum permitted length of lines in this Header. - * @return int - */ - public function getMaxLineLength() - { - return $this->_lineLength; - } - - /** - * Get this Header rendered as a RFC 2822 compliant string. - * @return string - * @throws Swift_RfcComplianceException - */ - public function toString() - { - return $this->_tokensToString($this->toTokens()); - } - - /** - * Returns a string representation of this object. - * - * @return string - * - * @see toString() - */ - public function __toString() - { - return $this->toString(); - } - - // -- Points of extension - - /** - * Set the name of this Header field. - * @param string $name - * @access protected - */ - protected function setFieldName($name) - { - $this->_name = $name; - } - - /** - * Produces a compliant, formatted RFC 2822 'phrase' based on the string given. - * @param Swift_Mime_Header $header - * @param string $string as displayed - * @param string $charset of the text - * @param Swift_Mime_HeaderEncoder $encoder - * @param boolean $shorten the first line to make remove for header name - * @return string - */ - protected function createPhrase(Swift_Mime_Header $header, $string, $charset, - Swift_Mime_HeaderEncoder $encoder = null, $shorten = false) - { - //Treat token as exactly what was given - $phraseStr = $string; - //If it's not valid - if (!preg_match('/^' . $this->getGrammar()->getDefinition('phrase') . '$/D', $phraseStr)) + + /** + * Set the character set used in this Header. + * + * @param string $charset + */ + public function setCharset($charset) { - // .. but it is just ascii text, try escaping some characters - // and make it a quoted-string - if (preg_match('/^' . $this->getGrammar()->getDefinition('text') . '*$/D', $phraseStr)) - { - $phraseStr = $this->getGrammar()->escapeSpecials( - $phraseStr, array('"'), $this->getGrammar()->getSpecials() - ); - $phraseStr = '"' . $phraseStr . '"'; - } - else // ... otherwise it needs encoding - { - //Determine space remaining on line if first line - if ($shorten) - { - $usedLength = strlen($header->getFieldName() . ': '); + $this->clearCachedValueIf($charset != $this->_charset); + $this->_charset = $charset; + if (isset($this->_encoder)) { + $this->_encoder->charsetChanged($charset); } - else - { - $usedLength = 0; + } + + /** + * Get the character set used in this Header. + * + * @return string + */ + public function getCharset() + { + return $this->_charset; + } + + /** + * Set the language used in this Header. + * + * For example, for US English, 'en-us'. + * This can be unspecified. + * + * @param string $lang + */ + public function setLanguage($lang) + { + $this->clearCachedValueIf($this->_lang != $lang); + $this->_lang = $lang; + } + + /** + * Get the language used in this Header. + * + * @return string + */ + public function getLanguage() + { + return $this->_lang; + } + + /** + * Set the encoder used for encoding the header. + * + * @param Swift_Mime_HeaderEncoder $encoder + */ + public function setEncoder(Swift_Mime_HeaderEncoder $encoder) + { + $this->_encoder = $encoder; + $this->setCachedValue(null); + } + + /** + * Get the encoder used for encoding this Header. + * + * @return Swift_Mime_HeaderEncoder + */ + public function getEncoder() + { + return $this->_encoder; + } + + /** + * Set the grammar used for the header. + * + * @param Swift_Mime_Grammar $grammar + */ + public function setGrammar(Swift_Mime_Grammar $grammar) + { + $this->_grammar = $grammar; + $this->setCachedValue(null); + } + + /** + * Get the grammar used for this Header. + * + * @return Swift_Mime_Grammar + */ + public function getGrammar() + { + return $this->_grammar; + } + + /** + * Get the name of this header (e.g. charset). + * + * @return string + */ + public function getFieldName() + { + return $this->_name; + } + + /** + * Set the maximum length of lines in the header (excluding EOL). + * + * @param int $lineLength + */ + public function setMaxLineLength($lineLength) + { + $this->clearCachedValueIf($this->_lineLength != $lineLength); + $this->_lineLength = $lineLength; + } + + /** + * Get the maximum permitted length of lines in this Header. + * + * @return int + */ + public function getMaxLineLength() + { + return $this->_lineLength; + } + + /** + * Get this Header rendered as a RFC 2822 compliant string. + * + * @return string + * + * @throws Swift_RfcComplianceException + */ + public function toString() + { + return $this->_tokensToString($this->toTokens()); + } + + /** + * Returns a string representation of this object. + * + * @return string + * + * @see toString() + */ + public function __toString() + { + return $this->toString(); + } + + // -- Points of extension + + /** + * Set the name of this Header field. + * + * @param string $name + */ + protected function setFieldName($name) + { + $this->_name = $name; + } + + /** + * Produces a compliant, formatted RFC 2822 'phrase' based on the string given. + * + * @param Swift_Mime_Header $header + * @param string $string as displayed + * @param string $charset of the text + * @param Swift_Mime_HeaderEncoder $encoder + * @param bool $shorten the first line to make remove for header name + * + * @return string + */ + protected function createPhrase(Swift_Mime_Header $header, $string, $charset, Swift_Mime_HeaderEncoder $encoder = null, $shorten = false) + { + // Treat token as exactly what was given + $phraseStr = $string; + // If it's not valid + if (!preg_match('/^' . $this->getGrammar()->getDefinition('phrase') . '$/D', $phraseStr)) { + // .. but it is just ascii text, try escaping some characters + // and make it a quoted-string + if (preg_match('/^' . $this->getGrammar()->getDefinition('text') . '*$/D', $phraseStr)) { + $phraseStr = $this->getGrammar()->escapeSpecials( + $phraseStr, array('"'), $this->getGrammar()->getSpecials() + ); + $phraseStr = '"' . $phraseStr . '"'; + } else { // ... otherwise it needs encoding + // Determine space remaining on line if first line + if ($shorten) { + $usedLength = strlen($header->getFieldName() . ': '); + } else { + $usedLength = 0; + } + $phraseStr = $this->encodeWords($header, $string, $usedLength); + } } - $phraseStr = $this->encodeWords($header, $string, $usedLength); - } + + return $phraseStr; } - - return $phraseStr; - } - - /** - * Encode needed word tokens within a string of input. - * @param string $input - * @param string $usedLength, optional - * @return string - */ - protected function encodeWords(Swift_Mime_Header $header, $input, - $usedLength = -1) - { - $value = ''; - - $tokens = $this->getEncodableWordTokens($input); - - foreach ($tokens as $token) + + /** + * Encode needed word tokens within a string of input. + * + * @param Swift_Mime_Header $header + * @param string $input + * @param string $usedLength optional + * + * @return string + */ + protected function encodeWords(Swift_Mime_Header $header, $input, $usedLength = -1) { - //See RFC 2822, Sect 2.2 (really 2.2 ??) - if ($this->tokenNeedsEncoding($token)) - { - //Don't encode starting WSP - $firstChar = substr($token, 0, 1); - switch($firstChar) - { - case ' ': - case "\t": - $value .= $firstChar; - $token = substr($token, 1); + $value = ''; + + $tokens = $this->getEncodableWordTokens($input); + + foreach ($tokens as $token) { + // See RFC 2822, Sect 2.2 (really 2.2 ??) + if ($this->tokenNeedsEncoding($token)) { + // Don't encode starting WSP + $firstChar = substr($token, 0, 1); + switch ($firstChar) { + case ' ': + case "\t": + $value .= $firstChar; + $token = substr($token, 1); + } + + if (-1 == $usedLength) { + $usedLength = strlen($header->getFieldName() . ': ') + strlen($value); + } + $value .= $this->getTokenAsEncodedWord($token, $usedLength); + + $header->setMaxLineLength(76); // Forcefully override + } else { + $value .= $token; + } } - - if (-1 == $usedLength) - { - $usedLength = strlen($header->getFieldName() . ': ') + strlen($value); + + return $value; + } + + /** + * Test if a token needs to be encoded or not. + * + * @param string $token + * + * @return bool + */ + protected function tokenNeedsEncoding($token) + { + return preg_match('~[\x00-\x08\x10-\x19\x7F-\xFF\r\n]~', $token); + } + + /** + * Splits a string into tokens in blocks of words which can be encoded quickly. + * + * @param string $string + * + * @return string[] + */ + protected function getEncodableWordTokens($string) + { + $tokens = array(); + + $encodedToken = ''; + // Split at all whitespace boundaries + foreach (preg_split('~(?=[\t ])~', $string) as $token) { + if ($this->tokenNeedsEncoding($token)) { + $encodedToken .= $token; + } else { + if (strlen($encodedToken) > 0) { + $tokens[] = $encodedToken; + $encodedToken = ''; + } + $tokens[] = $token; + } } - $value .= $this->getTokenAsEncodedWord($token, $usedLength); - - $header->setMaxLineLength(76); //Forefully override - } - else - { - $value .= $token; - } - } - - return $value; - } - - /** - * Test if a token needs to be encoded or not. - * @param string $token - * @return boolean - */ - protected function tokenNeedsEncoding($token) - { - return preg_match('~[\x00-\x08\x10-\x19\x7F-\xFF\r\n]~', $token); - } - - /** - * Splits a string into tokens in blocks of words which can be encoded quickly. - * @param string $string - * @return string[] - */ - protected function getEncodableWordTokens($string) - { - $tokens = array(); - - $encodedToken = ''; - //Split at all whitespace boundaries - foreach (preg_split('~(?=[\t ])~', $string) as $token) - { - if ($this->tokenNeedsEncoding($token)) - { - $encodedToken .= $token; - } - else - { - if (strlen($encodedToken) > 0) - { - $tokens[] = $encodedToken; - $encodedToken = ''; + if (strlen($encodedToken)) { + $tokens[] = $encodedToken; } - $tokens[] = $token; - } + + return $tokens; } - if (strlen($encodedToken)) + + /** + * Get a token as an encoded word for safe insertion into headers. + * + * @param string $token token to encode + * @param int $firstLineOffset optional + * + * @return string + */ + protected function getTokenAsEncodedWord($token, $firstLineOffset = 0) { - $tokens[] = $encodedToken; + // Adjust $firstLineOffset to account for space needed for syntax + $charsetDecl = $this->_charset; + if (isset($this->_lang)) { + $charsetDecl .= '*' . $this->_lang; + } + $encodingWrapperLength = strlen( + '=?' . $charsetDecl . '?' . $this->_encoder->getName() . '??=' + ); + + if ($firstLineOffset >= 75) { //Does this logic need to be here? + $firstLineOffset = 0; + } + + $encodedTextLines = explode("\r\n", + $this->_encoder->encodeString( + $token, $firstLineOffset, 75 - $encodingWrapperLength, $this->_charset + ) + ); + + if (strtolower($this->_charset) !== 'iso-2022-jp') { // special encoding for iso-2022-jp using mb_encode_mimeheader + foreach ($encodedTextLines as $lineNum => $line) { + $encodedTextLines[$lineNum] = '=?' . $charsetDecl . + '?' . $this->_encoder->getName() . + '?' . $line . '?='; + } + } + + return implode("\r\n ", $encodedTextLines); } - - return $tokens; - } - - /** - * Get a token as an encoded word for safe insertion into headers. - * @param string $token to encode - * @param int $firstLineOffset, optional - * @return string - */ - protected function getTokenAsEncodedWord($token, $firstLineOffset = 0) - { - //Adjust $firstLineOffset to account for space needed for syntax - $charsetDecl = $this->_charset; - if (isset($this->_lang)) + + /** + * Generates tokens from the given string which include CRLF as individual tokens. + * + * @param string $token + * + * @return string[] + */ + protected function generateTokenLines($token) { - $charsetDecl .= '*' . $this->_lang; + return preg_split('~(\r\n)~', $token, -1, PREG_SPLIT_DELIM_CAPTURE); } - $encodingWrapperLength = strlen( - '=?' . $charsetDecl . '?' . $this->_encoder->getName() . '??=' - ); - - if ($firstLineOffset >= 75) //Does this logic need to be here? + + /** + * Set a value into the cache. + * + * @param string $value + */ + protected function setCachedValue($value) { - $firstLineOffset = 0; + $this->_cachedValue = $value; } - - $encodedTextLines = explode("\r\n", - $this->_encoder->encodeString( - $token, $firstLineOffset, 75 - $encodingWrapperLength - ) - ); - - foreach ($encodedTextLines as $lineNum => $line) + + /** + * Get the value in the cache. + * + * @return string + */ + protected function getCachedValue() { - $encodedTextLines[$lineNum] = '=?' . $charsetDecl . - '?' . $this->_encoder->getName() . - '?' . $line . '?='; + return $this->_cachedValue; } - - return implode("\r\n ", $encodedTextLines); - } - - /** - * Generates tokens from the given string which include CRLF as individual tokens. - * @param string $token - * @return string[] - * @access protected - */ - protected function generateTokenLines($token) - { - return preg_split('~(\r\n)~', $token, -1, PREG_SPLIT_DELIM_CAPTURE); - } - - /** - * Set a value into the cache. - * @param string $value - * @access protected - */ - protected function setCachedValue($value) - { - $this->_cachedValue = $value; - } - - /** - * Get the value in the cache. - * @return string - * @access protected - */ - protected function getCachedValue() - { - return $this->_cachedValue; - } - - /** - * Clear the cached value if $condition is met. - * @param boolean $condition - * @access protected - */ - protected function clearCachedValueIf($condition) - { - if ($condition) + + /** + * Clear the cached value if $condition is met. + * + * @param bool $condition + */ + protected function clearCachedValueIf($condition) { - $this->setCachedValue(null); + if ($condition) { + $this->setCachedValue(null); + } } - } - - // -- Private methods - - /** - * Generate a list of all tokens in the final header. - * @param string $string input, optional - * @return string[] - * @access private - */ - protected function toTokens($string = null) - { - if (is_null($string)) + + // -- Private methods + + /** + * Generate a list of all tokens in the final header. + * + * @param string $string The string to tokenize + * + * @return array An array of tokens as strings + */ + protected function toTokens($string = null) { - $string = $this->getFieldBody(); + if (is_null($string)) { + $string = $this->getFieldBody(); + } + + $tokens = array(); + + // Generate atoms; split at all invisible boundaries followed by WSP + foreach (preg_split('~(?=[ \t])~', $string) as $token) { + $newTokens = $this->generateTokenLines($token); + foreach ($newTokens as $newToken) { + $tokens[] = $newToken; + } + } + return $tokens; } - - $tokens = array(); - - //Generate atoms; split at all invisible boundaries followed by WSP - foreach (preg_split('~(?=[ \t])~', $string) as $token) + + /** + * Takes an array of tokens which appear in the header and turns them into + * an RFC 2822 compliant string, adding FWSP where needed. + * + * @param string[] $tokens + * + * @return string + */ + private function _tokensToString(array $tokens) { - $tokens = array_merge($tokens, $this->generateTokenLines($token)); - } - - return $tokens; - } - - /** - * Takes an array of tokens which appear in the header and turns them into - * an RFC 2822 compliant string, adding FWSP where needed. - * @param string[] $tokens - * @return string - * @access private - */ - private function _tokensToString(array $tokens) - { - $lineCount = 0; - $headerLines = array(); - $headerLines[] = $this->_name . ': '; - $currentLine =& $headerLines[$lineCount++]; - - //Build all tokens back into compliant header - foreach ($tokens as $i => $token) - { - //Line longer than specified maximum or token was just a new line - if (("\r\n" == $token) || - ($i > 0 && strlen($currentLine . $token) > $this->_lineLength) - && 0 < strlen($currentLine)) - { - $headerLines[] = ''; + $lineCount = 0; + $headerLines = array(); + $headerLines[] = $this->_name . ': '; $currentLine =& $headerLines[$lineCount++]; - } - - //Append token to the line - if ("\r\n" != $token) - { - $currentLine .= $token; - } + + // Build all tokens back into compliant header + foreach ($tokens as $i => $token) { + // Line longer than specified maximum or token was just a new line + if (("\r\n" == $token) || + ($i > 0 && strlen($currentLine . $token) > $this->_lineLength) + && 0 < strlen($currentLine)) + { + $headerLines[] = ''; + $currentLine =& $headerLines[$lineCount++]; + } + + // Append token to the line + if ("\r\n" != $token) { + $currentLine .= $token; + } + } + + // Implode with FWS (RFC 2822, 2.2.3) + return implode("\r\n", $headerLines) . "\r\n"; } - - //Implode with FWS (RFC 2822, 2.2.3) - return implode("\r\n", $headerLines) . "\r\n"; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php index bb345fdc8..015bc4421 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php @@ -8,112 +8,120 @@ * file that was distributed with this source code. */ - - /** * A Date MIME Header for Swift Mailer. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_Headers_DateHeader extends Swift_Mime_Headers_AbstractHeader { - - /** - * The UNIX timestamp value of this Header. - * @var int - * @access private - */ - private $_timestamp; - - /** - * Creates a new DateHeader with $name and $timestamp. - * Example: - * - * - * - * @param string $name of Header - * @param Swift_Mime_Grammar $grammar - */ - public function __construct($name, Swift_Mime_Grammar $grammar) - { - $this->setFieldName($name); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * @return int - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - */ - public function getFieldType() - { - return self::TYPE_DATE; - } - - /** - * Set the model for the field body. - * This method takes a UNIX timestamp. - * @param int $model - */ - public function setFieldBodyModel($model) - { - $this->setTimestamp($model); - } - - /** - * Get the model for the field body. - * This method returns a UNIX timestamp. - * @return mixed - */ - public function getFieldBodyModel() - { - return $this->getTimestamp(); - } - - /** - * Get the UNIX timestamp of the Date in this Header. - * @return int - */ - public function getTimestamp() - { - return $this->_timestamp; - } - - /** - * Set the UNIX timestamp of the Date in this Header. - * @param int $timestamp - */ - public function setTimestamp($timestamp) - { - if (!is_null($timestamp)) + /** + * The UNIX timestamp value of this Header. + * + * @var int + */ + private $_timestamp; + + /** + * Creates a new DateHeader with $name and $timestamp. + * + * Example: + * + * + * + * + * @param string $name of Header + * @param Swift_Mime_Grammar $grammar + */ + public function __construct($name, Swift_Mime_Grammar $grammar) { - $timestamp = (int) $timestamp; + $this->setFieldName($name); + parent::__construct($grammar); } - $this->clearCachedValueIf($this->_timestamp != $timestamp); - $this->_timestamp = $timestamp; - } - - /** - * Get the string value of the body in this Header. - * This is not necessarily RFC 2822 compliant since folding white space will - * not be added at this stage (see {@link toString()} for that). - * @return string - * @see toString() - */ - public function getFieldBody() - { - if (!$this->getCachedValue()) + + /** + * Get the type of Header that this instance represents. + * + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + * + * @return int + */ + public function getFieldType() { - if (isset($this->_timestamp)) - { - $this->setCachedValue(date('r', $this->_timestamp)); - } + return self::TYPE_DATE; + } + + /** + * Set the model for the field body. + * + * This method takes a UNIX timestamp. + * + * @param int $model + */ + public function setFieldBodyModel($model) + { + $this->setTimestamp($model); + } + + /** + * Get the model for the field body. + * + * This method returns a UNIX timestamp. + * + * @return mixed + */ + public function getFieldBodyModel() + { + return $this->getTimestamp(); + } + + /** + * Get the UNIX timestamp of the Date in this Header. + * + * @return int + */ + public function getTimestamp() + { + return $this->_timestamp; + } + + /** + * Set the UNIX timestamp of the Date in this Header. + * + * @param int $timestamp + */ + public function setTimestamp($timestamp) + { + if (!is_null($timestamp)) { + $timestamp = (int) $timestamp; + } + $this->clearCachedValueIf($this->_timestamp != $timestamp); + $this->_timestamp = $timestamp; + } + + /** + * Get the string value of the body in this Header. + * + * This is not necessarily RFC 2822 compliant since folding white space will + * not be added at this stage (see {@link toString()} for that). + * + * @see toString() + * + * @return string + */ + public function getFieldBody() + { + if (!$this->getCachedValue()) { + if (isset($this->_timestamp)) { + $this->setCachedValue(date('r', $this->_timestamp)); + } + } + + return $this->getCachedValue(); } - return $this->getCachedValue(); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php index df978f0e3..1d00015e8 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php @@ -8,159 +8,176 @@ * file that was distributed with this source code. */ - /** * An ID MIME Header for something like Message-ID or Content-ID. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mime_Headers_IdentificationHeader - extends Swift_Mime_Headers_AbstractHeader +class Swift_Mime_Headers_IdentificationHeader extends Swift_Mime_Headers_AbstractHeader { - - /** - * The IDs used in the value of this Header. - * This may hold multiple IDs or just a single ID. - * @var string[] - * @access private - */ - private $_ids = array(); - - /** - * Creates a new IdentificationHeader with the given $name and $id. - * @param string $name - * @param Swift_Mime_Grammar $grammar - */ - public function __construct($name, Swift_Mime_Grammar $grammar) - { - $this->setFieldName($name); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * @return int - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - */ - public function getFieldType() - { - return self::TYPE_ID; - } - - /** - * Set the model for the field body. - * This method takes a string ID, or an array of IDs - * @param mixed $model - * @throws Swift_RfcComplianceException - */ - public function setFieldBodyModel($model) - { - $this->setId($model); - } - - /** - * Get the model for the field body. - * This method returns an array of IDs - * @return array - */ - public function getFieldBodyModel() - { - return $this->getIds(); - } - - /** - * Set the ID used in the value of this header. - * @param string $id - * @throws Swift_RfcComplianceException - */ - public function setId($id) - { - $this->setIds(array($id)); - } - - /** - * Get the ID used in the value of this Header. - * If multiple IDs are set only the first is returned. - * @return string - */ - public function getId() - { - if (count($this->_ids) > 0) + /** + * The IDs used in the value of this Header. + * + * This may hold multiple IDs or just a single ID. + * + * @var string[] + */ + private $_ids = array(); + + /** + * Creates a new IdentificationHeader with the given $name and $id. + * + * @param string $name + * @param Swift_Mime_Grammar $grammar + */ + public function __construct($name, Swift_Mime_Grammar $grammar) { - return $this->_ids[0]; + $this->setFieldName($name); + parent::__construct($grammar); } - } - - /** - * Set a collection of IDs to use in the value of this Header. - * @param string[] $ids - * @throws Swift_RfcComplianceException - */ - public function setIds(array $ids) - { - $actualIds = array(); - - foreach ($ids as $k => $id) + + /** + * Get the type of Header that this instance represents. + * + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + * + * @return int + */ + public function getFieldType() { - $this->_assertValidId($id); - $actualIds[] = $id; + return self::TYPE_ID; } - - $this->clearCachedValueIf($this->_ids != $actualIds); - $this->_ids = $actualIds; - } - - /** - * Get the list of IDs used in this Header. - * @return string[] - */ - public function getIds() - { - return $this->_ids; - } - - /** - * Get the string value of the body in this Header. - * This is not necessarily RFC 2822 compliant since folding white space will - * not be added at this stage (see {@link toString()} for that). - * @return string - * @see toString() - * @throws Swift_RfcComplianceException - */ - public function getFieldBody() - { - if (!$this->getCachedValue()) + + /** + * Set the model for the field body. + * + * This method takes a string ID, or an array of IDs. + * + * @param mixed $model + * + * @throws Swift_RfcComplianceException + */ + public function setFieldBodyModel($model) { - $angleAddrs = array(); - - foreach ($this->_ids as $id) - { - $angleAddrs[] = '<' . $id . '>'; - } - - $this->setCachedValue(implode(' ', $angleAddrs)); + $this->setId($model); } - return $this->getCachedValue(); - } - - /** - * Throws an Exception if the id passed does not comply with RFC 2822. - * @param string $id - * @throws Swift_RfcComplianceException - */ - private function _assertValidId($id) - { - if (!preg_match( - '/^' . $this->getGrammar()->getDefinition('id-left') . '@' . - $this->getGrammar()->getDefinition('id-right') . '$/D', - $id - )) + + /** + * Get the model for the field body. + * + * This method returns an array of IDs + * + * @return array + */ + public function getFieldBodyModel() { - throw new Swift_RfcComplianceException( - 'Invalid ID given <' . $id . '>' - ); + return $this->getIds(); + } + + /** + * Set the ID used in the value of this header. + * + * @param string|array $id + * + * @throws Swift_RfcComplianceException + */ + public function setId($id) + { + $this->setIds(is_array($id) ? $id : array($id)); + } + + /** + * Get the ID used in the value of this Header. + * + * If multiple IDs are set only the first is returned. + * + * @return string + */ + public function getId() + { + if (count($this->_ids) > 0) { + return $this->_ids[0]; + } + } + + /** + * Set a collection of IDs to use in the value of this Header. + * + * @param string[] $ids + * + * @throws Swift_RfcComplianceException + */ + public function setIds(array $ids) + { + $actualIds = array(); + + foreach ($ids as $id) { + $this->_assertValidId($id); + $actualIds[] = $id; + } + + $this->clearCachedValueIf($this->_ids != $actualIds); + $this->_ids = $actualIds; + } + + /** + * Get the list of IDs used in this Header. + * + * @return string[] + */ + public function getIds() + { + return $this->_ids; + } + + /** + * Get the string value of the body in this Header. + * + * This is not necessarily RFC 2822 compliant since folding white space will + * not be added at this stage (see {@see toString()} for that). + * + * @see toString() + * + * @return string + * + * @throws Swift_RfcComplianceException + */ + public function getFieldBody() + { + if (!$this->getCachedValue()) { + $angleAddrs = array(); + + foreach ($this->_ids as $id) { + $angleAddrs[] = '<' . $id . '>'; + } + + $this->setCachedValue(implode(' ', $angleAddrs)); + } + + return $this->getCachedValue(); + } + + /** + * Throws an Exception if the id passed does not comply with RFC 2822. + * + * @param string $id + * + * @throws Swift_RfcComplianceException + */ + private function _assertValidId($id) + { + if (!preg_match( + '/^' . $this->getGrammar()->getDefinition('id-left') . '@' . + $this->getGrammar()->getDefinition('id-right') . '$/D', + $id + )) + { + throw new Swift_RfcComplianceException( + 'Invalid ID given <' . $id . '>' + ); + } } - } } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php index 67551c86d..766d6a18d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php @@ -8,308 +8,351 @@ * file that was distributed with this source code. */ - /** * A Mailbox Address MIME Header for something like From or Sender. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_Headers_MailboxHeader extends Swift_Mime_Headers_AbstractHeader { - - /** - * The mailboxes used in this Header. - * @var string[] - * @access private - */ - private $_mailboxes = array(); - - /** - * Creates a new MailboxHeader with $name. - * @param string $name of Header - * @param Swift_Mime_HeaderEncoder $encoder - * @param Swift_Mime_Grammar $grammar - */ - public function __construct($name, Swift_Mime_HeaderEncoder $encoder, Swift_Mime_Grammar $grammar) - { - $this->setFieldName($name); - $this->setEncoder($encoder); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * @return int - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - */ - public function getFieldType() - { - return self::TYPE_MAILBOX; - } - - /** - * Set the model for the field body. - * This method takes a string, or an array of addresses. - * @param mixed $model - * @throws Swift_RfcComplianceException - */ - public function setFieldBodyModel($model) - { - $this->setNameAddresses($model); - } - - /** - * Get the model for the field body. - * This method returns an associative array like {@link getNameAddresses()} - * @return array - * @throws Swift_RfcComplianceException - */ - public function getFieldBodyModel() - { - return $this->getNameAddresses(); - } - - /** - * Set a list of mailboxes to be shown in this Header. - * The mailboxes can be a simple array of addresses, or an array of - * key=>value pairs where (email => personalName). - * Example: - * - * setNameAddresses(array( - * 'chris@swiftmailer.org' => 'Chris Corbyn', - * 'mark@swiftmailer.org' //No associated personal name - * )); - * ?> - * - * @param string|string[] $mailboxes - * @throws Swift_RfcComplianceException - * @see __construct() - * @see setAddresses() - * @see setValue() - */ - public function setNameAddresses($mailboxes) - { - $this->_mailboxes = $this->normalizeMailboxes((array) $mailboxes); - $this->setCachedValue(null); //Clear any cached value - } - - /** - * Get the full mailbox list of this Header as an array of valid RFC 2822 strings. - * Example: - * - * 'Chris Corbyn', - * 'mark@swiftmailer.org' => 'Mark Corbyn') - * ); - * print_r($header->getNameAddressStrings()); - * // array ( - * // 0 => Chris Corbyn , - * // 1 => Mark Corbyn - * // ) - * ?> - * - * @return string[] - * @throws Swift_RfcComplianceException - * @see getNameAddresses() - * @see toString() - */ - public function getNameAddressStrings() - { - return $this->_createNameAddressStrings($this->getNameAddresses()); - } - - /** - * Get all mailboxes in this Header as key=>value pairs. - * The key is the address and the value is the name (or null if none set). - * Example: - * - * 'Chris Corbyn', - * 'mark@swiftmailer.org' => 'Mark Corbyn') - * ); - * print_r($header->getNameAddresses()); - * // array ( - * // chris@swiftmailer.org => Chris Corbyn, - * // mark@swiftmailer.org => Mark Corbyn - * // ) - * ?> - * - * @return string[] - * @see getAddresses() - * @see getNameAddressStrings() - */ - public function getNameAddresses() - { - return $this->_mailboxes; - } - - /** - * Makes this Header represent a list of plain email addresses with no names. - * Example: - * - * setAddresses( - * array('one@domain.tld', 'two@domain.tld', 'three@domain.tld') - * ); - * ?> - * - * @param string[] $addresses - * @throws Swift_RfcComplianceException - * @see setNameAddresses() - * @see setValue() - */ - public function setAddresses($addresses) - { - $this->setNameAddresses(array_values((array) $addresses)); - } - - /** - * Get all email addresses in this Header. - * @return string[] - * @see getNameAddresses() - */ - public function getAddresses() - { - return array_keys($this->_mailboxes); - } - - /** - * Remove one or more addresses from this Header. - * @param string|string[] $addresses - */ - public function removeAddresses($addresses) - { - $this->setCachedValue(null); - foreach ((array) $addresses as $address) + /** + * The mailboxes used in this Header. + * + * @var string[] + */ + private $_mailboxes = array(); + + /** + * Creates a new MailboxHeader with $name. + * + * @param string $name of Header + * @param Swift_Mime_HeaderEncoder $encoder + * @param Swift_Mime_Grammar $grammar + */ + public function __construct($name, Swift_Mime_HeaderEncoder $encoder, Swift_Mime_Grammar $grammar) { - unset($this->_mailboxes[$address]); + $this->setFieldName($name); + $this->setEncoder($encoder); + parent::__construct($grammar); } - } - - /** - * Get the string value of the body in this Header. - * This is not necessarily RFC 2822 compliant since folding white space will - * not be added at this stage (see {@link toString()} for that). - * @return string - * @throws Swift_RfcComplianceException - * @see toString() - */ - public function getFieldBody() - { - //Compute the string value of the header only if needed - if (is_null($this->getCachedValue())) + + /** + * Get the type of Header that this instance represents. + * + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + * + * @return int + */ + public function getFieldType() { - $this->setCachedValue($this->createMailboxListString($this->_mailboxes)); + return self::TYPE_MAILBOX; } - return $this->getCachedValue(); - } - - // -- Points of extension - - /** - * Normalizes a user-input list of mailboxes into consistent key=>value pairs. - * @param string[] $mailboxes - * @return string[] - * @access protected - */ - protected function normalizeMailboxes(array $mailboxes) - { - $actualMailboxes = array(); - - foreach ($mailboxes as $key => $value) + + /** + * Set the model for the field body. + * + * This method takes a string, or an array of addresses. + * + * @param mixed $model + * + * @throws Swift_RfcComplianceException + */ + public function setFieldBodyModel($model) { - if (is_string($key)) //key is email addr - { - $address = $key; - $name = $value; - } - else - { - $address = $value; - $name = null; - } - $this->_assertValidAddress($address); - $actualMailboxes[$address] = $name; + $this->setNameAddresses($model); } - - return $actualMailboxes; - } - - /** - * Produces a compliant, formatted display-name based on the string given. - * @param string $displayName as displayed - * @param boolean $shorten the first line to make remove for header name - * @return string - * @access protected - */ - protected function createDisplayNameString($displayName, $shorten = false) - { - return $this->createPhrase($this, $displayName, - $this->getCharset(), $this->getEncoder(), $shorten - ); - } - - /** - * Creates a string form of all the mailboxes in the passed array. - * @param string[] $mailboxes - * @return string - * @throws Swift_RfcComplianceException - * @access protected - */ - protected function createMailboxListString(array $mailboxes) - { - return implode(', ', $this->_createNameAddressStrings($mailboxes)); - } - - // -- Private methods - - /** - * Return an array of strings conforming the the name-addr spec of RFC 2822. - * @param string[] $mailboxes - * @return string[] - * @access private - */ - private function _createNameAddressStrings(array $mailboxes) - { - $strings = array(); - - foreach ($mailboxes as $email => $name) + + /** + * Get the model for the field body. + * + * This method returns an associative array like {@link getNameAddresses()} + * + * @return array + * + * @throws Swift_RfcComplianceException + */ + public function getFieldBodyModel() { - $mailboxStr = $email; - if (!is_null($name)) - { - $nameStr = $this->createDisplayNameString($name, empty($strings)); - $mailboxStr = $nameStr . ' <' . $mailboxStr . '>'; - } - $strings[] = $mailboxStr; + return $this->getNameAddresses(); } - - return $strings; - } - - /** - * Throws an Exception if the address passed does not comply with RFC 2822. - * @param string $address - * @throws Swift_RfcComplianceException If invalid. - * @access private - */ - private function _assertValidAddress($address) - { - if (!preg_match('/^' . $this->getGrammar()->getDefinition('addr-spec') . '$/D', - $address)) + + /** + * Set a list of mailboxes to be shown in this Header. + * + * The mailboxes can be a simple array of addresses, or an array of + * key=>value pairs where (email => personalName). + * Example: + * + * setNameAddresses(array( + * 'chris@swiftmailer.org' => 'Chris Corbyn', + * 'mark@swiftmailer.org' //No associated personal name + * )); + * ?> + * + * + * @see __construct() + * @see setAddresses() + * @see setValue() + * + * @param string|string[] $mailboxes + * + * @throws Swift_RfcComplianceException + */ + public function setNameAddresses($mailboxes) { - throw new Swift_RfcComplianceException( - 'Address in mailbox given [' . $address . - '] does not comply with RFC 2822, 3.6.2.' - ); + $this->_mailboxes = $this->normalizeMailboxes((array) $mailboxes); + $this->setCachedValue(null); //Clear any cached value + } + + /** + * Get the full mailbox list of this Header as an array of valid RFC 2822 strings. + * + * Example: + * + * 'Chris Corbyn', + * 'mark@swiftmailer.org' => 'Mark Corbyn') + * ); + * print_r($header->getNameAddressStrings()); + * // array ( + * // 0 => Chris Corbyn , + * // 1 => Mark Corbyn + * // ) + * ?> + * + * + * @see getNameAddresses() + * @see toString() + * + * @return string[] + * + * @throws Swift_RfcComplianceException + */ + public function getNameAddressStrings() + { + return $this->_createNameAddressStrings($this->getNameAddresses()); + } + + /** + * Get all mailboxes in this Header as key=>value pairs. + * + * The key is the address and the value is the name (or null if none set). + * Example: + * + * 'Chris Corbyn', + * 'mark@swiftmailer.org' => 'Mark Corbyn') + * ); + * print_r($header->getNameAddresses()); + * // array ( + * // chris@swiftmailer.org => Chris Corbyn, + * // mark@swiftmailer.org => Mark Corbyn + * // ) + * ?> + * + * + * @see getAddresses() + * @see getNameAddressStrings() + * + * @return string[] + */ + public function getNameAddresses() + { + return $this->_mailboxes; + } + + /** + * Makes this Header represent a list of plain email addresses with no names. + * + * Example: + * + * setAddresses( + * array('one@domain.tld', 'two@domain.tld', 'three@domain.tld') + * ); + * ?> + * + * + * @see setNameAddresses() + * @see setValue() + * + * @param string[] $addresses + * + * @throws Swift_RfcComplianceException + */ + public function setAddresses($addresses) + { + $this->setNameAddresses(array_values((array) $addresses)); + } + + /** + * Get all email addresses in this Header. + * + * @see getNameAddresses() + * + * @return string[] + */ + public function getAddresses() + { + return array_keys($this->_mailboxes); + } + + /** + * Remove one or more addresses from this Header. + * + * @param string|string[] $addresses + */ + public function removeAddresses($addresses) + { + $this->setCachedValue(null); + foreach ((array) $addresses as $address) { + unset($this->_mailboxes[$address]); + } + } + + /** + * Get the string value of the body in this Header. + * + * This is not necessarily RFC 2822 compliant since folding white space will + * not be added at this stage (see {@link toString()} for that). + * + * @see toString() + * + * @return string + * + * @throws Swift_RfcComplianceException + */ + public function getFieldBody() + { + // Compute the string value of the header only if needed + if (is_null($this->getCachedValue())) { + $this->setCachedValue($this->createMailboxListString($this->_mailboxes)); + } + + return $this->getCachedValue(); + } + + // -- Points of extension + + /** + * Normalizes a user-input list of mailboxes into consistent key=>value pairs. + * + * @param string[] $mailboxes + * + * @return string[] + */ + protected function normalizeMailboxes(array $mailboxes) + { + $actualMailboxes = array(); + + foreach ($mailboxes as $key => $value) { + if (is_string($key)) { //key is email addr + $address = $key; + $name = $value; + } else { + $address = $value; + $name = null; + } + $this->_assertValidAddress($address); + $actualMailboxes[$address] = $name; + } + + return $actualMailboxes; + } + + /** + * Produces a compliant, formatted display-name based on the string given. + * + * @param string $displayName as displayed + * @param bool $shorten the first line to make remove for header name + * + * @return string + */ + protected function createDisplayNameString($displayName, $shorten = false) + { + return $this->createPhrase($this, $displayName, + $this->getCharset(), $this->getEncoder(), $shorten + ); + } + + /** + * Creates a string form of all the mailboxes in the passed array. + * + * @param string[] $mailboxes + * + * @return string + * + * @throws Swift_RfcComplianceException + */ + protected function createMailboxListString(array $mailboxes) + { + return implode(', ', $this->_createNameAddressStrings($mailboxes)); + } + + /** + * Redefine the encoding requirements for mailboxes. + * + * Commas and semicolons are used to separate + * multiple addresses, and should therefore be encoded + * + * @param string $token + * + * @return bool + */ + protected function tokenNeedsEncoding($token) + { + return preg_match('/[,;]/', $token) || parent::tokenNeedsEncoding($token); + } + + // -- Private methods + + /** + * Return an array of strings conforming the the name-addr spec of RFC 2822. + * + * @param string[] $mailboxes + * + * @return string[] + */ + private function _createNameAddressStrings(array $mailboxes) + { + $strings = array(); + + foreach ($mailboxes as $email => $name) { + $mailboxStr = $email; + if (!is_null($name)) { + $nameStr = $this->createDisplayNameString($name, empty($strings)); + $mailboxStr = $nameStr . ' <' . $mailboxStr . '>'; + } + $strings[] = $mailboxStr; + } + + return $strings; + } + + /** + * Throws an Exception if the address passed does not comply with RFC 2822. + * + * @param string $address + * + * @throws Swift_RfcComplianceException If invalid. + */ + private function _assertValidAddress($address) + { + if (!preg_match('/^' . $this->getGrammar()->getDefinition('addr-spec') . '$/D', + $address)) + { + throw new Swift_RfcComplianceException( + 'Address in mailbox given [' . $address . + '] does not comply with RFC 2822, 3.6.2.' + ); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/OpenDKIMHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/OpenDKIMHeader.php new file mode 100644 index 000000000..ecab7380b --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/OpenDKIMHeader.php @@ -0,0 +1,139 @@ + + */ +class Swift_Mime_Headers_OpenDKIMHeader implements Swift_Mime_Header +{ + /** + * The value of this Header. + * + * @var string + */ + private $_value; + + /** + * The name of this Header + * @var string + */ + private $_fieldName; + + /** + * Creates a new SimpleHeader with $name. + * + * @param string $name + * @param Swift_Mime_HeaderEncoder $encoder + * @param Swift_Mime_Grammar $grammar + */ + public function __construct($name) + { + $this->_fieldName = $name; + } + + /** + * Get the type of Header that this instance represents. + * + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + * + * @return int + */ + public function getFieldType() + { + return self::TYPE_TEXT; + } + + /** + * Set the model for the field body. + * + * This method takes a string for the field value. + * + * @param string $model + */ + public function setFieldBodyModel($model) + { + $this->setValue($model); + } + + /** + * Get the model for the field body. + * + * This method returns a string. + * + * @return string + */ + public function getFieldBodyModel() + { + return $this->getValue(); + } + + /** + * Get the (unencoded) value of this header. + * + * @return string + */ + public function getValue() + { + return $this->_value; + } + + /** + * Set the (unencoded) value of this header. + * + * @param string $value + */ + public function setValue($value) + { + $this->_value = $value; + } + + /** + * Get the value of this header prepared for rendering. + * + * @return string + */ + public function getFieldBody() + { + return $this->_value; + } + + /** + * Get this Header rendered as a RFC 2822 compliant string. + * + * @return string + */ + public function toString() + { + return $this->_fieldName.': '.$this->_value; + } + + /** + * Set the Header FieldName + * @see Swift_Mime_Header::getFieldName() + */ + public function getFieldName() + { + return $this->_fieldName; + } + + /** + * Ignored + */ + public function setCharset($charset) + { + + } + +} diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php index 08ebce4f2..7f52857e1 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php @@ -8,262 +8,258 @@ * file that was distributed with this source code. */ - /** * An abstract base MIME Header. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mime_Headers_ParameterizedHeader - extends Swift_Mime_Headers_UnstructuredHeader - implements Swift_Mime_ParameterizedHeader +class Swift_Mime_Headers_ParameterizedHeader extends Swift_Mime_Headers_UnstructuredHeader implements Swift_Mime_ParameterizedHeader { - - /** - * The Encoder used to encode the parameters. - * @var Swift_Encoder - * @access private - */ - private $_paramEncoder; - - /** - * The parameters as an associative array. - * @var string[] - * @access private - */ - private $_params = array(); - - /** - * RFC 2231's definition of a token. - * @var string - * @access private - */ - private $_tokenRe; - - /** - * Creates a new ParameterizedHeader with $name. - * @param string $name - * @param Swift_Mime_HeaderEncoder $encoder - * @param Swift_Encoder $paramEncoder, optional - * @param Swift_Mime_Grammar $grammar - */ - public function __construct($name, Swift_Mime_HeaderEncoder $encoder, - Swift_Encoder $paramEncoder = null, Swift_Mime_Grammar $grammar) - { - parent::__construct($name, $encoder, $grammar); - $this->_paramEncoder = $paramEncoder; - $this->_tokenRe = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)'; - } - - /** - * Get the type of Header that this instance represents. - * @return int - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - */ - public function getFieldType() - { - return self::TYPE_PARAMETERIZED; - } - - /** - * Set the character set used in this Header. - * @param string $charset - */ - public function setCharset($charset) - { - parent::setCharset($charset); - if (isset($this->_paramEncoder)) + /** + * RFC 2231's definition of a token. + * + * @var string + */ + const TOKEN_REGEX = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)'; + + /** + * The Encoder used to encode the parameters. + * + * @var Swift_Encoder + */ + private $_paramEncoder; + + /** + * The parameters as an associative array. + * + * @var string[] + */ + private $_params = array(); + + /** + * Creates a new ParameterizedHeader with $name. + * + * @param string $name + * @param Swift_Mime_HeaderEncoder $encoder + * @param Swift_Encoder $paramEncoder, optional + * @param Swift_Mime_Grammar $grammar + */ + public function __construct($name, Swift_Mime_HeaderEncoder $encoder, Swift_Encoder $paramEncoder = null, Swift_Mime_Grammar $grammar) { - $this->_paramEncoder->charsetChanged($charset); + parent::__construct($name, $encoder, $grammar); + $this->_paramEncoder = $paramEncoder; } - } - - /** - * Set the value of $parameter. - * @param string $parameter - * @param string $value - */ - public function setParameter($parameter, $value) - { - $this->setParameters(array_merge($this->getParameters(), array($parameter => $value))); - } - - /** - * Get the value of $parameter. - * @return string - */ - public function getParameter($parameter) - { - $params = $this->getParameters(); - return array_key_exists($parameter, $params) - ? $params[$parameter] - : null; - } - - /** - * Set an associative array of parameter names mapped to values. - * @param string[] - */ - public function setParameters(array $parameters) - { - $this->clearCachedValueIf($this->_params != $parameters); - $this->_params = $parameters; - } - - /** - * Returns an associative array of parameter names mapped to values. - * @return string[] - */ - public function getParameters() - { - return $this->_params; - } - - /** - * Get the value of this header prepared for rendering. - * @return string - */ - public function getFieldBody() //TODO: Check caching here - { - $body = parent::getFieldBody(); - foreach ($this->_params as $name => $value) + + /** + * Get the type of Header that this instance represents. + * + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + * + * @return int + */ + public function getFieldType() { - if (!is_null($value)) - { - //Add the parameter - $body .= '; ' . $this->_createParameter($name, $value); - } + return self::TYPE_PARAMETERIZED; } - return $body; - } - - // -- Protected methods - - /** - * Generate a list of all tokens in the final header. - * This doesn't need to be overridden in theory, but it is for implementation - * reasons to prevent potential breakage of attributes. - * @return string[] - * @access protected - */ - protected function toTokens($string = null) - { - $tokens = parent::toTokens(parent::getFieldBody()); - - //Try creating any parameters - foreach ($this->_params as $name => $value) + + /** + * Set the character set used in this Header. + * + * @param string $charset + */ + public function setCharset($charset) { - if (!is_null($value)) - { - //Add the semi-colon separator - $tokens[count($tokens)-1] .= ';'; - $tokens = array_merge($tokens, $this->generateTokenLines( - ' ' . $this->_createParameter($name, $value) - )); - } + parent::setCharset($charset); + if (isset($this->_paramEncoder)) { + $this->_paramEncoder->charsetChanged($charset); + } } - - return $tokens; - } - - // -- Private methods - - /** - * Render a RFC 2047 compliant header parameter from the $name and $value. - * @param string $name - * @param string $value - * @return string - * @access private - */ - private function _createParameter($name, $value) - { - $origValue = $value; - - $encoded = false; - //Allow room for parameter name, indices, "=" and DQUOTEs - $maxValueLength = $this->getMaxLineLength() - strlen($name . '=*N"";') - 1; - $firstLineOffset = 0; - - //If it's not already a valid parameter value... - if (!preg_match('/^' . $this->_tokenRe . '$/D', $value)) + + /** + * Set the value of $parameter. + * + * @param string $parameter + * @param string $value + */ + public function setParameter($parameter, $value) { - //TODO: text, or something else?? - //... and it's not ascii - if (!preg_match('/^' . $this->getGrammar()->getDefinition('text') . '*$/D', $value)) - { - $encoded = true; - //Allow space for the indices, charset and language - $maxValueLength = $this->getMaxLineLength() - strlen($name . '*N*="";') - 1; - $firstLineOffset = strlen( - $this->getCharset() . "'" . $this->getLanguage() . "'" - ); - } + $this->setParameters(array_merge($this->getParameters(), array($parameter => $value))); } - - //Encode if we need to - if ($encoded || strlen($value) > $maxValueLength) + + /** + * Get the value of $parameter. + * + * @param string $parameter + * + * @return string + */ + public function getParameter($parameter) { - if (isset($this->_paramEncoder)) - { - $value = $this->_paramEncoder->encodeString( - $origValue, $firstLineOffset, $maxValueLength - ); - } - else //We have to go against RFC 2183/2231 in some areas for interoperability - { - $value = $this->getTokenAsEncodedWord($origValue); + $params = $this->getParameters(); + + return array_key_exists($parameter, $params) + ? $params[$parameter] + : null; + } + + /** + * Set an associative array of parameter names mapped to values. + * + * @param string[] $parameters + */ + public function setParameters(array $parameters) + { + $this->clearCachedValueIf($this->_params != $parameters); + $this->_params = $parameters; + } + + /** + * Returns an associative array of parameter names mapped to values. + * + * @return string[] + */ + public function getParameters() + { + return $this->_params; + } + + /** + * Get the value of this header prepared for rendering. + * + * @return string + */ + public function getFieldBody() //TODO: Check caching here + { + $body = parent::getFieldBody(); + foreach ($this->_params as $name => $value) { + if (!is_null($value)) { + // Add the parameter + $body .= '; ' . $this->_createParameter($name, $value); + } + } + + return $body; + } + + // -- Protected methods + + /** + * Generate a list of all tokens in the final header. + * + * This doesn't need to be overridden in theory, but it is for implementation + * reasons to prevent potential breakage of attributes. + * + * @param string $string The string to tokenize + * + * @return array An array of tokens as strings + */ + protected function toTokens($string = null) + { + $tokens = parent::toTokens(parent::getFieldBody()); + + // Try creating any parameters + foreach ($this->_params as $name => $value) { + if (!is_null($value)) { + // Add the semi-colon separator + $tokens[count($tokens)-1] .= ';'; + $tokens = array_merge($tokens, $this->generateTokenLines( + ' ' . $this->_createParameter($name, $value) + )); + } + } + + return $tokens; + } + + // -- Private methods + + /** + * Render a RFC 2047 compliant header parameter from the $name and $value. + * + * @param string $name + * @param string $value + * + * @return string + */ + private function _createParameter($name, $value) + { + $origValue = $value; + $encoded = false; - } + // Allow room for parameter name, indices, "=" and DQUOTEs + $maxValueLength = $this->getMaxLineLength() - strlen($name . '=*N"";') - 1; + $firstLineOffset = 0; + + // If it's not already a valid parameter value... + if (!preg_match('/^' . self::TOKEN_REGEX . '$/D', $value)) { + // TODO: text, or something else?? + // ... and it's not ascii + if (!preg_match('/^' . $this->getGrammar()->getDefinition('text') . '*$/D', $value)) { + $encoded = true; + // Allow space for the indices, charset and language + $maxValueLength = $this->getMaxLineLength() - strlen($name . '*N*="";') - 1; + $firstLineOffset = strlen( + $this->getCharset() . "'" . $this->getLanguage() . "'" + ); + } + } + + // Encode if we need to + if ($encoded || strlen($value) > $maxValueLength) { + if (isset($this->_paramEncoder)) { + $value = $this->_paramEncoder->encodeString( + $origValue, $firstLineOffset, $maxValueLength, $this->getCharset() + ); + } else { // We have to go against RFC 2183/2231 in some areas for interoperability + $value = $this->getTokenAsEncodedWord($origValue); + $encoded = false; + } + } + + $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value); + + // Need to add indices + if (count($valueLines) > 1) { + $paramLines = array(); + foreach ($valueLines as $i => $line) { + $paramLines[] = $name . '*' . $i . + $this->_getEndOfParameterValue($line, true, $i == 0); + } + + return implode(";\r\n ", $paramLines); + } else { + return $name . $this->_getEndOfParameterValue( + $valueLines[0], $encoded, true + ); + } } - - $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value); - - //Need to add indices - if (count($valueLines) > 1) + + /** + * Returns the parameter value from the "=" and beyond. + * + * @param string $value to append + * @param bool $encoded + * @param bool $firstLine + * + * @return string + */ + private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false) { - $paramLines = array(); - foreach ($valueLines as $i => $line) - { - $paramLines[] = $name . '*' . $i . - $this->_getEndOfParameterValue($line, true, $i == 0); - } - return implode(";\r\n ", $paramLines); + if (!preg_match('/^' . self::TOKEN_REGEX . '$/D', $value)) { + $value = '"' . $value . '"'; + } + $prepend = '='; + if ($encoded) { + $prepend = '*='; + if ($firstLine) { + $prepend = '*=' . $this->getCharset() . "'" . $this->getLanguage() . + "'"; + } + } + + return $prepend . $value; } - else - { - return $name . $this->_getEndOfParameterValue( - $valueLines[0], $encoded, true - ); - } - } - - /** - * Returns the parameter value from the "=" and beyond. - * @param string $value to append - * @param boolean $encoded - * @param boolean $firstLine - * @return string - * @access private - */ - private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false) - { - if (!preg_match('/^' . $this->_tokenRe . '$/D', $value)) - { - $value = '"' . $value . '"'; - } - $prepend = '='; - if ($encoded) - { - $prepend = '*='; - if ($firstLine) - { - $prepend = '*=' . $this->getCharset() . "'" . $this->getLanguage() . - "'"; - } - } - return $prepend . $value; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php index 7f1252d92..bfecf3f47 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php @@ -8,133 +8,139 @@ * file that was distributed with this source code. */ - /** * A Path Header in Swift Mailer, such a Return-Path. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_Headers_PathHeader extends Swift_Mime_Headers_AbstractHeader { - - /** - * The address in this Header (if specified). - * @var string - * @access private - */ - private $_address; - - /** - * Creates a new PathHeader with the given $name. - * @param string $name - * @param Swift_Mime_Grammar $grammar - */ - public function __construct($name, Swift_Mime_Grammar $grammar) - { - $this->setFieldName($name); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * @return int - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - */ - public function getFieldType() - { - return self::TYPE_PATH; - } - - /** - * Set the model for the field body. - * This method takes a string for an address. - * @param string $model - * @throws Swift_RfcComplianceException - */ - public function setFieldBodyModel($model) - { - $this->setAddress($model); - } - - /** - * Get the model for the field body. - * This method returns a string email address. - * @return mixed - */ - public function getFieldBodyModel() - { - return $this->getAddress(); - } - - /** - * Set the Address which should appear in this Header. - * @param string $address - * @throws Swift_RfcComplianceException - */ - public function setAddress($address) - { - if (is_null($address)) + /** + * The address in this Header (if specified). + * + * @var string + */ + private $_address; + + /** + * Creates a new PathHeader with the given $name. + * + * @param string $name + * @param Swift_Mime_Grammar $grammar + */ + public function __construct($name, Swift_Mime_Grammar $grammar) { - $this->_address = null; + $this->setFieldName($name); + parent::__construct($grammar); } - elseif ('' == $address) + + /** + * Get the type of Header that this instance represents. + * + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + * + * @return int + */ + public function getFieldType() { - $this->_address = ''; + return self::TYPE_PATH; } - else + + /** + * Set the model for the field body. + * This method takes a string for an address. + * + * @param string $model + * + * @throws Swift_RfcComplianceException + */ + public function setFieldBodyModel($model) { - $this->_assertValidAddress($address); - $this->_address = $address; + $this->setAddress($model); } - $this->setCachedValue(null); - } - - /** - * Get the address which is used in this Header (if any). - * Null is returned if no address is set. - * @return string - */ - public function getAddress() - { - return $this->_address; - } - - /** - * Get the string value of the body in this Header. - * This is not necessarily RFC 2822 compliant since folding white space will - * not be added at this stage (see {@link toString()} for that). - * @return string - * @see toString() - */ - public function getFieldBody() - { - if (!$this->getCachedValue()) + + /** + * Get the model for the field body. + * This method returns a string email address. + * + * @return mixed + */ + public function getFieldBodyModel() { - if (isset($this->_address)) - { - $this->setCachedValue('<' . $this->_address . '>'); - } + return $this->getAddress(); } - return $this->getCachedValue(); - } - - /** - * Throws an Exception if the address passed does not comply with RFC 2822. - * @param string $address - * @throws Swift_RfcComplianceException If invalid. - * @access private - */ - private function _assertValidAddress($address) - { - if (!preg_match('/^' . $this->getGrammar()->getDefinition('addr-spec') . '$/D', - $address)) + + /** + * Set the Address which should appear in this Header. + * + * @param string $address + * + * @throws Swift_RfcComplianceException + */ + public function setAddress($address) { - throw new Swift_RfcComplianceException( - 'Address set in PathHeader does not comply with addr-spec of RFC 2822.' - ); + if (is_null($address)) { + $this->_address = null; + } elseif ('' == $address) { + $this->_address = ''; + } else { + $this->_assertValidAddress($address); + $this->_address = $address; + } + $this->setCachedValue(null); + } + + /** + * Get the address which is used in this Header (if any). + * + * Null is returned if no address is set. + * + * @return string + */ + public function getAddress() + { + return $this->_address; + } + + /** + * Get the string value of the body in this Header. + * + * This is not necessarily RFC 2822 compliant since folding white space will + * not be added at this stage (see {@link toString()} for that). + * + * @see toString() + * + * @return string + */ + public function getFieldBody() + { + if (!$this->getCachedValue()) { + if (isset($this->_address)) { + $this->setCachedValue('<' . $this->_address . '>'); + } + } + + return $this->getCachedValue(); + } + + /** + * Throws an Exception if the address passed does not comply with RFC 2822. + * + * @param string $address + * + * @throws Swift_RfcComplianceException If address is invalid + */ + private function _assertValidAddress($address) + { + if (!preg_match('/^' . $this->getGrammar()->getDefinition('addr-spec') . '$/D', + $address)) + { + throw new Swift_RfcComplianceException( + 'Address set in PathHeader does not comply with addr-spec of RFC 2822.' + ); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php index 491d7eb4a..2de49b4d0 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php @@ -8,100 +8,107 @@ * file that was distributed with this source code. */ - /** * A Simple MIME Header. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mime_Headers_UnstructuredHeader - extends Swift_Mime_Headers_AbstractHeader +class Swift_Mime_Headers_UnstructuredHeader extends Swift_Mime_Headers_AbstractHeader { - - /** - * The value of this Header. - * @var string - * @access private - */ - private $_value; - - /** - * Creates a new SimpleHeader with $name. - * @param string $name - * @param Swift_Mime_HeaderEncoder $encoder - * @param Swift_Mime_Grammar $grammar - */ - public function __construct($name, Swift_Mime_HeaderEncoder $encoder, Swift_Mime_Grammar $grammar) - { - $this->setFieldName($name); - $this->setEncoder($encoder); - parent::__construct($grammar); - } - - /** - * Get the type of Header that this instance represents. - * @return int - * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX - * @see TYPE_DATE, TYPE_ID, TYPE_PATH - */ - public function getFieldType() - { - return self::TYPE_TEXT; - } - - /** - * Set the model for the field body. - * This method takes a string for the field value. - * @param string $model - */ - public function setFieldBodyModel($model) - { - $this->setValue($model); - } - - /** - * Get the model for the field body. - * This method returns a string. - * @return string - */ - public function getFieldBodyModel() - { - return $this->getValue(); - } - - /** - * Get the (unencoded) value of this header. - * @return string - */ - public function getValue() - { - return $this->_value; - } - - /** - * Set the (unencoded) value of this header. - * @param string $value - */ - public function setValue($value) - { - $this->clearCachedValueIf($this->_value != $value); - $this->_value = $value; - } - - /** - * Get the value of this header prepared for rendering. - * @return string - */ - public function getFieldBody() - { - if (!$this->getCachedValue()) + /** + * The value of this Header. + * + * @var string + */ + private $_value; + + /** + * Creates a new SimpleHeader with $name. + * + * @param string $name + * @param Swift_Mime_HeaderEncoder $encoder + * @param Swift_Mime_Grammar $grammar + */ + public function __construct($name, Swift_Mime_HeaderEncoder $encoder, Swift_Mime_Grammar $grammar) { - $this->setCachedValue( - $this->encodeWords($this, $this->_value) - ); + $this->setFieldName($name); + $this->setEncoder($encoder); + parent::__construct($grammar); + } + + /** + * Get the type of Header that this instance represents. + * + * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX + * @see TYPE_DATE, TYPE_ID, TYPE_PATH + * + * @return int + */ + public function getFieldType() + { + return self::TYPE_TEXT; + } + + /** + * Set the model for the field body. + * + * This method takes a string for the field value. + * + * @param string $model + */ + public function setFieldBodyModel($model) + { + $this->setValue($model); + } + + /** + * Get the model for the field body. + * + * This method returns a string. + * + * @return string + */ + public function getFieldBodyModel() + { + return $this->getValue(); + } + + /** + * Get the (unencoded) value of this header. + * + * @return string + */ + public function getValue() + { + return $this->_value; + } + + /** + * Set the (unencoded) value of this header. + * + * @param string $value + */ + public function setValue($value) + { + $this->clearCachedValueIf($this->_value != $value); + $this->_value = $value; + } + + /** + * Get the value of this header prepared for rendering. + * + * @return string + */ + public function getFieldBody() + { + if (!$this->getCachedValue()) { + $this->setCachedValue( + $this->encodeWords($this, $this->_value) + ); + } + + return $this->getCachedValue(); } - return $this->getCachedValue(); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/Message.php b/lib/swiftmailer/lib/classes/Swift/Mime/Message.php index 497f36eaa..59df2f2e9 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/Message.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/Message.php @@ -8,222 +8,218 @@ * file that was distributed with this source code. */ - /** * A Message (RFC 2822) object. - * - * @package Swift + * + * @package Swift * @subpackage Mime - * - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_Message extends Swift_Mime_MimeEntity { - - /** - * Generates a valid Message-ID and switches to it. - * - * @return string - */ - public function generateId(); - - /** - * Set the subject of the message. - * - * @param string $subject - */ - public function setSubject($subject); - - /** - * Get the subject of the message. - * - * @return string - */ - public function getSubject(); - - /** - * Set the origination date of the message as a UNIX timestamp. - * - * @param int $date - */ - public function setDate($date); - - /** - * Get the origination date of the message as a UNIX timestamp. - * - * @return int - */ - public function getDate(); - - /** - * Set the return-path (bounce-detect) address. - * - * @param string $address - */ - public function setReturnPath($address); - - /** - * Get the return-path (bounce-detect) address. - * - * @return string - */ - public function getReturnPath(); - - /** - * Set the sender of this message. - * - * If multiple addresses are present in the From field, this SHOULD be set. - * - * According to RFC 2822 it is a requirement when there are multiple From - * addresses, but Swift itself does not require it directly. - * - * An associative array (with one element!) can be used to provide a display- - * name: i.e. array('email@address' => 'Real Name'). - * - * If the second parameter is provided and the first is a string, then $name - * is associated with the address. - * - * @param mixed $address - * @param string $name optional - */ - public function setSender($address, $name = null); - - /** - * Get the sender address for this message. - * - * This has a higher significance than the From address. - * - * @return string - */ - public function getSender(); - - /** - * Set the From address of this message. - * - * It is permissible for multiple From addresses to be set using an array. - * - * If multiple From addresses are used, you SHOULD set the Sender address and - * according to RFC 2822, MUST set the sender address. - * - * An array can be used if display names are to be provided: i.e. - * array('email@address.com' => 'Real Name'). - * - * If the second parameter is provided and the first is a string, then $name - * is associated with the address. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setFrom($addresses, $name = null); - - /** - * Get the From address(es) of this message. - * - * This method always returns an associative array where the keys are the - * addresses. - * - * @return string[] - */ - public function getFrom(); - - /** - * Set the Reply-To address(es). - * - * Any replies from the receiver will be sent to this address. - * - * It is permissible for multiple reply-to addresses to be set using an array. - * - * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. - * - * If the second parameter is provided and the first is a string, then $name - * is associated with the address. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setReplyTo($addresses, $name = null); - - /** - * Get the Reply-To addresses for this message. - * - * This method always returns an associative array where the keys provide the - * email addresses. - * - * @return string[] - */ - public function getReplyTo(); - - /** - * Set the To address(es). - * - * Recipients set in this field will receive a copy of this message. - * - * This method has the same synopsis as {@link setFrom()} and {@link setCc()}. - * - * If the second parameter is provided and the first is a string, then $name - * is associated with the address. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setTo($addresses, $name = null); - - /** - * Get the To addresses for this message. - * - * This method always returns an associative array, whereby the keys provide - * the actual email addresses. - * - * @return string[] - */ - public function getTo(); - - /** - * Set the Cc address(es). - * - * Recipients set in this field will receive a 'carbon-copy' of this message. - * - * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setCc($addresses, $name = null); - - /** - * Get the Cc addresses for this message. - * - * This method always returns an associative array, whereby the keys provide - * the actual email addresses. - * - * @return string[] - */ - public function getCc(); - - /** - * Set the Bcc address(es). - * - * Recipients set in this field will receive a 'blind-carbon-copy' of this - * message. - * - * In other words, they will get the message, but any other recipients of the - * message will have no such knowledge of their receipt of it. - * - * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. - * - * @param mixed $addresses - * @param string $name optional - */ - public function setBcc($addresses, $name = null); - - /** - * Get the Bcc addresses for this message. - * - * This method always returns an associative array, whereby the keys provide - * the actual email addresses. - * - * @return string[] - */ - public function getBcc(); - + /** + * Generates a valid Message-ID and switches to it. + * + * @return string + */ + public function generateId(); + + /** + * Set the subject of the message. + * + * @param string $subject + */ + public function setSubject($subject); + + /** + * Get the subject of the message. + * + * @return string + */ + public function getSubject(); + + /** + * Set the origination date of the message as a UNIX timestamp. + * + * @param int $date + */ + public function setDate($date); + + /** + * Get the origination date of the message as a UNIX timestamp. + * + * @return int + */ + public function getDate(); + + /** + * Set the return-path (bounce-detect) address. + * + * @param string $address + */ + public function setReturnPath($address); + + /** + * Get the return-path (bounce-detect) address. + * + * @return string + */ + public function getReturnPath(); + + /** + * Set the sender of this message. + * + * If multiple addresses are present in the From field, this SHOULD be set. + * + * According to RFC 2822 it is a requirement when there are multiple From + * addresses, but Swift itself does not require it directly. + * + * An associative array (with one element!) can be used to provide a display- + * name: i.e. array('email@address' => 'Real Name'). + * + * If the second parameter is provided and the first is a string, then $name + * is associated with the address. + * + * @param mixed $address + * @param string $name optional + */ + public function setSender($address, $name = null); + + /** + * Get the sender address for this message. + * + * This has a higher significance than the From address. + * + * @return string + */ + public function getSender(); + + /** + * Set the From address of this message. + * + * It is permissible for multiple From addresses to be set using an array. + * + * If multiple From addresses are used, you SHOULD set the Sender address and + * according to RFC 2822, MUST set the sender address. + * + * An array can be used if display names are to be provided: i.e. + * array('email@address.com' => 'Real Name'). + * + * If the second parameter is provided and the first is a string, then $name + * is associated with the address. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setFrom($addresses, $name = null); + + /** + * Get the From address(es) of this message. + * + * This method always returns an associative array where the keys are the + * addresses. + * + * @return string[] + */ + public function getFrom(); + + /** + * Set the Reply-To address(es). + * + * Any replies from the receiver will be sent to this address. + * + * It is permissible for multiple reply-to addresses to be set using an array. + * + * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. + * + * If the second parameter is provided and the first is a string, then $name + * is associated with the address. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setReplyTo($addresses, $name = null); + + /** + * Get the Reply-To addresses for this message. + * + * This method always returns an associative array where the keys provide the + * email addresses. + * + * @return string[] + */ + public function getReplyTo(); + + /** + * Set the To address(es). + * + * Recipients set in this field will receive a copy of this message. + * + * This method has the same synopsis as {@link setFrom()} and {@link setCc()}. + * + * If the second parameter is provided and the first is a string, then $name + * is associated with the address. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setTo($addresses, $name = null); + + /** + * Get the To addresses for this message. + * + * This method always returns an associative array, whereby the keys provide + * the actual email addresses. + * + * @return string[] + */ + public function getTo(); + + /** + * Set the Cc address(es). + * + * Recipients set in this field will receive a 'carbon-copy' of this message. + * + * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setCc($addresses, $name = null); + + /** + * Get the Cc addresses for this message. + * + * This method always returns an associative array, whereby the keys provide + * the actual email addresses. + * + * @return string[] + */ + public function getCc(); + + /** + * Set the Bcc address(es). + * + * Recipients set in this field will receive a 'blind-carbon-copy' of this + * message. + * + * In other words, they will get the message, but any other recipients of the + * message will have no such knowledge of their receipt of it. + * + * This method has the same synopsis as {@link setFrom()} and {@link setTo()}. + * + * @param mixed $addresses + * @param string $name optional + */ + public function setBcc($addresses, $name = null); + + /** + * Get the Bcc addresses for this message. + * + * This method always returns an associative array, whereby the keys provide + * the actual email addresses. + * + * @return string[] + */ + public function getBcc(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php b/lib/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php index b46c296d6..bc9f2ad37 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php @@ -8,98 +8,110 @@ * file that was distributed with this source code. */ - /** * A MIME entity, such as an attachment. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -interface Swift_Mime_MimeEntity - extends Swift_Mime_CharsetObserver, Swift_Mime_EncodingObserver +interface Swift_Mime_MimeEntity extends Swift_Mime_CharsetObserver, Swift_Mime_EncodingObserver { - - /** Main message document; there can only be one of these */ - const LEVEL_TOP = 16; - - /** An entity which nests with the same precedence as an attachment */ - const LEVEL_MIXED = 256; - - /** An entity which nests with the same precedence as a mime part */ - const LEVEL_ALTERNATIVE = 4096; - - /** An entity which nests with the same precedence as embedded content */ - const LEVEL_RELATED = 65536; - - /** - * Get the level at which this entity shall be nested in final document. - * The lower the value, the more outermost the entity will be nested. - * @return int - * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE - */ - public function getNestingLevel(); - - /** - * Get the qualified content-type of this mime entity. - * @return string - */ - public function getContentType(); - - /** - * Returns a unique ID for this entity. - * For most entities this will likely be the Content-ID, though it has - * no explicit semantic meaning and can be considered an identifier for - * programming logic purposes. - * If a Content-ID header is present, this value SHOULD match the value of - * the header. - * @return string - */ - public function getId(); - - /** - * Get all children nested inside this entity. - * These are not just the immediate children, but all children. - * @return Swift_Mime_MimeEntity[] - */ - public function getChildren(); - - /** - * Set all children nested inside this entity. - * This includes grandchildren. - * @param Swift_Mime_MimeEntity[] $children - */ - public function setChildren(array $children); - - /** - * Get the collection of Headers in this Mime entity. - * @return Swift_Mime_Header[] - */ - public function getHeaders(); - - /** - * Get the body content of this entity as a string. - * Returns NULL if no body has been set. - * @return string - */ - public function getBody(); - - /** - * Set the body content of this entity as a string. - * @param string $body - * @param string $contentType optional - */ - public function setBody($body, $contentType = null); - - /** - * Get this entire entity in its string form. - * @return string - */ - public function toString(); - - /** - * Get this entire entity as a ByteStream. - * @param Swift_InputByteStream $is to write to - */ - public function toByteStream(Swift_InputByteStream $is); - + /** Main message document; there can only be one of these */ + const LEVEL_TOP = 16; + + /** An entity which nests with the same precedence as an attachment */ + const LEVEL_MIXED = 256; + + /** An entity which nests with the same precedence as a mime part */ + const LEVEL_ALTERNATIVE = 4096; + + /** An entity which nests with the same precedence as embedded content */ + const LEVEL_RELATED = 65536; + + /** + * Get the level at which this entity shall be nested in final document. + * + * The lower the value, the more outermost the entity will be nested. + * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE + * + * @return int + */ + public function getNestingLevel(); + + /** + * Get the qualified content-type of this mime entity. + * @return string + */ + public function getContentType(); + + /** + * Returns a unique ID for this entity. + * + * For most entities this will likely be the Content-ID, though it has + * no explicit semantic meaning and can be considered an identifier for + * programming logic purposes. + * + * If a Content-ID header is present, this value SHOULD match the value of + * the header. + * + * @return string + */ + public function getId(); + + /** + * Get all children nested inside this entity. + * + * These are not just the immediate children, but all children. + * + * @return Swift_Mime_MimeEntity[] + */ + public function getChildren(); + + /** + * Set all children nested inside this entity. + * + * This includes grandchildren. + * + * @param Swift_Mime_MimeEntity[] $children + */ + public function setChildren(array $children); + + /** + * Get the collection of Headers in this Mime entity. + * + * @return Swift_Mime_Header[] + */ + public function getHeaders(); + + /** + * Get the body content of this entity as a string. + * + * Returns NULL if no body has been set. + * + * @return string|null + */ + public function getBody(); + + /** + * Set the body content of this entity as a string. + * + * @param string $body + * @param string $contentType optional + */ + public function setBody($body, $contentType = null); + + /** + * Get this entire entity in its string form. + * + * @return string + */ + public function toString(); + + /** + * Get this entire entity as a ByteStream. + * + * @param Swift_InputByteStream $is to write to + */ + public function toByteStream(Swift_InputByteStream $is); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/MimePart.php b/lib/swiftmailer/lib/classes/Swift/Mime/MimePart.php index a8c5ef936..1efcc8cd7 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/MimePart.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/MimePart.php @@ -8,186 +8,211 @@ * file that was distributed with this source code. */ - /** * A MIME part, in a multipart message. - * - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity { - - /** The format parameter last specified by the user */ - protected $_userFormat; - - /** The charset last specified by the user */ - protected $_userCharset; - - /** The delsp parameter last specified by the user */ - protected $_userDelSp; - - /** The nesting level of this MimePart */ - private $_nestingLevel = self::LEVEL_ALTERNATIVE; - - /** - * Create a new MimePart with $headers, $encoder and $cache. - * - * @param Swift_Mime_HeaderSet $headers - * @param Swift_Mime_ContentEncoder $encoder - * @param Swift_KeyCache $cache - * @param Swift_Mime_Grammar $grammar - * @param string $charset - */ - public function __construct(Swift_Mime_HeaderSet $headers, - Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $charset = null) - { - parent::__construct($headers, $encoder, $cache, $grammar); - $this->setContentType('text/plain'); - if (!is_null($charset)) + /** The format parameter last specified by the user */ + protected $_userFormat; + + /** The charset last specified by the user */ + protected $_userCharset; + + /** The delsp parameter last specified by the user */ + protected $_userDelSp; + + /** The nesting level of this MimePart */ + private $_nestingLevel = self::LEVEL_ALTERNATIVE; + + /** + * Create a new MimePart with $headers, $encoder and $cache. + * + * @param Swift_Mime_HeaderSet $headers + * @param Swift_Mime_ContentEncoder $encoder + * @param Swift_KeyCache $cache + * @param Swift_Mime_Grammar $grammar + * @param string $charset + */ + public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $charset = null) { - $this->setCharset($charset); + parent::__construct($headers, $encoder, $cache, $grammar); + $this->setContentType('text/plain'); + if (!is_null($charset)) { + $this->setCharset($charset); + } } - } - - /** - * Set the body of this entity, either as a string, or as an instance of - * {@link Swift_OutputByteStream}. - * - * @param mixed $body - * @param string $contentType optional - * @param string $charset optional - */ - public function setBody($body, $contentType = null, $charset = null) - { - parent::setBody($body, $contentType); - if (isset($charset)) + + /** + * Set the body of this entity, either as a string, or as an instance of + * {@link Swift_OutputByteStream}. + * + * @param mixed $body + * @param string $contentType optional + * @param string $charset optional + * + * @return Swift_Mime_MimePart + */ + public function setBody($body, $contentType = null, $charset = null) { - $this->setCharset($charset); + if (isset($charset)) { + $this->setCharset($charset); + } + $body = $this->_convertString($body); + + parent::setBody($body, $contentType); + + return $this; } - return $this; - } - - /** - * Get the character set of this entity. - * - * @return string - */ - public function getCharset() - { - return $this->_getHeaderParameter('Content-Type', 'charset'); - } - - /** - * Set the character set of this entity. - * - * @param string $charset - */ - public function setCharset($charset) - { - $this->_setHeaderParameter('Content-Type', 'charset', $charset); - if ($charset !== $this->_userCharset) + + /** + * Get the character set of this entity. + * + * @return string + */ + public function getCharset() { - $this->_clearCache(); + return $this->_getHeaderParameter('Content-Type', 'charset'); } - $this->_userCharset = $charset; - parent::charsetChanged($charset); - return $this; - } - - /** - * Get the format of this entity (i.e. flowed or fixed). - * - * @return string - */ - public function getFormat() - { - return $this->_getHeaderParameter('Content-Type', 'format'); - } - - /** - * Set the format of this entity (flowed or fixed). - * - * @param string $format - */ - public function setFormat($format) - { - $this->_setHeaderParameter('Content-Type', 'format', $format); - $this->_userFormat = $format; - return $this; - } - - /** - * Test if delsp is being used for this entity. - * - * @return boolean - */ - public function getDelSp() - { - return ($this->_getHeaderParameter('Content-Type', 'delsp') == 'yes') - ? true - : false; - } - - /** - * Turn delsp on or off for this entity. - * - * @param boolean $delsp - */ - public function setDelSp($delsp = true) - { - $this->_setHeaderParameter('Content-Type', 'delsp', $delsp ? 'yes' : null); - $this->_userDelSp = $delsp; - return $this; - } - - /** - * Get the nesting level of this entity. - * - * @return int - * @see LEVEL_TOP, LEVEL_ALTERNATIVE, LEVEL_MIXED, LEVEL_RELATED - */ - public function getNestingLevel() - { - return $this->_nestingLevel; - } - - /** - * Receive notification that the charset has changed on this document, or a - * parent document. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->setCharset($charset); - } - - // -- Protected methods - - /** Fix the content-type and encoding of this entity */ - protected function _fixHeaders() - { - parent::_fixHeaders(); - if (count($this->getChildren())) + + /** + * Set the character set of this entity. + * + * @param string $charset + * + * @return Swift_Mime_MimePart + */ + public function setCharset($charset) { - $this->_setHeaderParameter('Content-Type', 'charset', null); - $this->_setHeaderParameter('Content-Type', 'format', null); - $this->_setHeaderParameter('Content-Type', 'delsp', null); + $this->_setHeaderParameter('Content-Type', 'charset', $charset); + if ($charset !== $this->_userCharset) { + $this->_clearCache(); + } + $this->_userCharset = $charset; + parent::charsetChanged($charset); + + return $this; } - else + + /** + * Get the format of this entity (i.e. flowed or fixed). + * + * @return string + */ + public function getFormat() { - $this->setCharset($this->_userCharset); - $this->setFormat($this->_userFormat); - $this->setDelSp($this->_userDelSp); + return $this->_getHeaderParameter('Content-Type', 'format'); + } + + /** + * Set the format of this entity (flowed or fixed). + * + * @param string $format + * + * @return Swift_Mime_MimePart + */ + public function setFormat($format) + { + $this->_setHeaderParameter('Content-Type', 'format', $format); + $this->_userFormat = $format; + + return $this; + } + + /** + * Test if delsp is being used for this entity. + * + * @return bool + */ + public function getDelSp() + { + return ($this->_getHeaderParameter('Content-Type', 'delsp') == 'yes') + ? true + : false; + } + + /** + * Turn delsp on or off for this entity. + * + * @param bool $delsp + * + * @return Swift_Mime_MimePart + */ + public function setDelSp($delsp = true) + { + $this->_setHeaderParameter('Content-Type', 'delsp', $delsp ? 'yes' : null); + $this->_userDelSp = $delsp; + + return $this; + } + + /** + * Get the nesting level of this entity. + * + * @see LEVEL_TOP, LEVEL_ALTERNATIVE, LEVEL_MIXED, LEVEL_RELATED + * + * @return int + */ + public function getNestingLevel() + { + return $this->_nestingLevel; + } + + /** + * Receive notification that the charset has changed on this document, or a + * parent document. + * + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->setCharset($charset); + } + + // -- Protected methods + + /** Fix the content-type and encoding of this entity */ + protected function _fixHeaders() + { + parent::_fixHeaders(); + if (count($this->getChildren())) { + $this->_setHeaderParameter('Content-Type', 'charset', null); + $this->_setHeaderParameter('Content-Type', 'format', null); + $this->_setHeaderParameter('Content-Type', 'delsp', null); + } else { + $this->setCharset($this->_userCharset); + $this->setFormat($this->_userFormat); + $this->setDelSp($this->_userDelSp); + } + } + + /** Set the nesting level of this entity */ + protected function _setNestingLevel($level) + { + $this->_nestingLevel = $level; + } + + /** Encode charset when charset is not utf-8 */ + protected function _convertString($string) + { + $charset = strtolower($this->getCharset()); + if (!in_array($charset, array('utf-8', 'iso-8859-1', ''))) { + // mb_convert_encoding must be the first one to check, since iconv cannot convert some words. + if (function_exists('mb_convert_encoding')) { + $string = mb_convert_encoding($string, 'utf-8', $charset); + } elseif (function_exists('iconv')) { + $string = iconv($charset, 'utf-8//TRANSLIT//IGNORE', $string); + } else { + throw new Swift_SwiftException('No suitable convert encoding function (use UTF-8 as your charset or install the mbstring or iconv extension).'); + } + + return $string; + } + + return $string; } - } - - /** Set the nesting level of this entity */ - protected function _setNestingLevel($level) - { - $this->_nestingLevel = $level; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php b/lib/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php index 12e3586cc..95172ec40 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php @@ -8,27 +8,29 @@ * file that was distributed with this source code. */ - /** * A MIME Header with parameters. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Mime_ParameterizedHeader extends Swift_Mime_Header { - - /** - * Set the value of $parameter. - * @param string $parameter - * @param string $value - */ - public function setParameter($parameter, $value); - - /** - * Get the value of $parameter. - * @return string - */ - public function getParameter($parameter); - + /** + * Set the value of $parameter. + * + * @param string $parameter + * @param string $value + */ + public function setParameter($parameter, $value); + + /** + * Get the value of $parameter. + * + * @param string $parameter + * + * @return string + */ + public function getParameter($parameter); } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php b/lib/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php index 35156d32a..b82e33b4d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php @@ -8,177 +8,185 @@ * file that was distributed with this source code. */ - /** * Creates MIME headers. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_SimpleHeaderFactory implements Swift_Mime_HeaderFactory { + /** The HeaderEncoder used by these headers */ + private $_encoder; - /** The HeaderEncoder used by these headers */ - private $_encoder; - - /** The Encoder used by parameters */ - private $_paramEncoder; - - /** The Grammar */ - private $_grammar; - - /** The charset of created Headers */ - private $_charset; - - /** - * Creates a new SimpleHeaderFactory using $encoder and $paramEncoder. - * @param Swift_Mime_HeaderEncoder $encoder - * @param Swift_Encoder $paramEncoder - * @param Swift_Mime_Grammar $grammar - * @param string $charset - */ - public function __construct(Swift_Mime_HeaderEncoder $encoder, - Swift_Encoder $paramEncoder, Swift_Mime_Grammar $grammar, $charset = null) - { - $this->_encoder = $encoder; - $this->_paramEncoder = $paramEncoder; - $this->_grammar = $grammar; - $this->_charset = $charset; - } - - /** - * Create a new Mailbox Header with a list of $addresses. - * @param string $name - * @param array|string $addresses - * @return Swift_Mime_Header - */ - public function createMailboxHeader($name, $addresses = null) - { - $header = new Swift_Mime_Headers_MailboxHeader($name, $this->_encoder, $this->_grammar); - if (isset($addresses)) + /** The Encoder used by parameters */ + private $_paramEncoder; + + /** The Grammar */ + private $_grammar; + + /** The charset of created Headers */ + private $_charset; + + /** + * Creates a new SimpleHeaderFactory using $encoder and $paramEncoder. + * + * @param Swift_Mime_HeaderEncoder $encoder + * @param Swift_Encoder $paramEncoder + * @param Swift_Mime_Grammar $grammar + * @param string|null $charset + */ + public function __construct(Swift_Mime_HeaderEncoder $encoder, Swift_Encoder $paramEncoder, Swift_Mime_Grammar $grammar, $charset = null) { - $header->setFieldBodyModel($addresses); + $this->_encoder = $encoder; + $this->_paramEncoder = $paramEncoder; + $this->_grammar = $grammar; + $this->_charset = $charset; } - $this->_setHeaderCharset($header); - return $header; - } - - /** - * Create a new Date header using $timestamp (UNIX time). - * @param string $name - * @param int $timestamp - * @return Swift_Mime_Header - */ - public function createDateHeader($name, $timestamp = null) - { - $header = new Swift_Mime_Headers_DateHeader($name, $this->_grammar); - if (isset($timestamp)) + + /** + * Create a new Mailbox Header with a list of $addresses. + * + * @param string $name + * @param array|string|null $addresses + * + * @return Swift_Mime_Header + */ + public function createMailboxHeader($name, $addresses = null) { - $header->setFieldBodyModel($timestamp); + $header = new Swift_Mime_Headers_MailboxHeader($name, $this->_encoder, $this->_grammar); + if (isset($addresses)) { + $header->setFieldBodyModel($addresses); + } + $this->_setHeaderCharset($header); + + return $header; } - $this->_setHeaderCharset($header); - return $header; - } - - /** - * Create a new basic text header with $name and $value. - * @param string $name - * @param string $value - * @return Swift_Mime_Header - */ - public function createTextHeader($name, $value = null) - { - $header = new Swift_Mime_Headers_UnstructuredHeader($name, $this->_encoder, $this->_grammar); - if (isset($value)) + + /** + * Create a new Date header using $timestamp (UNIX time). + * @param string $name + * @param int|null $timestamp + * + * @return Swift_Mime_Header + */ + public function createDateHeader($name, $timestamp = null) { - $header->setFieldBodyModel($value); + $header = new Swift_Mime_Headers_DateHeader($name, $this->_grammar); + if (isset($timestamp)) { + $header->setFieldBodyModel($timestamp); + } + $this->_setHeaderCharset($header); + + return $header; } - $this->_setHeaderCharset($header); - return $header; - } - - /** - * Create a new ParameterizedHeader with $name, $value and $params. - * @param string $name - * @param string $value - * @param array $params - * @return Swift_Mime_ParameterizedHeader - */ - public function createParameterizedHeader($name, $value = null, - $params = array()) - { - $header = new Swift_Mime_Headers_ParameterizedHeader($name, - $this->_encoder, (strtolower($name) == 'content-disposition') - ? $this->_paramEncoder - : null, - $this->_grammar - ); - if (isset($value)) + + /** + * Create a new basic text header with $name and $value. + * + * @param string $name + * @param string $value + * + * @return Swift_Mime_Header + */ + public function createTextHeader($name, $value = null) { - $header->setFieldBodyModel($value); + $header = new Swift_Mime_Headers_UnstructuredHeader($name, $this->_encoder, $this->_grammar); + if (isset($value)) { + $header->setFieldBodyModel($value); + } + $this->_setHeaderCharset($header); + + return $header; } - foreach ($params as $k => $v) + + /** + * Create a new ParameterizedHeader with $name, $value and $params. + * + * @param string $name + * @param string $value + * @param array $params + * + * @return Swift_Mime_ParameterizedHeader + */ + public function createParameterizedHeader($name, $value = null, + $params = array()) { - $header->setParameter($k, $v); + $header = new Swift_Mime_Headers_ParameterizedHeader($name, + $this->_encoder, (strtolower($name) == 'content-disposition') + ? $this->_paramEncoder + : null, + $this->_grammar + ); + if (isset($value)) { + $header->setFieldBodyModel($value); + } + foreach ($params as $k => $v) { + $header->setParameter($k, $v); + } + $this->_setHeaderCharset($header); + + return $header; } - $this->_setHeaderCharset($header); - return $header; - } - - /** - * Create a new ID header for Message-ID or Content-ID. - * @param string $name - * @param string|array $ids - * @return Swift_Mime_Header - */ - public function createIdHeader($name, $ids = null) - { - $header = new Swift_Mime_Headers_IdentificationHeader($name, $this->_grammar); - if (isset($ids)) + + /** + * Create a new ID header for Message-ID or Content-ID. + * + * @param string $name + * @param string|array $ids + * + * @return Swift_Mime_Header + */ + public function createIdHeader($name, $ids = null) { - $header->setFieldBodyModel($ids); + $header = new Swift_Mime_Headers_IdentificationHeader($name, $this->_grammar); + if (isset($ids)) { + $header->setFieldBodyModel($ids); + } + $this->_setHeaderCharset($header); + + return $header; } - $this->_setHeaderCharset($header); - return $header; - } - - /** - * Create a new Path header with an address (path) in it. - * @param string $name - * @param string $path - * @return Swift_Mime_Header - */ - public function createPathHeader($name, $path = null) - { - $header = new Swift_Mime_Headers_PathHeader($name, $this->_grammar); - if (isset($path)) + + /** + * Create a new Path header with an address (path) in it. + * + * @param string $name + * @param string $path + * + * @return Swift_Mime_Header + */ + public function createPathHeader($name, $path = null) { - $header->setFieldBodyModel($path); + $header = new Swift_Mime_Headers_PathHeader($name, $this->_grammar); + if (isset($path)) { + $header->setFieldBodyModel($path); + } + $this->_setHeaderCharset($header); + + return $header; } - $this->_setHeaderCharset($header); - return $header; - } - - /** - * Notify this observer that the entity's charset has changed. - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->_charset = $charset; - $this->_encoder->charsetChanged($charset); - $this->_paramEncoder->charsetChanged($charset); - } - - // -- Private methods - - /** Apply the charset to the Header */ - private function _setHeaderCharset(Swift_Mime_Header $header) - { - if (isset($this->_charset)) + + /** + * Notify this observer that the entity's charset has changed. + * + * @param string $charset + */ + public function charsetChanged($charset) { - $header->setCharset($this->_charset); + $this->_charset = $charset; + $this->_encoder->charsetChanged($charset); + $this->_paramEncoder->charsetChanged($charset); + } + + // -- Private methods + + /** Apply the charset to the Header */ + private function _setHeaderCharset(Swift_Mime_Header $header) + { + if (isset($this->_charset)) { + $header->setCharset($this->_charset); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php b/lib/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php index e3435ad8d..bd6ed6bcd 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php @@ -8,387 +8,380 @@ * file that was distributed with this source code. */ - /** * A collection of MIME headers. - * - * @package Swift + * + * @package Swift * @subpackage Mime - * - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_SimpleHeaderSet implements Swift_Mime_HeaderSet { - - /** HeaderFactory */ - private $_factory; - - /** Collection of set Headers */ - private $_headers = array(); - - /** Field ordering details */ - private $_order = array(); - - /** List of fields which are required to be displayed */ - private $_required = array(); - - /** The charset used by Headers */ - private $_charset; - - /** - * Create a new SimpleHeaderSet with the given $factory. - * - * @param Swift_Mime_HeaderFactory $factory - * @param string $charset - */ - public function __construct(Swift_Mime_HeaderFactory $factory, - $charset = null) - { - $this->_factory = $factory; - if (isset($charset)) + /** HeaderFactory */ + private $_factory; + + /** Collection of set Headers */ + private $_headers = array(); + + /** Field ordering details */ + private $_order = array(); + + /** List of fields which are required to be displayed */ + private $_required = array(); + + /** The charset used by Headers */ + private $_charset; + + /** + * Create a new SimpleHeaderSet with the given $factory. + * + * @param Swift_Mime_HeaderFactory $factory + * @param string $charset + */ + public function __construct(Swift_Mime_HeaderFactory $factory, $charset = null) { - $this->setCharset($charset); + $this->_factory = $factory; + if (isset($charset)) { + $this->setCharset($charset); + } } - } - - /** - * Set the charset used by these headers. - * - * @param string $charset - */ - public function setCharset($charset) - { - $this->_charset = $charset; - $this->_factory->charsetChanged($charset); - $this->_notifyHeadersOfCharset($charset); - } - - /** - * Add a new Mailbox Header with a list of $addresses. - * - * @param string $name - * @param array|string $addresses - */ - public function addMailboxHeader($name, $addresses = null) - { - $this->_storeHeader($name, - $this->_factory->createMailboxHeader($name, $addresses)); - } - - /** - * Add a new Date header using $timestamp (UNIX time). - * - * @param string $name - * @param int $timestamp - */ - public function addDateHeader($name, $timestamp = null) - { - $this->_storeHeader($name, - $this->_factory->createDateHeader($name, $timestamp)); - } - - /** - * Add a new basic text header with $name and $value. - * - * @param string $name - * @param string $value - */ - public function addTextHeader($name, $value = null) - { - $this->_storeHeader($name, - $this->_factory->createTextHeader($name, $value)); - } - - /** - * Add a new ParameterizedHeader with $name, $value and $params. - * - * @param string $name - * @param string $value - * @param array $params - */ - public function addParameterizedHeader($name, $value = null, - $params = array()) - { - $this->_storeHeader($name, - $this->_factory->createParameterizedHeader($name, $value, - $params)); - } - - /** - * Add a new ID header for Message-ID or Content-ID. - * - * @param string $name - * @param string|array $ids - */ - public function addIdHeader($name, $ids = null) - { - $this->_storeHeader($name, $this->_factory->createIdHeader($name, $ids)); - } - - /** - * Add a new Path header with an address (path) in it. - * - * @param string $name - * @param string $path - */ - public function addPathHeader($name, $path = null) - { - $this->_storeHeader($name, $this->_factory->createPathHeader($name, $path)); - } - - /** - * Returns true if at least one header with the given $name exists. - * - * If multiple headers match, the actual one may be specified by $index. - * - * @param string $name - * @param int $index - * - * @return boolean - */ - public function has($name, $index = 0) - { - $lowerName = strtolower($name); - return array_key_exists($lowerName, $this->_headers) - && array_key_exists($index, $this->_headers[$lowerName]); - } - - /** - * Set a header in the HeaderSet. - * - * The header may be a previously fetched header via {@link get()} or it may - * be one that has been created separately. - * - * If $index is specified, the header will be inserted into the set at this - * offset. - * - * @param Swift_Mime_Header $header - * @param int $index - */ - public function set(Swift_Mime_Header $header, $index = 0) - { - $this->_storeHeader($header->getFieldName(), $header, $index); - } - - /** - * Get the header with the given $name. - * - * If multiple headers match, the actual one may be specified by $index. - * Returns NULL if none present. - * - * @param string $name - * @param int $index - * - * @return Swift_Mime_Header - */ - public function get($name, $index = 0) - { - if ($this->has($name, $index)) + + /** + * Set the charset used by these headers. + * + * @param string $charset + */ + public function setCharset($charset) { - $lowerName = strtolower($name); - return $this->_headers[$lowerName][$index]; + $this->_charset = $charset; + $this->_factory->charsetChanged($charset); + $this->_notifyHeadersOfCharset($charset); } - } - - /** - * Get all headers with the given $name. - * - * @param string $name - * - * @return array - */ - public function getAll($name = null) - { - if (!isset($name)) + + /** + * Add a new Mailbox Header with a list of $addresses. + * + * @param string $name + * @param array|string $addresses + */ + public function addMailboxHeader($name, $addresses = null) { - $headers = array(); - foreach ($this->_headers as $collection) - { - $headers = array_merge($headers, $collection); - } - return $headers; + $this->_storeHeader($name, + $this->_factory->createMailboxHeader($name, $addresses)); } - - $lowerName = strtolower($name); - if (!array_key_exists($lowerName, $this->_headers)) + + /** + * Add a new Date header using $timestamp (UNIX time). + * + * @param string $name + * @param int $timestamp + */ + public function addDateHeader($name, $timestamp = null) { - return array(); + $this->_storeHeader($name, + $this->_factory->createDateHeader($name, $timestamp)); + } + + /** + * Add a new basic text header with $name and $value. + * + * @param string $name + * @param string $value + */ + public function addTextHeader($name, $value = null) + { + $this->_storeHeader($name, + $this->_factory->createTextHeader($name, $value)); + } + + /** + * Add a new ParameterizedHeader with $name, $value and $params. + * + * @param string $name + * @param string $value + * @param array $params + */ + public function addParameterizedHeader($name, $value = null, $params = array()) + { + $this->_storeHeader($name, $this->_factory->createParameterizedHeader($name, $value, $params)); + } + + /** + * Add a new ID header for Message-ID or Content-ID. + * + * @param string $name + * @param string|array $ids + */ + public function addIdHeader($name, $ids = null) + { + $this->_storeHeader($name, $this->_factory->createIdHeader($name, $ids)); + } + + /** + * Add a new Path header with an address (path) in it. + * + * @param string $name + * @param string $path + */ + public function addPathHeader($name, $path = null) + { + $this->_storeHeader($name, $this->_factory->createPathHeader($name, $path)); + } + + /** + * Returns true if at least one header with the given $name exists. + * + * If multiple headers match, the actual one may be specified by $index. + * + * @param string $name + * @param int $index + * + * @return bool + */ + public function has($name, $index = 0) + { + $lowerName = strtolower($name); + + return array_key_exists($lowerName, $this->_headers) && array_key_exists($index, $this->_headers[$lowerName]); + } + + /** + * Set a header in the HeaderSet. + * + * The header may be a previously fetched header via {@link get()} or it may + * be one that has been created separately. + * + * If $index is specified, the header will be inserted into the set at this + * offset. + * + * @param Swift_Mime_Header $header + * @param int $index + */ + public function set(Swift_Mime_Header $header, $index = 0) + { + $this->_storeHeader($header->getFieldName(), $header, $index); + } + + /** + * Get the header with the given $name. + * + * If multiple headers match, the actual one may be specified by $index. + * Returns NULL if none present. + * + * @param string $name + * @param int $index + * + * @return Swift_Mime_Header + */ + public function get($name, $index = 0) + { + if ($this->has($name, $index)) { + $lowerName = strtolower($name); + + return $this->_headers[$lowerName][$index]; + } + } + + /** + * Get all headers with the given $name. + * + * @param string $name + * + * @return array + */ + public function getAll($name = null) + { + if (!isset($name)) { + $headers = array(); + foreach ($this->_headers as $collection) { + $headers = array_merge($headers, $collection); + } + + return $headers; + } + + $lowerName = strtolower($name); + if (!array_key_exists($lowerName, $this->_headers)) { + return array(); + } + + return $this->_headers[$lowerName]; + } + + /** + * Return the name of all Headers + * + * @return array + */ + public function listAll() + { + $headers = $this->_headers; + if ($this->_canSort()) { + uksort($headers, array($this, '_sortHeaders')); + } + + return array_keys($headers); } - return $this->_headers[$lowerName]; - } - - /** - * Remove the header with the given $name if it's set. - * - * If multiple headers match, the actual one may be specified by $index. - * - * @param string $name - * @param int $index - */ - public function remove($name, $index = 0) - { - $lowerName = strtolower($name); - unset($this->_headers[$lowerName][$index]); - } - - /** - * Remove all headers with the given $name. - * - * @param string $name - */ - public function removeAll($name) - { - $lowerName = strtolower($name); - unset($this->_headers[$lowerName]); - } - - /** - * Create a new instance of this HeaderSet. - * - * @return Swift_Mime_HeaderSet - */ - public function newInstance() - { - return new self($this->_factory); - } - - /** - * Define a list of Header names as an array in the correct order. - * - * These Headers will be output in the given order where present. - * - * @param array $sequence - */ - public function defineOrdering(array $sequence) - { - $this->_order = array_flip(array_map('strtolower', $sequence)); - } - - /** - * Set a list of header names which must always be displayed when set. - * - * Usually headers without a field value won't be output unless set here. - * - * @param array $names - */ - public function setAlwaysDisplayed(array $names) - { - $this->_required = array_flip(array_map('strtolower', $names)); - } /** - * Notify this observer that the entity's charset has changed. - * - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->setCharset($charset); - } - - /** - * Returns a string with a representation of all headers. - * - * @return string - */ - public function toString() - { - $string = ''; - $headers = $this->_headers; - if ($this->_canSort()) + * Remove the header with the given $name if it's set. + * + * If multiple headers match, the actual one may be specified by $index. + * + * @param string $name + * @param int $index + */ + public function remove($name, $index = 0) { - uksort($headers, array($this, '_sortHeaders')); + $lowerName = strtolower($name); + unset($this->_headers[$lowerName][$index]); } - foreach ($headers as $collection) + + /** + * Remove all headers with the given $name. + * + * @param string $name + */ + public function removeAll($name) { - foreach ($collection as $header) - { - if ($this->_isDisplayed($header) || $header->getFieldBody() != '') - { - $string .= $header->toString(); + $lowerName = strtolower($name); + unset($this->_headers[$lowerName]); + } + + /** + * Create a new instance of this HeaderSet. + * + * @return Swift_Mime_HeaderSet + */ + public function newInstance() + { + return new self($this->_factory); + } + + /** + * Define a list of Header names as an array in the correct order. + * + * These Headers will be output in the given order where present. + * + * @param array $sequence + */ + public function defineOrdering(array $sequence) + { + $this->_order = array_flip(array_map('strtolower', $sequence)); + } + + /** + * Set a list of header names which must always be displayed when set. + * + * Usually headers without a field value won't be output unless set here. + * + * @param array $names + */ + public function setAlwaysDisplayed(array $names) + { + $this->_required = array_flip(array_map('strtolower', $names)); + } + + /** + * Notify this observer that the entity's charset has changed. + * + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->setCharset($charset); + } + + /** + * Returns a string with a representation of all headers. + * + * @return string + */ + public function toString() + { + $string = ''; + $headers = $this->_headers; + if ($this->_canSort()) { + uksort($headers, array($this, '_sortHeaders')); } - } + foreach ($headers as $collection) { + foreach ($collection as $header) { + if ($this->_isDisplayed($header) || $header->getFieldBody() != '') { + $string .= $header->toString(); + } + } + } + + return $string; } - return $string; - } - - /** - * Returns a string representation of this object. - * - * @return string - * - * @see toString() - */ - public function __toString() - { - return $this->toString(); - } - - // -- Private methods - - /** Save a Header to the internal collection */ - private function _storeHeader($name, Swift_Mime_Header $header, $offset = null) - { - if (!isset($this->_headers[strtolower($name)])) + + /** + * Returns a string representation of this object. + * + * @return string + * + * @see toString() + */ + public function __toString() { - $this->_headers[strtolower($name)] = array(); + return $this->toString(); } - if (!isset($offset)) + + // -- Private methods + + /** Save a Header to the internal collection */ + private function _storeHeader($name, Swift_Mime_Header $header, $offset = null) { - $this->_headers[strtolower($name)][] = $header; + if (!isset($this->_headers[strtolower($name)])) { + $this->_headers[strtolower($name)] = array(); + } + if (!isset($offset)) { + $this->_headers[strtolower($name)][] = $header; + } else { + $this->_headers[strtolower($name)][$offset] = $header; + } } - else + + /** Test if the headers can be sorted */ + private function _canSort() { - $this->_headers[strtolower($name)][$offset] = $header; + return count($this->_order) > 0; } - } - - /** Test if the headers can be sorted */ - private function _canSort() - { - return count($this->_order) > 0; - } - - /** uksort() algorithm for Header ordering */ - private function _sortHeaders($a, $b) - { - $lowerA = strtolower($a); - $lowerB = strtolower($b); - $aPos = array_key_exists($lowerA, $this->_order) - ? $this->_order[$lowerA] - : -1; - $bPos = array_key_exists($lowerB, $this->_order) - ? $this->_order[$lowerB] - : -1; - - if ($aPos == -1) + + /** uksort() algorithm for Header ordering */ + private function _sortHeaders($a, $b) { - return 1; + $lowerA = strtolower($a); + $lowerB = strtolower($b); + $aPos = array_key_exists($lowerA, $this->_order) + ? $this->_order[$lowerA] + : -1; + $bPos = array_key_exists($lowerB, $this->_order) + ? $this->_order[$lowerB] + : -1; + + if ($aPos == -1) { + return 1; + } elseif ($bPos == -1) { + return -1; + } + + return ($aPos < $bPos) ? -1 : 1; } - elseif ($bPos == -1) + + /** Test if the given Header is always displayed */ + private function _isDisplayed(Swift_Mime_Header $header) { - return -1; + return array_key_exists(strtolower($header->getFieldName()), $this->_required); } - - return ($aPos < $bPos) ? -1 : 1; - } - - /** Test if the given Header is always displayed */ - private function _isDisplayed(Swift_Mime_Header $header) - { - return array_key_exists(strtolower($header->getFieldName()), $this->_required); - } - - /** Notify all Headers of the new charset */ - private function _notifyHeadersOfCharset($charset) - { - foreach ($this->_headers as $headerGroup) + + /** Notify all Headers of the new charset */ + private function _notifyHeadersOfCharset($charset) { - foreach ($headerGroup as $header) - { - $header->setCharset($charset); - } + foreach ($this->_headers as $headerGroup) { + foreach ($headerGroup as $header) { + $header->setCharset($charset); + } + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php b/lib/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php index 068787a72..4b2c88b4d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php @@ -8,598 +8,649 @@ * file that was distributed with this source code. */ - /** * The default email message class. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart - implements Swift_Mime_Message +class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart implements Swift_Mime_Message { - - /** - * Create a new SimpleMessage with $headers, $encoder and $cache. - * @param Swift_Mime_HeaderSet $headers - * @param Swift_Mime_ContentEncoder $encoder - * @param Swift_KeyCache $cache - * @param Swift_Mime_Grammar $grammar - * @param string $charset - */ - public function __construct(Swift_Mime_HeaderSet $headers, - Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $charset = null) - { - parent::__construct($headers, $encoder, $cache, $grammar, $charset); - $this->getHeaders()->defineOrdering(array( - 'Return-Path', - 'Sender', - 'Message-ID', - 'Date', - 'Subject', - 'From', - 'Reply-To', - 'To', - 'Cc', - 'Bcc', - 'MIME-Version', - 'Content-Type', - 'Content-Transfer-Encoding' - )); - $this->getHeaders()->setAlwaysDisplayed( - array('Date', 'Message-ID', 'From') - ); - $this->getHeaders()->addTextHeader('MIME-Version', '1.0'); - $this->setDate(time()); - $this->setId($this->getId()); - $this->getHeaders()->addMailboxHeader('From'); - } - - /** - * Always returns {@link LEVEL_TOP} for a message instance. - * @return int - */ - public function getNestingLevel() - { - return self::LEVEL_TOP; - } - - /** - * Set the subject of this message. - * @param string $subject - */ - public function setSubject($subject) - { - if (!$this->_setHeaderFieldModel('Subject', $subject)) + /** + * Create a new SimpleMessage with $headers, $encoder and $cache. + * + * @param Swift_Mime_HeaderSet $headers + * @param Swift_Mime_ContentEncoder $encoder + * @param Swift_KeyCache $cache + * @param Swift_Mime_Grammar $grammar + * @param string $charset + */ + public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $charset = null) { - $this->getHeaders()->addTextHeader('Subject', $subject); + parent::__construct($headers, $encoder, $cache, $grammar, $charset); + $this->getHeaders()->defineOrdering(array( + 'Return-Path', + 'Received', + 'DKIM-Signature', + 'DomainKey-Signature', + 'Sender', + 'Message-ID', + 'Date', + 'Subject', + 'From', + 'Reply-To', + 'To', + 'Cc', + 'Bcc', + 'MIME-Version', + 'Content-Type', + 'Content-Transfer-Encoding' + )); + $this->getHeaders()->setAlwaysDisplayed(array('Date', 'Message-ID', 'From')); + $this->getHeaders()->addTextHeader('MIME-Version', '1.0'); + $this->setDate(time()); + $this->setId($this->getId()); + $this->getHeaders()->addMailboxHeader('From'); } - return $this; - } - - /** - * Get the subject of this message. - * @return string - */ - public function getSubject() - { - return $this->_getHeaderFieldModel('Subject'); - } - - /** - * Set the date at which this message was created. - * @param int $date - */ - public function setDate($date) - { - if (!$this->_setHeaderFieldModel('Date', $date)) + + /** + * Always returns {@link LEVEL_TOP} for a message instance. + * + * @return int + */ + public function getNestingLevel() { - $this->getHeaders()->addDateHeader('Date', $date); + return self::LEVEL_TOP; } - return $this; - } - - /** - * Get the date at which this message was created. - * @return int - */ - public function getDate() - { - return $this->_getHeaderFieldModel('Date'); - } - - /** - * Set the return-path (the bounce address) of this message. - * @param string $address - */ - public function setReturnPath($address) - { - if (!$this->_setHeaderFieldModel('Return-Path', $address)) + + /** + * Set the subject of this message. + * + * @param string $subject + * + * @return Swift_Mime_SimpleMessage + */ + public function setSubject($subject) { - $this->getHeaders()->addPathHeader('Return-Path', $address); + if (!$this->_setHeaderFieldModel('Subject', $subject)) { + $this->getHeaders()->addTextHeader('Subject', $subject); + } + + return $this; } - return $this; - } - - /** - * Get the return-path (bounce address) of this message. - * @return string - */ - public function getReturnPath() - { - return $this->_getHeaderFieldModel('Return-Path'); - } - - /** - * Set the sender of this message. - * This does not override the From field, but it has a higher significance. - * @param string $sender - * @param string $name optional - */ - public function setSender($address, $name = null) - { - if (!is_array($address) && isset($name)) + + /** + * Get the subject of this message. + * + * @return string + */ + public function getSubject() { - $address = array($address => $name); + return $this->_getHeaderFieldModel('Subject'); } - - if (!$this->_setHeaderFieldModel('Sender', (array) $address)) + + /** + * Set the date at which this message was created. + * + * @param int $date + * + * @return Swift_Mime_SimpleMessage + */ + public function setDate($date) { - $this->getHeaders()->addMailboxHeader('Sender', (array) $address); + if (!$this->_setHeaderFieldModel('Date', $date)) { + $this->getHeaders()->addDateHeader('Date', $date); + } + + return $this; } - return $this; - } - - /** - * Get the sender of this message. - * @return string - */ - public function getSender() - { - return $this->_getHeaderFieldModel('Sender'); - } - - /** - * Add a From: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - */ - public function addFrom($address, $name = null) - { - $current = $this->getFrom(); - $current[$address] = $name; - return $this->setFrom($current); - } - - /** - * Set the from address of this message. - * - * You may pass an array of addresses if this message is from multiple people. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param string $addresses - * @param string $name optional - */ - public function setFrom($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) + + /** + * Get the date at which this message was created. + * + * @return int + */ + public function getDate() { - $addresses = array($addresses => $name); + return $this->_getHeaderFieldModel('Date'); } - - if (!$this->_setHeaderFieldModel('From', (array) $addresses)) + + /** + * Set the return-path (the bounce address) of this message. + * + * @param string $address + * + * @return Swift_Mime_SimpleMessage + */ + public function setReturnPath($address) { - $this->getHeaders()->addMailboxHeader('From', (array) $addresses); + if (!$this->_setHeaderFieldModel('Return-Path', $address)) { + $this->getHeaders()->addPathHeader('Return-Path', $address); + } + + return $this; } - return $this; - } - - /** - * Get the from address of this message. - * - * @return string - */ - public function getFrom() - { - return $this->_getHeaderFieldModel('From'); - } - - /** - * Add a Reply-To: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - */ - public function addReplyTo($address, $name = null) - { - $current = $this->getReplyTo(); - $current[$address] = $name; - return $this->setReplyTo($current); - } - - /** - * Set the reply-to address of this message. - * - * You may pass an array of addresses if replies will go to multiple people. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param string $addresses - * @param string $name optional - */ - public function setReplyTo($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) + + /** + * Get the return-path (bounce address) of this message. + * + * @return string + */ + public function getReturnPath() { - $addresses = array($addresses => $name); + return $this->_getHeaderFieldModel('Return-Path'); } - - if (!$this->_setHeaderFieldModel('Reply-To', (array) $addresses)) + + /** + * Set the sender of this message. + * + * This does not override the From field, but it has a higher significance. + * + * @param string $address + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function setSender($address, $name = null) { - $this->getHeaders()->addMailboxHeader('Reply-To', (array) $addresses); + if (!is_array($address) && isset($name)) { + $address = array($address => $name); + } + + if (!$this->_setHeaderFieldModel('Sender', (array) $address)) { + $this->getHeaders()->addMailboxHeader('Sender', (array) $address); + } + + return $this; } - return $this; - } - - /** - * Get the reply-to address of this message. - * - * @return string - */ - public function getReplyTo() - { - return $this->_getHeaderFieldModel('Reply-To'); - } - - /** - * Add a To: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - */ - public function addTo($address, $name = null) - { - $current = $this->getTo(); - $current[$address] = $name; - return $this->setTo($current); - } - - /** - * Set the to addresses of this message. - * - * If multiple recipients will receive the message and array should be used. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param array $addresses - * @param string $name optional - */ - public function setTo($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) + + /** + * Get the sender of this message. + * + * @return string + */ + public function getSender() { - $addresses = array($addresses => $name); + return $this->_getHeaderFieldModel('Sender'); } - - if (!$this->_setHeaderFieldModel('To', (array) $addresses)) + + /** + * Add a From: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function addFrom($address, $name = null) { - $this->getHeaders()->addMailboxHeader('To', (array) $addresses); + $current = $this->getFrom(); + $current[$address] = $name; + + return $this->setFrom($current); } - return $this; - } - - /** - * Get the To addresses of this message. - * - * @return array - */ - public function getTo() - { - return $this->_getHeaderFieldModel('To'); - } - - /** - * Add a Cc: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - */ - public function addCc($address, $name = null) - { - $current = $this->getCc(); - $current[$address] = $name; - return $this->setCc($current); - } - - /** - * Set the Cc addresses of this message. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param array $addresses - * @param string $name optional - */ - public function setCc($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) + + /** + * Set the from address of this message. + * + * You may pass an array of addresses if this message is from multiple people. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param string $addresses + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function setFrom($addresses, $name = null) { - $addresses = array($addresses => $name); + if (!is_array($addresses) && isset($name)) { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('From', (array) $addresses)) { + $this->getHeaders()->addMailboxHeader('From', (array) $addresses); + } + + return $this; } - - if (!$this->_setHeaderFieldModel('Cc', (array) $addresses)) + + /** + * Get the from address of this message. + * + * @return string + */ + public function getFrom() { - $this->getHeaders()->addMailboxHeader('Cc', (array) $addresses); + return $this->_getHeaderFieldModel('From'); } - return $this; - } - - /** - * Get the Cc address of this message. - * - * @return array - */ - public function getCc() - { - return $this->_getHeaderFieldModel('Cc'); - } - - /** - * Add a Bcc: address to this message. - * - * If $name is passed this name will be associated with the address. - * - * @param string $address - * @param string $name optional - */ - public function addBcc($address, $name = null) - { - $current = $this->getBcc(); - $current[$address] = $name; - return $this->setBcc($current); - } - - /** - * Set the Bcc addresses of this message. - * - * If $name is passed and the first parameter is a string, this name will be - * associated with the address. - * - * @param array $addresses - * @param string $name optional - */ - public function setBcc($addresses, $name = null) - { - if (!is_array($addresses) && isset($name)) + + /** + * Add a Reply-To: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function addReplyTo($address, $name = null) { - $addresses = array($addresses => $name); + $current = $this->getReplyTo(); + $current[$address] = $name; + + return $this->setReplyTo($current); } - - if (!$this->_setHeaderFieldModel('Bcc', (array) $addresses)) + + /** + * Set the reply-to address of this message. + * + * You may pass an array of addresses if replies will go to multiple people. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param string $addresses + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function setReplyTo($addresses, $name = null) { - $this->getHeaders()->addMailboxHeader('Bcc', (array) $addresses); + if (!is_array($addresses) && isset($name)) { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('Reply-To', (array) $addresses)) { + $this->getHeaders()->addMailboxHeader('Reply-To', (array) $addresses); + } + + return $this; } - return $this; - } - - /** - * Get the Bcc addresses of this message. - * - * @return array - */ - public function getBcc() - { - return $this->_getHeaderFieldModel('Bcc'); - } - - /** - * Set the priority of this message. - * The value is an integer where 1 is the highest priority and 5 is the lowest. - * @param int $priority - */ - public function setPriority($priority) - { - $priorityMap = array( - 1 => 'Highest', - 2 => 'High', - 3 => 'Normal', - 4 => 'Low', - 5 => 'Lowest' - ); - $pMapKeys = array_keys($priorityMap); - if ($priority > max($pMapKeys)) + + /** + * Get the reply-to address of this message. + * + * @return string + */ + public function getReplyTo() { - $priority = max($pMapKeys); + return $this->_getHeaderFieldModel('Reply-To'); } - elseif ($priority < min($pMapKeys)) + + /** + * Add a To: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function addTo($address, $name = null) { - $priority = min($pMapKeys); + $current = $this->getTo(); + $current[$address] = $name; + + return $this->setTo($current); } - if (!$this->_setHeaderFieldModel('X-Priority', - sprintf('%d (%s)', $priority, $priorityMap[$priority]))) + + /** + * Set the to addresses of this message. + * + * If multiple recipients will receive the message an array should be used. + * Example: array('receiver@domain.org', 'other@domain.org' => 'A name') + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param mixed $addresses + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function setTo($addresses, $name = null) { - $this->getHeaders()->addTextHeader('X-Priority', - sprintf('%d (%s)', $priority, $priorityMap[$priority])); + if (!is_array($addresses) && isset($name)) { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('To', (array) $addresses)) { + $this->getHeaders()->addMailboxHeader('To', (array) $addresses); + } + + return $this; } - return $this; - } - - /** - * Get the priority of this message. - * The returned value is an integer where 1 is the highest priority and 5 - * is the lowest. - * @return int - */ - public function getPriority() - { - list($priority) = sscanf($this->_getHeaderFieldModel('X-Priority'), - '%[1-5]' - ); - return isset($priority) ? $priority : 3; - } - - /** - * Ask for a delivery receipt from the recipient to be sent to $addresses - * @param array $addresses - */ - public function setReadReceiptTo($addresses) - { - if (!$this->_setHeaderFieldModel('Disposition-Notification-To', $addresses)) + + /** + * Get the To addresses of this message. + * + * @return array + */ + public function getTo() { - $this->getHeaders() - ->addMailboxHeader('Disposition-Notification-To', $addresses); + return $this->_getHeaderFieldModel('To'); } - return $this; - } - - /** - * Get the addresses to which a read-receipt will be sent. - * @return string - */ - public function getReadReceiptTo() - { - return $this->_getHeaderFieldModel('Disposition-Notification-To'); - } - - /** - * Attach a {@link Swift_Mime_MimeEntity} such as an Attachment or MimePart. - * @param Swift_Mime_MimeEntity $entity - */ - public function attach(Swift_Mime_MimeEntity $entity) - { - $this->setChildren(array_merge($this->getChildren(), array($entity))); - return $this; - } - - /** - * Remove an already attached entity. - * @param Swift_Mime_MimeEntity $entity - */ - public function detach(Swift_Mime_MimeEntity $entity) - { - $newChildren = array(); - foreach ($this->getChildren() as $child) + + /** + * Add a Cc: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function addCc($address, $name = null) { - if ($entity !== $child) - { - $newChildren[] = $child; - } + $current = $this->getCc(); + $current[$address] = $name; + + return $this->setCc($current); } - $this->setChildren($newChildren); - return $this; - } - - /** - * Attach a {@link Swift_Mime_MimeEntity} and return it's CID source. - * This method should be used when embedding images or other data in a message. - * @param Swift_Mime_MimeEntity $entity - * @return string - */ - public function embed(Swift_Mime_MimeEntity $entity) - { - $this->attach($entity); - return 'cid:' . $entity->getId(); - } - - /** - * Get this message as a complete string. - * @return string - */ - public function toString() - { - if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') + + /** + * Set the Cc addresses of this message. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param mixed $addresses + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function setCc($addresses, $name = null) { - $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); - $string = parent::toString(); - $this->setChildren($children); + if (!is_array($addresses) && isset($name)) { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('Cc', (array) $addresses)) { + $this->getHeaders()->addMailboxHeader('Cc', (array) $addresses); + } + + return $this; } - else + + /** + * Get the Cc address of this message. + * + * @return array + */ + public function getCc() { - $string = parent::toString(); + return $this->_getHeaderFieldModel('Cc'); } - return $string; - } - - /** - * Returns a string representation of this object. - * - * @return string - * - * @see toString() - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Write this message to a {@link Swift_InputByteStream}. - * @param Swift_InputByteStream $is - */ - public function toByteStream(Swift_InputByteStream $is) - { - if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') + + /** + * Add a Bcc: address to this message. + * + * If $name is passed this name will be associated with the address. + * + * @param string $address + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function addBcc($address, $name = null) { - $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); - parent::toByteStream($is); - $this->setChildren($children); + $current = $this->getBcc(); + $current[$address] = $name; + + return $this->setBcc($current); } - else + + /** + * Set the Bcc addresses of this message. + * + * If $name is passed and the first parameter is a string, this name will be + * associated with the address. + * + * @param mixed $addresses + * @param string $name optional + * + * @return Swift_Mime_SimpleMessage + */ + public function setBcc($addresses, $name = null) { - parent::toByteStream($is); + if (!is_array($addresses) && isset($name)) { + $addresses = array($addresses => $name); + } + + if (!$this->_setHeaderFieldModel('Bcc', (array) $addresses)) { + $this->getHeaders()->addMailboxHeader('Bcc', (array) $addresses); + } + + return $this; } - } - - // -- Protected methods - - /** @see Swift_Mime_SimpleMimeEntity::_getIdField() */ - protected function _getIdField() - { - return 'Message-ID'; - } - - // -- Private methods - - /** Turn the body of this message into a child of itself if needed */ - private function _becomeMimePart() - { - $part = new parent($this->getHeaders()->newInstance(), $this->getEncoder(), - $this->_getCache(), $this->_getGrammar(), $this->_userCharset - ); - $part->setContentType($this->_userContentType); - $part->setBody($this->getBody()); - $part->setFormat($this->_userFormat); - $part->setDelSp($this->_userDelSp); - $part->_setNestingLevel($this->_getTopNestingLevel()); - return $part; - } - - /** Get the highest nesting level nested inside this message */ - private function _getTopNestingLevel() - { - $highestLevel = $this->getNestingLevel(); - foreach ($this->getChildren() as $child) + + /** + * Get the Bcc addresses of this message. + * + * @return array + */ + public function getBcc() { - $childLevel = $child->getNestingLevel(); - if ($highestLevel < $childLevel) - { - $highestLevel = $childLevel; - } + return $this->_getHeaderFieldModel('Bcc'); + } + + /** + * Set the priority of this message. + * + * The value is an integer where 1 is the highest priority and 5 is the lowest. + * + * @param int $priority + * + * @return Swift_Mime_SimpleMessage + */ + public function setPriority($priority) + { + $priorityMap = array( + 1 => 'Highest', + 2 => 'High', + 3 => 'Normal', + 4 => 'Low', + 5 => 'Lowest' + ); + $pMapKeys = array_keys($priorityMap); + if ($priority > max($pMapKeys)) { + $priority = max($pMapKeys); + } elseif ($priority < min($pMapKeys)) { + $priority = min($pMapKeys); + } + if (!$this->_setHeaderFieldModel('X-Priority', + sprintf('%d (%s)', $priority, $priorityMap[$priority]))) + { + $this->getHeaders()->addTextHeader('X-Priority', + sprintf('%d (%s)', $priority, $priorityMap[$priority])); + } + + return $this; + } + + /** + * Get the priority of this message. + * + * The returned value is an integer where 1 is the highest priority and 5 + * is the lowest. + * + * @return int + */ + public function getPriority() + { + list($priority) = sscanf($this->_getHeaderFieldModel('X-Priority'), + '%[1-5]' + ); + + return isset($priority) ? $priority : 3; + } + + /** + * Ask for a delivery receipt from the recipient to be sent to $addresses + * + * @param array $addresses + * + * @return Swift_Mime_SimpleMessage + */ + public function setReadReceiptTo($addresses) + { + if (!$this->_setHeaderFieldModel('Disposition-Notification-To', $addresses)) { + $this->getHeaders() + ->addMailboxHeader('Disposition-Notification-To', $addresses); + } + + return $this; + } + + /** + * Get the addresses to which a read-receipt will be sent. + * + * @return string + */ + public function getReadReceiptTo() + { + return $this->_getHeaderFieldModel('Disposition-Notification-To'); + } + + /** + * Attach a {@link Swift_Mime_MimeEntity} such as an Attachment or MimePart. + * + * @param Swift_Mime_MimeEntity $entity + * + * @return Swift_Mime_SimpleMessage + */ + public function attach(Swift_Mime_MimeEntity $entity) + { + $this->setChildren(array_merge($this->getChildren(), array($entity))); + + return $this; + } + + /** + * Remove an already attached entity. + * + * @param Swift_Mime_MimeEntity $entity + * + * @return Swift_Mime_SimpleMessage + */ + public function detach(Swift_Mime_MimeEntity $entity) + { + $newChildren = array(); + foreach ($this->getChildren() as $child) { + if ($entity !== $child) { + $newChildren[] = $child; + } + } + $this->setChildren($newChildren); + + return $this; + } + + /** + * Attach a {@link Swift_Mime_MimeEntity} and return it's CID source. + * This method should be used when embedding images or other data in a message. + * + * @param Swift_Mime_MimeEntity $entity + * + * @return string + */ + public function embed(Swift_Mime_MimeEntity $entity) + { + $this->attach($entity); + + return 'cid:' . $entity->getId(); + } + + /** + * Get this message as a complete string. + * + * @return string + */ + public function toString() + { + if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') { + $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); + $string = parent::toString(); + $this->setChildren($children); + } else { + $string = parent::toString(); + } + + return $string; + } + + /** + * Returns a string representation of this object. + * + * @see toString() + * + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * Write this message to a {@link Swift_InputByteStream}. + * + * @param Swift_InputByteStream $is + */ + public function toByteStream(Swift_InputByteStream $is) + { + if (count($children = $this->getChildren()) > 0 && $this->getBody() != '') { + $this->setChildren(array_merge(array($this->_becomeMimePart()), $children)); + parent::toByteStream($is); + $this->setChildren($children); + } else { + parent::toByteStream($is); + } + } + + // -- Protected methods + + /** @see Swift_Mime_SimpleMimeEntity::_getIdField() */ + protected function _getIdField() + { + return 'Message-ID'; + } + + /** Turn the body of this message into a child of itself if needed */ + protected function _becomeMimePart() + { + $part = new parent($this->getHeaders()->newInstance(), $this->getEncoder(), + $this->_getCache(), $this->_getGrammar(), $this->_userCharset + ); + $part->setContentType($this->_userContentType); + $part->setBody($this->getBody()); + $part->setFormat($this->_userFormat); + $part->setDelSp($this->_userDelSp); + $part->_setNestingLevel($this->_getTopNestingLevel()); + + return $part; + } + + // -- Private methods + + /** Get the highest nesting level nested inside this message */ + private function _getTopNestingLevel() + { + $highestLevel = $this->getNestingLevel(); + foreach ($this->getChildren() as $child) { + $childLevel = $child->getNestingLevel(); + if ($highestLevel < $childLevel) { + $highestLevel = $childLevel; + } + } + + return $highestLevel; } - return $highestLevel; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php b/lib/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php index 8398bd679..e2fc7296d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php +++ b/lib/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php @@ -8,837 +8,852 @@ * file that was distributed with this source code. */ - /** * A MIME entity, in a multipart message. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Mime_SimpleMimeEntity implements Swift_Mime_MimeEntity { - - /** A collection of Headers for this mime entity */ - private $_headers; - - /** The body as a string, or a stream */ - private $_body; - - /** The encoder that encodes the body into a streamable format */ - private $_encoder; + /** A collection of Headers for this mime entity */ + private $_headers; - /** The grammar to use for id validation */ - private $_grammar; - - /** A mime bounary, if any is used */ - private $_boundary; - - /** Mime types to be used based on the nesting level */ - private $_compositeRanges = array( - 'multipart/mixed' => array(self::LEVEL_TOP, self::LEVEL_MIXED), - 'multipart/alternative' => array(self::LEVEL_MIXED, self::LEVEL_ALTERNATIVE), - 'multipart/related' => array(self::LEVEL_ALTERNATIVE, self::LEVEL_RELATED) + /** The body as a string, or a stream */ + private $_body; + + /** The encoder that encodes the body into a streamable format */ + private $_encoder; + + /** The grammar to use for id validation */ + private $_grammar; + + /** A mime boundary, if any is used */ + private $_boundary; + + /** Mime types to be used based on the nesting level */ + private $_compositeRanges = array( + 'multipart/mixed' => array(self::LEVEL_TOP, self::LEVEL_MIXED), + 'multipart/alternative' => array(self::LEVEL_MIXED, self::LEVEL_ALTERNATIVE), + 'multipart/related' => array(self::LEVEL_ALTERNATIVE, self::LEVEL_RELATED) ); - - /** A set of filter rules to define what level an entity should be nested at */ - private $_compoundLevelFilters = array(); - - /** The nesting level of this entity */ - private $_nestingLevel = self::LEVEL_ALTERNATIVE; - - /** A KeyCache instance used during encoding and streaming */ - private $_cache; - - /** Direct descendants of this entity */ - private $_immediateChildren = array(); - - /** All descendants of this entity */ - private $_children = array(); - - /** The maximum line length of the body of this entity */ - private $_maxLineLength = 78; - - /** The order in which alternative mime types should appear */ - private $_alternativePartOrder = array( - 'text/plain' => 1, - 'text/html' => 2, - 'multipart/related' => 3 + + /** A set of filter rules to define what level an entity should be nested at */ + private $_compoundLevelFilters = array(); + + /** The nesting level of this entity */ + private $_nestingLevel = self::LEVEL_ALTERNATIVE; + + /** A KeyCache instance used during encoding and streaming */ + private $_cache; + + /** Direct descendants of this entity */ + private $_immediateChildren = array(); + + /** All descendants of this entity */ + private $_children = array(); + + /** The maximum line length of the body of this entity */ + private $_maxLineLength = 78; + + /** The order in which alternative mime types should appear */ + private $_alternativePartOrder = array( + 'text/plain' => 1, + 'text/html' => 2, + 'multipart/related' => 3 ); - - /** The CID of this entity */ - private $_id; - - /** The key used for accessing the cache */ - private $_cacheKey; - - protected $_userContentType; - - /** - * Create a new SimpleMimeEntity with $headers, $encoder and $cache. - * @param Swift_Mime_HeaderSet $headers - * @param Swift_Mime_ContentEncoder $encoder - * @param Swift_KeyCache $cache - * @param Swift_Mime_Grammar $grammar - */ - public function __construct(Swift_Mime_HeaderSet $headers, - Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, - Swift_Mime_Grammar $grammar) - { - $this->_cacheKey = uniqid(); - $this->_cache = $cache; - $this->_headers = $headers; - $this->_grammar = $grammar; - $this->setEncoder($encoder); - $this->_headers->defineOrdering( - array('Content-Type', 'Content-Transfer-Encoding') - ); - - // This array specifies that, when the entire MIME document contains - // $compoundLevel, then for each child within $level, if its Content-Type - // is $contentType then it should be treated as if it's level is - // $neededLevel instead. I tried to write that unambiguously! :-\ - // Data Structure: - // array ( - // $compoundLevel => array( - // $level => array( - // $contentType => $neededLevel - // ) - // ) - // ) - - $this->_compoundLevelFilters = array( - (self::LEVEL_ALTERNATIVE + self::LEVEL_RELATED) => array( - self::LEVEL_ALTERNATIVE => array( - 'text/plain' => self::LEVEL_ALTERNATIVE, - 'text/html' => self::LEVEL_RELATED - ) - ) - ); - $this->_id = $this->getRandomId(); - } - - /** - * Generate a new Content-ID or Message-ID for this MIME entity. - * @return string - */ - public function generateId() - { - $this->setId($this->getRandomId()); - return $this->_id; - } - - /** - * Get the {@link Swift_Mime_HeaderSet} for this entity. - * @return Swift_Mime_HeaderSet - */ - public function getHeaders() - { - return $this->_headers; - } - - /** - * Get the nesting level of this entity. - * @return int - * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE - */ - public function getNestingLevel() - { - return $this->_nestingLevel; - } - - /** - * Get the Content-type of this entity. - * @return string - */ - public function getContentType() - { - return $this->_getHeaderFieldModel('Content-Type'); - } - - /** - * Set the Content-type of this entity. - * @param string $type - */ - public function setContentType($type) - { - $this->_setContentTypeInHeaders($type); - // Keep track of the value so that if the content-type changes automatically - // due to added child entities, it can be restored if they are later removed - $this->_userContentType = $type; - return $this; - } - - /** - * Get the CID of this entity. - * The CID will only be present in headers if a Content-ID header is present. - * @return string - */ - public function getId() - { - return $this->_headers->has($this->_getIdField()) - ? current((array) $this->_getHeaderFieldModel($this->_getIdField())) - : $this->_id; - } - - /** - * Set the CID of this entity. - * @param string $id - */ - public function setId($id) - { - if (!$this->_setHeaderFieldModel($this->_getIdField(), $id)) - { - $this->_headers->addIdHeader($this->_getIdField(), $id); - } - $this->_id = $id; - return $this; - } - - /** - * Get the description of this entity. - * This value comes from the Content-Description header if set. - * @return string - */ - public function getDescription() - { - return $this->_getHeaderFieldModel('Content-Description'); - } - - /** - * Set the description of this entity. - * This method sets a value in the Content-ID header. - * @param string $description - */ - public function setDescription($description) - { - if (!$this->_setHeaderFieldModel('Content-Description', $description)) - { - $this->_headers->addTextHeader('Content-Description', $description); - } - return $this; - } - - /** - * Get the maximum line length of the body of this entity. - * @return int - */ - public function getMaxLineLength() - { - return $this->_maxLineLength; - } - - /** - * Set the maximum line length of lines in this body. - * Though not enforced by the library, lines should not exceed 1000 chars. - * @param int $length - */ - public function setMaxLineLength($length) - { - $this->_maxLineLength = $length; - return $this; - } - - /** - * Get all children added to this entity. - * @return array of Swift_Mime_Entity - */ - public function getChildren() - { - return $this->_children; - } - - /** - * Set all children of this entity. - * @param array $children Swiift_Mime_Entity instances - * @param int $compoundLevel For internal use only - */ - public function setChildren(array $children, $compoundLevel = null) - { - //TODO: Try to refactor this logic - - $compoundLevel = isset($compoundLevel) - ? $compoundLevel - : $this->_getCompoundLevel($children) - ; - - $immediateChildren = array(); - $grandchildren = array(); - $newContentType = $this->_userContentType; - - foreach ($children as $child) - { - $level = $this->_getNeededChildLevel($child, $compoundLevel); - if (empty($immediateChildren)) //first iteration - { - $immediateChildren = array($child); - } - else - { - $nextLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel); - if ($nextLevel == $level) - { - $immediateChildren[] = $child; - } - elseif ($level < $nextLevel) - { - //Re-assign immediateChildren to grandchilden - $grandchildren = array_merge($grandchildren, $immediateChildren); - //Set new children - $immediateChildren = array($child); - } - else - { - $grandchildren[] = $child; - } - } - } - - if (!empty($immediateChildren)) - { - $lowestLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel); - - //Determine which composite media type is needed to accomodate the - // immediate children - foreach ($this->_compositeRanges as $mediaType => $range) - { - if ($lowestLevel > $range[0] - && $lowestLevel <= $range[1]) - { - $newContentType = $mediaType; - break; - } - } - - //Put any grandchildren in a subpart - if (!empty($grandchildren)) - { - $subentity = $this->_createChild(); - $subentity->_setNestingLevel($lowestLevel); - $subentity->setChildren($grandchildren, $compoundLevel); - array_unshift($immediateChildren, $subentity); - } - } - - $this->_immediateChildren = $immediateChildren; - $this->_children = $children; - $this->_setContentTypeInHeaders($newContentType); - $this->_fixHeaders(); - $this->_sortChildren(); - - return $this; - } - - /** - * Get the body of this entity as a string. - * @return string - */ - public function getBody() - { - return ($this->_body instanceof Swift_OutputByteStream) - ? $this->_readStream($this->_body) - : $this->_body; - } - - /** - * Set the body of this entity, either as a string, or as an instance of - * {@link Swift_OutputByteStream}. - * @param mixed $body - * @param string $contentType optional - */ - public function setBody($body, $contentType = null) - { - if ($body !== $this->_body) - { - $this->_clearCache(); - } - - $this->_body = $body; - if (isset($contentType)) - { - $this->setContentType($contentType); - } - return $this; - } - - /** - * Get the encoder used for the body of this entity. - * @return Swift_Mime_ContentEncoder - */ - public function getEncoder() - { - return $this->_encoder; - } - - /** - * Set the encoder used for the body of this entity. - * @param Swift_Mime_ContentEncoder $encoder - */ - public function setEncoder(Swift_Mime_ContentEncoder $encoder) - { - if ($encoder !== $this->_encoder) - { - $this->_clearCache(); - } - - $this->_encoder = $encoder; - $this->_setEncoding($encoder->getName()); - $this->_notifyEncoderChanged($encoder); - return $this; - } - - /** - * Get the boundary used to separate children in this entity. - * @return string - */ - public function getBoundary() - { - if (!isset($this->_boundary)) - { - $this->_boundary = '_=_swift_v4_' . time() . uniqid() . '_=_'; - } - return $this->_boundary; - } - - /** - * Set the boundary used to separate children in this entity. - * @param string $boundary - * @throws Swift_RfcComplianceException - */ - public function setBoundary($boundary) - { - $this->_assertValidBoundary($boundary); - $this->_boundary = $boundary; - return $this; - } - - /** - * Receive notification that the charset of this entity, or a parent entity - * has changed. - * @param string $charset - */ - public function charsetChanged($charset) - { - $this->_notifyCharsetChanged($charset); - } - - /** - * Receive notification that the encoder of this entity or a parent entity - * has changed. - * @param Swift_Mime_ContentEncoder $encoder - */ - public function encoderChanged(Swift_Mime_ContentEncoder $encoder) - { - $this->_notifyEncoderChanged($encoder); - } - - /** - * Get this entire entity as a string. - * @return string - */ - public function toString() - { - $string = $this->_headers->toString(); - if (isset($this->_body) && empty($this->_immediateChildren)) - { - if ($this->_cache->hasKey($this->_cacheKey, 'body')) - { - $body = $this->_cache->getString($this->_cacheKey, 'body'); - } - else - { - $body = "\r\n" . $this->_encoder->encodeString($this->getBody(), 0, - $this->getMaxLineLength() - ); - $this->_cache->setString($this->_cacheKey, 'body', $body, - Swift_KeyCache::MODE_WRITE - ); - } - $string .= $body; - } - - if (!empty($this->_immediateChildren)) - { - foreach ($this->_immediateChildren as $child) - { - $string .= "\r\n\r\n--" . $this->getBoundary() . "\r\n"; - $string .= $child->toString(); - } - $string .= "\r\n\r\n--" . $this->getBoundary() . "--\r\n"; - } - - return $string; - } - - /** - * Returns a string representation of this object. - * - * @return string - * - * @see toString() - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Write this entire entity to a {@link Swift_InputByteStream}. - * @param Swift_InputByteStream - */ - public function toByteStream(Swift_InputByteStream $is) - { - $is->write($this->_headers->toString()); - $is->commit(); - - if (empty($this->_immediateChildren)) - { - if (isset($this->_body)) - { - if ($this->_cache->hasKey($this->_cacheKey, 'body')) - { - $this->_cache->exportToByteStream($this->_cacheKey, 'body', $is); - } - else - { - $cacheIs = $this->_cache->getInputByteStream($this->_cacheKey, 'body'); - if ($cacheIs) - { - $is->bind($cacheIs); - } - - $is->write("\r\n"); - - if ($this->_body instanceof Swift_OutputByteStream) - { - $this->_body->setReadPointer(0); - - $this->_encoder->encodeByteStream($this->_body, $is, 0, - $this->getMaxLineLength() - ); - } - else - { - $is->write($this->_encoder->encodeString( - $this->getBody(), 0, $this->getMaxLineLength() - )); - } - - if ($cacheIs) - { - $is->unbind($cacheIs); - } - } - } - } - - if (!empty($this->_immediateChildren)) - { - foreach ($this->_immediateChildren as $child) - { - $is->write("\r\n\r\n--" . $this->getBoundary() . "\r\n"); - $child->toByteStream($is); - } - $is->write("\r\n\r\n--" . $this->getBoundary() . "--\r\n"); - } - } - - // -- Protected methods - - /** - * Get the name of the header that provides the ID of this entity */ - protected function _getIdField() - { - return 'Content-ID'; - } - - /** - * Get the model data (usually an array or a string) for $field. - */ - protected function _getHeaderFieldModel($field) - { - if ($this->_headers->has($field)) - { - return $this->_headers->get($field)->getFieldBodyModel(); - } - } - - /** - * Set the model data for $field. - */ - protected function _setHeaderFieldModel($field, $model) - { - if ($this->_headers->has($field)) - { - $this->_headers->get($field)->setFieldBodyModel($model); - return true; - } - else - { - return false; - } - } - - /** - * Get the parameter value of $parameter on $field header. - */ - protected function _getHeaderParameter($field, $parameter) - { - if ($this->_headers->has($field)) - { - return $this->_headers->get($field)->getParameter($parameter); - } - } - - /** - * Set the parameter value of $parameter on $field header. - */ - protected function _setHeaderParameter($field, $parameter, $value) - { - if ($this->_headers->has($field)) - { - $this->_headers->get($field)->setParameter($parameter, $value); - return true; - } - else - { - return false; - } - } - - /** - * Re-evaluate what content type and encoding should be used on this entity. - */ - protected function _fixHeaders() - { - if (count($this->_immediateChildren)) - { - $this->_setHeaderParameter('Content-Type', 'boundary', - $this->getBoundary() - ); - $this->_headers->remove('Content-Transfer-Encoding'); - } - else - { - $this->_setHeaderParameter('Content-Type', 'boundary', null); - $this->_setEncoding($this->_encoder->getName()); - } - } - - /** - * Get the KeyCache used in this entity. - */ - protected function _getCache() - { - return $this->_cache; - } - - /** - * Get the grammar used for validation. - * @return Swift_Mime_Grammar - */ - protected function _getGrammar() - { - return $this->_grammar; - } - - /** - * Empty the KeyCache for this entity. - */ - protected function _clearCache() - { - $this->_cache->clearKey($this->_cacheKey, 'body'); - } - - /** - * Returns a random Content-ID or Message-ID. - * @return string - */ - protected function getRandomId() - { - $idLeft = time() . '.' . uniqid(); - $idRight = !empty($_SERVER['SERVER_NAME']) - ? $_SERVER['SERVER_NAME'] - : 'swift.generated'; - $id = $idLeft . '@' . $idRight; + /** The CID of this entity */ + private $_id; - try + /** The key used for accessing the cache */ + private $_cacheKey; + + protected $_userContentType; + + /** + * Create a new SimpleMimeEntity with $headers, $encoder and $cache. + * + * @param Swift_Mime_HeaderSet $headers + * @param Swift_Mime_ContentEncoder $encoder + * @param Swift_KeyCache $cache + * @param Swift_Mime_Grammar $grammar + */ + public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar) { - $this->_assertValidId($id); - } - catch (Swift_RfcComplianceException $e) - { - $id = $idLeft . '@swift.generated'; + $this->_cacheKey = md5(uniqid(getmypid().mt_rand(), true)); + $this->_cache = $cache; + $this->_headers = $headers; + $this->_grammar = $grammar; + $this->setEncoder($encoder); + $this->_headers->defineOrdering(array('Content-Type', 'Content-Transfer-Encoding')); + + // This array specifies that, when the entire MIME document contains + // $compoundLevel, then for each child within $level, if its Content-Type + // is $contentType then it should be treated as if it's level is + // $neededLevel instead. I tried to write that unambiguously! :-\ + // Data Structure: + // array ( + // $compoundLevel => array( + // $level => array( + // $contentType => $neededLevel + // ) + // ) + // ) + + $this->_compoundLevelFilters = array( + (self::LEVEL_ALTERNATIVE + self::LEVEL_RELATED) => array( + self::LEVEL_ALTERNATIVE => array( + 'text/plain' => self::LEVEL_ALTERNATIVE, + 'text/html' => self::LEVEL_RELATED + ) + ) + ); + + $this->_id = $this->getRandomId(); } - return $id; - } - - // -- Private methods - - private function _readStream(Swift_OutputByteStream $os) - { - $string = ''; - while (false !== $bytes = $os->read(8192)) + /** + * Generate a new Content-ID or Message-ID for this MIME entity. + * + * @return string + */ + public function generateId() { - $string .= $bytes; + $this->setId($this->getRandomId()); + + return $this->_id; } - return $string; - } - - private function _setEncoding($encoding) - { - if (!$this->_setHeaderFieldModel('Content-Transfer-Encoding', $encoding)) + + /** + * Get the {@link Swift_Mime_HeaderSet} for this entity. + * + * @return Swift_Mime_HeaderSet + */ + public function getHeaders() { - $this->_headers->addTextHeader('Content-Transfer-Encoding', $encoding); + return $this->_headers; } - } - - private function _assertValidBoundary($boundary) - { - if (!preg_match( - '/^[a-z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-z0-9\'\(\)\+_\-,\.\/:=\?]$/Di', - $boundary)) + + /** + * Get the nesting level of this entity. + * + * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE + * + * @return int + */ + public function getNestingLevel() { - throw new Swift_RfcComplianceException('Mime boundary set is not RFC 2046 compliant.'); + return $this->_nestingLevel; } - } - - private function _setContentTypeInHeaders($type) - { - if (!$this->_setHeaderFieldModel('Content-Type', $type)) + + /** + * Get the Content-type of this entity. + * + * @return string + */ + public function getContentType() { - $this->_headers->addParameterizedHeader('Content-Type', $type); + return $this->_getHeaderFieldModel('Content-Type'); } - } - - private function _setNestingLevel($level) - { - $this->_nestingLevel = $level; - } - - private function _getCompoundLevel($children) - { - $level = 0; - foreach ($children as $child) + + /** + * Set the Content-type of this entity. + * + * @param string $type + * + * @return Swift_Mime_SimpleMimeEntity + */ + public function setContentType($type) { - $level |= $child->getNestingLevel(); + $this->_setContentTypeInHeaders($type); + // Keep track of the value so that if the content-type changes automatically + // due to added child entities, it can be restored if they are later removed + $this->_userContentType = $type; + + return $this; } - return $level; - } - - private function _getNeededChildLevel($child, $compoundLevel) - { - $filter = array(); - foreach ($this->_compoundLevelFilters as $bitmask => $rules) + + /** + * Get the CID of this entity. + * + * The CID will only be present in headers if a Content-ID header is present. + * + * @return string + */ + public function getId() { - if (($compoundLevel & $bitmask) === $bitmask) - { - $filter = $rules + $filter; - } + $tmp = (array) $this->_getHeaderFieldModel($this->_getIdField()); + + return $this->_headers->has($this->_getIdField()) ? current($tmp) : $this->_id; } - - $realLevel = $child->getNestingLevel(); - $lowercaseType = strtolower($child->getContentType()); - - if (isset($filter[$realLevel]) - && isset($filter[$realLevel][$lowercaseType])) + + /** + * Set the CID of this entity. + * + * @param string $id + * + * @return Swift_Mime_SimpleMimeEntity + */ + public function setId($id) { - return $filter[$realLevel][$lowercaseType]; + if (!$this->_setHeaderFieldModel($this->_getIdField(), $id)) { + $this->_headers->addIdHeader($this->_getIdField(), $id); + } + $this->_id = $id; + + return $this; } - else + + /** + * Get the description of this entity. + * + * This value comes from the Content-Description header if set. + * + * @return string + */ + public function getDescription() { - return $realLevel; + return $this->_getHeaderFieldModel('Content-Description'); } - } - - private function _createChild() - { - return new self($this->_headers->newInstance(), - $this->_encoder, $this->_cache, $this->_grammar); - } - - private function _notifyEncoderChanged(Swift_Mime_ContentEncoder $encoder) - { - foreach ($this->_immediateChildren as $child) + + /** + * Set the description of this entity. + * + * This method sets a value in the Content-ID header. + * + * @param string $description + * + * @return Swift_Mime_SimpleMimeEntity + */ + public function setDescription($description) { - $child->encoderChanged($encoder); + if (!$this->_setHeaderFieldModel('Content-Description', $description)) { + $this->_headers->addTextHeader('Content-Description', $description); + } + + return $this; } - } - - private function _notifyCharsetChanged($charset) - { - $this->_encoder->charsetChanged($charset); - $this->_headers->charsetChanged($charset); - foreach ($this->_immediateChildren as $child) + + /** + * Get the maximum line length of the body of this entity. + * + * @return int + */ + public function getMaxLineLength() { - $child->charsetChanged($charset); + return $this->_maxLineLength; } - } - - private function _sortChildren() - { - $shouldSort = false; - foreach ($this->_immediateChildren as $child) + + /** + * Set the maximum line length of lines in this body. + * + * Though not enforced by the library, lines should not exceed 1000 chars. + * + * @param int $length + * + * @return Swift_Mime_SimpleMimeEntity + */ + public function setMaxLineLength($length) { - //NOTE: This include alternative parts moved into a related part - if ($child->getNestingLevel() == self::LEVEL_ALTERNATIVE) - { - $shouldSort = true; - break; - } + $this->_maxLineLength = $length; + + return $this; } - - //Sort in order of preference, if there is one - if ($shouldSort) + + /** + * Get all children added to this entity. + * + * @return array of Swift_Mime_Entity + */ + public function getChildren() { - usort($this->_immediateChildren, array($this, '_childSortAlgorithm')); + return $this->_children; } - } - - private function _childSortAlgorithm($a, $b) - { - $typePrefs = array(); - $types = array( - strtolower($a->getContentType()), - strtolower($b->getContentType()) - ); - foreach ($types as $type) + + /** + * Set all children of this entity. + * + * @param array $children Swift_Mime_Entity instances + * @param int $compoundLevel For internal use only + * + * @return Swift_Mime_SimpleMimeEntity + */ + public function setChildren(array $children, $compoundLevel = null) { - $typePrefs[] = (array_key_exists($type, $this->_alternativePartOrder)) - ? $this->_alternativePartOrder[$type] - : (max($this->_alternativePartOrder) + 1); + // TODO: Try to refactor this logic + + $compoundLevel = isset($compoundLevel) + ? $compoundLevel + : $this->_getCompoundLevel($children) + ; + + $immediateChildren = array(); + $grandchildren = array(); + $newContentType = $this->_userContentType; + + foreach ($children as $child) { + $level = $this->_getNeededChildLevel($child, $compoundLevel); + if (empty($immediateChildren)) { //first iteration + $immediateChildren = array($child); + } else { + $nextLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel); + if ($nextLevel == $level) { + $immediateChildren[] = $child; + } elseif ($level < $nextLevel) { + // Re-assign immediateChildren to grandchildren + $grandchildren = array_merge($grandchildren, $immediateChildren); + // Set new children + $immediateChildren = array($child); + } else { + $grandchildren[] = $child; + } + } + } + + if (!empty($immediateChildren)) { + $lowestLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel); + + // Determine which composite media type is needed to accommodate the + // immediate children + foreach ($this->_compositeRanges as $mediaType => $range) { + if ($lowestLevel > $range[0] + && $lowestLevel <= $range[1]) + { + $newContentType = $mediaType; + break; + } + } + + // Put any grandchildren in a subpart + if (!empty($grandchildren)) { + $subentity = $this->_createChild(); + $subentity->_setNestingLevel($lowestLevel); + $subentity->setChildren($grandchildren, $compoundLevel); + array_unshift($immediateChildren, $subentity); + } + } + + $this->_immediateChildren = $immediateChildren; + $this->_children = $children; + $this->_setContentTypeInHeaders($newContentType); + $this->_fixHeaders(); + $this->_sortChildren(); + + return $this; } - return ($typePrefs[0] >= $typePrefs[1]) ? 1 : -1; - } - - // -- Destructor - - /** - * Empties it's own contents from the cache. - */ - public function __destruct() - { - $this->_cache->clearAll($this->_cacheKey); - } - - /** - * Throws an Exception if the id passed does not comply with RFC 2822. - * @param string $id - * @throws Swift_RfcComplianceException - */ - private function _assertValidId($id) - { - if (!preg_match( - '/^' . $this->_grammar->getDefinition('id-left') . '@' . - $this->_grammar->getDefinition('id-right') . '$/D', - $id - )) + + /** + * Get the body of this entity as a string. + * + * @return string + */ + public function getBody() { - throw new Swift_RfcComplianceException( - 'Invalid ID given <' . $id . '>' - ); + return ($this->_body instanceof Swift_OutputByteStream) + ? $this->_readStream($this->_body) + : $this->_body; + } + + /** + * Set the body of this entity, either as a string, or as an instance of + * {@link Swift_OutputByteStream}. + * + * @param mixed $body + * @param string $contentType optional + * + * @return Swift_Mime_SimpleMimeEntity + */ + public function setBody($body, $contentType = null) + { + if ($body !== $this->_body) { + $this->_clearCache(); + } + + $this->_body = $body; + if (isset($contentType)) { + $this->setContentType($contentType); + } + + return $this; + } + + /** + * Get the encoder used for the body of this entity. + * + * @return Swift_Mime_ContentEncoder + */ + public function getEncoder() + { + return $this->_encoder; + } + + /** + * Set the encoder used for the body of this entity. + * + * @param Swift_Mime_ContentEncoder $encoder + * + * @return Swift_Mime_SimpleMimeEntity + */ + public function setEncoder(Swift_Mime_ContentEncoder $encoder) + { + if ($encoder !== $this->_encoder) { + $this->_clearCache(); + } + + $this->_encoder = $encoder; + $this->_setEncoding($encoder->getName()); + $this->_notifyEncoderChanged($encoder); + + return $this; + } + + /** + * Get the boundary used to separate children in this entity. + * + * @return string + */ + public function getBoundary() + { + if (!isset($this->_boundary)) { + $this->_boundary = '_=_swift_v4_' . time() . '_' . md5(getmypid().mt_rand().uniqid('', true)) . '_=_'; + } + + return $this->_boundary; + } + + /** + * Set the boundary used to separate children in this entity. + * + * @param string $boundary + * + * @return Swift_Mime_SimpleMimeEntity + * + * @throws Swift_RfcComplianceException + */ + public function setBoundary($boundary) + { + $this->_assertValidBoundary($boundary); + $this->_boundary = $boundary; + + return $this; + } + + /** + * Receive notification that the charset of this entity, or a parent entity + * has changed. + * + * @param string $charset + */ + public function charsetChanged($charset) + { + $this->_notifyCharsetChanged($charset); + } + + /** + * Receive notification that the encoder of this entity or a parent entity + * has changed. + * + * @param Swift_Mime_ContentEncoder $encoder + */ + public function encoderChanged(Swift_Mime_ContentEncoder $encoder) + { + $this->_notifyEncoderChanged($encoder); + } + + /** + * Get this entire entity as a string. + * + * @return string + */ + public function toString() + { + $string = $this->_headers->toString(); + $string .= $this->_bodyToString(); + + return $string; + } + + /** + * Get this entire entity as a string. + * + * @return string + */ + protected function _bodyToString() + { + $string = ''; + + if (isset($this->_body) && empty($this->_immediateChildren)) { + if ($this->_cache->hasKey($this->_cacheKey, 'body')) { + $body = $this->_cache->getString($this->_cacheKey, 'body'); + } else { + $body = "\r\n" . $this->_encoder->encodeString($this->getBody(), 0, + $this->getMaxLineLength() + ); + $this->_cache->setString($this->_cacheKey, 'body', $body, + Swift_KeyCache::MODE_WRITE + ); + } + $string .= $body; + } + + if (!empty($this->_immediateChildren)) { + foreach ($this->_immediateChildren as $child) { + $string .= "\r\n\r\n--" . $this->getBoundary() . "\r\n"; + $string .= $child->toString(); + } + $string .= "\r\n\r\n--" . $this->getBoundary() . "--\r\n"; + } + + return $string; + } + + /** + * Returns a string representation of this object. + * + * @see toString() + * + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * Write this entire entity to a {@see Swift_InputByteStream}. + * + * @param Swift_InputByteStream + */ + public function toByteStream(Swift_InputByteStream $is) + { + $is->write($this->_headers->toString()); + $is->commit(); + + $this->_bodyToByteStream($is); + } + + /** + * Write this entire entity to a {@link Swift_InputByteStream}. + * + * @param Swift_InputByteStream + */ + protected function _bodyToByteStream(Swift_InputByteStream $is) + { + if (empty($this->_immediateChildren)) { + if (isset($this->_body)) { + if ($this->_cache->hasKey($this->_cacheKey, 'body')) { + $this->_cache->exportToByteStream($this->_cacheKey, 'body', $is); + } else { + $cacheIs = $this->_cache->getInputByteStream($this->_cacheKey, 'body'); + if ($cacheIs) { + $is->bind($cacheIs); + } + + $is->write("\r\n"); + + if ($this->_body instanceof Swift_OutputByteStream) { + $this->_body->setReadPointer(0); + + $this->_encoder->encodeByteStream($this->_body, $is, 0, $this->getMaxLineLength()); + } else { + $is->write($this->_encoder->encodeString($this->getBody(), 0, $this->getMaxLineLength())); + } + + if ($cacheIs) { + $is->unbind($cacheIs); + } + } + } + } + + if (!empty($this->_immediateChildren)) { + foreach ($this->_immediateChildren as $child) { + $is->write("\r\n\r\n--" . $this->getBoundary() . "\r\n"); + $child->toByteStream($is); + } + $is->write("\r\n\r\n--" . $this->getBoundary() . "--\r\n"); + } + } + + // -- Protected methods + + /** + * Get the name of the header that provides the ID of this entity + */ + protected function _getIdField() + { + return 'Content-ID'; + } + + /** + * Get the model data (usually an array or a string) for $field. + */ + protected function _getHeaderFieldModel($field) + { + if ($this->_headers->has($field)) { + return $this->_headers->get($field)->getFieldBodyModel(); + } + } + + /** + * Set the model data for $field. + */ + protected function _setHeaderFieldModel($field, $model) + { + if ($this->_headers->has($field)) { + $this->_headers->get($field)->setFieldBodyModel($model); + + return true; + } else { + return false; + } + } + + /** + * Get the parameter value of $parameter on $field header. + */ + protected function _getHeaderParameter($field, $parameter) + { + if ($this->_headers->has($field)) { + return $this->_headers->get($field)->getParameter($parameter); + } + } + + /** + * Set the parameter value of $parameter on $field header. + */ + protected function _setHeaderParameter($field, $parameter, $value) + { + if ($this->_headers->has($field)) { + $this->_headers->get($field)->setParameter($parameter, $value); + + return true; + } else { + return false; + } + } + + /** + * Re-evaluate what content type and encoding should be used on this entity. + */ + protected function _fixHeaders() + { + if (count($this->_immediateChildren)) { + $this->_setHeaderParameter('Content-Type', 'boundary', + $this->getBoundary() + ); + $this->_headers->remove('Content-Transfer-Encoding'); + } else { + $this->_setHeaderParameter('Content-Type', 'boundary', null); + $this->_setEncoding($this->_encoder->getName()); + } + } + + /** + * Get the KeyCache used in this entity. + * + * @return Swift_KeyCache + */ + protected function _getCache() + { + return $this->_cache; + } + + /** + * Get the grammar used for validation. + * + * @return Swift_Mime_Grammar + */ + protected function _getGrammar() + { + return $this->_grammar; + } + + /** + * Empty the KeyCache for this entity. + */ + protected function _clearCache() + { + $this->_cache->clearKey($this->_cacheKey, 'body'); + } + + /** + * Returns a random Content-ID or Message-ID. + * + * @return string + */ + protected function getRandomId() + { + $idLeft = md5(getmypid() . '.' . time() . '.' . uniqid(mt_rand(), true)); + $idRight = !empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'swift.generated'; + $id = $idLeft . '@' . $idRight; + + try { + $this->_assertValidId($id); + } catch (Swift_RfcComplianceException $e) { + $id = $idLeft . '@swift.generated'; + } + + return $id; + } + + // -- Private methods + + private function _readStream(Swift_OutputByteStream $os) + { + $string = ''; + while (false !== $bytes = $os->read(8192)) { + $string .= $bytes; + } + + return $string; + } + + private function _setEncoding($encoding) + { + if (!$this->_setHeaderFieldModel('Content-Transfer-Encoding', $encoding)) { + $this->_headers->addTextHeader('Content-Transfer-Encoding', $encoding); + } + } + + private function _assertValidBoundary($boundary) + { + if (!preg_match( + '/^[a-z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-z0-9\'\(\)\+_\-,\.\/:=\?]$/Di', + $boundary)) + { + throw new Swift_RfcComplianceException('Mime boundary set is not RFC 2046 compliant.'); + } + } + + private function _setContentTypeInHeaders($type) + { + if (!$this->_setHeaderFieldModel('Content-Type', $type)) { + $this->_headers->addParameterizedHeader('Content-Type', $type); + } + } + + private function _setNestingLevel($level) + { + $this->_nestingLevel = $level; + } + + private function _getCompoundLevel($children) + { + $level = 0; + foreach ($children as $child) { + $level |= $child->getNestingLevel(); + } + + return $level; + } + + private function _getNeededChildLevel($child, $compoundLevel) + { + $filter = array(); + foreach ($this->_compoundLevelFilters as $bitmask => $rules) { + if (($compoundLevel & $bitmask) === $bitmask) { + $filter = $rules + $filter; + } + } + + $realLevel = $child->getNestingLevel(); + $lowercaseType = strtolower($child->getContentType()); + + if (isset($filter[$realLevel]) + && isset($filter[$realLevel][$lowercaseType])) + { + return $filter[$realLevel][$lowercaseType]; + } else { + return $realLevel; + } + } + + private function _createChild() + { + return new self($this->_headers->newInstance(), + $this->_encoder, $this->_cache, $this->_grammar); + } + + private function _notifyEncoderChanged(Swift_Mime_ContentEncoder $encoder) + { + foreach ($this->_immediateChildren as $child) { + $child->encoderChanged($encoder); + } + } + + private function _notifyCharsetChanged($charset) + { + $this->_encoder->charsetChanged($charset); + $this->_headers->charsetChanged($charset); + foreach ($this->_immediateChildren as $child) { + $child->charsetChanged($charset); + } + } + + private function _sortChildren() + { + $shouldSort = false; + foreach ($this->_immediateChildren as $child) { + // NOTE: This include alternative parts moved into a related part + if ($child->getNestingLevel() == self::LEVEL_ALTERNATIVE) { + $shouldSort = true; + break; + } + } + + // Sort in order of preference, if there is one + if ($shouldSort) { + usort($this->_immediateChildren, array($this, '_childSortAlgorithm')); + } + } + + private function _childSortAlgorithm($a, $b) + { + $typePrefs = array(); + $types = array( + strtolower($a->getContentType()), + strtolower($b->getContentType()) + ); + foreach ($types as $type) { + $typePrefs[] = (array_key_exists($type, $this->_alternativePartOrder)) + ? $this->_alternativePartOrder[$type] + : (max($this->_alternativePartOrder) + 1); + } + + return ($typePrefs[0] >= $typePrefs[1]) ? 1 : -1; + } + + // -- Destructor + + /** + * Empties it's own contents from the cache. + */ + public function __destruct() + { + $this->_cache->clearAll($this->_cacheKey); + } + + /** + * Throws an Exception if the id passed does not comply with RFC 2822. + * + * @param string $id + * + * @throws Swift_RfcComplianceException + */ + private function _assertValidId($id) + { + if (!preg_match( + '/^' . $this->_grammar->getDefinition('id-left') . '@' . + $this->_grammar->getDefinition('id-right') . '$/D', + $id + )) + { + throw new Swift_RfcComplianceException( + 'Invalid ID given <' . $id . '>' + ); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/MimePart.php b/lib/swiftmailer/lib/classes/Swift/MimePart.php index e22f15e6e..10a4f3c86 100644 --- a/lib/swiftmailer/lib/classes/Swift/MimePart.php +++ b/lib/swiftmailer/lib/classes/Swift/MimePart.php @@ -8,56 +8,54 @@ * file that was distributed with this source code. */ - /** * A MIME part, in a multipart message. - * @package Swift + * + * @package Swift * @subpackage Mime - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_MimePart extends Swift_Mime_MimePart { - - /** - * Create a new MimePart. - * Details may be optionally passed into the constructor. - * @param string $body - * @param string $contentType - * @param string $charset - */ - public function __construct($body = null, $contentType = null, - $charset = null) - { - call_user_func_array( - array($this, 'Swift_Mime_MimePart::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('mime.part') - ); - - if (!isset($charset)) + /** + * Create a new MimePart. + * + * Details may be optionally passed into the constructor. + * + * @param string $body + * @param string $contentType + * @param string $charset + */ + public function __construct($body = null, $contentType = null, $charset = null) { - $charset = Swift_DependencyContainer::getInstance() - ->lookup('properties.charset'); + call_user_func_array( + array($this, 'Swift_Mime_MimePart::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('mime.part') + ); + + if (!isset($charset)) { + $charset = Swift_DependencyContainer::getInstance() + ->lookup('properties.charset'); + } + $this->setBody($body); + $this->setCharset($charset); + if ($contentType) { + $this->setContentType($contentType); + } } - $this->setBody($body); - $this->setCharset($charset); - if ($contentType) + + /** + * Create a new MimePart. + * + * @param string $body + * @param string $contentType + * @param string $charset + * + * @return Swift_Mime_MimePart + */ + public static function newInstance($body = null, $contentType = null, $charset = null) { - $this->setContentType($contentType); + return new self($body, $contentType, $charset); } - } - - /** - * Create a new MimePart. - * @param string $body - * @param string $contentType - * @param string $charset - * @return Swift_Mime_MimePart - */ - public static function newInstance($body = null, $contentType = null, - $charset = null) - { - return new self($body, $contentType, $charset); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/NullTransport.php b/lib/swiftmailer/lib/classes/Swift/NullTransport.php index 8c82ee282..335c47934 100644 --- a/lib/swiftmailer/lib/classes/Swift/NullTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/NullTransport.php @@ -10,29 +10,31 @@ /** * Pretends messages have been sent, but just ignores them. + * * @package Swift * @author Fabien Potencier */ class Swift_NullTransport extends Swift_Transport_NullTransport { - /** - * Create a new NullTransport. - */ - public function __construct() - { - call_user_func_array( - array($this, 'Swift_Transport_NullTransport::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.null') - ); - } - - /** - * Create a new NullTransport instance. - * @return Swift_NullTransport - */ - public static function newInstance() - { - return new self(); - } + /** + * Create a new NullTransport. + */ + public function __construct() + { + call_user_func_array( + array($this, 'Swift_Transport_NullTransport::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.null') + ); + } + + /** + * Create a new NullTransport instance. + * + * @return Swift_NullTransport + */ + public static function newInstance() + { + return new self(); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/OutputByteStream.php b/lib/swiftmailer/lib/classes/Swift/OutputByteStream.php index 951b83834..47faa73af 100644 --- a/lib/swiftmailer/lib/classes/Swift/OutputByteStream.php +++ b/lib/swiftmailer/lib/classes/Swift/OutputByteStream.php @@ -10,32 +10,39 @@ /** * An abstract means of reading data. + * * Classes implementing this interface may use a subsystem which requires less * memory than working with large strings of data. - * @package Swift + * + * @package Swift * @subpackage ByteStream - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_OutputByteStream { - - /** - * Reads $length bytes from the stream into a string and moves the pointer - * through the stream by $length. If less bytes exist than are requested the - * remaining bytes are given instead. If no bytes are remaining at all, boolean - * false is returned. - * @param int $length - * @return string - * @throws Swift_IoException - */ - public function read($length); - - /** - * Move the internal read pointer to $byteOffset in the stream. - * @param int $byteOffset - * @return boolean - * @throws Swift_IoException - */ - public function setReadPointer($byteOffset); - + /** + * Reads $length bytes from the stream into a string and moves the pointer + * through the stream by $length. + * + * If less bytes exist than are requested the remaining bytes are given instead. + * If no bytes are remaining at all, boolean false is returned. + * + * @param int $length + * + * @return string|bool + * + * @throws Swift_IoException + */ + public function read($length); + + /** + * Move the internal read pointer to $byteOffset in the stream. + * + * @param int $byteOffset + * + * @return bool + * + * @throws Swift_IoException + */ + public function setReadPointer($byteOffset); } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php index 34e3d147f..307da9d77 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/AntiFloodPlugin.php @@ -8,137 +8,136 @@ * file that was distributed with this source code. */ - /** * Reduces network flooding when sending large amounts of mail. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Plugins_AntiFloodPlugin - implements Swift_Events_SendListener, Swift_Plugins_Sleeper +class Swift_Plugins_AntiFloodPlugin implements Swift_Events_SendListener, Swift_Plugins_Sleeper { - - /** - * The number of emails to send before restarting Transport. - * @var int - * @access private - */ - private $_threshold; - - /** - * The number of seconds to sleep for during a restart. - * @var int - * @access private - */ - private $_sleep; - - /** - * The internal counter. - * @var int - * @access private - */ - private $_counter = 0; - - /** - * The Sleeper instance for sleeping. - * @var Swift_Plugins_Sleeper - * @access private - */ - private $_sleeper; - - /** - * Create a new AntiFloodPlugin with $threshold and $sleep time. - * @param int $threshold - * @param int $sleep time - * @param Swift_Plugins_Sleeper $sleeper (not needed really) - */ - public function __construct($threshold = 99, $sleep = 0, - Swift_Plugins_Sleeper $sleeper = null) - { - $this->setThreshold($threshold); - $this->setSleepTime($sleep); - $this->_sleeper = $sleeper; - } - - /** - * Set the number of emails to send before restarting. - * @param int $threshold - */ - public function setThreshold($threshold) - { - $this->_threshold = $threshold; - } - - /** - * Get the number of emails to send before restarting. - * @return int - */ - public function getThreshold() - { - return $this->_threshold; - } - - /** - * Set the number of seconds to sleep for during a restart. - * @param int $sleep time - */ - public function setSleepTime($sleep) - { - $this->_sleep = $sleep; - } - - /** - * Get the number of seconds to sleep for during a restart. - * @return int - */ - public function getSleepTime() - { - return $this->_sleep; - } - - /** - * Invoked immediately before the Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - } - - /** - * Invoked immediately after the Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - ++$this->_counter; - if ($this->_counter >= $this->_threshold) + /** + * The number of emails to send before restarting Transport. + * + * @var int + */ + private $_threshold; + + /** + * The number of seconds to sleep for during a restart. + * + * @var int + */ + private $_sleep; + + /** + * The internal counter. + * + * @var int + */ + private $_counter = 0; + + /** + * The Sleeper instance for sleeping. + * + * @var Swift_Plugins_Sleeper + */ + private $_sleeper; + + /** + * Create a new AntiFloodPlugin with $threshold and $sleep time. + * + * @param int $threshold + * @param int $sleep time + * @param Swift_Plugins_Sleeper $sleeper (not needed really) + */ + public function __construct($threshold = 99, $sleep = 0, Swift_Plugins_Sleeper $sleeper = null) { - $transport = $evt->getTransport(); - $transport->stop(); - if ($this->_sleep) - { - $this->sleep($this->_sleep); - } - $transport->start(); - $this->_counter = 0; + $this->setThreshold($threshold); + $this->setSleepTime($sleep); + $this->_sleeper = $sleeper; } - } - - /** - * Sleep for $seconds. - * @param int $seconds - */ - public function sleep($seconds) - { - if (isset($this->_sleeper)) + + /** + * Set the number of emails to send before restarting. + * + * @param int $threshold + */ + public function setThreshold($threshold) { - $this->_sleeper->sleep($seconds); + $this->_threshold = $threshold; } - else + + /** + * Get the number of emails to send before restarting. + * + * @return int + */ + public function getThreshold() { - sleep($seconds); + return $this->_threshold; + } + + /** + * Set the number of seconds to sleep for during a restart. + * + * @param int $sleep time + */ + public function setSleepTime($sleep) + { + $this->_sleep = $sleep; + } + + /** + * Get the number of seconds to sleep for during a restart. + * + * @return int + */ + public function getSleepTime() + { + return $this->_sleep; + } + + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + } + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + ++$this->_counter; + if ($this->_counter >= $this->_threshold) { + $transport = $evt->getTransport(); + $transport->stop(); + if ($this->_sleep) { + $this->sleep($this->_sleep); + } + $transport->start(); + $this->_counter = 0; + } + } + + /** + * Sleep for $seconds. + * + * @param int $seconds + */ + public function sleep($seconds) + { + if (isset($this->_sleeper)) { + $this->_sleeper->sleep($seconds); + } else { + sleep($seconds); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php index f56d3374a..8794aacf0 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php @@ -8,159 +8,159 @@ * file that was distributed with this source code. */ - /** * Reduces network flooding when sending large amounts of mail. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Plugins_BandwidthMonitorPlugin - implements Swift_Events_SendListener, Swift_Events_CommandListener, - Swift_Events_ResponseListener, Swift_InputByteStream +class Swift_Plugins_BandwidthMonitorPlugin implements Swift_Events_SendListener, Swift_Events_CommandListener, Swift_Events_ResponseListener, Swift_InputByteStream { - - /** - * The outgoing traffic counter. - * @var int - * @access private - */ - private $_out = 0; - - /** - * The incoming traffic counter. - * @var int - * @access private - */ - private $_in = 0; - - /** Bound byte streams */ - private $_mirrors = array(); - - /** - * Not used. - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - } - - /** - * Invoked immediately after the Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - $message->toByteStream($this); - } - - /** - * Invoked immediately following a command being sent. - * @param Swift_Events_ResponseEvent $evt - */ - public function commandSent(Swift_Events_CommandEvent $evt) - { - $command = $evt->getCommand(); - $this->_out += strlen($command); - } - - /** - * Invoked immediately following a response coming back. - * @param Swift_Events_ResponseEvent $evt - */ - public function responseReceived(Swift_Events_ResponseEvent $evt) - { - $response = $evt->getResponse(); - $this->_in += strlen($response); - } - - /** - * Called when a message is sent so that the outgoing counter can be increased. - * @param string $bytes - */ - public function write($bytes) - { - $this->_out += strlen($bytes); - foreach ($this->_mirrors as $stream) + /** + * The outgoing traffic counter. + * + * @var int + */ + private $_out = 0; + + /** + * The incoming traffic counter. + * + * @var int + */ + private $_in = 0; + + /** Bound byte streams */ + private $_mirrors = array(); + + /** + * Not used. + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) { - $stream->write($bytes); } - } - - /** - * Not used. - */ - public function commit() - { - } - - /** - * Attach $is to this stream. - * The stream acts as an observer, receiving all data that is written. - * All {@link write()} and {@link flushBuffers()} operations will be mirrored. - * - * @param Swift_InputByteStream $is - */ - public function bind(Swift_InputByteStream $is) - { - $this->_mirrors[] = $is; - } - - /** - * Remove an already bound stream. - * If $is is not bound, no errors will be raised. - * If the stream currently has any buffered data it will be written to $is - * before unbinding occurs. - * - * @param Swift_InputByteStream $is - */ - public function unbind(Swift_InputByteStream $is) - { - foreach ($this->_mirrors as $k => $stream) + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) { - if ($is === $stream) - { - unset($this->_mirrors[$k]); - } + $message = $evt->getMessage(); + $message->toByteStream($this); } - } - - /** - * Not used. - */ - public function flushBuffers() - { - foreach ($this->_mirrors as $stream) + + /** + * Invoked immediately following a command being sent. + * + * @param Swift_Events_CommandEvent $evt + */ + public function commandSent(Swift_Events_CommandEvent $evt) { - $stream->flushBuffers(); + $command = $evt->getCommand(); + $this->_out += strlen($command); + } + + /** + * Invoked immediately following a response coming back. + * + * @param Swift_Events_ResponseEvent $evt + */ + public function responseReceived(Swift_Events_ResponseEvent $evt) + { + $response = $evt->getResponse(); + $this->_in += strlen($response); + } + + /** + * Called when a message is sent so that the outgoing counter can be increased. + * + * @param string $bytes + */ + public function write($bytes) + { + $this->_out += strlen($bytes); + foreach ($this->_mirrors as $stream) { + $stream->write($bytes); + } + } + + /** + * Not used. + */ + public function commit() + { + } + + /** + * Attach $is to this stream. + * + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + */ + public function bind(Swift_InputByteStream $is) + { + $this->_mirrors[] = $is; + } + + /** + * Remove an already bound stream. + * + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + */ + public function unbind(Swift_InputByteStream $is) + { + foreach ($this->_mirrors as $k => $stream) { + if ($is === $stream) { + unset($this->_mirrors[$k]); + } + } + } + + /** + * Not used. + */ + public function flushBuffers() + { + foreach ($this->_mirrors as $stream) { + $stream->flushBuffers(); + } + } + + /** + * Get the total number of bytes sent to the server. + * + * @return int + */ + public function getBytesOut() + { + return $this->_out; + } + + /** + * Get the total number of bytes received from the server. + * + * @return int + */ + public function getBytesIn() + { + return $this->_in; + } + + /** + * Reset the internal counters to zero. + */ + public function reset() + { + $this->_out = 0; + $this->_in = 0; } - } - - /** - * Get the total number of bytes sent to the server. - * @return int - */ - public function getBytesOut() - { - return $this->_out; - } - - /** - * Get the total number of bytes received from the server. - * @return int - */ - public function getBytesIn() - { - return $this->_in; - } - - /** - * Reset the internal counters to zero. - */ - public function reset() - { - $this->_out = 0; - $this->_in = 0; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php index 9735d0a04..3269c6982 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Decorator/Replacements.php @@ -10,27 +10,24 @@ /** * Allows customization of Messages on-the-fly. - * - * @package Swift + * + * @package Swift * @subpackage Plugins - * - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Plugins_Decorator_Replacements { - - /** - * Return the array of replacements for $address. - * - * This method is invoked once for every single recipient of a message. - * - * If no replacements can be found, an empty value (NULL) should be returned - * and no replacements will then be made on the message. - * - * @param string $address - * - * @return array - */ - public function getReplacementsFor($address); - + /** + * Return the array of replacements for $address. + * + * This method is invoked once for every single recipient of a message. + * + * If no replacements can be found, an empty value (NULL) should be returned + * and no replacements will then be made on the message. + * + * @param string $address + * + * @return array + */ + public function getReplacementsFor($address); } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php index a92985766..84f70709e 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php @@ -8,224 +8,204 @@ * file that was distributed with this source code. */ - /** * Allows customization of Messages on-the-fly. - * - * @package Swift + * + * @package Swift * @subpackage Plugins - * - * @author Chris Corbyn - * @author Fabien Potencier + * @author Chris Corbyn + * @author Fabien Potencier */ -class Swift_Plugins_DecoratorPlugin - implements Swift_Events_SendListener, Swift_Plugins_Decorator_Replacements +class Swift_Plugins_DecoratorPlugin implements Swift_Events_SendListener, Swift_Plugins_Decorator_Replacements { + /** The replacement map */ + private $_replacements; - /** The replacement map */ - private $_replacements; - - /** The body as it was before replacements */ - private $_orginalBody; + /** The body as it was before replacements */ + private $_originalBody; - /** The original headers of the message, before replacements */ - private $_originalHeaders = array(); + /** The original headers of the message, before replacements */ + private $_originalHeaders = array(); - /** Bodies of children before they are replaced */ - private $_originalChildBodies = array(); + /** Bodies of children before they are replaced */ + private $_originalChildBodies = array(); - /** The Message that was last replaced */ - private $_lastMessage; + /** The Message that was last replaced */ + private $_lastMessage; - /** - * Create a new DecoratorPlugin with $replacements. - * - * The $replacements can either be an associative array, or an implementation - * of {@link Swift_Plugins_Decorator_Replacements}. - * - * When using an array, it should be of the form: - * - * $replacements = array( - * "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"), - * "address2@domain.tld" => array("{a}" => "x", "{c}" => "y") - * ) - * - * - * When using an instance of {@link Swift_Plugins_Decorator_Replacements}, - * the object should return just the array of replacements for the address - * given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}. - * - * @param mixed $replacements - */ - public function __construct($replacements) - { - if (!($replacements instanceof Swift_Plugins_Decorator_Replacements)) + /** + * Create a new DecoratorPlugin with $replacements. + * + * The $replacements can either be an associative array, or an implementation + * of {@link Swift_Plugins_Decorator_Replacements}. + * + * When using an array, it should be of the form: + * + * $replacements = array( + * "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"), + * "address2@domain.tld" => array("{a}" => "x", "{c}" => "y") + * ) + * + * + * When using an instance of {@link Swift_Plugins_Decorator_Replacements}, + * the object should return just the array of replacements for the address + * given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}. + * + * @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements + */ + public function __construct($replacements) { - $this->_replacements = (array) $replacements; + $this->setReplacements($replacements); } - else + + /** + * Sets replacements. + * + * @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements + * + * @see __construct() + */ + public function setReplacements($replacements) { - $this->_replacements = $replacements; + if (!($replacements instanceof Swift_Plugins_Decorator_Replacements)) { + $this->_replacements = (array) $replacements; + } else { + $this->_replacements = $replacements; + } } - } - /** - * Invoked immediately before the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - $this->_restoreMessage($message); - $to = array_keys($message->getTo()); - $address = array_shift($to); - if ($replacements = $this->getReplacementsFor($address)) + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) { - $body = $message->getBody(); - $search = array_keys($replacements); - $replace = array_values($replacements); - $bodyReplaced = str_replace( - $search, $replace, $body - ); - if ($body != $bodyReplaced) - { - $this->_originalBody = $body; - $message->setBody($bodyReplaced); - } - - foreach ($message->getHeaders()->getAll() as $header) - { - $body = $header->getFieldBodyModel(); - $count = 0; - if (is_array($body)) - { - $bodyReplaced = array(); - foreach ($body as $key => $value) - { - $count1 = 0; - $count2 = 0; - $key = is_string($key) ? str_replace($search, $replace, $key, $count1) : $key; - $value = is_string($value) ? str_replace($search, $replace, $value, $count2) : $value; - $bodyReplaced[$key] = $value; - - if (!$count && ($count1 || $count2)) - { - $count = 1; + $message = $evt->getMessage(); + $this->_restoreMessage($message); + $to = array_keys($message->getTo()); + $address = array_shift($to); + if ($replacements = $this->getReplacementsFor($address)) { + $body = $message->getBody(); + $search = array_keys($replacements); + $replace = array_values($replacements); + $bodyReplaced = str_replace( + $search, $replace, $body + ); + if ($body != $bodyReplaced) { + $this->_originalBody = $body; + $message->setBody($bodyReplaced); } - } - } - else - { - $bodyReplaced = str_replace($search, $replace, $body, $count); - } - if ($count) - { - $this->_originalHeaders[$header->getFieldName()] = $body; - $header->setFieldBodyModel($bodyReplaced); - } - } + foreach ($message->getHeaders()->getAll() as $header) { + $body = $header->getFieldBodyModel(); + $count = 0; + if (is_array($body)) { + $bodyReplaced = array(); + foreach ($body as $key => $value) { + $count1 = 0; + $count2 = 0; + $key = is_string($key) ? str_replace($search, $replace, $key, $count1) : $key; + $value = is_string($value) ? str_replace($search, $replace, $value, $count2) : $value; + $bodyReplaced[$key] = $value; - $children = (array) $message->getChildren(); - foreach ($children as $child) - { - list($type, ) = sscanf($child->getContentType(), '%[^/]/%s'); - if ('text' == $type) - { - $body = $child->getBody(); - $bodyReplaced = str_replace( - $search, $replace, $body - ); - if ($body != $bodyReplaced) - { - $child->setBody($bodyReplaced); - $this->_originalChildBodies[$child->getId()] = $body; - } + if (!$count && ($count1 || $count2)) { + $count = 1; + } + } + } else { + $bodyReplaced = str_replace($search, $replace, $body, $count); + } + + if ($count) { + $this->_originalHeaders[$header->getFieldName()] = $body; + $header->setFieldBodyModel($bodyReplaced); + } + } + + $children = (array) $message->getChildren(); + foreach ($children as $child) { + list($type, ) = sscanf($child->getContentType(), '%[^/]/%s'); + if ('text' == $type) { + $body = $child->getBody(); + $bodyReplaced = str_replace( + $search, $replace, $body + ); + if ($body != $bodyReplaced) { + $child->setBody($bodyReplaced); + $this->_originalChildBodies[$child->getId()] = $body; + } + } + } + $this->_lastMessage = $message; } - } - $this->_lastMessage = $message; } - } - - /** - * Find a map of replacements for the address. - * - * If this plugin was provided with a delegate instance of - * {@link Swift_Plugins_Decorator_Replacements} then the call will be - * delegated to it. Otherwise, it will attempt to find the replacements - * from the array provided in the constructor. - * - * If no replacements can be found, an empty value (NULL) is returned. - * - * @param string $address - * - * @return array - */ - public function getReplacementsFor($address) - { - if ($this->_replacements instanceof Swift_Plugins_Decorator_Replacements) + + /** + * Find a map of replacements for the address. + * + * If this plugin was provided with a delegate instance of + * {@link Swift_Plugins_Decorator_Replacements} then the call will be + * delegated to it. Otherwise, it will attempt to find the replacements + * from the array provided in the constructor. + * + * If no replacements can be found, an empty value (NULL) is returned. + * + * @param string $address + * + * @return array + */ + public function getReplacementsFor($address) { - return $this->_replacements->getReplacementsFor($address); - } - else - { - return isset($this->_replacements[$address]) - ? $this->_replacements[$address] - : null - ; - } - } - - /** - * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - $this->_restoreMessage($evt->getMessage()); - } - - // -- Private methods - - /** Restore a changed message back to its original state */ - private function _restoreMessage(Swift_Mime_Message $message) - { - if ($this->_lastMessage === $message) - { - if (isset($this->_originalBody)) - { - $message->setBody($this->_originalBody); - $this->_originalBody = null; - } - if (!empty($this->_originalHeaders)) - { - foreach ($message->getHeaders()->getAll() as $header) - { - $body = $header->getFieldBodyModel(); - if (array_key_exists($header->getFieldName(), $this->_originalHeaders)) - { - $header->setFieldBodyModel($this->_originalHeaders[$header->getFieldName()]); - } + if ($this->_replacements instanceof Swift_Plugins_Decorator_Replacements) { + return $this->_replacements->getReplacementsFor($address); + } else { + return isset($this->_replacements[$address]) + ? $this->_replacements[$address] + : null + ; } - $this->_originalHeaders = array(); - } - if (!empty($this->_originalChildBodies)) - { - $children = (array) $message->getChildren(); - foreach ($children as $child) - { - $id = $child->getId(); - if (array_key_exists($id, $this->_originalChildBodies)) - { - $child->setBody($this->_originalChildBodies[$id]); - } - } - $this->_originalChildBodies = array(); - } - $this->_lastMessage = null; } - } + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + $this->_restoreMessage($evt->getMessage()); + } + + // -- Private methods + + /** Restore a changed message back to its original state */ + private function _restoreMessage(Swift_Mime_Message $message) + { + if ($this->_lastMessage === $message) { + if (isset($this->_originalBody)) { + $message->setBody($this->_originalBody); + $this->_originalBody = null; + } + if (!empty($this->_originalHeaders)) { + foreach ($message->getHeaders()->getAll() as $header) { + if (array_key_exists($header->getFieldName(), $this->_originalHeaders)) { + $header->setFieldBodyModel($this->_originalHeaders[$header->getFieldName()]); + } + } + $this->_originalHeaders = array(); + } + if (!empty($this->_originalChildBodies)) { + $children = (array) $message->getChildren(); + foreach ($children as $child) { + $id = $child->getId(); + if (array_key_exists($id, $this->_originalChildBodies)) { + $child->setBody($this->_originalChildBodies[$id]); + } + } + $this->_originalChildBodies = array(); + } + $this->_lastMessage = null; + } + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php index a269f3a28..1f1e4430c 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/ImpersonatePlugin.php @@ -10,35 +10,36 @@ /** * Replaces the sender of a message. * - * @package Swift + * @package Swift * @subpackage Plugins - * @author Arjen Brouwer + * @author Arjen Brouwer */ -class Swift_Plugins_ImpersonatePlugin implements \Swift_Events_SendListener { - +class Swift_Plugins_ImpersonatePlugin implements Swift_Events_SendListener +{ /** * The sender to impersonate. - * + * * @var String - * @access private */ private $_sender; /** * Create a new ImpersonatePlugin to impersonate $sender. - * + * * @param string $sender address */ - public function __construct($sender) { + public function __construct($sender) + { $this->_sender = $sender; } /** * Invoked immediately before the Message is sent. - * + * * @param Swift_Events_SendEvent $evt */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) { + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { $message = $evt->getMessage(); $headers = $message->getHeaders(); @@ -51,18 +52,19 @@ class Swift_Plugins_ImpersonatePlugin implements \Swift_Events_SendListener { /** * Invoked immediately after the Message is sent. - * + * * @param Swift_Events_SendEvent $evt */ - public function sendPerformed(Swift_Events_SendEvent $evt) { + public function sendPerformed(Swift_Events_SendEvent $evt) + { $message = $evt->getMessage(); // restore original headers $headers = $message->getHeaders(); if ($headers->has('X-Swift-Return-Path')) { - $message->setReturnPath($headers->get('X-Swift-Return-Path')->getAddress()); - $headers->removeAll('X-Swift-Return-Path'); + $message->setReturnPath($headers->get('X-Swift-Return-Path')->getAddress()); + $headers->removeAll('X-Swift-Return-Path'); } } } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Logger.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Logger.php index 9864da0dd..81c1d9bb8 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Logger.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Logger.php @@ -10,28 +10,29 @@ /** * Logs events in the Transport system. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Plugins_Logger { - - /** - * Add a log entry. - * @param string $entry - */ - public function add($entry); - - /** - * Clear the log contents. - */ - public function clear(); - - /** - * Get this log as a string. - * @return string - */ - public function dump(); - + /** + * Add a log entry. + * + * @param string $entry + */ + public function add($entry); + + /** + * Clear the log contents. + */ + public function clear(); + + /** + * Get this log as a string. + * + * @return string + */ + public function dump(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php index 20e5490b3..cfe9ca134 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php @@ -8,143 +8,136 @@ * file that was distributed with this source code. */ - /** * Does real time logging of Transport level information. - * - * @package Swift + * + * @package Swift * @subpackage Plugins - * - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Plugins_LoggerPlugin - implements Swift_Events_CommandListener, Swift_Events_ResponseListener, - Swift_Events_TransportChangeListener, Swift_Events_TransportExceptionListener, - Swift_Plugins_Logger +class Swift_Plugins_LoggerPlugin implements Swift_Events_CommandListener, Swift_Events_ResponseListener, Swift_Events_TransportChangeListener, Swift_Events_TransportExceptionListener, Swift_Plugins_Logger { - - /** The logger which is delegated to */ - private $_logger; - - /** - * Create a new LoggerPlugin using $logger. - * - * @param Swift_Plugins_Logger $logger - */ - public function __construct(Swift_Plugins_Logger $logger) - { - $this->_logger = $logger; - } - - /** - * Add a log entry. - * - * @param string $entry - */ - public function add($entry) - { - $this->_logger->add($entry); - } - - /** - * Clear the log contents. - */ - public function clear() - { - $this->_logger->clear(); - } - - /** - * Get this log as a string. - * - * @return string - */ - public function dump() - { - return $this->_logger->dump(); - } - - /** - * Invoked immediately following a command being sent. - * - * @param Swift_Events_ResponseEvent $evt - */ - public function commandSent(Swift_Events_CommandEvent $evt) - { - $command = $evt->getCommand(); - $this->_logger->add(sprintf(">> %s", $command)); - } - - /** - * Invoked immediately following a response coming back. - * - * @param Swift_Events_ResponseEvent $evt - */ - public function responseReceived(Swift_Events_ResponseEvent $evt) - { - $response = $evt->getResponse(); - $this->_logger->add(sprintf("<< %s", $response)); - } - - /** - * Invoked just before a Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) - { - $transportName = get_class($evt->getSource()); - $this->_logger->add(sprintf("++ Starting %s", $transportName)); - } - - /** - * Invoked immediately after the Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function transportStarted(Swift_Events_TransportChangeEvent $evt) - { - $transportName = get_class($evt->getSource()); - $this->_logger->add(sprintf("++ %s started", $transportName)); - } - - /** - * Invoked just before a Transport is stopped. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) - { - $transportName = get_class($evt->getSource()); - $this->_logger->add(sprintf("++ Stopping %s", $transportName)); - } - - /** - * Invoked immediately after the Transport is stopped. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function transportStopped(Swift_Events_TransportChangeEvent $evt) - { - $transportName = get_class($evt->getSource()); - $this->_logger->add(sprintf("++ %s stopped", $transportName)); - } - - /** - * Invoked as a TransportException is thrown in the Transport system. - * - * @param Swift_Events_TransportExceptionEvent $evt - */ - public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt) - { - $e = $evt->getException(); - $message = $e->getMessage(); - $this->_logger->add(sprintf("!! %s", $message)); - $message .= PHP_EOL; - $message .= 'Log data:' . PHP_EOL; - $message .= $this->_logger->dump(); - $evt->cancelBubble(); - throw new Swift_TransportException($message); - } - + /** The logger which is delegated to */ + private $_logger; + + /** + * Create a new LoggerPlugin using $logger. + * + * @param Swift_Plugins_Logger $logger + */ + public function __construct(Swift_Plugins_Logger $logger) + { + $this->_logger = $logger; + } + + /** + * Add a log entry. + * + * @param string $entry + */ + public function add($entry) + { + $this->_logger->add($entry); + } + + /** + * Clear the log contents. + */ + public function clear() + { + $this->_logger->clear(); + } + + /** + * Get this log as a string. + * + * @return string + */ + public function dump() + { + return $this->_logger->dump(); + } + + /** + * Invoked immediately following a command being sent. + * + * @param Swift_Events_CommandEvent $evt + */ + public function commandSent(Swift_Events_CommandEvent $evt) + { + $command = $evt->getCommand(); + $this->_logger->add(sprintf(">> %s", $command)); + } + + /** + * Invoked immediately following a response coming back. + * + * @param Swift_Events_ResponseEvent $evt + */ + public function responseReceived(Swift_Events_ResponseEvent $evt) + { + $response = $evt->getResponse(); + $this->_logger->add(sprintf("<< %s", $response)); + } + + /** + * Invoked just before a Transport is started. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) + { + $transportName = get_class($evt->getSource()); + $this->_logger->add(sprintf("++ Starting %s", $transportName)); + } + + /** + * Invoked immediately after the Transport is started. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function transportStarted(Swift_Events_TransportChangeEvent $evt) + { + $transportName = get_class($evt->getSource()); + $this->_logger->add(sprintf("++ %s started", $transportName)); + } + + /** + * Invoked just before a Transport is stopped. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) + { + $transportName = get_class($evt->getSource()); + $this->_logger->add(sprintf("++ Stopping %s", $transportName)); + } + + /** + * Invoked immediately after the Transport is stopped. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function transportStopped(Swift_Events_TransportChangeEvent $evt) + { + $transportName = get_class($evt->getSource()); + $this->_logger->add(sprintf("++ %s stopped", $transportName)); + } + + /** + * Invoked as a TransportException is thrown in the Transport system. + * + * @param Swift_Events_TransportExceptionEvent $evt + */ + public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt) + { + $e = $evt->getException(); + $message = $e->getMessage(); + $this->_logger->add(sprintf("!! %s", $message)); + $message .= PHP_EOL; + $message .= 'Log data:' . PHP_EOL; + $message .= $this->_logger->dump(); + $evt->cancelBubble(); + throw new Swift_TransportException($message); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php index 930eca25f..eb362ef83 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php @@ -10,64 +10,65 @@ /** * Logs to an Array backend. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Plugins_Loggers_ArrayLogger implements Swift_Plugins_Logger { - - /** - * The log contents. - * @var array - * @access private - */ - private $_log = array(); - - /** - * Max size of the log. - * @var int - * @access private - */ - private $_size = 0; - - /** - * Create a new ArrayLogger with a maximum of $size entries. - * @var int $size - */ - public function __construct($size = 50) - { - $this->_size = $size; - } - - /** - * Add a log entry. - * @param string $entry - */ - public function add($entry) - { - $this->_log[] = $entry; - while (count($this->_log) > $this->_size) + /** + * The log contents. + * + * @var array + */ + private $_log = array(); + + /** + * Max size of the log. + * + * @var int + */ + private $_size = 0; + + /** + * Create a new ArrayLogger with a maximum of $size entries. + * + * @var int $size + */ + public function __construct($size = 50) { - array_shift($this->_log); + $this->_size = $size; + } + + /** + * Add a log entry. + * + * @param string $entry + */ + public function add($entry) + { + $this->_log[] = $entry; + while (count($this->_log) > $this->_size) { + array_shift($this->_log); + } + } + + /** + * Clear the log contents. + */ + public function clear() + { + $this->_log = array(); + } + + /** + * Get this log as a string. + * + * @return string + */ + public function dump() + { + return implode(PHP_EOL, $this->_log); } - } - - /** - * Clear the log contents. - */ - public function clear() - { - $this->_log = array(); - } - - /** - * Get this log as a string. - * @return string - */ - public function dump() - { - return implode(PHP_EOL, $this->_log); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php index 83dd54b5f..73b95545b 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Loggers/EchoLogger.php @@ -10,55 +10,51 @@ /** * Prints all log messages in real time. - * - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Plugins_Loggers_EchoLogger implements Swift_Plugins_Logger { - - /** Whether or not HTML should be output */ - private $_isHtml; - - /** - * Create a new EchoLogger. - * - * @param boolean $isHtml - */ - public function __construct($isHtml = true) - { - $this->_isHtml = $isHtml; - } - - /** - * Add a log entry. - * @param string $entry - */ - public function add($entry) - { - if ($this->_isHtml) + /** Whether or not HTML should be output */ + private $_isHtml; + + /** + * Create a new EchoLogger. + * + * @param bool $isHtml + */ + public function __construct($isHtml = true) { - printf('%s%s%s', htmlspecialchars($entry, ENT_QUOTES), '
', PHP_EOL); + $this->_isHtml = $isHtml; } - else + + /** + * Add a log entry. + * + * @param string $entry + */ + public function add($entry) + { + if ($this->_isHtml) { + printf('%s%s%s', htmlspecialchars($entry, ENT_QUOTES), '
', PHP_EOL); + } else { + printf('%s%s', $entry, PHP_EOL); + } + } + + /** + * Not implemented. + */ + public function clear() + { + } + + /** + * Not implemented. + */ + public function dump() { - printf('%s%s', $entry, PHP_EOL); } - } - - /** - * Not implemented. - */ - public function clear() - { - } - - /** - * Not implemented. - */ - public function dump() - { - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php b/lib/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php new file mode 100644 index 000000000..b5dfa8b13 --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php @@ -0,0 +1,77 @@ +messages = array(); + } + + /** + * Get the message list + * + * @return array + */ + public function getMessages() + { + return $this->messages; + } + + /** + * Get the message count + * + * @return int count + */ + public function countMessages() + { + return count($this->messages); + } + + /** + * Empty the message list + * + */ + public function clear() + { + $this->messages = array(); + } + + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + $this->messages[] = clone $evt->getMessage(); + } + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php index 1c96dcfaf..d24172152 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Connection.php @@ -10,27 +10,24 @@ /** * Pop3Connection interface for connecting and disconnecting to a POP3 host. - * - * @package Swift + * + * @package Swift * @subpackage Plugins - * - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Plugins_Pop_Pop3Connection { - - /** - * Connect to the POP3 host and throw an Exception if it fails. - * - * @throws Swift_Plugins_Pop_Pop3Exception - */ - public function connect(); - - /** - * Disconnect from the POP3 host and throw an Exception if it fails. - * - * @throws Swift_Plugins_Pop_Pop3Exception - */ - public function disconnect(); - + /** + * Connect to the POP3 host and throw an Exception if it fails. + * + * @throws Swift_Plugins_Pop_Pop3Exception + */ + public function connect(); + + /** + * Disconnect from the POP3 host and throw an Exception if it fails. + * + * @throws Swift_Plugins_Pop_Pop3Exception + */ + public function disconnect(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php index 006d25745..02d421e70 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Pop/Pop3Exception.php @@ -8,26 +8,22 @@ * file that was distributed with this source code. */ - /** * Pop3Exception thrown when an error occurs connecting to a POP3 host. - * - * @package Swift + * + * @package Swift * @subpackage Transport - * - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Plugins_Pop_Pop3Exception extends Swift_IoException { - - /** - * Create a new Pop3Exception with $message. - * - * @param string $message - */ - public function __construct($message) - { - parent::__construct($message); - } - + /** + * Create a new Pop3Exception with $message. + * + * @param string $message + */ + public function __construct($message) + { + parent::__construct($message); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php index e21981ce3..379c45141 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php @@ -8,279 +8,271 @@ * file that was distributed with this source code. */ - /** * Makes sure a connection to a POP3 host has been established prior to connecting to SMTP. - * - * @package Swift + * + * @package Swift * @subpackage Plugins - * - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Plugins_PopBeforeSmtpPlugin - implements Swift_Events_TransportChangeListener, Swift_Plugins_Pop_Pop3Connection +class Swift_Plugins_PopBeforeSmtpPlugin implements Swift_Events_TransportChangeListener, Swift_Plugins_Pop_Pop3Connection { - - /** A delegate connection to use (mostly a test hook) */ - private $_connection; - - /** Hostname of the POP3 server */ - private $_host; - - /** Port number to connect on */ - private $_port; - - /** Encryption type to use (if any) */ - private $_crypto; - - /** Username to use (if any) */ - private $_username; - - /** Password to use (if any) */ - private $_password; - - /** Established connection via TCP socket */ - private $_socket; - - /** Connect timeout in seconds */ - private $_timeout = 10; - - /** SMTP Transport to bind to */ - private $_transport; - - /** - * Create a new PopBeforeSmtpPlugin for $host and $port. - * - * @param string $host - * @param int $port - * @param string $cypto as "tls" or "ssl" - */ - public function __construct($host, $port = 110, $crypto = null) - { - $this->_host = $host; - $this->_port = $port; - $this->_crypto = $crypto; - } - - /** - * Create a new PopBeforeSmtpPlugin for $host and $port. - * - * @param string $host - * @param int $port - * @param string $cypto as "tls" or "ssl" - * - * @return Swift_Plugins_PopBeforeSmtpPlugin - */ - public static function newInstance($host, $port = 110, $crypto = null) - { - return new self($host, $port, $crypto); - } - - /** - * Set a Pop3Connection to delegate to instead of connecting directly. - * - * @param Swift_Plugins_Pop_Pop3Connection $connection - */ - public function setConnection(Swift_Plugins_Pop_Pop3Connection $connection) - { - $this->_connection = $connection; - return $this; - } - - /** - * Bind this plugin to a specific SMTP transport instance. - * - * @param Swift_Transport - */ - public function bindSmtp(Swift_Transport $smtp) - { - $this->_transport = $smtp; - } - - /** - * Set the connection timeout in seconds (default 10). - * - * @param int $timeout - */ - public function setTimeout($timeout) - { - $this->_timeout = (int) $timeout; - return $this; - } - - /** - * Set the username to use when connecting (if needed). - * - * @param string $username - */ - public function setUsername($username) - { - $this->_username = $username; - return $this; - } - - /** - * Set the password to use when connecting (if needed). - * - * @param string $password - */ - public function setPassword($password) - { - $this->_password = $password; - return $this; - } - - /** - * Connect to the POP3 host and authenticate. - * - * @throws Swift_Plugins_Pop_Pop3Exception if connection fails - */ - public function connect() - { - if (isset($this->_connection)) + /** A delegate connection to use (mostly a test hook) */ + private $_connection; + + /** Hostname of the POP3 server */ + private $_host; + + /** Port number to connect on */ + private $_port; + + /** Encryption type to use (if any) */ + private $_crypto; + + /** Username to use (if any) */ + private $_username; + + /** Password to use (if any) */ + private $_password; + + /** Established connection via TCP socket */ + private $_socket; + + /** Connect timeout in seconds */ + private $_timeout = 10; + + /** SMTP Transport to bind to */ + private $_transport; + + /** + * Create a new PopBeforeSmtpPlugin for $host and $port. + * + * @param string $host + * @param int $port + * @param string $crypto as "tls" or "ssl" + */ + public function __construct($host, $port = 110, $crypto = null) { - $this->_connection->connect(); + $this->_host = $host; + $this->_port = $port; + $this->_crypto = $crypto; } - else + + /** + * Create a new PopBeforeSmtpPlugin for $host and $port. + * + * @param string $host + * @param int $port + * @param string $crypto as "tls" or "ssl" + * + * @return Swift_Plugins_PopBeforeSmtpPlugin + */ + public static function newInstance($host, $port = 110, $crypto = null) { - if (!isset($this->_socket)) - { - if (!$socket = fsockopen( - $this->_getHostString(), $this->_port, $errno, $errstr, $this->_timeout)) - { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to connect to POP3 host [%s]: %s', $this->_host, $errstr) - ); + return new self($host, $port, $crypto); + } + + /** + * Set a Pop3Connection to delegate to instead of connecting directly. + * + * @param Swift_Plugins_Pop_Pop3Connection $connection + * + * @return Swift_Plugins_PopBeforeSmtpPlugin + */ + public function setConnection(Swift_Plugins_Pop_Pop3Connection $connection) + { + $this->_connection = $connection; + + return $this; + } + + /** + * Bind this plugin to a specific SMTP transport instance. + * + * @param Swift_Transport + */ + public function bindSmtp(Swift_Transport $smtp) + { + $this->_transport = $smtp; + } + + /** + * Set the connection timeout in seconds (default 10). + * + * @param int $timeout + * + * @return Swift_Plugins_PopBeforeSmtpPlugin + */ + public function setTimeout($timeout) + { + $this->_timeout = (int) $timeout; + + return $this; + } + + /** + * Set the username to use when connecting (if needed). + * + * @param string $username + * + * @return Swift_Plugins_PopBeforeSmtpPlugin + */ + public function setUsername($username) + { + $this->_username = $username; + + return $this; + } + + /** + * Set the password to use when connecting (if needed). + * + * @param string $password + * + * @return Swift_Plugins_PopBeforeSmtpPlugin + */ + public function setPassword($password) + { + $this->_password = $password; + + return $this; + } + + /** + * Connect to the POP3 host and authenticate. + * + * @throws Swift_Plugins_Pop_Pop3Exception if connection fails + */ + public function connect() + { + if (isset($this->_connection)) { + $this->_connection->connect(); + } else { + if (!isset($this->_socket)) { + if (!$socket = fsockopen( + $this->_getHostString(), $this->_port, $errno, $errstr, $this->_timeout)) + { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('Failed to connect to POP3 host [%s]: %s', $this->_host, $errstr) + ); + } + $this->_socket = $socket; + + if (false === $greeting = fgets($this->_socket)) { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('Failed to connect to POP3 host [%s]', trim($greeting)) + ); + } + + $this->_assertOk($greeting); + + if ($this->_username) { + $this->_command(sprintf("USER %s\r\n", $this->_username)); + $this->_command(sprintf("PASS %s\r\n", $this->_password)); + } + } } - $this->_socket = $socket; - - if (false === $greeting = fgets($this->_socket)) - { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to connect to POP3 host [%s]', trim($greeting)) - ); + } + + /** + * Disconnect from the POP3 host. + */ + public function disconnect() + { + if (isset($this->_connection)) { + $this->_connection->disconnect(); + } else { + $this->_command("QUIT\r\n"); + if (!fclose($this->_socket)) { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('POP3 host [%s] connection could not be stopped', $this->_host) + ); + } + $this->_socket = null; } - - $this->_assertOk($greeting); - - if ($this->_username) - { - $this->_command(sprintf("USER %s\r\n", $this->_username)); - $this->_command(sprintf("PASS %s\r\n", $this->_password)); + } + + /** + * Invoked just before a Transport is started. + * + * @param Swift_Events_TransportChangeEvent $evt + */ + public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) + { + if (isset($this->_transport)) { + if ($this->_transport !== $evt->getTransport()) { + return; + } } - } + + $this->connect(); + $this->disconnect(); } - } - - /** - * Disconnect from the POP3 host. - */ - public function disconnect() - { - if (isset($this->_connection)) + + /** + * Not used. + */ + public function transportStarted(Swift_Events_TransportChangeEvent $evt) { - $this->_connection->disconnect(); } - else + + /** + * Not used. + */ + public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) { - $this->_command("QUIT\r\n"); - if (!fclose($this->_socket)) - { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('POP3 host [%s] connection could not be stopped', $this->_host) - ); - } - $this->_socket = null; } - } - - /** - * Invoked just before a Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt - */ - public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) - { - if (isset($this->_transport)) + + /** + * Not used. + */ + public function transportStopped(Swift_Events_TransportChangeEvent $evt) { - if ($this->_transport !== $evt->getTransport()) - { - return; - } } - - $this->connect(); - $this->disconnect(); - } - - /** - * Not used. - */ - public function transportStarted(Swift_Events_TransportChangeEvent $evt) - { - } - - /** - * Not used. - */ - public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) - { - } - - /** - * Not used. - */ - public function transportStopped(Swift_Events_TransportChangeEvent $evt) - { - } - - // -- Private Methods - - private function _command($command) - { - if (!fwrite($this->_socket, $command)) + + // -- Private Methods + + private function _command($command) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to write command [%s] to POP3 host', trim($command)) - ); + if (!fwrite($this->_socket, $command)) { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('Failed to write command [%s] to POP3 host', trim($command)) + ); + } + + if (false === $response = fgets($this->_socket)) { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('Failed to read from POP3 host after command [%s]', trim($command)) + ); + } + + $this->_assertOk($response); + + return $response; } - - if (false === $response = fgets($this->_socket)) + + private function _assertOk($response) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to read from POP3 host after command [%s]', trim($command)) - ); + if (substr($response, 0, 3) != '+OK') { + throw new Swift_Plugins_Pop_Pop3Exception( + sprintf('POP3 command failed [%s]', trim($response)) + ); + } } - - $this->_assertOk($response); - - return $response; - } - - private function _assertOk($response) - { - if (substr($response, 0, 3) != '+OK') + + private function _getHostString() { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('POP3 command failed [%s]', trim($response)) - ); + $host = $this->_host; + switch (strtolower($this->_crypto)) { + case 'ssl': + $host = 'ssl://' . $host; + break; + + case 'tls': + $host = 'tls://' . $host; + break; + } + + return $host; } - } - - private function _getHostString() - { - $host = $this->_host; - switch (strtolower($this->_crypto)) - { - case 'ssl': - $host = 'ssl://' . $host; - break; - - case 'tls': - $host = 'tls://' . $host; - break; - } - return $host; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php index 71a3e6094..3b006b67a 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php @@ -10,100 +10,200 @@ /** * Redirects all email to a single recipient. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Fabien Potencier + * @author Fabien Potencier */ -class Swift_Plugins_RedirectingPlugin - implements Swift_Events_SendListener +class Swift_Plugins_RedirectingPlugin implements Swift_Events_SendListener { - /** - * The recipient who will receive all messages. - * @var string - * @access private - */ - private $_recipient; - - /** - * Create a new RedirectingPlugin. - * @param int $recipient - */ - public function __construct($recipient) - { - $this->_recipient = $recipient; - } - - /** - * Set the recipient of all messages. - * @param int $threshold - */ - public function setRecipient($recipient) - { - $this->_recipient = $recipient; - } - - /** - * Get the recipient of all messages. - * @return int - */ - public function getRecipient() - { - return $this->_recipient; - } - - /** - * Invoked immediately before the Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - $headers = $message->getHeaders(); + /** + * The recipient who will receive all messages. + * + * @var mixed + */ + private $_recipient; - // save current recipients - $headers->addMailboxHeader('X-Swift-To', $message->getTo()); - $headers->addMailboxHeader('X-Swift-Cc', $message->getCc()); - $headers->addMailboxHeader('X-Swift-Bcc', $message->getBcc()); + /** + * List of regular expression for recipient whitelisting + * + * @var array + */ + private $_whitelist = array(); - // replace them with the one to send to - $message->setTo($this->_recipient); - $headers->removeAll('Cc'); - $headers->removeAll('Bcc'); - } - - /** - * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - $this->_restoreMessage($evt->getMessage()); - } - - // -- Private methods - - private function _restoreMessage(Swift_Mime_Message $message) - { - // restore original headers - $headers = $message->getHeaders(); - - if ($headers->has('X-Swift-To')) + /** + * Create a new RedirectingPlugin. + * + * @param mixed $recipient + * @param array $whitelist + */ + public function __construct($recipient, array $whitelist = array()) { - $message->setTo($headers->get('X-Swift-To')->getNameAddresses()); - $headers->removeAll('X-Swift-To'); + $this->_recipient = $recipient; + $this->_whitelist = $whitelist; } - if ($headers->has('X-Swift-Cc')) + /** + * Set the recipient of all messages. + * + * @param mixed $recipient + */ + public function setRecipient($recipient) { - $message->setCc($headers->get('X-Swift-Cc')->getNameAddresses()); - $headers->removeAll('X-Swift-Cc'); + $this->_recipient = $recipient; } - if ($headers->has('X-Swift-Bcc')) + /** + * Get the recipient of all messages. + * + * @return mixed + */ + public function getRecipient() { - $message->setBcc($headers->get('X-Swift-Bcc')->getNameAddresses()); - $headers->removeAll('X-Swift-Bcc'); + return $this->_recipient; + } + + /** + * Set a list of regular expressions to whitelist certain recipients + * + * @param array $whitelist + */ + public function setWhitelist(array $whitelist) + { + $this->_whitelist = $whitelist; + } + + /** + * Get the whitelist + * + * @return array + */ + public function getWhitelist() + { + return $this->_whitelist; + } + + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) + { + $message = $evt->getMessage(); + $headers = $message->getHeaders(); + + // conditionally save current recipients + + if ($headers->has('to')) { + $headers->addMailboxHeader('X-Swift-To', $message->getTo()); + } + + if ($headers->has('cc')) { + $headers->addMailboxHeader('X-Swift-Cc', $message->getCc()); + } + + if ($headers->has('bcc')) { + $headers->addMailboxHeader('X-Swift-Bcc', $message->getBcc()); + } + + // Filter remaining headers against whitelist + $this->_filterHeaderSet($headers, 'To'); + $this->_filterHeaderSet($headers, 'Cc'); + $this->_filterHeaderSet($headers, 'Bcc'); + + // Add each hard coded recipient + foreach ( (array) $this->_recipient as $recipient) { + if (!array_key_exists($recipient, $message->getTo())) { + $message->addTo($recipient); + } + } + + } + + /** + * Filter header set against a whitelist of regular expressions + * + * @param Swift_Mime_HeaderSet $headerSet + * @param string $type + */ + private function _filterHeaderSet(Swift_Mime_HeaderSet $headerSet, $type) + { + foreach ($headerSet->getAll($type) as $headers) { + $headers->setNameAddresses($this->_filterNameAddresses($headers->getNameAddresses())); + } + } + + /** + * Filtered list of addresses => name pairs + * + * @param array $recipients + * @return array + */ + private function _filterNameAddresses(array $recipients) + { + $filtered = array(); + + foreach ($recipients as $address => $name) { + if ($this->_isWhitelisted($address)) { + $filtered[$address] = $name; + } + } + + return $filtered; + } + + /** + * Matches address against whitelist of regular expressions + * + * @param $recipient + * @return bool + */ + protected function _isWhitelisted($recipient) + { + if (in_array($recipient, (array) $this->_recipient)) { + return true; + } + + foreach ($this->_whitelist as $pattern) { + if (preg_match($pattern, $recipient)) { + return true; + } + } + + return false; + } + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) + { + $this->_restoreMessage($evt->getMessage()); + } + + // -- Private methods + + private function _restoreMessage(Swift_Mime_Message $message) + { + // restore original headers + $headers = $message->getHeaders(); + + if ($headers->has('X-Swift-To')) { + $message->setTo($headers->get('X-Swift-To')->getNameAddresses()); + $headers->removeAll('X-Swift-To'); + } + + if ($headers->has('X-Swift-Cc')) { + $message->setCc($headers->get('X-Swift-Cc')->getNameAddresses()); + $headers->removeAll('X-Swift-Cc'); + } + + if ($headers->has('X-Swift-Bcc')) { + $message->setBcc($headers->get('X-Swift-Bcc')->getNameAddresses()); + $headers->removeAll('X-Swift-Bcc'); + } } - } } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Reporter.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Reporter.php index d87fdc3f9..504c0c888 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Reporter.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Reporter.php @@ -8,28 +8,27 @@ * file that was distributed with this source code. */ - /** * The Reporter plugin sends pass/fail notification to a Reporter. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Plugins_Reporter { - - /** The recipient was accepted for delivery */ - const RESULT_PASS = 0x01; - - /** The recipient could not be accepted */ - const RESULT_FAIL = 0x10; - - /** - * Notifies this ReportNotifier that $address failed or succeeded. - * @param Swift_Mime_Message $message - * @param string $address - * @param int $result from {@link RESULT_PASS, RESULT_FAIL} - */ - public function notify(Swift_Mime_Message $message, $address, $result); - + /** The recipient was accepted for delivery */ + const RESULT_PASS = 0x01; + + /** The recipient could not be accepted */ + const RESULT_FAIL = 0x10; + + /** + * Notifies this ReportNotifier that $address failed or succeeded. + * + * @param Swift_Mime_Message $message + * @param string $address + * @param int $result from {@link RESULT_PASS, RESULT_FAIL} + */ + public function notify(Swift_Mime_Message $message, $address, $result); } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php index b5e0e9327..e79c6bbff 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php @@ -8,72 +8,68 @@ * file that was distributed with this source code. */ - /** * Does real time reporting of pass/fail for each recipient. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Plugins_ReporterPlugin - implements Swift_Events_SendListener +class Swift_Plugins_ReporterPlugin implements Swift_Events_SendListener { - - /** - * The reporter backend which takes notifications. - * @var Swift_Plugin_Reporter - * @access private - */ - private $_reporter; - - /** - * Create a new ReporterPlugin using $reporter. - * @param Swift_Plugins_Reporter $reporter - */ - public function __construct(Swift_Plugins_Reporter $reporter) - { - $this->_reporter = $reporter; - } - - /** - * Not used. - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - } - - /** - * Invoked immediately after the Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - $message = $evt->getMessage(); - $failures = array_flip($evt->getFailedRecipients()); - foreach ((array) $message->getTo() as $address => $null) + /** + * The reporter backend which takes notifications. + * + * @var Swift_Plugin_Reporter + */ + private $_reporter; + + /** + * Create a new ReporterPlugin using $reporter. + * + * @param Swift_Plugins_Reporter $reporter + */ + public function __construct(Swift_Plugins_Reporter $reporter) { - $this->_reporter->notify( - $message, $address, (array_key_exists($address, $failures) - ? Swift_Plugins_Reporter::RESULT_FAIL - : Swift_Plugins_Reporter::RESULT_PASS) - ); + $this->_reporter = $reporter; } - foreach ((array) $message->getCc() as $address => $null) + + /** + * Not used. + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) { - $this->_reporter->notify( - $message, $address, (array_key_exists($address, $failures) - ? Swift_Plugins_Reporter::RESULT_FAIL - : Swift_Plugins_Reporter::RESULT_PASS) - ); } - foreach ((array) $message->getBcc() as $address => $null) + + /** + * Invoked immediately after the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) { - $this->_reporter->notify( - $message, $address, (array_key_exists($address, $failures) - ? Swift_Plugins_Reporter::RESULT_FAIL - : Swift_Plugins_Reporter::RESULT_PASS) - ); + $message = $evt->getMessage(); + $failures = array_flip($evt->getFailedRecipients()); + foreach ((array) $message->getTo() as $address => $null) { + $this->_reporter->notify( + $message, $address, (array_key_exists($address, $failures) + ? Swift_Plugins_Reporter::RESULT_FAIL + : Swift_Plugins_Reporter::RESULT_PASS) + ); + } + foreach ((array) $message->getCc() as $address => $null) { + $this->_reporter->notify( + $message, $address, (array_key_exists($address, $failures) + ? Swift_Plugins_Reporter::RESULT_FAIL + : Swift_Plugins_Reporter::RESULT_PASS) + ); + } + foreach ((array) $message->getBcc() as $address => $null) { + $this->_reporter->notify( + $message, $address, (array_key_exists($address, $failures) + ? Swift_Plugins_Reporter::RESULT_FAIL + : Swift_Plugins_Reporter::RESULT_PASS) + ); + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php index af5d7e386..5890eea91 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Reporters/HitReporter.php @@ -8,54 +8,54 @@ * file that was distributed with this source code. */ - /** * A reporter which "collects" failures for the Reporter plugin. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Plugins_Reporters_HitReporter implements Swift_Plugins_Reporter { - - /** - * The list of failures. - * @var array - * @access private - */ - private $_failures = array(); - private $_failures_cache = array(); - - /** - * Notifies this ReportNotifier that $address failed or succeeded. - * @param Swift_Mime_Message $message - * @param string $address - * @param int $result from {@link RESULT_PASS, RESULT_FAIL} - */ - public function notify(Swift_Mime_Message $message, $address, $result) - { - if (self::RESULT_FAIL == $result && !isset($this->_failures_cache[$address])) + /** + * The list of failures. + * + * @var array + */ + private $_failures = array(); + + private $_failures_cache = array(); + + /** + * Notifies this ReportNotifier that $address failed or succeeded. + * + * @param Swift_Mime_Message $message + * @param string $address + * @param int $result from {@link RESULT_PASS, RESULT_FAIL} + */ + public function notify(Swift_Mime_Message $message, $address, $result) { - $this->_failures[] = $address; - $this->_failures_cache[$address] = true; + if (self::RESULT_FAIL == $result && !isset($this->_failures_cache[$address])) { + $this->_failures[] = $address; + $this->_failures_cache[$address] = true; + } + } + + /** + * Get an array of addresses for which delivery failed. + * + * @return array + */ + public function getFailedRecipients() + { + return $this->_failures; + } + + /** + * Clear the buffer (empty the list). + */ + public function clear() + { + $this->_failures = $this->_failures_cache = array(); } - } - - /** - * Get an array of addresses for which delivery failed. - * @return array - */ - public function getFailedRecipients() - { - return $this->_failures; - } - - /** - * Clear the buffer (empty the list). - */ - public function clear() - { - $this->_failures = $this->_failures_cache = array(); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php index 119c4b271..cd3b98425 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Reporters/HtmlReporter.php @@ -8,38 +8,34 @@ * file that was distributed with this source code. */ - /** * A HTML output reporter for the Reporter plugin. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Plugins_Reporters_HtmlReporter implements Swift_Plugins_Reporter { - - /** - * Notifies this ReportNotifier that $address failed or succeeded. - * @param Swift_Mime_Message $message - * @param string $address - * @param int $result from {@link RESULT_PASS, RESULT_FAIL} - */ - public function notify(Swift_Mime_Message $message, $address, $result) - { - if (self::RESULT_PASS == $result) + /** + * Notifies this ReportNotifier that $address failed or succeeded. + * + * @param Swift_Mime_Message $message + * @param string $address + * @param int $result from {@see RESULT_PASS, RESULT_FAIL} + */ + public function notify(Swift_Mime_Message $message, $address, $result) { - echo "
" . PHP_EOL; - echo "PASS " . $address . PHP_EOL; - echo "
" . PHP_EOL; - flush(); + if (self::RESULT_PASS == $result) { + echo "
" . PHP_EOL; + echo "PASS " . $address . PHP_EOL; + echo "
" . PHP_EOL; + flush(); + } else { + echo "
" . PHP_EOL; + echo "FAIL " . $address . PHP_EOL; + echo "
" . PHP_EOL; + flush(); + } } - else - { - echo "
" . PHP_EOL; - echo "FAIL " . $address . PHP_EOL; - echo "
" . PHP_EOL; - flush(); - } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php index 148cbd3e8..35a63b4fb 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Sleeper.php @@ -10,17 +10,17 @@ /** * Sleeps for a duration of time. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Plugins_Sleeper { - - /** - * Sleep for $seconds. - * @param int $seconds - */ - public function sleep($seconds); - + /** + * Sleep for $seconds. + * + * @param int $seconds + */ + public function sleep($seconds); } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php b/lib/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php index 7e18c2873..933104e08 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/ThrottlerPlugin.php @@ -8,177 +8,197 @@ * file that was distributed with this source code. */ - /** * Throttles the rate at which emails are sent. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Plugins_ThrottlerPlugin - extends Swift_Plugins_BandwidthMonitorPlugin - implements Swift_Plugins_Sleeper, Swift_Plugins_Timer +class Swift_Plugins_ThrottlerPlugin extends Swift_Plugins_BandwidthMonitorPlugin implements Swift_Plugins_Sleeper, Swift_Plugins_Timer { - - /** Flag for throttling in bytes per minute */ - const BYTES_PER_MINUTE = 0x01; - - /** Flag for throttling in emails per minute */ - const MESSAGES_PER_MINUTE = 0x10; - - /** - * The Sleeper instance for sleeping. - * @var Swift_Plugins_Sleeper - * @access private - */ - private $_sleeper; - - /** - * The Timer instance which provides the timestamp. - * @var Swift_Plugins_Timer - * @access private - */ - private $_timer; - - /** - * The time at which the first email was sent. - * @var int - * @access private - */ - private $_start; - - /** - * The rate at which messages should be sent. - * @var int - * @access private - */ - private $_rate; - - /** - * The mode for throttling. - * This is {@link BYTES_PER_MINUTE} or {@link MESSAGES_PER_MINUTE} - * @var int - * @access private - */ - private $_mode; - - /** - * An internal counter of the number of messages sent. - * @var int - * @access private - */ - private $_messages = 0; - - /** - * Create a new ThrottlerPlugin. - * @param int $rate - * @param int $mode, defaults to {@link BYTES_PER_MINUTE} - * @param Swift_Plugins_Sleeper $sleeper (only needed in testing) - * @param Swift_Plugins_Timer $timer (only needed in testing) - */ - public function __construct($rate, $mode = self::BYTES_PER_MINUTE, - Swift_Plugins_Sleeper $sleeper = null, Swift_Plugins_Timer $timer = null) - { - $this->_rate = $rate; - $this->_mode = $mode; - $this->_sleeper = $sleeper; - $this->_timer = $timer; - } - - /** - * Invoked immediately before the Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function beforeSendPerformed(Swift_Events_SendEvent $evt) - { - $time = $this->getTimestamp(); - if (!isset($this->_start)) + /** Flag for throttling in bytes per minute */ + const BYTES_PER_MINUTE = 0x01; + + /** Flag for throttling in emails per second (Amazon SES) */ + const MESSAGES_PER_SECOND = 0x11; + + /** Flag for throttling in emails per minute */ + const MESSAGES_PER_MINUTE = 0x10; + + /** + * The Sleeper instance for sleeping. + * + * @var Swift_Plugins_Sleeper + */ + private $_sleeper; + + /** + * The Timer instance which provides the timestamp. + * + * @var Swift_Plugins_Timer + */ + private $_timer; + + /** + * The time at which the first email was sent. + * + * @var int + */ + private $_start; + + /** + * The rate at which messages should be sent. + * + * @var int + */ + private $_rate; + + /** + * The mode for throttling. + * + * This is {@link BYTES_PER_MINUTE} or {@link MESSAGES_PER_MINUTE} + * + * @var int + */ + private $_mode; + + /** + * An internal counter of the number of messages sent. + * + * @var int + */ + private $_messages = 0; + + /** + * Create a new ThrottlerPlugin. + * + * @param int $rate + * @param int $mode, defaults to {@link BYTES_PER_MINUTE} + * @param Swift_Plugins_Sleeper $sleeper (only needed in testing) + * @param Swift_Plugins_Timer $timer (only needed in testing) + */ + public function __construct($rate, $mode = self::BYTES_PER_MINUTE, Swift_Plugins_Sleeper $sleeper = null, Swift_Plugins_Timer $timer = null) { - $this->_start = $time; + $this->_rate = $rate; + $this->_mode = $mode; + $this->_sleeper = $sleeper; + $this->_timer = $timer; } - $duration = $time - $this->_start; - - if (self::BYTES_PER_MINUTE == $this->_mode) + + /** + * Invoked immediately before the Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function beforeSendPerformed(Swift_Events_SendEvent $evt) { - $sleep = $this->_throttleBytesPerMinute($duration); + $time = $this->getTimestamp(); + if (!isset($this->_start)) { + $this->_start = $time; + } + $duration = $time - $this->_start; + + switch($this->_mode) { + case self::BYTES_PER_MINUTE : + $sleep = $this->_throttleBytesPerMinute($duration); + break; + case self::MESSAGES_PER_SECOND : + $sleep = $this->_throttleMessagesPerSecond($duration); + break; + case self::MESSAGES_PER_MINUTE : + $sleep = $this->_throttleMessagesPerMinute($duration); + break; + default : + $sleep = 0; + break; + } + + if ($sleep > 0) { + $this->sleep($sleep); + } } - else + + /** + * Invoked when a Message is sent. + * + * @param Swift_Events_SendEvent $evt + */ + public function sendPerformed(Swift_Events_SendEvent $evt) { - $sleep = $this->_throttleMessagesPerMinute($duration); + parent::sendPerformed($evt); + ++$this->_messages; } - - if ($sleep > 0) + + /** + * Sleep for $seconds. + * + * @param int $seconds + */ + public function sleep($seconds) { - $this->sleep($sleep); + if (isset($this->_sleeper)) { + $this->_sleeper->sleep($seconds); + } else { + sleep($seconds); + } } - } - - /** - * Invoked when a Message is sent. - * @param Swift_Events_SendEvent $evt - */ - public function sendPerformed(Swift_Events_SendEvent $evt) - { - parent::sendPerformed($evt); - ++$this->_messages; - } - - /** - * Sleep for $seconds. - * @param int $seconds - */ - public function sleep($seconds) - { - if (isset($this->_sleeper)) + + /** + * Get the current UNIX timestamp. + * + * @return int + */ + public function getTimestamp() { - $this->_sleeper->sleep($seconds); + if (isset($this->_timer)) { + return $this->_timer->getTimestamp(); + } else { + return time(); + } } - else + + // -- Private methods + + /** + * Get a number of seconds to sleep for. + * + * @param int $timePassed + * + * @return int + */ + private function _throttleBytesPerMinute($timePassed) { - sleep($seconds); + $expectedDuration = $this->getBytesOut() / ($this->_rate / 60); + + return (int) ceil($expectedDuration - $timePassed); } - } - - /** - * Get the current UNIX timestamp - * @return int - */ - public function getTimestamp() - { - if (isset($this->_timer)) + + /** + * Get a number of seconds to sleep for. + * + * @param int $timePassed + * + * @return int + */ + private function _throttleMessagesPerSecond($timePassed) { - return $this->_timer->getTimestamp(); + $expectedDuration = $this->_messages / ($this->_rate); + + return (int) ceil($expectedDuration - $timePassed); } - else + + /** + * Get a number of seconds to sleep for. + * + * @param int $timePassed + * + * @return int + */ + private function _throttleMessagesPerMinute($timePassed) { - return time(); + $expectedDuration = $this->_messages / ($this->_rate / 60); + + return (int) ceil($expectedDuration - $timePassed); } - } - - // -- Private methods - - /** - * Get a number of seconds to sleep for. - * @param int $timePassed - * @return int - * @access private - */ - private function _throttleBytesPerMinute($timePassed) - { - $expectedDuration = $this->getBytesOut() / ($this->_rate / 60); - return (int) ceil($expectedDuration - $timePassed); - } - - /** - * Get a number of seconds to sleep for. - * @param int $timePassed - * @return int - * @access private - */ - private function _throttleMessagesPerMinute($timePassed) - { - $expectedDuration = $this->_messages / ($this->_rate / 60); - return (int) ceil($expectedDuration - $timePassed); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Plugins/Timer.php b/lib/swiftmailer/lib/classes/Swift/Plugins/Timer.php index 92207bff9..12dd09b8b 100644 --- a/lib/swiftmailer/lib/classes/Swift/Plugins/Timer.php +++ b/lib/swiftmailer/lib/classes/Swift/Plugins/Timer.php @@ -10,17 +10,17 @@ /** * Provides timestamp data. - * @package Swift + * + * @package Swift * @subpackage Plugins - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Plugins_Timer { - - /** - * Get the current UNIX timestamp. - * @return int - */ - public function getTimestamp(); - + /** + * Get the current UNIX timestamp. + * + * @return int + */ + public function getTimestamp(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Preferences.php b/lib/swiftmailer/lib/classes/Swift/Preferences.php index 4f32c3944..629436f57 100644 --- a/lib/swiftmailer/lib/classes/Swift/Preferences.php +++ b/lib/swiftmailer/lib/classes/Swift/Preferences.php @@ -8,83 +8,97 @@ * file that was distributed with this source code. */ - /** * Changes some global preference settings in Swift Mailer. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Preferences { - - /** Singleton instance */ - private static $_instance = null; - - /** Constructor not to be used */ - private function __construct() { } - - /** - * Get a new instance of Preferences. - * @return Swift_Preferences - */ - public static function getInstance() - { - if (!isset(self::$_instance)) + /** Singleton instance */ + private static $_instance = null; + + /** Constructor not to be used */ + private function __construct() { - self::$_instance = new self(); } - return self::$_instance; - } - - /** - * Set the default charset used. - * @param string - * @return Swift_Preferences - */ - public function setCharset($charset) - { - Swift_DependencyContainer::getInstance() - ->register('properties.charset')->asValue($charset); - return $this; - } - - /** - * Set the directory where temporary files can be saved. - * @param string $dir - * @return Swift_Preferences - */ - public function setTempDir($dir) - { - Swift_DependencyContainer::getInstance() - ->register('tempdir')->asValue($dir); - return $this; - } - - /** - * Set the type of cache to use (i.e. "disk" or "array"). - * @param string $type - * @return Swift_Preferences - */ - public function setCacheType($type) - { - Swift_DependencyContainer::getInstance() - ->register('cache')->asAliasOf(sprintf('cache.%s', $type)); - return $this; - } - - /** - * Add the - * @param boolean $dotEscape - */ - public function setQPDotEscape($dotEscape) - { - $dotEscape=!empty($dotEscape); - Swift_DependencyContainer::getInstance() - -> register('mime.qpcontentencoder') - -> asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder') - -> withDependencies(array('mime.charstream', 'mime.bytecanonicalizer')) - -> addConstructorValue($dotEscape); - return $this; - } - + + /** + * Gets the instance of Preferences. + * + * @return Swift_Preferences + */ + public static function getInstance() + { + if (!isset(self::$_instance)) { + self::$_instance = new self(); + } + + return self::$_instance; + } + + /** + * Set the default charset used. + * + * @param string $charset + * + * @return Swift_Preferences + */ + public function setCharset($charset) + { + Swift_DependencyContainer::getInstance() + ->register('properties.charset')->asValue($charset); + + return $this; + } + + /** + * Set the directory where temporary files can be saved. + * + * @param string $dir + * + * @return Swift_Preferences + */ + public function setTempDir($dir) + { + Swift_DependencyContainer::getInstance() + ->register('tempdir')->asValue($dir); + + return $this; + } + + /** + * Set the type of cache to use (i.e. "disk" or "array"). + * + * @param string $type + * + * @return Swift_Preferences + */ + public function setCacheType($type) + { + Swift_DependencyContainer::getInstance() + ->register('cache')->asAliasOf(sprintf('cache.%s', $type)); + + return $this; + } + + /** + * Set the QuotedPrintable dot escaper preference. + * + * @param bool $dotEscape + * + * @return Swift_Preferences + */ + public function setQPDotEscape($dotEscape) + { + $dotEscape = !empty($dotEscape); + Swift_DependencyContainer::getInstance() + ->register('mime.qpcontentencoder') + ->asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder') + ->withDependencies(array('mime.charstream', 'mime.bytecanonicalizer')) + ->addConstructorValue($dotEscape); + + return $this; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php b/lib/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php index db29e6dba..4b6eed584 100644 --- a/lib/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php +++ b/lib/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php @@ -10,18 +10,19 @@ /** * Creates StreamFilters. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_ReplacementFilterFactory { - - /** - * Create a filter to replace $search with $replace. - * @param mixed $search - * @param mixed $replace - * @return Swift_StreamFilter - */ - public function createFilter($search, $replace); - + /** + * Create a filter to replace $search with $replace. + * + * @param mixed $search + * @param mixed $replace + * + * @return Swift_StreamFilter + */ + public function createFilter($search, $replace); } diff --git a/lib/swiftmailer/lib/classes/Swift/RfcComplianceException.php b/lib/swiftmailer/lib/classes/Swift/RfcComplianceException.php index 6e3c78724..6a2a49b87 100644 --- a/lib/swiftmailer/lib/classes/Swift/RfcComplianceException.php +++ b/lib/swiftmailer/lib/classes/Swift/RfcComplianceException.php @@ -8,22 +8,21 @@ * file that was distributed with this source code. */ - /** * RFC Compliance Exception class. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_RfcComplianceException extends Swift_SwiftException { - - /** - * Create a new RfcComplianceException with $message. - * @param string $message - */ - public function __construct($message) - { - parent::__construct($message); - } - + /** + * Create a new RfcComplianceException with $message. + * + * @param string $message + */ + public function __construct($message) + { + parent::__construct($message); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/SendmailTransport.php b/lib/swiftmailer/lib/classes/Swift/SendmailTransport.php index 59ea207db..d5fc72d7f 100644 --- a/lib/swiftmailer/lib/classes/Swift/SendmailTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/SendmailTransport.php @@ -8,39 +8,40 @@ * file that was distributed with this source code. */ - /** - * SendmailTransport for sending mail through a sendmail/postfix (etc..) binary. - * @package Swift + * SendmailTransport for sending mail through a Sendmail/Postfix (etc..) binary. + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_SendmailTransport extends Swift_Transport_SendmailTransport { - - /** - * Create a new SendmailTransport, optionally using $command for sending. - * @param string $command - */ - public function __construct($command = '/usr/sbin/sendmail -bs') - { - call_user_func_array( - array($this, 'Swift_Transport_SendmailTransport::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.sendmail') - ); - - $this->setCommand($command); - } - - /** - * Create a new SendmailTransport instance. - * @param string $command - * @return Swift_SendmailTransport - */ - public static function newInstance($command = '/usr/sbin/sendmail -bs') - { - return new self($command); - } - + /** + * Create a new SendmailTransport, optionally using $command for sending. + * + * @param string $command + */ + public function __construct($command = '/usr/sbin/sendmail -bs') + { + call_user_func_array( + array($this, 'Swift_Transport_SendmailTransport::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.sendmail') + ); + + $this->setCommand($command); + } + + /** + * Create a new SendmailTransport instance. + * + * @param string $command + * + * @return Swift_SendmailTransport + */ + public static function newInstance($command = '/usr/sbin/sendmail -bs') + { + return new self($command); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/SignedMessage.php b/lib/swiftmailer/lib/classes/Swift/SignedMessage.php new file mode 100644 index 000000000..c4fb2c73c --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/SignedMessage.php @@ -0,0 +1,25 @@ + + * @deprecated + */ +class Swift_SignedMessage extends Swift_Message +{ + +} diff --git a/lib/swiftmailer/lib/classes/Swift/Signer.php b/lib/swiftmailer/lib/classes/Swift/Signer.php new file mode 100644 index 000000000..865f557e0 --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Signer.php @@ -0,0 +1,22 @@ + + */ +interface Swift_Signer +{ + public function reset(); +} diff --git a/lib/swiftmailer/lib/classes/Swift/Signers/BodySigner.php b/lib/swiftmailer/lib/classes/Swift/Signers/BodySigner.php new file mode 100644 index 000000000..1d700fb17 --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Signers/BodySigner.php @@ -0,0 +1,35 @@ + + */ +interface Swift_Signers_BodySigner extends Swift_Signer +{ + /** + * Change the Swift_Signed_Message to apply the singing. + * + * @param Swift_Message $message + * + * @return Swift_Signers_BodySigner + */ + public function signMessage(Swift_Message $message); + + /** + * Return the list of header a signer might tamper + * + * @return array + */ + public function getAlteredHeaders(); +} diff --git a/lib/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php b/lib/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php new file mode 100644 index 000000000..f2a25149f --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php @@ -0,0 +1,690 @@ + + */ +class Swift_Signers_DKIMSigner implements Swift_Signers_HeaderSigner +{ + /** + * PrivateKey + * + * @var string + */ + protected $_privateKey; + + /** + * DomainName + * + * @var string + */ + protected $_domainName; + + /** + * Selector + * + * @var string + */ + protected $_selector; + + /** + * Hash algorithm used + * + * @var string + */ + protected $_hashAlgorithm = 'rsa-sha1'; + + /** + * Body canon method + * + * @var string + */ + protected $_bodyCanon = 'simple'; + + /** + * Header canon method + * + * @var string + */ + protected $_headerCanon = 'simple'; + + /** + * Headers not being signed + * + * @var array + */ + protected $_ignoredHeaders = array(); + + /** + * Signer identity + * + * @var unknown_type + */ + protected $_signerIdentity; + + /** + * BodyLength + * + * @var int + */ + protected $_bodyLen = 0; + + /** + * Maximum signedLen + * + * @var int + */ + protected $_maxLen = PHP_INT_MAX; + + /** + * Embbed bodyLen in signature + * + * @var bool + */ + protected $_showLen = false; + + /** + * When the signature has been applied (true means time()), false means not embedded + * + * @var mixed + */ + protected $_signatureTimestamp = true; + + /** + * When will the signature expires false means not embedded, if sigTimestamp is auto + * Expiration is relative, otherwhise it's absolute + * + * @var int + */ + protected $_signatureExpiration = false; + + /** + * Must we embed signed headers? + * + * @var bool + */ + protected $_debugHeaders = false; + + // work variables + /** + * Headers used to generate hash + * + * @var array + */ + protected $_signedHeaders = array(); + + /** + * If debugHeaders is set store debugDatas here + * + * @var string + */ + private $_debugHeadersData = ''; + + /** + * Stores the bodyHash + * + * @var string + */ + private $_bodyHash = ''; + + /** + * Stores the signature header + * + * @var Swift_Mime_Headers_ParameterizedHeader + */ + protected $_dkimHeader; + + /** + * Hash Handler + * + * @var hash_ressource + */ + private $_headerHashHandler; + + private $_bodyHashHandler; + + private $_headerHash; + + private $_headerCanonData = ''; + + private $_bodyCanonEmptyCounter = 0; + + private $_bodyCanonIgnoreStart = 2; + + private $_bodyCanonSpace = false; + + private $_bodyCanonLastChar = null; + + private $_bodyCanonLine = ''; + + private $_bound = array(); + + /** + * Constructor + * + * @param string $privateKey + * @param string $domainName + * @param string $selector + */ + public function __construct($privateKey, $domainName, $selector) + { + $this->_privateKey = $privateKey; + $this->_domainName = $domainName; + $this->_signerIdentity = '@' . $domainName; + $this->_selector = $selector; + } + + /** + * Instanciate DKIMSigner + * + * @param string $privateKey + * @param string $domainName + * @param string $selector + * @return Swift_Signers_DKIMSigner + */ + public static function newInstance($privateKey, $domainName, $selector) + { + return new static($privateKey, $domainName, $selector); + } + + + /** + * Reset the Signer + * @see Swift_Signer::reset() + */ + public function reset() + { + $this->_headerHash = null; + $this->_signedHeaders = array(); + $this->_headerHashHandler = null; + $this->_bodyHash = null; + $this->_bodyHashHandler = null; + $this->_bodyCanonIgnoreStart = 2; + $this->_bodyCanonEmptyCounter = 0; + $this->_bodyCanonLastChar = NULL; + $this->_bodyCanonSpace = false; + } + + /** + * Writes $bytes to the end of the stream. + * + * Writing may not happen immediately if the stream chooses to buffer. If + * you want to write these bytes with immediate effect, call {@link commit()} + * after calling write(). + * + * This method returns the sequence ID of the write (i.e. 1 for first, 2 for + * second, etc etc). + * + * @param string $bytes + * @return int + * @throws Swift_IoException + */ + public function write($bytes) + { + $this->_canonicalizeBody($bytes); + foreach ($this->_bound as $is) { + $is->write($bytes); + } + } + + /** + * For any bytes that are currently buffered inside the stream, force them + * off the buffer. + * + * @throws Swift_IoException + */ + public function commit() + { + // Nothing to do + return; + } + + /** + * Attach $is to this stream. + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + */ + public function bind(Swift_InputByteStream $is) + { + // Don't have to mirror anything + $this->_bound[] = $is; + + return; + } + + /** + * Remove an already bound stream. + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + */ + public function unbind(Swift_InputByteStream $is) + { + // Don't have to mirror anything + foreach ($this->_bound as $k => $stream) { + if ($stream === $is) { + unset($this->_bound[$k]); + return; + } + } + + return; + } + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + * + * @throws Swift_IoException + */ + public function flushBuffers() + { + $this->reset(); + } + + /** + * Set hash_algorithm, must be one of rsa-sha256 | rsa-sha1 defaults to rsa-sha256 + * + * @param string $hash + * @return Swift_Signers_DKIMSigner + */ + public function setHashAlgorithm($hash) + { + // Unable to sign with rsa-sha256 + if ($hash == 'rsa-sha1') { + $this->_hashAlgorithm = 'rsa-sha1'; + } else { + $this->_hashAlgorithm = 'rsa-sha256'; + } + + return $this; + } + + /** + * Set the body canonicalization algorithm + * + * @param string $canon + * @return Swift_Signers_DKIMSigner + */ + public function setBodyCanon($canon) + { + if ($canon == 'relaxed') { + $this->_bodyCanon = 'relaxed'; + } else { + $this->_bodyCanon = 'simple'; + } + + return $this; + } + + /** + * Set the header canonicalization algorithm + * + * @param string $canon + * @return Swift_Signers_DKIMSigner + */ + public function setHeaderCanon($canon) + { + if ($canon == 'relaxed') { + $this->_headerCanon = 'relaxed'; + } else { + $this->_headerCanon = 'simple'; + } + + return $this; + } + + /** + * Set the signer identity + * + * @param string $identity + * @return Swift_Signers_DKIMSigner + */ + public function setSignerIdentity($identity) + { + $this->_signerIdentity = $identity; + + return $this; + } + + /** + * Set the length of the body to sign + * + * @param mixed $len (bool or int) + * @return Swift_Signers_DKIMSigner + */ + public function setBodySignedLen($len) + { + if ($len === true) { + $this->_showLen = true; + $this->_maxLen = PHP_INT_MAX; + } elseif ($len === false) { + $this->showLen = false; + $this->_maxLen = PHP_INT_MAX; + } else { + $this->_showLen = true; + $this->_maxLen = (int) $len; + } + + return $this; + } + + /** + * Set the signature timestamp + * + * @param timestamp $time + * @return Swift_Signers_DKIMSigner + */ + public function setSignatureTimestamp($time) + { + $this->_signatureTimestamp = $time; + + return $this; + } + + /** + * Set the signature expiration timestamp + * + * @param timestamp $time + * @return Swift_Signers_DKIMSigner + */ + public function setSignatureExpiration($time) + { + $this->_signatureExpiration = $time; + + return $this; + } + + /** + * Enable / disable the DebugHeaders + * + * @param bool $debug + * @return Swift_Signers_DKIMSigner + */ + public function setDebugHeaders($debug) + { + $this->_debugHeaders = (bool) $debug; + + return $this; + } + + /** + * Start Body + * + */ + public function startBody() + { + // Init + switch ($this->_hashAlgorithm) { + case 'rsa-sha256' : + $this->_bodyHashHandler = hash_init('sha256'); + break; + case 'rsa-sha1' : + $this->_bodyHashHandler = hash_init('sha1'); + break; + } + $this->_bodyCanonLine = ''; + } + + /** + * End Body + * + */ + public function endBody() + { + $this->_endOfBody(); + } + + /** + * Returns the list of Headers Tampered by this plugin + * + * @return array + */ + public function getAlteredHeaders() + { + if ($this->_debugHeaders) { + return array('DKIM-Signature', 'X-DebugHash'); + } else { + return array('DKIM-Signature'); + } + } + + /** + * Adds an ignored Header + * + * @param string $header_name + * @return Swift_Signers_DKIMSigner + */ + public function ignoreHeader($header_name) + { + $this->_ignoredHeaders[strtolower($header_name)] = true; + + return $this; + } + + /** + * Set the headers to sign + * + * @param Swift_Mime_HeaderSet $headers + * @return Swift_Signers_DKIMSigner + */ + public function setHeaders(Swift_Mime_HeaderSet $headers) + { + $this->_headerCanonData = ''; + // Loop through Headers + $listHeaders = $headers->listAll(); + foreach ($listHeaders as $hName) { + // Check if we need to ignore Header + if (! isset($this->_ignoredHeaders[strtolower($hName)])) { + if ($headers->has($hName)) { + $tmp = $headers->getAll($hName); + foreach ($tmp as $header) { + if ($header->getFieldBody() != '') { + $this->_addHeader($header->toString()); + $this->_signedHeaders[] = $header->getFieldName(); + } + } + } + } + } + + return $this; + } + + /** + * Add the signature to the given Headers + * + * @param Swift_Mime_HeaderSet $headers + * @return Swift_Signers_DKIMSigner + */ + public function addSignature(Swift_Mime_HeaderSet $headers) + { + // Prepare the DKIM-Signature + $params = array('v' => '1', 'a' => $this->_hashAlgorithm, 'bh' => base64_encode($this->_bodyHash), 'd' => $this->_domainName, 'h' => implode(': ', $this->_signedHeaders), 'i' => $this->_signerIdentity, 's' => $this->_selector); + if ($this->_bodyCanon != 'simple') { + $params['c'] = $this->_headerCanon . '/' . $this->_bodyCanon; + } elseif ($this->_headerCanon != 'simple') { + $params['c'] = $this->_headerCanon; + } + if ($this->_showLen) { + $params['l'] = $this->_bodyLen; + } + if ($this->_signatureTimestamp === true) { + $params['t'] = time(); + if ($this->_signatureExpiration !== false) { + $params['x'] = $params['t'] + $this->_signatureExpiration; + } + } else { + if ($this->_signatureTimestamp !== false) { + $params['t'] = $this->_signatureTimestamp; + } + if ($this->_signatureExpiration !== false) { + $params['x'] = $this->_signatureExpiration; + } + } + if ($this->_debugHeaders) { + $params['z'] = implode('|', $this->_debugHeadersData); + } + $string = ''; + foreach ($params as $k => $v) { + $string .= $k . '=' . $v . '; '; + } + $string = trim($string); + $headers->addTextHeader('DKIM-Signature', $string); + // Add the last DKIM-Signature + $tmp = $headers->getAll('DKIM-Signature'); + $this->_dkimHeader = end($tmp); + $this->_addHeader(trim($this->_dkimHeader->toString()) . "\r\n b=", true); + $this->_endOfHeaders(); + if ($this->_debugHeaders) { + $headers->addTextHeader('X-DebugHash', base64_encode($this->_headerHash)); + } + $this->_dkimHeader->setValue($string . " b=" . trim(chunk_split(base64_encode($this->_getEncryptedHash()), 73, " "))); + + return $this; + } + + /* Private helpers */ + + protected function _addHeader($header, $is_sig = false) + { + switch ($this->_headerCanon) { + case 'relaxed' : + // Prepare Header and cascade + $exploded = explode(':', $header, 2); + $name = strtolower(trim($exploded[0])); + $value = str_replace("\r\n", "", $exploded[1]); + $value = preg_replace("/[ \t][ \t]+/", " ", $value); + $header = $name . ":" . trim($value) . ($is_sig ? '' : "\r\n"); + case 'simple' : + // Nothing to do + } + $this->_addToHeaderHash($header); + } + + protected function _endOfHeaders() + { + //$this->_headerHash=hash_final($this->_headerHashHandler, true); + } + + protected function _canonicalizeBody($string) + { + $len = strlen($string); + $canon = ''; + $method = ($this->_bodyCanon == "relaxed"); + for ($i = 0; $i < $len; ++$i) { + if ($this->_bodyCanonIgnoreStart > 0) { + --$this->_bodyCanonIgnoreStart; + continue; + } + switch ($string[$i]) { + case "\r" : + $this->_bodyCanonLastChar = "\r"; + break; + case "\n" : + if ($this->_bodyCanonLastChar == "\r") { + if ($method) { + $this->_bodyCanonSpace = false; + } + if ($this->_bodyCanonLine == '') { + ++$this->_bodyCanonEmptyCounter; + } else { + $this->_bodyCanonLine = ''; + $canon .= "\r\n"; + } + } else { + // Wooops Error + // todo handle it but should never happen + } + break; + case " " : + case "\t" : + if ($method) { + $this->_bodyCanonSpace = true; + break; + } + default : + if ($this->_bodyCanonEmptyCounter > 0) { + $canon .= str_repeat("\r\n", $this->_bodyCanonEmptyCounter); + $this->_bodyCanonEmptyCounter = 0; + } + if ($this->_bodyCanonSpace) { + $this->_bodyCanonLine .= ' '; + $canon .= ' '; + $this->_bodyCanonSpace = false; + } + $this->_bodyCanonLine .= $string[$i]; + $canon .= $string[$i]; + } + } + $this->_addToBodyHash($canon); + } + + protected function _endOfBody() + { + // Add trailing Line return if last line is non empty + if (strlen($this->_bodyCanonLine) > 0) { + $this->_addToBodyHash("\r\n"); + } + $this->_bodyHash = hash_final($this->_bodyHashHandler, true); + } + + private function _addToBodyHash($string) + { + $len = strlen($string); + if ($len > ($new_len = ($this->_maxLen - $this->_bodyLen))) { + $string = substr($string, 0, $new_len); + $len = $new_len; + } + hash_update($this->_bodyHashHandler, $string); + $this->_bodyLen += $len; + } + + private function _addToHeaderHash($header) + { + if ($this->_debugHeaders) { + $this->_debugHeadersData[] = trim($header); + } + $this->_headerCanonData .= $header; + } + + /** + * @throws Swift_SwiftException + * @return string + */ + private function _getEncryptedHash() + { + $signature = ''; + switch ($this->_hashAlgorithm) { + case 'rsa-sha1': + $algorithm = OPENSSL_ALGO_SHA1; + break; + case 'rsa-sha256': + $algorithm = OPENSSL_ALGO_SHA256; + break; + } + $pkeyId=openssl_get_privatekey($this->_privateKey); + if (!$pkeyId) { + throw new Swift_SwiftException('Unable to load DKIM Private Key ['.openssl_error_string().']'); + } + if (openssl_sign($this->_headerCanonData, $signature, $pkeyId, $algorithm)) { + return $signature; + } + throw new Swift_SwiftException('Unable to sign DKIM Hash ['.openssl_error_string().']'); + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php b/lib/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php new file mode 100644 index 000000000..d6d728fcc --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php @@ -0,0 +1,520 @@ + + */ +class Swift_Signers_DomainKeySigner implements Swift_Signers_HeaderSigner +{ + /** + * PrivateKey + * + * @var string + */ + protected $_privateKey; + + /** + * DomainName + * + * @var string + */ + protected $_domainName; + + /** + * Selector + * + * @var string + */ + protected $_selector; + + /** + * Hash algorithm used + * + * @var string + */ + protected $_hashAlgorithm = 'rsa-sha1'; + + /** + * Canonisation method + * + * @var string + */ + protected $_canon = 'simple'; + + /** + * Headers not being signed + * + * @var array + */ + protected $_ignoredHeaders = array(); + + /** + * Signer identity + * + * @var unknown_type + */ + protected $_signerIdentity; + + /** + * Must we embed signed headers? + * + * @var bool + */ + protected $_debugHeaders = false; + + // work variables + /** + * Headers used to generate hash + * + * @var array + */ + private $_signedHeaders = array(); + + /** + * If debugHeaders is set store debugDatas here + * + * @var string + */ + private $_debugHeadersData = ''; + + /** + * Stores the signature header + * + * @var Swift_Mime_Headers_ParameterizedHeader + */ + protected $_domainKeyHeader; + + /** + * Hash Handler + * + * @var hash_ressource + */ + private $_hashHandler; + + private $_hash; + + private $_canonData = ''; + + private $_bodyCanonEmptyCounter = 0; + + private $_bodyCanonIgnoreStart = 2; + + private $_bodyCanonSpace = false; + + private $_bodyCanonLastChar = null; + + private $_bodyCanonLine = ''; + + private $_bound = array(); + + /** + * Constructor + * + * @param string $privateKey + * @param string $domainName + * @param string $selector + */ + public function __construct($privateKey, $domainName, $selector) + { + $this->_privateKey = $privateKey; + $this->_domainName = $domainName; + $this->_signerIdentity = '@' . $domainName; + $this->_selector = $selector; + } + + /** + * Instanciate DomainKeySigner + * + * @param string $privateKey + * @param string $domainName + * @param string $selector + * @return Swift_Signers_DomainKeySigner + */ + public static function newInstance($privateKey, $domainName, $selector) { + return new static($privateKey, $domainName, $selector); + } + + /** + * Resets internal states + * + * @return Swift_Signers_DomainKeysSigner + */ + public function reset() + { + $this->_hash = null; + $this->_hashHandler = null; + $this->_bodyCanonIgnoreStart = 2; + $this->_bodyCanonEmptyCounter = 0; + $this->_bodyCanonLastChar = NULL; + $this->_bodyCanonSpace = false; + + return $this; + } + + /** + * Writes $bytes to the end of the stream. + * + * Writing may not happen immediately if the stream chooses to buffer. If + * you want to write these bytes with immediate effect, call {@link commit()} + * after calling write(). + * + * This method returns the sequence ID of the write (i.e. 1 for first, 2 for + * second, etc etc). + * + * @param string $bytes + * @return int + * @throws Swift_IoException + * @return Swift_Signers_DomainKeysSigner + */ + public function write($bytes) + { + $this->_canonicalizeBody($bytes); + foreach ($this->_bound as $is) { + $is->write($bytes); + } + + return $this; + } + + /** + * For any bytes that are currently buffered inside the stream, force them + * off the buffer. + * + * @throws Swift_IoException + * @return Swift_Signers_DomainKeysSigner + */ + public function commit() + { + // Nothing to do + return $this; + } + + /** + * Attach $is to this stream. + * The stream acts as an observer, receiving all data that is written. + * All {@link write()} and {@link flushBuffers()} operations will be mirrored. + * + * @param Swift_InputByteStream $is + * @return Swift_Signers_DomainKeysSigner + */ + public function bind(Swift_InputByteStream $is) + { + // Don't have to mirror anything + $this->_bound[] = $is; + + return $this; + } + + /** + * Remove an already bound stream. + * If $is is not bound, no errors will be raised. + * If the stream currently has any buffered data it will be written to $is + * before unbinding occurs. + * + * @param Swift_InputByteStream $is + * @return Swift_Signers_DomainKeysSigner + */ + public function unbind(Swift_InputByteStream $is) + { + // Don't have to mirror anything + foreach ($this->_bound as $k => $stream) { + if ($stream === $is) { + unset($this->_bound[$k]); + + return; + } + } + + return $this; + } + + /** + * Flush the contents of the stream (empty it) and set the internal pointer + * to the beginning. + * + * @throws Swift_IoException + * @return Swift_Signers_DomainKeysSigner + */ + public function flushBuffers() + { + $this->reset(); + + return $this; + } + + /** + * Set hash_algorithm, must be one of rsa-sha256 | rsa-sha1 defaults to rsa-sha256 + * + * @param string $hash + * @return Swift_Signers_DomainKeysSigner + */ + public function setHashAlgorithm($hash) + { + $this->_hashAlgorithm = 'rsa-sha1'; + + return $this; + } + + /** + * Set the canonicalization algorithm + * + * @param string $canon simple | nofws defaults to simple + * @return Swift_Signers_DomainKeysSigner + */ + public function setCanon($canon) + { + if ($canon == 'nofws') { + $this->_canon = 'nofws'; + } else { + $this->_canon = 'simple'; + } + + return $this; + } + + /** + * Set the signer identity + * + * @param string $identity + * @return Swift_Signers_DomainKeySigner + */ + public function setSignerIdentity($identity) + { + $this->_signerIdentity = $identity; + + return $this; + } + + /** + * Enable / disable the DebugHeaders + * + * @param bool $debug + * @return Swift_Signers_DomainKeySigner + */ + public function setDebugHeaders($debug) + { + $this->_debugHeaders = (bool) $debug; + + return $this; + } + + /** + * Start Body + * + */ + public function startBody() + { + } + + /** + * End Body + * + */ + public function endBody() + { + $this->_endOfBody(); + } + + /** + * Returns the list of Headers Tampered by this plugin + * + * @return array + */ + public function getAlteredHeaders() + { + if ($this->_debugHeaders) { + return array('DomainKey-Signature', 'X-DebugHash'); + } else { + return array('DomainKey-Signature'); + } + } + + /** + * Adds an ignored Header + * + * @param string $header_name + * @return Swift_Signers_DomainKeySigner + */ + public function ignoreHeader($header_name) + { + $this->_ignoredHeaders[strtolower($header_name)] = true; + + return $this; + } + + /** + * Set the headers to sign + * + * @param Swift_Mime_HeaderSet $headers + * @return Swift_Signers_DomainKeySigner + */ + public function setHeaders(Swift_Mime_HeaderSet $headers) + { + $this->_startHash(); + $this->_canonData = ''; + // Loop through Headers + $listHeaders = $headers->listAll(); + foreach ($listHeaders as $hName) { + // Check if we need to ignore Header + if (! isset($this->_ignoredHeaders[strtolower($hName)])) { + if ($headers->has($hName)) { + $tmp = $headers->getAll($hName); + foreach ($tmp as $header) { + if ($header->getFieldBody() != '') { + $this->_addHeader($header->toString()); + $this->_signedHeaders[] = $header->getFieldName(); + } + } + } + } + } + $this->_endOfHeaders(); + + return $this; + } + + /** + * Add the signature to the given Headers + * + * @param Swift_Mime_HeaderSet $headers + * @return Swift_Signers_DomainKeySigner + */ + public function addSignature(Swift_Mime_HeaderSet $headers) + { + // Prepare the DomainKey-Signature Header + $params = array('a' => $this->_hashAlgorithm, 'b' => chunk_split(base64_encode($this->_getEncryptedHash()), 73, " "), 'c' => $this->_canon, 'd' => $this->_domainName, 'h' => implode(': ', $this->_signedHeaders), 'q' => 'dns', 's' => $this->_selector); + $string = ''; + foreach ($params as $k => $v) { + $string .= $k . '=' . $v . '; '; + } + $string = trim($string); + $headers->addTextHeader('DomainKey-Signature', $string); + + return $this; + } + + /* Private helpers */ + + protected function _addHeader($header) + { + switch ($this->_canon) { + case 'nofws' : + // Prepare Header and cascade + $exploded = explode(':', $header, 2); + $name = strtolower(trim($exploded[0])); + $value = str_replace("\r\n", "", $exploded[1]); + $value = preg_replace("/[ \t][ \t]+/", " ", $value); + $header = $name . ":" . trim($value) . "\r\n"; + case 'simple' : + // Nothing to do + } + $this->_addToHash($header); + } + + protected function _endOfHeaders() + { + $this->_bodyCanonEmptyCounter = 1; + } + + protected function _canonicalizeBody($string) + { + $len = strlen($string); + $canon = ''; + $nofws = ($this->_canon == "nofws"); + for ($i = 0; $i < $len; ++$i) { + if ($this->_bodyCanonIgnoreStart > 0) { + --$this->_bodyCanonIgnoreStart; + continue; + } + switch ($string[$i]) { + case "\r" : + $this->_bodyCanonLastChar = "\r"; + break; + case "\n" : + if ($this->_bodyCanonLastChar == "\r") { + if ($nofws) { + $this->_bodyCanonSpace = false; + } + if ($this->_bodyCanonLine == '') { + ++$this->_bodyCanonEmptyCounter; + } else { + $this->_bodyCanonLine = ''; + $canon .= "\r\n"; + } + } else { + // Wooops Error + throw new Swift_SwiftException('Invalid new line sequence in mail found \n without preceding \r'); + } + break; + case " " : + case "\t" : + case "\x09": //HTAB + if ($nofws) { + $this->_bodyCanonSpace = true; + break; + } + default : + if ($this->_bodyCanonEmptyCounter > 0) { + $canon .= str_repeat("\r\n", $this->_bodyCanonEmptyCounter); + $this->_bodyCanonEmptyCounter = 0; + } + $this->_bodyCanonLine .= $string[$i]; + $canon .= $string[$i]; + } + } + $this->_addToHash($canon); + } + + protected function _endOfBody() + { + if (strlen($this->_bodyCanonLine) > 0) { + $this->_addToHash("\r\n"); + } + $this->_hash = hash_final($this->_hashHandler, true); + } + + private function _addToHash($string) + { + $this->_canonData .= $string; + hash_update($this->_hashHandler, $string); + } + + private function _startHash() + { + // Init + switch ($this->_hashAlgorithm) { + case 'rsa-sha1' : + $this->_hashHandler = hash_init('sha1'); + break; + } + $this->_canonLine = ''; + } + + /** + * @throws Swift_SwiftException + * @return string + */ + private function _getEncryptedHash() + { + $signature = ''; + $pkeyId=openssl_get_privatekey($this->_privateKey); + if (!$pkeyId) { + throw new Swift_SwiftException('Unable to load DomainKey Private Key ['.openssl_error_string().']'); + } + if (openssl_sign($this->_canonData, $signature, $pkeyId, OPENSSL_ALGO_SHA1)) { + return $signature; + } + throw new Swift_SwiftException('Unable to sign DomainKey Hash ['.openssl_error_string().']'); + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php b/lib/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php new file mode 100644 index 000000000..944deac6f --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php @@ -0,0 +1,67 @@ + + */ +interface Swift_Signers_HeaderSigner extends Swift_Signer, Swift_InputByteStream +{ + /** + * Exclude an header from the signed headers + * + * @param string $header_name + * + * @return Swift_Signers_HeaderSigner + */ + public function ignoreHeader($header_name); + + /** + * Prepare the Signer to get a new Body + * + * @return Swift_Signers_HeaderSigner + */ + public function startBody(); + + /** + * Give the signal that the body has finished streaming + * + * @return Swift_Signers_HeaderSigner + */ + public function endBody(); + + /** + * Give the headers already given + * + * @param Swift_Mime_SimpleHeaderSet $headers + * + * @return Swift_Signers_HeaderSigner + */ + public function setHeaders(Swift_Mime_HeaderSet $headers); + + /** + * Add the header(s) to the headerSet + * + * @param Swift_Mime_HeaderSet $headers + * + * @return Swift_Signers_HeaderSigner + */ + public function addSignature(Swift_Mime_HeaderSet $headers); + + /** + * Return the list of header a signer might tamper + * + * @return array + */ + public function getAlteredHeaders(); +} diff --git a/lib/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php b/lib/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php new file mode 100644 index 000000000..22b57cb8b --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php @@ -0,0 +1,184 @@ + + */ +class Swift_Signers_OpenDKIMSigner extends Swift_Signers_DKIMSigner +{ + private $_peclLoaded = false; + + private $_dkimHandler = null; + + private $dropFirstLF = true; + + const CANON_RELAXED = 1; + const CANON_SIMPLE = 2; + const SIG_RSA_SHA1 = 3; + const SIG_RSA_SHA256 = 4; + + public function __construct($privateKey, $domainName, $selector) + { + if (extension_loaded('opendkim')) { + $this->_peclLoaded = true; + } else { + throw new Swift_SwiftException('php-opendkim extension not found'); + } + parent::__construct($privateKey, $domainName, $selector); + } + + public static function newInstance($privateKey, $domainName, $selector) + { + return new static($privateKey, $domainName, $selector); + } + + public function addSignature(Swift_Mime_HeaderSet $headers) + { + $header = new Swift_Mime_Headers_OpenDKIMHeader('DKIM-Signature'); + $headerVal=$this->_dkimHandler->getSignatureHeader(); + if (!$headerVal) { + throw new Swift_SwiftException('OpenDKIM Error: '.$this->_dkimHandler->getError()); + } + $header->setValue($headerVal); + $headers->set($header); + + return $this; + } + + public function setHeaders(Swift_Mime_HeaderSet $headers) + { + $bodyLen = $this->_bodyLen; + if (is_bool($bodyLen)) { + $bodyLen = - 1; + } + $hash = ($this->_hashAlgorithm == 'rsa-sha1') ? OpenDKIMSign::ALG_RSASHA1 : OpenDKIMSign::ALG_RSASHA256; + $bodyCanon = ($this->_bodyCanon == 'simple') ? OpenDKIMSign::CANON_SIMPLE : OpenDKIMSign::CANON_RELAXED; + $headerCanon = ($this->_headerCanon == 'simple') ? OpenDKIMSign::CANON_SIMPLE : OpenDKIMSign::CANON_RELAXED; + $this->_dkimHandler = new OpenDKIMSign($this->_privateKey, $this->_selector, $this->_domainName, $headerCanon, $bodyCanon, $hash, $bodyLen); + // Hardcode signature Margin for now + $this->_dkimHandler->setMargin(78); + + if (!is_numeric($this->_signatureTimestamp)) { + OpenDKIM::setOption(OpenDKIM::OPTS_FIXEDTIME, time()); + } else { + if (!OpenDKIM::setOption(OpenDKIM::OPTS_FIXEDTIME, $this->_signatureTimestamp)) { + throw new Swift_SwiftException('Unable to force signature timestamp ['.openssl_error_string().']'); + } + } + if (isset($this->_signerIdentity)) { + $this->_dkimHandler->setSigner($this->_signerIdentity); + } + $listHeaders = $headers->listAll(); + foreach ($listHeaders as $hName) { + // Check if we need to ignore Header + if (! isset($this->_ignoredHeaders[strtolower($hName)])) { + $tmp = $headers->getAll($hName); + if ($headers->has($hName)) { + foreach ($tmp as $header) { + if ($header->getFieldBody() != '') { + $htosign = $header->toString(); + $this->_dkimHandler->header($htosign); + $this->_signedHeaders[] = $header->getFieldName(); + } + } + } + } + } + return $this; + } + + public function startBody() + { + if (! $this->_peclLoaded) { + return parent::startBody(); + } + $this->dropFirstLF = true; + $this->_dkimHandler->eoh(); + return $this; + } + + public function endBody() + { + if (! $this->_peclLoaded) { + return parent::endBody(); + } + $this->_dkimHandler->eom(); + return $this; + } + + public function reset() + { + $this->_dkimHandler = null; + parent::reset(); + return $this; + } + + /** + * Set the signature timestamp + * + * @param timestamp $time + * @return Swift_Signers_DKIMSigner + */ + public function setSignatureTimestamp($time) + { + $this->_signatureTimestamp = $time; + return $this; + } + + /** + * Set the signature expiration timestamp + * + * @param timestamp $time + * @return Swift_Signers_DKIMSigner + */ + public function setSignatureExpiration($time) + { + $this->_signatureExpiration = $time; + + return $this; + } + + /** + * Enable / disable the DebugHeaders + * + * @param bool $debug + * @return Swift_Signers_DKIMSigner + */ + public function setDebugHeaders($debug) + { + $this->_debugHeaders = (bool) $debug; + + return $this; + } + + // Protected + + protected function _canonicalizeBody($string) + { + if (! $this->_peclLoaded) { + return parent::_canonicalizeBody($string); + } + if (false && $this->dropFirstLF === true) { + if ($string[0]=="\r" && $string[1]=="\n") { + $string=substr($string, 2); + } + } + $this->dropFirstLF = false; + if (strlen($string)) { + $this->_dkimHandler->body($string); + } + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php b/lib/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php new file mode 100644 index 000000000..5b75e9bcb --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php @@ -0,0 +1,430 @@ + + */ +class Swift_Signers_SMimeSigner implements Swift_Signers_BodySigner +{ + protected $signCertificate; + protected $signPrivateKey; + protected $encryptCert; + protected $signThenEncrypt = true; + protected $signLevel; + protected $encryptLevel; + protected $signOptions; + protected $encryptOptions; + protected $encryptCipher; + + /** + * @var Swift_StreamFilters_StringReplacementFilterFactory + */ + protected $replacementFactory; + + /** + * @var Swift_Mime_HeaderFactory + */ + protected $headerFactory; + + /** + * Constructor. + * + * @param string $certificate + * @param string $privateKey + * @param string $encryptCertificate + */ + public function __construct($signCertificate = null, $signPrivateKey = null, $encryptCertificate = null) + { + if (null !== $signPrivateKey) { + $this->setSignCertificate($signCertificate, $signPrivateKey); + } + + if (null !== $encryptCertificate) { + $this->setEncryptCertificate($encryptCertificate); + } + + $this->replacementFactory = Swift_DependencyContainer::getInstance() + ->lookup('transport.replacementfactory'); + + $this->signOptions = PKCS7_DETACHED; + + // Supported since php5.4 + if (defined('OPENSSL_CIPHER_AES_128_CBC')) { + $this->encryptCipher = OPENSSL_CIPHER_AES_128_CBC; + } else { + $this->encryptCipher = OPENSSL_CIPHER_RC2_128; + } + } + + /** + * Returns an new Swift_Signers_SMimeSigner instance. + * + * @param string $certificate + * @param string $privateKey + * + * @return Swift_Signers_SMimeSigner + */ + public static function newInstance($certificate = null, $privateKey = null) + { + return new self($certificate, $privateKey); + } + + /** + * Set the certificate location to use for signing. + * + * @link http://www.php.net/manual/en/openssl.pkcs7.flags.php + * + * @param string $certificate + * @param string|array $privateKey If the key needs an passphrase use array('file-location', 'passphrase') instead + * @param int $signOptions Bitwise operator options for openssl_pkcs7_sign() + * + * @return Swift_Signers_SMimeSigner + */ + public function setSignCertificate($certificate, $privateKey = null, $signOptions = PKCS7_DETACHED) + { + $this->signCertificate = 'file://' . str_replace('\\', '/', realpath($certificate)); + + if (null !== $privateKey) { + if (is_array($privateKey)) { + $this->signPrivateKey = $privateKey; + $this->signPrivateKey[0] = 'file://' . str_replace('\\', '/', realpath($privateKey[0])); + } else { + $this->signPrivateKey = 'file://' . str_replace('\\', '/', realpath($privateKey)); + } + } + + $this->signOptions = $signOptions; + + return $this; + } + + /** + * Set the certificate location to use for encryption. + * + * @link http://www.php.net/manual/en/openssl.pkcs7.flags.php + * @link http://nl3.php.net/manual/en/openssl.ciphers.php + * + * @param string|array $recipientCerts Either an single X.509 certificate, or an assoc array of X.509 certificates. + * @param int $cipher + * + * @return Swift_Signers_SMimeSigner + */ + public function setEncryptCertificate($recipientCerts, $cipher = null) + { + if (is_array($recipientCerts)) { + $this->encryptCert = array(); + + foreach ($recipientCerts as $cert) { + $this->encryptCert[] = 'file://' . str_replace('\\', '/', realpath($cert)); + } + } else { + $this->encryptCert = 'file://' . str_replace('\\', '/', realpath($recipientCerts)); + } + + if (null !== $cipher) { + $this->encryptCipher = $cipher; + } + + return $this; + } + + /** + * @return string + */ + public function getSignCertificate() + { + return $this->signCertificate; + } + + /** + * @return string + */ + public function getSignPrivateKey() + { + return $this->signPrivateKey; + } + + /** + * Set perform signing before encryption. + * + * The default is to first sign the message and then encrypt. + * But some older mail clients, namely Microsoft Outlook 2000 will work when the message first encrypted. + * As this goes against the official specs, its recommended to only use 'encryption -> signing' when specifically targeting these 'broken' clients. + * + * @param string $signThenEncrypt + * + * @return Swift_Signers_SMimeSigner + */ + public function setSignThenEncrypt($signThenEncrypt = true) + { + $this->signThenEncrypt = $signThenEncrypt; + + return $this; + } + + /** + * @return bool + */ + public function isSignThenEncrypt() + { + return $this->signThenEncrypt; + } + + /** + * Resets internal states. + * + * @return Swift_Signers_SMimeSigner + */ + public function reset() + { + return $this; + } + + /** + * Change the Swift_Message to apply the signing. + * + * @param Swift_Message $message + * + * @return Swift_Signers_SMimeSigner + */ + public function signMessage(Swift_Message $message) + { + if (null === $this->signCertificate && null === $this->encryptCert) { + return $this; + } + + // Store the message using ByteStream to a file{1} + // Remove all Children + // Sign file{1}, parse the new MIME headers and set them on the primary MimeEntity + // Set the singed-body as the new body (without boundary) + + $messageStream = new Swift_ByteStream_TemporaryFileByteStream(); + $this->toSMimeByteStream($messageStream, $message); + $message->setEncoder(Swift_DependencyContainer::getInstance()->lookup('mime.rawcontentencoder')); + + $message->setChildren(array()); + $this->streamToMime($messageStream, $message); + + } + + /** + * Return the list of header a signer might tamper. + * + * @return array + */ + public function getAlteredHeaders() + { + return array('Content-Type', 'Content-Transfer-Encoding', 'Content-Disposition'); + } + + /** + * @param Swift_InputByteStream $inputStream + * @param Swift_Message $mimeEntity + */ + protected function toSMimeByteStream(Swift_InputByteStream $inputStream, Swift_Message $message) + { + $mimeEntity = $this->createMessage($message); + $messageStream = new Swift_ByteStream_TemporaryFileByteStream(); + + $mimeEntity->toByteStream($messageStream); + $messageStream->commit(); + + if (null !== $this->signCertificate && null !== $this->encryptCert) { + $temporaryStream = new Swift_ByteStream_TemporaryFileByteStream(); + + if ($this->signThenEncrypt) { + $this->messageStreamToSignedByteStream($messageStream, $temporaryStream); + $this->messageStreamToEncryptedByteStream($temporaryStream, $inputStream); + } else { + $this->messageStreamToEncryptedByteStream($messageStream, $temporaryStream); + $this->messageStreamToSignedByteStream($temporaryStream, $inputStream); + } + } elseif ($this->signCertificate !== null) { + $this->messageStreamToSignedByteStream($messageStream, $inputStream); + } else { + $this->messageStreamToEncryptedByteStream($messageStream, $inputStream); + } + } + + /** + * @param Swift_Message $message + * + * @return Swift_Message + */ + protected function createMessage(Swift_Message $message) + { + $mimeEntity = new Swift_Message('', $message->getBody(), $message->getContentType(), $message->getCharset()); + $mimeEntity->setChildren($message->getChildren()); + + $messageHeaders = $mimeEntity->getHeaders(); + $messageHeaders->remove('Message-ID'); + $messageHeaders->remove('Date'); + $messageHeaders->remove('Subject'); + $messageHeaders->remove('MIME-Version'); + $messageHeaders->remove('To'); + $messageHeaders->remove('From'); + + return $mimeEntity; + } + + /** + * @param Swift_FileStream $outputStream + * @param Swift_InputByteStream $inputStream + * + * @throws Swift_IoException + */ + protected function messageStreamToSignedByteStream(Swift_FileStream $outputStream, Swift_InputByteStream $inputStream) + { + $signedMessageStream = new Swift_ByteStream_TemporaryFileByteStream(); + + if (!openssl_pkcs7_sign($outputStream->getPath(), $signedMessageStream->getPath(), $this->signCertificate, $this->signPrivateKey, array(), $this->signOptions)) { + throw new Swift_IoException(sprintf('Failed to sign S/Mime message. Error: "%s".', openssl_error_string())); + } + + $this->copyFromOpenSSLOutput($signedMessageStream, $inputStream); + } + + /** + * @param Swift_FileStream $outputStream + * @param Swift_InputByteStream $is + * + * @throws Swift_IoException + */ + protected function messageStreamToEncryptedByteStream(Swift_FileStream $outputStream, Swift_InputByteStream $is) + { + $encryptedMessageStream = new Swift_ByteStream_TemporaryFileByteStream(); + + if (!openssl_pkcs7_encrypt($outputStream->getPath(), $encryptedMessageStream->getPath(), $this->encryptCert, array(), 0, $this->encryptCipher)) { + throw new Swift_IoException(sprintf('Failed to encrypt S/Mime message. Error: "%s".', openssl_error_string())); + } + + $this->copyFromOpenSSLOutput($encryptedMessageStream, $is); + } + + /** + * @param Swift_OutputByteStream $fromStream + * @param Swift_InputByteStream $toStream + */ + protected function copyFromOpenSSLOutput(Swift_OutputByteStream $fromStream, Swift_InputByteStream $toStream) + { + $bufferLength = 4096; + $filteredStream = new Swift_ByteStream_TemporaryFileByteStream(); + $filteredStream->addFilter($this->replacementFactory->createFilter("\r\n", "\n"), 'CRLF to LF'); + $filteredStream->addFilter($this->replacementFactory->createFilter("\n", "\r\n"), 'LF to CRLF'); + + while (false !== ($buffer = $fromStream->read($bufferLength))) { + $filteredStream->write($buffer); + } + + $filteredStream->flushBuffers(); + + while (false !== ($buffer = $filteredStream->read($bufferLength))) { + $toStream->write($buffer); + } + + $toStream->commit(); + } + + /** + * Merges an OutputByteStream to Swift_Message. + * + * @param Swift_OutputByteStream $fromStream + * @param Swift_Message $message + */ + protected function streamToMime(Swift_OutputByteStream $fromStream, Swift_Message $message) + { + $bufferLength = 78; + $headerData = ''; + + $fromStream->setReadPointer(0); + + while (($buffer = $fromStream->read($bufferLength)) !== false) { + $headerData .= $buffer; + + if (false !== strpos($buffer, "\r\n\r\n")) { + break; + } + } + + $headersPosEnd = strpos($headerData, "\r\n\r\n"); + $headerData = trim($headerData); + $headerData = substr($headerData, 0, $headersPosEnd); + $headerLines = explode("\r\n", $headerData); + unset($headerData); + + $headers = array(); + $currentHeaderName = ''; + + foreach ($headerLines as $headerLine) { + // Line separated + if (ctype_space($headerLines[0]) || false === strpos($headerLine, ':')) { + $headers[$currentHeaderName] .= ' ' . trim($headerLine); + continue; + } + + $header = explode(':', $headerLine, 2); + $currentHeaderName = strtolower($header[0]); + $headers[$currentHeaderName] = trim($header[1]); + } + + $messageStream = new Swift_ByteStream_TemporaryFileByteStream(); + $messageStream->addFilter($this->replacementFactory->createFilter("\r\n", "\n"), 'CRLF to LF'); + $messageStream->addFilter($this->replacementFactory->createFilter("\n", "\r\n"), 'LF to CRLF'); + + $messageHeaders = $message->getHeaders(); + + // No need to check for 'application/pkcs7-mime', as this is always base64 + if ('multipart/signed;' === substr($headers['content-type'], 0, 17)) { + if (!preg_match('/boundary=("[^"]+"|(?:[^\s]+|$))/is', $headers['content-type'], $contentTypeData)) { + throw new Swift_SwiftException('Failed to find Boundary parameter'); + } + + $boundary = trim($contentTypeData['1'], '"'); + $boundaryLen = strlen($boundary); + + // Skip the header and CRLF CRLF + $fromStream->setReadPointer($headersPosEnd + 4); + + while (false !== ($buffer = $fromStream->read($bufferLength))) { + $messageStream->write($buffer); + } + + $messageStream->commit(); + + $messageHeaders->remove('Content-Transfer-Encoding'); + $message->setContentType($headers['content-type']); + $message->setBoundary($boundary); + $message->setBody($messageStream); + } else { + $fromStream->setReadPointer($headersPosEnd + 4); + + if (null === $this->headerFactory) { + $this->headerFactory = Swift_DependencyContainer::getInstance()->lookup('mime.headerfactory'); + } + + $message->setContentType($headers['content-type']); + $messageHeaders->set($this->headerFactory->createTextHeader('Content-Transfer-Encoding', $headers['content-transfer-encoding'])); + $messageHeaders->set($this->headerFactory->createTextHeader('Content-Disposition', $headers['content-disposition'])); + + while (false !== ($buffer = $fromStream->read($bufferLength))) { + $messageStream->write($buffer); + } + + $messageStream->commit(); + $message->setBody($messageStream); + } + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/SmtpTransport.php b/lib/swiftmailer/lib/classes/Swift/SmtpTransport.php index 0e69b3769..b369f0451 100644 --- a/lib/swiftmailer/lib/classes/Swift/SmtpTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/SmtpTransport.php @@ -8,47 +8,52 @@ * file that was distributed with this source code. */ - /** * Sends Messages over SMTP with ESMTP support. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn + * @method Swift_SmtpTransport setUsername(string $username) Set the username to authenticate with. + * @method string getUsername() Get the username to authenticate with. + * @method Swift_SmtpTransport setPassword(string $password) Set the password to authenticate with. + * @method string getPassword() Get the password to authenticate with. + * @method Swift_SmtpTransport setAuthMode(string $mode) Set the auth mode to use to authenticate. + * @method string getAuthMode() Get the auth mode to use to authenticate. */ class Swift_SmtpTransport extends Swift_Transport_EsmtpTransport { - - /** - * Create a new SmtpTransport, optionally with $host, $port and $security. - * @param string $host - * @param int $port - * @param int $security - */ - public function __construct($host = 'localhost', $port = 25, - $security = null) - { - call_user_func_array( - array($this, 'Swift_Transport_EsmtpTransport::__construct'), - Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.smtp') - ); - - $this->setHost($host); - $this->setPort($port); - $this->setEncryption($security); - } - - /** - * Create a new SmtpTransport instance. - * @param string $host - * @param int $port - * @param int $security - * @return Swift_SmtpTransport - */ - public static function newInstance($host = 'localhost', $port = 25, - $security = null) - { - return new self($host, $port, $security); - } - + /** + * Create a new SmtpTransport, optionally with $host, $port and $security. + * + * @param string $host + * @param int $port + * @param string $security + */ + public function __construct($host = 'localhost', $port = 25, $security = null) + { + call_user_func_array( + array($this, 'Swift_Transport_EsmtpTransport::__construct'), + Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.smtp') + ); + + $this->setHost($host); + $this->setPort($port); + $this->setEncryption($security); + } + + /** + * Create a new SmtpTransport instance. + * + * @param string $host + * @param int $port + * @param string $security + * + * @return Swift_SmtpTransport + */ + public static function newInstance($host = 'localhost', $port = 25, $security = null) + { + return new self($host, $port, $security); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Spool.php b/lib/swiftmailer/lib/classes/Swift/Spool.php index 6d0670975..670be25bd 100644 --- a/lib/swiftmailer/lib/classes/Swift/Spool.php +++ b/lib/swiftmailer/lib/classes/Swift/Spool.php @@ -10,41 +10,45 @@ /** * Interface for spools. + * * @package Swift * @author Fabien Potencier */ interface Swift_Spool { - /** - * Starts this Spool mechanism. - */ - public function start(); + /** + * Starts this Spool mechanism. + */ + public function start(); - /** - * Stops this Spool mechanism. - */ - public function stop(); + /** + * Stops this Spool mechanism. + */ + public function stop(); - /** - * Tests if this Spool mechanism has started. - * - * @return boolean - */ - public function isStarted(); + /** + * Tests if this Spool mechanism has started. + * + * @return bool + */ + public function isStarted(); - /** - * Queues a message. - * @param Swift_Mime_Message $message The message to store - */ - public function queueMessage(Swift_Mime_Message $message); + /** + * Queues a message. + * + * @param Swift_Mime_Message $message The message to store + * + * @return bool Whether the operation has succeeded + */ + public function queueMessage(Swift_Mime_Message $message); - /** - * Sends messages using the given transport instance. - * - * @param Swift_Transport $transport A transport instance - * @param string[] &$failedRecipients An array of failures by-reference - * - * @return int The number of sent emails - */ - public function flushQueue(Swift_Transport $transport, &$failedRecipients = null); + /** + * Sends messages using the given transport instance. + * + * @param Swift_Transport $transport A transport instance + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int The number of sent emails + */ + public function flushQueue(Swift_Transport $transport, &$failedRecipients = null); } diff --git a/lib/swiftmailer/lib/classes/Swift/SpoolTransport.php b/lib/swiftmailer/lib/classes/Swift/SpoolTransport.php index 156f9b6a8..8a135d4ca 100644 --- a/lib/swiftmailer/lib/classes/Swift/SpoolTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/SpoolTransport.php @@ -10,35 +10,39 @@ /** * Stores Messages in a queue. + * * @package Swift * @author Fabien Potencier */ class Swift_SpoolTransport extends Swift_Transport_SpoolTransport { - /** - * Create a new SpoolTransport. - * @param Swift_Spool $spool - */ - public function __construct(Swift_Spool $spool) - { - $arguments = Swift_DependencyContainer::getInstance() - ->createDependenciesFor('transport.spool'); + /** + * Create a new SpoolTransport. + * + * @param Swift_Spool $spool + */ + public function __construct(Swift_Spool $spool) + { + $arguments = Swift_DependencyContainer::getInstance() + ->createDependenciesFor('transport.spool'); - $arguments[] = $spool; + $arguments[] = $spool; - call_user_func_array( - array($this, 'Swift_Transport_SpoolTransport::__construct'), - $arguments - ); - } - - /** - * Create a new SpoolTransport instance. - * @param Swift_Spool $spool - * @return Swift_SpoolTransport - */ - public static function newInstance(Swift_Spool $spool) - { - return new self($spool); - } + call_user_func_array( + array($this, 'Swift_Transport_SpoolTransport::__construct'), + $arguments + ); + } + + /** + * Create a new SpoolTransport instance. + * + * @param Swift_Spool $spool + * + * @return Swift_SpoolTransport + */ + public static function newInstance(Swift_Spool $spool) + { + return new self($spool); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/StreamFilter.php b/lib/swiftmailer/lib/classes/Swift/StreamFilter.php index 6c262ce3a..b62e75159 100644 --- a/lib/swiftmailer/lib/classes/Swift/StreamFilter.php +++ b/lib/swiftmailer/lib/classes/Swift/StreamFilter.php @@ -10,24 +10,27 @@ /** * Processes bytes as they pass through a stream and performs filtering. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_StreamFilter { - - /** - * Based on the buffer given, this returns true if more buffering is needed. - * @param mixed $buffer - * @return boolean - */ - public function shouldBuffer($buffer); - - /** - * Filters $buffer and returns the changes. - * @param mixed $buffer - * @return mixed - */ - public function filter($buffer); - + /** + * Based on the buffer given, this returns true if more buffering is needed. + * + * @param mixed $buffer + * + * @return bool + */ + public function shouldBuffer($buffer); + + /** + * Filters $buffer and returns the changes. + * + * @param mixed $buffer + * + * @return mixed + */ + public function filter($buffer); } diff --git a/lib/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php b/lib/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php index 56baeff34..8cedcbeef 100644 --- a/lib/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php +++ b/lib/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php @@ -8,180 +8,164 @@ * file that was distributed with this source code. */ - /** * Processes bytes as they pass through a buffer and replaces sequences in it. + * * This stream filter deals with Byte arrays rather than simple strings. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_StreamFilters_ByteArrayReplacementFilter - implements Swift_StreamFilter +class Swift_StreamFilters_ByteArrayReplacementFilter implements Swift_StreamFilter { + /** The needle(s) to search for */ + private $_search; - /** The needle(s) to search for */ - private $_search; + /** The replacement(s) to make */ + private $_replace; - /** The replacement(s) to make */ - private $_replace; + /** The Index for searching */ + private $_index; - /** The Index for searching */ - private $_index; + /** The Search Tree */ + private $_tree = array(); - /** The Search Tree */ - private $_tree = array(); + /** Gives the size of the largest search */ + private $_treeMaxLen = 0; - /** Gives the size of the largest search */ - private $_treeMaxLen = 0; - - private $_repSize; + private $_repSize; - /** - * Create a new ByteArrayReplacementFilter with $search and $replace. - * @param array $search - * @param array $replace - */ - public function __construct($search, $replace) - { - $this->_search = $search; - $this->_index = array(); - $this->_tree = array(); - $this->_replace = array(); - $this->_repSize = array(); - - $tree = null; - $i = null; - $last_size = $size = 0; - foreach ($search as $i => $search_element) + /** + * Create a new ByteArrayReplacementFilter with $search and $replace. + * + * @param array $search + * @param array $replace + */ + public function __construct($search, $replace) { - if ($tree !== null) - { - $tree[-1] = min (count($replace) - 1, $i - 1); - $tree[-2] = $last_size; - } - $tree = &$this->_tree; - if (is_array ($search_element)) - { - foreach ($search_element as $k => $char) - { - $this->_index[$char] = true; - if (!isset($tree[$char])) - { - $tree[$char] = array(); - } - $tree = &$tree[$char]; + $this->_search = $search; + $this->_index = array(); + $this->_tree = array(); + $this->_replace = array(); + $this->_repSize = array(); + + $tree = null; + $i = null; + $last_size = $size = 0; + foreach ($search as $i => $search_element) { + if ($tree !== null) { + $tree[-1] = min (count($replace) - 1, $i - 1); + $tree[-2] = $last_size; + } + $tree = &$this->_tree; + if (is_array ($search_element)) { + foreach ($search_element as $k => $char) { + $this->_index[$char] = true; + if (!isset($tree[$char])) { + $tree[$char] = array(); + } + $tree = &$tree[$char]; + } + $last_size = $k+1; + $size = max($size, $last_size); + } else { + $last_size = 1; + if (!isset($tree[$search_element])) { + $tree[$search_element] = array(); + } + $tree = &$tree[$search_element]; + $size = max($last_size, $size); + $this->_index[$search_element] = true; + } } - $last_size = $k+1; - $size = max($size, $last_size); - } - else - { - $last_size = 1; - if (!isset($tree[$search_element])) - { - $tree[$search_element] = array(); + if ($i !== null) { + $tree[-1] = min (count ($replace) - 1, $i); + $tree[-2] = $last_size; + $this->_treeMaxLen = $size; } - $tree = &$tree[$search_element]; - $size = max($last_size, $size); - $this->_index[$search_element] = true; - } - } - if ($i !== null) - { - $tree[-1] = min (count ($replace) - 1, $i); - $tree[-2] = $last_size; - $this->_treeMaxLen = $size; - } - foreach ($replace as $rep) - { - if (!is_array($rep)) - { - $rep = array ($rep); - } - $this->_replace[] = $rep; - } - for ($i = count($this->_replace) - 1; $i >= 0; --$i) - { - $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i); - $this->_repSize[$i] = count($rep); - } - } - - /** - * Returns true if based on the buffer passed more bytes should be buffered. - * @param array $buffer - * @return boolean - */ - public function shouldBuffer($buffer) - { - $endOfBuffer = end($buffer); - return isset ($this->_index[$endOfBuffer]); - } - - /** - * Perform the actual replacements on $buffer and return the result. - * @param array $buffer - * @return array - */ - public function filter($buffer, $_minReplaces = -1) - { - if ($this->_treeMaxLen == 0) - { - return $buffer; - } - - $newBuffer = array(); - $buf_size = count($buffer); - for ($i = 0; $i < $buf_size; ++$i) - { - $search_pos = $this->_tree; - $last_found = PHP_INT_MAX; - // We try to find if the next byte is part of a search pattern - for ($j = 0; $j <= $this->_treeMaxLen; ++$j) - { - // We have a new byte for a search pattern - if (isset ($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]])) - { - $search_pos = $search_pos[$buffer[$p]]; - // We have a complete pattern, save, in case we don't find a better match later - if (isset($search_pos[- 1]) && $search_pos[-1] < $last_found - && $search_pos[-1] > $_minReplaces) - { - $last_found = $search_pos[-1]; - $last_size = $search_pos[-2]; - } + foreach ($replace as $rep) { + if (!is_array($rep)) { + $rep = array ($rep); + } + $this->_replace[] = $rep; } - // We got a complete pattern - elseif ($last_found !== PHP_INT_MAX) - { - // Adding replacement datas to output buffer - $rep_size = $this->_repSize[$last_found]; - for ($j = 0; $j < $rep_size; ++$j) - { - $newBuffer[] = $this->_replace[$last_found][$j]; - } - // We Move cursor forward - $i += $last_size - 1; - // Edge Case, last position in buffer - if ($i >= $buf_size) - { + for ($i = count($this->_replace) - 1; $i >= 0; --$i) { + $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i); + $this->_repSize[$i] = count($rep); + } + } + + /** + * Returns true if based on the buffer passed more bytes should be buffered. + * + * @param array $buffer + * + * @return bool + */ + public function shouldBuffer($buffer) + { + $endOfBuffer = end($buffer); + + return isset ($this->_index[$endOfBuffer]); + } + + /** + * Perform the actual replacements on $buffer and return the result. + * + * @param array $buffer + * @param int $_minReplaces + * + * @return array + */ + public function filter($buffer, $_minReplaces = -1) + { + if ($this->_treeMaxLen == 0) { + return $buffer; + } + + $newBuffer = array(); + $buf_size = count($buffer); + for ($i = 0; $i < $buf_size; ++$i) { + $search_pos = $this->_tree; + $last_found = PHP_INT_MAX; + // We try to find if the next byte is part of a search pattern + for ($j = 0; $j <= $this->_treeMaxLen; ++$j) { + // We have a new byte for a search pattern + if (isset ($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]])) { + $search_pos = $search_pos[$buffer[$p]]; + // We have a complete pattern, save, in case we don't find a better match later + if (isset($search_pos[- 1]) && $search_pos[-1] < $last_found + && $search_pos[-1] > $_minReplaces) + { + $last_found = $search_pos[-1]; + $last_size = $search_pos[-2]; + } + } + // We got a complete pattern + elseif ($last_found !== PHP_INT_MAX) { + // Adding replacement datas to output buffer + $rep_size = $this->_repSize[$last_found]; + for ($j = 0; $j < $rep_size; ++$j) { + $newBuffer[] = $this->_replace[$last_found][$j]; + } + // We Move cursor forward + $i += $last_size - 1; + // Edge Case, last position in buffer + if ($i >= $buf_size) { + $newBuffer[] = $buffer[$i]; + } + + // We start the next loop + continue 2; + } else { + // this byte is not in a pattern and we haven't found another pattern + break; + } + } + // Normal byte, move it to output buffer $newBuffer[] = $buffer[$i]; - } - - // We start the next loop - continue 2; } - else - { - // this byte is not in a pattern and we haven't found another pattern - break; - } - } - // Normal byte, move it to output buffer - $newBuffer[] = $buffer[$i]; - } - - return $newBuffer; - } + return $newBuffer; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php b/lib/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php index deebcd615..4075d08a8 100644 --- a/lib/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php +++ b/lib/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilter.php @@ -8,58 +8,60 @@ * file that was distributed with this source code. */ - /** * Processes bytes as they pass through a buffer and replaces sequences in it. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_StreamFilters_StringReplacementFilter implements Swift_StreamFilter { - - /** The needle(s) to search for */ - private $_search; - - /** The replacement(s) to make */ - private $_replace; - - /** - * Create a new StringReplacementFilter with $search and $replace. - * @param string|array $search - * @param string|array $replace - */ - public function __construct($search, $replace) - { - $this->_search = $search; - $this->_replace = $replace; - } - - /** - * Returns true if based on the buffer passed more bytes should be buffered. - * @param string $buffer - * @return boolean - */ - public function shouldBuffer($buffer) - { - $endOfBuffer = substr($buffer, -1); - foreach ((array) $this->_search as $needle) + /** The needle(s) to search for */ + private $_search; + + /** The replacement(s) to make */ + private $_replace; + + /** + * Create a new StringReplacementFilter with $search and $replace. + * + * @param string|array $search + * @param string|array $replace + */ + public function __construct($search, $replace) { - if (false !== strpos($needle, $endOfBuffer)) - { - return true; - } + $this->_search = $search; + $this->_replace = $replace; + } + + /** + * Returns true if based on the buffer passed more bytes should be buffered. + * + * @param string $buffer + * + * @return bool + */ + public function shouldBuffer($buffer) + { + $endOfBuffer = substr($buffer, -1); + foreach ((array) $this->_search as $needle) { + if (false !== strpos($needle, $endOfBuffer)) { + return true; + } + } + + return false; + } + + /** + * Perform the actual replacements on $buffer and return the result. + * + * @param string $buffer + * + * @return string + */ + public function filter($buffer) + { + return str_replace($this->_search, $this->_replace, $buffer); } - return false; - } - - /** - * Perform the actual replacements on $buffer and return the result. - * @param string $buffer - * @return string - */ - public function filter($buffer) - { - return str_replace($this->_search, $this->_replace, $buffer); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php b/lib/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php index 4b6448746..bb4af7785 100644 --- a/lib/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php +++ b/lib/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php @@ -8,44 +8,39 @@ * file that was distributed with this source code. */ - /** * Creates filters for replacing needles in a string buffer. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_StreamFilters_StringReplacementFilterFactory - implements Swift_ReplacementFilterFactory +class Swift_StreamFilters_StringReplacementFilterFactory implements Swift_ReplacementFilterFactory { - - /** Lazy-loaded filters */ - private $_filters = array(); - - /** - * Create a new StreamFilter to replace $search with $replace in a string. - * @param string $search - * @param string $replace - * @return Swift_StreamFilter - */ - public function createFilter($search, $replace) - { - if (!isset($this->_filters[$search][$replace])) + /** Lazy-loaded filters */ + private $_filters = array(); + + /** + * Create a new StreamFilter to replace $search with $replace in a string. + * + * @param string $search + * @param string $replace + * + * @return Swift_StreamFilter + */ + public function createFilter($search, $replace) { - if (!isset($this->_filters[$search])) - { - $this->_filters[$search] = array(); - } - - if (!isset($this->_filters[$search][$replace])) - { - $this->_filters[$search][$replace] = array(); - } - - $this->_filters[$search][$replace] - = new Swift_StreamFilters_StringReplacementFilter($search, $replace); + if (!isset($this->_filters[$search][$replace])) { + if (!isset($this->_filters[$search])) { + $this->_filters[$search] = array(); + } + + if (!isset($this->_filters[$search][$replace])) { + $this->_filters[$search][$replace] = array(); + } + + $this->_filters[$search][$replace] = new Swift_StreamFilters_StringReplacementFilter($search, $replace); + } + + return $this->_filters[$search][$replace]; } - - return $this->_filters[$search][$replace]; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/SwiftException.php b/lib/swiftmailer/lib/classes/Swift/SwiftException.php index bd3b656a5..f3bcbed90 100644 --- a/lib/swiftmailer/lib/classes/Swift/SwiftException.php +++ b/lib/swiftmailer/lib/classes/Swift/SwiftException.php @@ -10,19 +10,19 @@ /** * Base Exception class. + * * @package Swift - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_SwiftException extends Exception { - - /** - * Create a new SwiftException with $message. - * @param string $message - */ - public function __construct($message) - { - parent::__construct($message); - } - + /** + * Create a new SwiftException with $message. + * + * @param string $message + */ + public function __construct($message) + { + parent::__construct($message); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport.php b/lib/swiftmailer/lib/classes/Swift/Transport.php index 343a2acaa..69eec54f7 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport.php @@ -8,51 +8,49 @@ * file that was distributed with this source code. */ - /** * Sends Messages via an abstract Transport subsystem. - * - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Transport { + /** + * Test if this Transport mechanism has started. + * + * @return bool + */ + public function isStarted(); - /** - * Test if this Transport mechanism has started. - * - * @return boolean - */ - public function isStarted(); - - /** - * Start this Transport mechanism. - */ - public function start(); - - /** - * Stop this Transport mechanism. - */ - public function stop(); - - /** - * Send the given Message. - * - * Recipient/sender data will be retreived from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * - * @param Swift_Mime_Message $message - * @param string[] &$failedRecipients to collect failures by-reference - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null); - - /** - * Register a plugin in the Transport. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin); - + /** + * Start this Transport mechanism. + */ + public function start(); + + /** + * Stop this Transport mechanism. + */ + public function stop(); + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * + * @param Swift_Mime_Message $message + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null); + + /** + * Register a plugin in the Transport. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin); } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php b/lib/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php index 9de9260d2..d140f4b3e 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php @@ -8,551 +8,500 @@ * file that was distributed with this source code. */ - /** * Sends Messages over SMTP. - * - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -abstract class Swift_Transport_AbstractSmtpTransport - implements Swift_Transport +abstract class Swift_Transport_AbstractSmtpTransport implements Swift_Transport { - - /** Input-Output buffer for sending/receiving SMTP commands and responses */ - protected $_buffer; - - /** Connection status */ - protected $_started = false; - - /** The domain name to use in HELO command */ - protected $_domain = '[127.0.0.1]'; - - /** The event dispatching layer */ - protected $_eventDispatcher; - - /** Source Ip */ - protected $_sourceIp; - - /** Return an array of params for the Buffer */ - abstract protected function _getBufferParams(); - - /** - * Creates a new EsmtpTransport using the given I/O buffer. - * - * @param Swift_Transport_IoBuffer $buf - * @param Swift_Events_EventDispatcher $dispatcher - */ - public function __construct(Swift_Transport_IoBuffer $buf, - Swift_Events_EventDispatcher $dispatcher) - { - $this->_eventDispatcher = $dispatcher; - $this->_buffer = $buf; - $this->_lookupHostname(); - } - - /** - * Set the name of the local domain which Swift will identify itself as. - * This should be a fully-qualified domain name and should be truly the domain - * you're using. If your server doesn't have a domain name, use the IP in square - * brackets (i.e. [127.0.0.1]). - * - * @param string $domain - */ - public function setLocalDomain($domain) - { - $this->_domain = $domain; - return $this; - } - - /** - * Get the name of the domain Swift will identify as. - * - * @return string - */ - public function getLocalDomain() - { - return $this->_domain; - } - + /** Input-Output buffer for sending/receiving SMTP commands and responses */ + protected $_buffer; - /** - * Sets the sourceIp - * @param string $source - */ - public function setSourceIp($source) - { - $this->_sourceIp=$source; - } + /** Connection status */ + protected $_started = false; - /** - * Returns the ip used to connect to the destination - * @return string - */ - public function getSourceIp() - { - return $this->_sourceIp; - } + /** The domain name to use in HELO command */ + protected $_domain = '[127.0.0.1]'; - /** - * Start the SMTP connection. - */ - public function start() - { - if (!$this->_started) + /** The event dispatching layer */ + protected $_eventDispatcher; + + /** Source Ip */ + protected $_sourceIp; + + /** Return an array of params for the Buffer */ + abstract protected function _getBufferParams(); + + /** + * Creates a new EsmtpTransport using the given I/O buffer. + * + * @param Swift_Transport_IoBuffer $buf + * @param Swift_Events_EventDispatcher $dispatcher + */ + public function __construct(Swift_Transport_IoBuffer $buf, Swift_Events_EventDispatcher $dispatcher) { - if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) - { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStarted'); - if ($evt->bubbleCancelled()) - { - return; + $this->_eventDispatcher = $dispatcher; + $this->_buffer = $buf; + $this->_lookupHostname(); + } + + /** + * Set the name of the local domain which Swift will identify itself as. + * + * This should be a fully-qualified domain name and should be truly the domain + * you're using. + * + * If your server doesn't have a domain name, use the IP in square + * brackets (i.e. [127.0.0.1]). + * + * @param string $domain + * + * @return Swift_Transport_AbstractSmtpTransport + */ + public function setLocalDomain($domain) + { + $this->_domain = $domain; + + return $this; + } + + /** + * Get the name of the domain Swift will identify as. + * + * @return string + */ + public function getLocalDomain() + { + return $this->_domain; + } + + /** + * Sets the source IP. + * + * @param string $source + */ + public function setSourceIp($source) + { + $this->_sourceIp=$source; + } + + /** + * Returns the IP used to connect to the destination + * + * @return string + */ + public function getSourceIp() + { + return $this->_sourceIp; + } + + /** + * Start the SMTP connection. + */ + public function start() + { + if (!$this->_started) { + if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStarted'); + if ($evt->bubbleCancelled()) { + return; + } + } + + try { + $this->_buffer->initialize($this->_getBufferParams()); + } catch (Swift_TransportException $e) { + $this->_throwException($e); + } + $this->_readGreeting(); + $this->_doHeloCommand(); + + if ($evt) { + $this->_eventDispatcher->dispatchEvent($evt, 'transportStarted'); + } + + $this->_started = true; } - } - - try - { - $this->_buffer->initialize($this->_getBufferParams()); - } - catch (Swift_TransportException $e) - { - $this->_throwException($e); - } - $this->_readGreeting(); - $this->_doHeloCommand(); - - if ($evt) - { - $this->_eventDispatcher->dispatchEvent($evt, 'transportStarted'); - } - - $this->_started = true; } - } - - /** - * Test if an SMTP connection has been established. - * - * @return boolean - */ - public function isStarted() - { - return $this->_started; - } - - /** - * Send the given Message. - * - * Recipient/sender data will be retreived from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * - * @param Swift_Mime_Message $message - * @param string[] &$failedRecipients to collect failures by-reference - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $sent = 0; - $failedRecipients = (array) $failedRecipients; - - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + + /** + * Test if an SMTP connection has been established. + * + * @return bool + */ + public function isStarted() { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) - { - return 0; - } + return $this->_started; } - - if (!$reversePath = $this->_getReversePath($message)) + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * + * @param Swift_Mime_Message $message + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) { - throw new Swift_TransportException( - 'Cannot send message without a sender address' - ); - } - - $to = (array) $message->getTo(); - $cc = (array) $message->getCc(); - $bcc = (array) $message->getBcc(); - - $message->setBcc(array()); - - try - { - $sent += $this->_sendTo($message, $reversePath, $to, $failedRecipients); - $sent += $this->_sendCc($message, $reversePath, $cc, $failedRecipients); - $sent += $this->_sendBcc($message, $reversePath, $bcc, $failedRecipients); - } - catch (Exception $e) - { - $message->setBcc($bcc); - throw $e; - } - - $message->setBcc($bcc); - - if ($evt) - { - if ($sent == count($to) + count($cc) + count($bcc)) - { - $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); - } - elseif ($sent > 0) - { - $evt->setResult(Swift_Events_SendEvent::RESULT_TENTATIVE); - } - else - { - $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED); - } - $evt->setFailedRecipients($failedRecipients); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - - $message->generateId(); //Make sure a new Message ID is used - - return $sent; - } - - /** - * Stop the SMTP connection. - */ - public function stop() - { - if ($this->_started) - { - if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) - { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStopped'); - if ($evt->bubbleCancelled()) - { - return; + $sent = 0; + $failedRecipients = (array) $failedRecipients; + + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) { + return 0; + } } - } - - try - { - $this->executeCommand("QUIT\r\n", array(221)); - } - catch (Swift_TransportException $e) {} - - try - { - $this->_buffer->terminate(); - - if ($evt) - { - $this->_eventDispatcher->dispatchEvent($evt, 'transportStopped'); + + if (!$reversePath = $this->_getReversePath($message)) { + throw new Swift_TransportException( + 'Cannot send message without a sender address' + ); } - } - catch (Swift_TransportException $e) - { - $this->_throwException($e); - } + + $to = (array) $message->getTo(); + $cc = (array) $message->getCc(); + $bcc = (array) $message->getBcc(); + + $message->setBcc(array()); + + try { + $sent += $this->_sendTo($message, $reversePath, $to, $failedRecipients); + $sent += $this->_sendCc($message, $reversePath, $cc, $failedRecipients); + $sent += $this->_sendBcc($message, $reversePath, $bcc, $failedRecipients); + } catch (Exception $e) { + $message->setBcc($bcc); + throw $e; + } + + $message->setBcc($bcc); + + if ($evt) { + if ($sent == count($to) + count($cc) + count($bcc)) { + $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); + } elseif ($sent > 0) { + $evt->setResult(Swift_Events_SendEvent::RESULT_TENTATIVE); + } else { + $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED); + } + $evt->setFailedRecipients($failedRecipients); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + $message->generateId(); //Make sure a new Message ID is used + + return $sent; } - $this->_started = false; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_eventDispatcher->bindEventListener($plugin); - } - - /** - * Reset the current mail transaction. - */ - public function reset() - { - $this->executeCommand("RSET\r\n", array(250)); - } - - /** - * Get the IoBuffer where read/writes are occurring. - * - * @return Swift_Transport_IoBuffer - */ - public function getBuffer() - { - return $this->_buffer; - } - - /** - * Run a command against the buffer, expecting the given response codes. - * - * If no response codes are given, the response will not be validated. - * If codes are given, an exception will be thrown on an invalid response. - * - * @param string $command - * @param int[] $codes - * @param string[] &$failures - * @return string - */ - public function executeCommand($command, $codes = array(), &$failures = null) - { - $failures = (array) $failures; - $seq = $this->_buffer->write($command); - $response = $this->_getFullResponse($seq); - if ($evt = $this->_eventDispatcher->createCommandEvent($this, $command, $codes)) + + /** + * Stop the SMTP connection. + */ + public function stop() { - $this->_eventDispatcher->dispatchEvent($evt, 'commandSent'); + if ($this->_started) { + if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStopped'); + if ($evt->bubbleCancelled()) { + return; + } + } + + try { + $this->executeCommand("QUIT\r\n", array(221)); + } catch (Swift_TransportException $e) {} + + try { + $this->_buffer->terminate(); + + if ($evt) { + $this->_eventDispatcher->dispatchEvent($evt, 'transportStopped'); + } + } catch (Swift_TransportException $e) { + $this->_throwException($e); + } + } + $this->_started = false; } - $this->_assertResponseCode($response, $codes); - return $response; - } - - // -- Protected methods - - /** Read the opening SMTP greeting */ - protected function _readGreeting() - { - $this->_assertResponseCode($this->_getFullResponse(0), array(220)); - } - - /** Send the HELO welcome */ - protected function _doHeloCommand() - { - $this->executeCommand( - sprintf("HELO %s\r\n", $this->_domain), array(250) - ); - } - - /** Send the MAIL FROM command */ - protected function _doMailFromCommand($address) - { - $this->executeCommand( - sprintf("MAIL FROM: <%s>\r\n", $address), array(250) - ); - } - - /** Send the RCPT TO command */ - protected function _doRcptToCommand($address) - { - $this->executeCommand( - sprintf("RCPT TO: <%s>\r\n", $address), array(250, 251, 252) - ); - } - - /** Send the DATA command */ - protected function _doDataCommand() - { - $this->executeCommand("DATA\r\n", array(354)); - } - - /** Stream the contents of the message over the buffer */ - protected function _streamMessage(Swift_Mime_Message $message) - { - $this->_buffer->setWriteTranslations(array("\r\n." => "\r\n..")); - try + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) { - $message->toByteStream($this->_buffer); - $this->_buffer->flushBuffers(); + $this->_eventDispatcher->bindEventListener($plugin); } - catch (Swift_TransportException $e) + + /** + * Reset the current mail transaction. + */ + public function reset() { - $this->_throwException($e); + $this->executeCommand("RSET\r\n", array(250)); } - $this->_buffer->setWriteTranslations(array()); - $this->executeCommand("\r\n.\r\n", array(250)); - } - - /** Determine the best-use reverse path for this message */ - protected function _getReversePath(Swift_Mime_Message $message) - { - $return = $message->getReturnPath(); - $sender = $message->getSender(); - $from = $message->getFrom(); - $path = null; - if (!empty($return)) + + /** + * Get the IoBuffer where read/writes are occurring. + * + * @return Swift_Transport_IoBuffer + */ + public function getBuffer() { - $path = $return; + return $this->_buffer; } - elseif (!empty($sender)) + + /** + * Run a command against the buffer, expecting the given response codes. + * + * If no response codes are given, the response will not be validated. + * If codes are given, an exception will be thrown on an invalid response. + * + * @param string $command + * @param int[] $codes + * @param string[] $failures An array of failures by-reference + * + * @return string + */ + public function executeCommand($command, $codes = array(), &$failures = null) { - // Don't use array_keys - reset($sender); // Reset Pointer to first pos - $path = key($sender); // Get key + $failures = (array) $failures; + $seq = $this->_buffer->write($command); + $response = $this->_getFullResponse($seq); + if ($evt = $this->_eventDispatcher->createCommandEvent($this, $command, $codes)) { + $this->_eventDispatcher->dispatchEvent($evt, 'commandSent'); + } + $this->_assertResponseCode($response, $codes); + + return $response; } - elseif (!empty($from)) + + // -- Protected methods + + /** Read the opening SMTP greeting */ + protected function _readGreeting() { - reset($from); // Reset Pointer to first pos - $path = key($from); // Get key + $this->_assertResponseCode($this->_getFullResponse(0), array(220)); } - return $path; - } - - /** Throw a TransportException, first sending it to any listeners */ - protected function _throwException(Swift_TransportException $e) - { - if ($evt = $this->_eventDispatcher->createTransportExceptionEvent($this, $e)) + + /** Send the HELO welcome */ + protected function _doHeloCommand() { - $this->_eventDispatcher->dispatchEvent($evt, 'exceptionThrown'); - if (!$evt->bubbleCancelled()) - { - throw $e; - } + $this->executeCommand( + sprintf("HELO %s\r\n", $this->_domain), array(250) + ); } - else + + /** Send the MAIL FROM command */ + protected function _doMailFromCommand($address) { - throw $e; + $this->executeCommand( + sprintf("MAIL FROM: <%s>\r\n", $address), array(250) + ); } - } - - /** Throws an Exception if a response code is incorrect */ - protected function _assertResponseCode($response, $wanted) - { - list($code, $separator, $text) = sscanf($response, '%3d%[ -]%s'); - $valid = (empty($wanted) || in_array($code, $wanted)); - - if ($evt = $this->_eventDispatcher->createResponseEvent($this, $response, - $valid)) + + /** Send the RCPT TO command */ + protected function _doRcptToCommand($address) { - $this->_eventDispatcher->dispatchEvent($evt, 'responseReceived'); + $this->executeCommand( + sprintf("RCPT TO: <%s>\r\n", $address), array(250, 251, 252) + ); } - - if (!$valid) + + /** Send the DATA command */ + protected function _doDataCommand() { - $this->_throwException( - new Swift_TransportException( - 'Expected response code ' . implode('/', $wanted) . ' but got code ' . - '"' . $code . '", with message "' . $response . '"' - ) - ); + $this->executeCommand("DATA\r\n", array(354)); } - } - - /** Get an entire multi-line response using its sequence number */ - protected function _getFullResponse($seq) - { - $response = ''; - try + + /** Stream the contents of the message over the buffer */ + protected function _streamMessage(Swift_Mime_Message $message) { - do - { - $line = $this->_buffer->readLine($seq); - $response .= $line; - } - while (null !== $line && false !== $line && ' ' != $line{3}); + $this->_buffer->setWriteTranslations(array("\r\n." => "\r\n..")); + try { + $message->toByteStream($this->_buffer); + $this->_buffer->flushBuffers(); + } catch (Swift_TransportException $e) { + $this->_throwException($e); + } + $this->_buffer->setWriteTranslations(array()); + $this->executeCommand("\r\n.\r\n", array(250)); } - catch (Swift_TransportException $e) + + /** Determine the best-use reverse path for this message */ + protected function _getReversePath(Swift_Mime_Message $message) { - $this->_throwException($e); + $return = $message->getReturnPath(); + $sender = $message->getSender(); + $from = $message->getFrom(); + $path = null; + if (!empty($return)) { + $path = $return; + } elseif (!empty($sender)) { + // Don't use array_keys + reset($sender); // Reset Pointer to first pos + $path = key($sender); // Get key + } elseif (!empty($from)) { + reset($from); // Reset Pointer to first pos + $path = key($from); // Get key + } + + return $path; } - return $response; - } - - // -- Private methods - - /** Send an email to the given recipients from the given reverse path */ - private function _doMailTransaction($message, $reversePath, - array $recipients, array &$failedRecipients) - { - $sent = 0; - $this->_doMailFromCommand($reversePath); - foreach ($recipients as $forwardPath) + + /** Throw a TransportException, first sending it to any listeners */ + protected function _throwException(Swift_TransportException $e) { - try - { - $this->_doRcptToCommand($forwardPath); - $sent++; - } - catch (Swift_TransportException $e) - { - $failedRecipients[] = $forwardPath; - } + if ($evt = $this->_eventDispatcher->createTransportExceptionEvent($this, $e)) { + $this->_eventDispatcher->dispatchEvent($evt, 'exceptionThrown'); + if (!$evt->bubbleCancelled()) { + throw $e; + } + } else { + throw $e; + } } - - if ($sent != 0) + + /** Throws an Exception if a response code is incorrect */ + protected function _assertResponseCode($response, $wanted) { - $this->_doDataCommand(); - $this->_streamMessage($message); + list($code) = sscanf($response, '%3d'); + $valid = (empty($wanted) || in_array($code, $wanted)); + + if ($evt = $this->_eventDispatcher->createResponseEvent($this, $response, + $valid)) + { + $this->_eventDispatcher->dispatchEvent($evt, 'responseReceived'); + } + + if (!$valid) { + $this->_throwException( + new Swift_TransportException( + 'Expected response code ' . implode('/', $wanted) . ' but got code ' . + '"' . $code . '", with message "' . $response . '"', + $code) + ); + } } - else + + /** Get an entire multi-line response using its sequence number */ + protected function _getFullResponse($seq) { - $this->reset(); + $response = ''; + try { + do { + $line = $this->_buffer->readLine($seq); + $response .= $line; + } while (null !== $line && false !== $line && ' ' != $line{3}); + } catch (Swift_IoException $e) { + $this->_throwException( + new Swift_TransportException( + $e->getMessage()) + ); + } catch (Swift_TransportException $e) { + $this->_throwException($e); + } + + return $response; } - - return $sent; - } - - /** Send a message to the given To: recipients */ - private function _sendTo(Swift_Mime_Message $message, $reversePath, - array $to, array &$failedRecipients) - { - if (empty($to)) + + // -- Private methods + + /** Send an email to the given recipients from the given reverse path */ + private function _doMailTransaction($message, $reversePath, array $recipients, array &$failedRecipients) { - return 0; + $sent = 0; + $this->_doMailFromCommand($reversePath); + foreach ($recipients as $forwardPath) { + try { + $this->_doRcptToCommand($forwardPath); + $sent++; + } catch (Swift_TransportException $e) { + $failedRecipients[] = $forwardPath; + } + } + + if ($sent != 0) { + $this->_doDataCommand(); + $this->_streamMessage($message); + } else { + $this->reset(); + } + + return $sent; } - return $this->_doMailTransaction($message, $reversePath, array_keys($to), - $failedRecipients); - } - - /** Send a message to the given Cc: recipients */ - private function _sendCc(Swift_Mime_Message $message, $reversePath, - array $cc, array &$failedRecipients) - { - if (empty($cc)) + + /** Send a message to the given To: recipients */ + private function _sendTo(Swift_Mime_Message $message, $reversePath, array $to, array &$failedRecipients) { - return 0; + if (empty($to)) { + return 0; + } + + return $this->_doMailTransaction($message, $reversePath, array_keys($to), + $failedRecipients); } - return $this->_doMailTransaction($message, $reversePath, array_keys($cc), - $failedRecipients); - } - - /** Send a message to all Bcc: recipients */ - private function _sendBcc(Swift_Mime_Message $message, $reversePath, - array $bcc, array &$failedRecipients) - { - $sent = 0; - foreach ($bcc as $forwardPath => $name) + + /** Send a message to the given Cc: recipients */ + private function _sendCc(Swift_Mime_Message $message, $reversePath, array $cc, array &$failedRecipients) { - $message->setBcc(array($forwardPath => $name)); - $sent += $this->_doMailTransaction( - $message, $reversePath, array($forwardPath), $failedRecipients - ); + if (empty($cc)) { + return 0; + } + + return $this->_doMailTransaction($message, $reversePath, array_keys($cc), + $failedRecipients); } - return $sent; - } - - /** Try to determine the hostname of the server this is run on */ - private function _lookupHostname() - { - if (!empty($_SERVER['SERVER_NAME']) - && $this->_isFqdn($_SERVER['SERVER_NAME'])) + + /** Send a message to all Bcc: recipients */ + private function _sendBcc(Swift_Mime_Message $message, $reversePath, array $bcc, array &$failedRecipients) { - $this->_domain = $_SERVER['SERVER_NAME']; + $sent = 0; + foreach ($bcc as $forwardPath => $name) { + $message->setBcc(array($forwardPath => $name)); + $sent += $this->_doMailTransaction( + $message, $reversePath, array($forwardPath), $failedRecipients + ); + } + + return $sent; } - elseif (!empty($_SERVER['SERVER_ADDR'])) + + /** Try to determine the hostname of the server this is run on */ + private function _lookupHostname() { - $this->_domain = sprintf('[%s]', $_SERVER['SERVER_ADDR']); + if (!empty($_SERVER['SERVER_NAME']) + && $this->_isFqdn($_SERVER['SERVER_NAME'])) + { + $this->_domain = $_SERVER['SERVER_NAME']; + } elseif (!empty($_SERVER['SERVER_ADDR'])) { + $this->_domain = sprintf('[%s]', $_SERVER['SERVER_ADDR']); + } } - } - - /** Determine is the $hostname is a fully-qualified name */ - private function _isFqdn($hostname) - { - //We could do a really thorough check, but there's really no point - if (false !== $dotPos = strpos($hostname, '.')) + + /** Determine is the $hostname is a fully-qualified name */ + private function _isFqdn($hostname) { - return ($dotPos > 0) && ($dotPos != strlen($hostname) - 1); + // We could do a really thorough check, but there's really no point + if (false !== $dotPos = strpos($hostname, '.')) { + return ($dotPos > 0) && ($dotPos != strlen($hostname) - 1); + } else { + return false; + } } - else + + /** + * Destructor. + */ + public function __destruct() { - return false; + $this->stop(); } - } - - /** - * Destructor. - */ - public function __destruct() - { - $this->stop(); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php index 1595211b4..5c26e4b8b 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php @@ -8,78 +8,76 @@ * file that was distributed with this source code. */ - /** * Handles CRAM-MD5 authentication. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Transport_Esmtp_Auth_CramMd5Authenticator - implements Swift_Transport_Esmtp_Authenticator +class Swift_Transport_Esmtp_Auth_CramMd5Authenticator implements Swift_Transport_Esmtp_Authenticator { - - /** - * Get the name of the AUTH mechanism this Authenticator handles. - * @return string - */ - public function getAuthKeyword() - { - return 'CRAM-MD5'; - } - - /** - * Try to authenticate the user with $username and $password. - * @param Swift_Transport_SmtpAgent $agent - * @param string $username - * @param string $password - * @return boolean - */ - public function authenticate(Swift_Transport_SmtpAgent $agent, - $username, $password) - { - try + /** + * Get the name of the AUTH mechanism this Authenticator handles. + * + * @return string + */ + public function getAuthKeyword() { - $challenge = $agent->executeCommand("AUTH CRAM-MD5\r\n", array(334)); - $challenge = base64_decode(substr($challenge, 4)); - $message = base64_encode( - $username . ' ' . $this->_getResponse($password, $challenge) - ); - $agent->executeCommand(sprintf("%s\r\n", $message), array(235)); - return true; + return 'CRAM-MD5'; } - catch (Swift_TransportException $e) - { - $agent->executeCommand("RSET\r\n", array(250)); - return false; - } - } - - /** - * Generate a CRAM-MD5 response from a server challenge. - * @param string $secret - * @param string $challenge - * @return string - */ - private function _getResponse($secret, $challenge) - { - if (strlen($secret) > 64) - { - $secret = pack('H32', md5($secret)); - } - - if (strlen($secret) < 64) - { - $secret = str_pad($secret, 64, chr(0)); - } - - $k_ipad = substr($secret, 0, 64) ^ str_repeat(chr(0x36), 64); - $k_opad = substr($secret, 0, 64) ^ str_repeat(chr(0x5C), 64); - $inner = pack('H32', md5($k_ipad . $challenge)); - $digest = md5($k_opad . $inner); + /** + * Try to authenticate the user with $username and $password. + * + * @param Swift_Transport_SmtpAgent $agent + * @param string $username + * @param string $password + * + * @return bool + */ + public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password) + { + try { + $challenge = $agent->executeCommand("AUTH CRAM-MD5\r\n", array(334)); + $challenge = base64_decode(substr($challenge, 4)); + $message = base64_encode( + $username . ' ' . $this->_getResponse($password, $challenge) + ); + $agent->executeCommand(sprintf("%s\r\n", $message), array(235)); - return $digest; - } - + return true; + } catch (Swift_TransportException $e) { + $agent->executeCommand("RSET\r\n", array(250)); + + return false; + } + } + + /** + * Generate a CRAM-MD5 response from a server challenge. + * + * @param string $secret + * @param string $challenge + * + * @return string + */ + private function _getResponse($secret, $challenge) + { + if (strlen($secret) > 64) { + $secret = pack('H32', md5($secret)); + } + + if (strlen($secret) < 64) { + $secret = str_pad($secret, 64, chr(0)); + } + + $k_ipad = substr($secret, 0, 64) ^ str_repeat(chr(0x36), 64); + $k_opad = substr($secret, 0, 64) ^ str_repeat(chr(0x5C), 64); + + $inner = pack('H32', md5($k_ipad . $challenge)); + $digest = md5($k_opad . $inner); + + return $digest; + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php index 312b7e20d..8ff7dee86 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php @@ -8,48 +8,46 @@ * file that was distributed with this source code. */ - /** * Handles LOGIN authentication. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Transport_Esmtp_Auth_LoginAuthenticator - implements Swift_Transport_Esmtp_Authenticator +class Swift_Transport_Esmtp_Auth_LoginAuthenticator implements Swift_Transport_Esmtp_Authenticator { - - /** - * Get the name of the AUTH mechanism this Authenticator handles. - * @return string - */ - public function getAuthKeyword() - { - return 'LOGIN'; - } - - /** - * Try to authenticate the user with $username and $password. - * @param Swift_Transport_SmtpAgent $agent - * @param string $username - * @param string $password - * @return boolean - */ - public function authenticate(Swift_Transport_SmtpAgent $agent, - $username, $password) - { - try + /** + * Get the name of the AUTH mechanism this Authenticator handles. + * + * @return string + */ + public function getAuthKeyword() { - $agent->executeCommand("AUTH LOGIN\r\n", array(334)); - $agent->executeCommand(sprintf("%s\r\n", base64_encode($username)), array(334)); - $agent->executeCommand(sprintf("%s\r\n", base64_encode($password)), array(235)); - return true; + return 'LOGIN'; } - catch (Swift_TransportException $e) + + /** + * Try to authenticate the user with $username and $password. + * + * @param Swift_Transport_SmtpAgent $agent + * @param string $username + * @param string $password + * + * @return bool + */ + public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password) { - $agent->executeCommand("RSET\r\n", array(250)); - return false; + try { + $agent->executeCommand("AUTH LOGIN\r\n", array(334)); + $agent->executeCommand(sprintf("%s\r\n", base64_encode($username)), array(334)); + $agent->executeCommand(sprintf("%s\r\n", base64_encode($password)), array(235)); + + return true; + } catch (Swift_TransportException $e) { + $agent->executeCommand("RSET\r\n", array(250)); + + return false; + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php new file mode 100644 index 000000000..62eacdd7b --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php @@ -0,0 +1,701 @@ + + */ +class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Esmtp_Authenticator +{ + const NTLMSIG = "NTLMSSP\x00"; + const DESCONST = "KGS!@#$%"; + + /** + * Get the name of the AUTH mechanism this Authenticator handles. + * + * @return string + */ + public function getAuthKeyword() + { + return 'NTLM'; + } + + /** + * Try to authenticate the user with $username and $password. + * + * @param Swift_Transport_SmtpAgent $agent + * @param string $username + * @param string $password + * + * @return bool + */ + public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password) + { + if (!function_exists('mcrypt_module_open')) { + throw new LogicException('The mcrypt functions need to be enabled to use the NTLM authenticator.'); + } + + if (!function_exists('openssl_random_pseudo_bytes')) { + throw new LogicException('The OpenSSL extension must be enabled to use the NTLM authenticator.'); + } + + if (!function_exists('bcmul')) { + throw new LogicException('The BCMatch functions must be enabled to use the NTLM authenticator.'); + } + + try { + // execute AUTH command and filter out the code at the beginning + // AUTH NTLM xxxx + $response = base64_decode(substr(trim($this->sendMessage1($agent)), 4)); + + // extra parameters for our unit cases + $timestamp = func_num_args() > 3 ? func_get_arg(3) : $this->getCorrectTimestamp(bcmul(microtime(true), "1000")); + $client = func_num_args() > 4 ? func_get_arg(4) : $this->getRandomBytes(8); + + // Message 3 response + $this->sendMessage3($response, $username, $password, $timestamp, $client, $agent); + + return true; + } catch (Swift_TransportException $e) { + $agent->executeCommand("RSET\r\n", array(250)); + + return false; + } + } + + protected function si2bin($si, $bits = 32) + { + $bin = null; + if ($si >= -pow(2, $bits - 1) && ($si <= pow(2, $bits - 1))) { + // positive or zero + if ($si >= 0) { + $bin = base_convert($si, 10, 2); + // pad to $bits bit + $bin_length = strlen($bin); + if ($bin_length < $bits) { + $bin = str_repeat("0", $bits - $bin_length) . $bin; + } + } else { // negative + $si = -$si - pow(2, $bits); + $bin = base_convert($si, 10, 2); + $bin_length = strlen($bin); + if ($bin_length > $bits) { + $bin = str_repeat("1", $bits - $bin_length) . $bin; + } + } + } + + return $bin; + } + + /** + * Send our auth message and returns the response + * + * @param Swift_Transport_SmtpAgent $agent + * @return string SMTP Response + */ + protected function sendMessage1(Swift_Transport_SmtpAgent $agent) + { + $message = $this->createMessage1(); + + return $agent->executeCommand(sprintf("AUTH %s %s\r\n", $this->getAuthKeyword(), base64_encode($message)), array(334)); + } + + /** + * Fetch all details of our response (message 2) + * + * @param string $response + * @return array our response parsed + */ + protected function parseMessage2($response) + { + $responseHex = bin2hex($response); + $length = floor(hexdec(substr($responseHex, 28, 4)) / 256) * 2; + $offset = floor(hexdec(substr($responseHex, 32, 4)) / 256) * 2; + $challenge = $this->hex2bin(substr($responseHex, 48, 16)); + $context = $this->hex2bin(substr($responseHex, 64, 16)); + $targetInfoH = $this->hex2bin(substr($responseHex, 80, 16)); + $targetName = $this->hex2bin(substr($responseHex, $offset, $length)); + $offset = floor(hexdec(substr($responseHex, 88, 4)) / 256) * 2; + $targetInfoBlock = substr($responseHex, $offset); + list($domainName, $serverName, $DNSDomainName, $DNSServerName, $terminatorByte) = $this->readSubBlock($targetInfoBlock); + + return array( + $challenge, + $context, + $targetInfoH, + $targetName, + $domainName, + $serverName, + $DNSDomainName, + $DNSServerName, + $this->hex2bin($targetInfoBlock), + $terminatorByte + ); + } + + /** + * Read the blob information in from message2 + * + * @param $block + * @return array + */ + protected function readSubBlock($block) + { + // remove terminatorByte cause it's always the same + $block = substr($block, 0, -8); + + $length = strlen($block); + $offset = 0; + $data = array(); + while ($offset < $length) { + $blockLength = hexdec(substr(substr($block, $offset, 8), -4)) / 256; + $offset += 8; + $data[] = $this->hex2bin(substr($block, $offset, $blockLength * 2)); + $offset += $blockLength * 2; + } + + if (count($data) == 3) { + $data[] = $data[2]; + $data[2] = ''; + } + + $data[] = $this->createByte('00'); + + return $data; + } + + /** + * Send our final message with all our data + * + * @param string $response Message 1 response (message 2) + * @param string $username + * @param string $password + * @param string $timestamp + * @param string $client + * @param Swift_Transport_SmtpAgent $agent + * @param bool $v2 Use version2 of the protocol + * @return string + */ + protected function sendMessage3($response, $username, $password, $timestamp, $client, Swift_Transport_SmtpAgent $agent, $v2 = true) + { + list($domain, $username) = $this->getDomainAndUsername($username); + //$challenge, $context, $targetInfoH, $targetName, $domainName, $workstation, $DNSDomainName, $DNSServerName, $blob, $ter + list($challenge, , , , , $workstation, , , $blob) = $this->parseMessage2($response); + + if (!$v2) { + // LMv1 + $lmResponse = $this->createLMPassword($password, $challenge); + // NTLMv1 + $ntlmResponse = $this->createNTLMPassword($password, $challenge); + } else { + // LMv2 + $lmResponse = $this->createLMv2Password($password, $username, $domain, $challenge, $client); + // NTLMv2 + $ntlmResponse = $this->createNTLMv2Hash($password, $username, $domain, $challenge, $blob, $timestamp, $client); + } + + $message = $this->createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse); + + return $agent->executeCommand(sprintf("%s\r\n", base64_encode($message)), array(235)); + } + + /** + * Create our message 1 + * + * @return string + */ + protected function createMessage1() + { + return self::NTLMSIG + . $this->createByte('01') // Message 1 + . $this->createByte('0702'); // Flags + } + + /** + * Create our message 3 + * + * @param string $domain + * @param string $username + * @param string $workstation + * @param string $lmResponse + * @param string $ntlmResponse + * @return string + */ + protected function createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse) + { + // Create security buffers + $domainSec = $this->createSecurityBuffer($domain, 64); + $domainInfo = $this->readSecurityBuffer(bin2hex($domainSec)); + $userSec = $this->createSecurityBuffer($username, ($domainInfo[0] + $domainInfo[1]) / 2); + $userInfo = $this->readSecurityBuffer(bin2hex($userSec)); + $workSec = $this->createSecurityBuffer($workstation, ($userInfo[0] + $userInfo[1]) / 2); + $workInfo = $this->readSecurityBuffer(bin2hex($workSec)); + $lmSec = $this->createSecurityBuffer($lmResponse, ($workInfo[0] + $workInfo[1]) / 2, true); + $lmInfo = $this->readSecurityBuffer(bin2hex($lmSec)); + $ntlmSec = $this->createSecurityBuffer($ntlmResponse, ($lmInfo[0] + $lmInfo[1]) / 2, true); + + return self::NTLMSIG + . $this->createByte('03') // TYPE 3 message + . $lmSec // LM response header + . $ntlmSec // NTLM response header + . $domainSec // Domain header + . $userSec // User header + . $workSec // Workstation header + . $this->createByte("000000009a", 8) // session key header (empty) + . $this->createByte('01020000') // FLAGS + . $this->convertTo16bit($domain) // domain name + . $this->convertTo16bit($username) // username + . $this->convertTo16bit($workstation) // workstation + . $lmResponse + . $ntlmResponse; + } + + /** + * @param string $timestamp Epoch timestamp in microseconds + * @param string $client Random bytes + * @param string $targetInfo + * @return string + */ + protected function createBlob($timestamp, $client, $targetInfo) + { + return $this->createByte('0101') + . $this->createByte('00') + . $timestamp + . $client + . $this->createByte('00') + . $targetInfo + . $this->createByte('00'); + } + + /** + * Get domain and username from our username + * + * @example DOMAIN\username + * + * @param string $name + * @return array + */ + protected function getDomainAndUsername($name) + { + if (strpos($name, '\\') !== false) { + return explode('\\', $name); + } + + list($user, $domain) = explode('@', $name); + + return array($domain, $user); + } + + /** + * Create LMv1 response + * + * @param string $password + * @param string $challenge + * @return string + */ + protected function createLMPassword($password, $challenge) + { + // FIRST PART + $password = $this->createByte(strtoupper($password), 14, false); + list($key1, $key2) = str_split($password, 7); + + $desKey1 = $this->createDesKey($key1); + $desKey2 = $this->createDesKey($key2); + + $constantDecrypt = $this->createByte($this->desEncrypt(self::DESCONST, $desKey1) . $this->desEncrypt(self::DESCONST, $desKey2), 21, false); + + // SECOND PART + list($key1, $key2, $key3) = str_split($constantDecrypt, 7); + + $desKey1 = $this->createDesKey($key1); + $desKey2 = $this->createDesKey($key2); + $desKey3 = $this->createDesKey($key3); + + return $this->desEncrypt($challenge, $desKey1) . $this->desEncrypt($challenge, $desKey2) . $this->desEncrypt($challenge, $desKey3); + } + + /** + * Create NTLMv1 response + * + * @param string $password + * @param string $challenge + * @return string + */ + protected function createNTLMPassword($password, $challenge) + { + // FIRST PART + $ntlmHash = $this->createByte($this->md4Encrypt($password), 21, false); + list($key1, $key2, $key3) = str_split($ntlmHash, 7); + + $desKey1 = $this->createDesKey($key1); + $desKey2 = $this->createDesKey($key2); + $desKey3 = $this->createDesKey($key3); + + return $this->desEncrypt($challenge, $desKey1) . $this->desEncrypt($challenge, $desKey2) . $this->desEncrypt($challenge, $desKey3); + } + + /** + * Convert a normal timestamp to a tenth of a microtime epoch time + * + * @param string $time + * @return string + */ + protected function getCorrectTimestamp($time) + { + // Get our timestamp (tricky!) + bcscale(0); + + $time = number_format($time, 0, '.', ''); // save microtime to string + $time = bcadd($time, "11644473600000"); // add epoch time + $time = bcmul($time, 10000); // tenths of a microsecond. + + $binary = $this->si2bin($time, 64); // create 64 bit binary string + $timestamp = ""; + for ($i = 0; $i < 8; $i++) { + $timestamp .= chr(bindec(substr($binary, -(($i + 1) * 8), 8))); + } + + return $timestamp; + } + + /** + * Create LMv2 response + * + * @param string $password + * @param string $username + * @param string $domain + * @param string $challenge NTLM Challenge + * @param string $client Random string + * @return string + */ + protected function createLMv2Password($password, $username, $domain, $challenge, $client) + { + $lmPass = '00'; // by default 00 + // if $password > 15 than we can't use this method + if (strlen($password) <= 15) { + $ntlmHash = $this->md4Encrypt($password); + $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username) . $domain)); + + $lmPass = bin2hex($this->md5Encrypt($ntml2Hash, $challenge . $client) . $client); + } + + return $this->createByte($lmPass, 24); + } + + /** + * Create NTLMv2 response + * + * @param string $password + * @param string $username + * @param string $domain + * @param string $challenge Hex values + * @param string $targetInfo Hex values + * @param string $timestamp + * @param string $client Random bytes + * @return string + * @see http://davenport.sourceforge.net/ntlm.html#theNtlmResponse + */ + protected function createNTLMv2Hash($password, $username, $domain, $challenge, $targetInfo, $timestamp, $client) + { + $ntlmHash = $this->md4Encrypt($password); + $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username) . $domain)); + + // create blob + $blob = $this->createBlob($timestamp, $client, $targetInfo); + + $ntlmv2Response = $this->md5Encrypt($ntml2Hash, $challenge . $blob); + + return $ntlmv2Response . $blob; + } + + protected function createDesKey($key) + { + $material = array(bin2hex($key[0])); + $len = strlen($key); + for ($i = 1; $i < $len; $i++) { + list($high, $low) = str_split(bin2hex($key[$i])); + $v = $this->castToByte(ord($key[$i - 1]) << (7 + 1 - $i) | $this->uRShift(hexdec(dechex(hexdec($high) & 0xf) . dechex(hexdec($low) & 0xf)), $i)); + $material[] = str_pad(substr(dechex($v), -2), 2, '0', STR_PAD_LEFT); // cast to byte + } + $material[] = str_pad(substr(dechex($this->castToByte(ord($key[6]) << 1)), -2), 2, '0'); + + // odd parity + foreach ($material as $k => $v) { + $b = $this->castToByte(hexdec($v)); + $needsParity = (($this->uRShift($b, 7) ^ $this->uRShift($b, 6) ^ $this->uRShift($b, 5) + ^ $this->uRShift($b, 4) ^ $this->uRShift($b, 3) ^ $this->uRShift($b, 2) + ^ $this->uRShift($b, 1)) & 0x01) == 0; + + list($high, $low) = str_split($v); + if ($needsParity) { + $material[$k] = dechex(hexdec($high) | 0x0) . dechex(hexdec($low) | 0x1); + } else { + $material[$k] = dechex(hexdec($high) & 0xf) . dechex(hexdec($low) & 0xe); + } + } + + return $this->hex2bin(implode('', $material)); + } + + /** HELPER FUNCTIONS */ + /** + * Create our security buffer depending on length and offset + * + * @param string $value Value we want to put in + * @param int $offset start of value + * @param bool $is16 Do we 16bit string or not? + * @return string + */ + protected function createSecurityBuffer($value, $offset, $is16 = false) + { + $length = strlen(bin2hex($value)); + $length = $is16 ? $length / 2 : $length; + $length = $this->createByte(str_pad(dechex($length), 2, '0', STR_PAD_LEFT), 2); + + return $length . $length . $this->createByte(dechex($offset), 4); + } + + /** + * Read our security buffer to fetch length and offset of our value + * + * @param string $value Securitybuffer in hex + * @return array array with length and offset + */ + protected function readSecurityBuffer($value) + { + $length = floor(hexdec(substr($value, 0, 4)) / 256) * 2; + $offset = floor(hexdec(substr($value, 8, 4)) / 256) * 2; + + return array($length, $offset); + } + + /** + * Cast to byte java equivalent to (byte) + * + * @param int $v + * @return int + */ + protected function castToByte($v) + { + return (($v + 128) % 256) - 128; + } + + /** + * Java unsigned right bitwise + * $a >>> $b + * + * @param int $a + * @param int $b + * @return int + */ + protected function uRShift($a, $b) + { + if ($b == 0) { + return $a; + } + + return ($a >> $b) & ~(1 << (8 * PHP_INT_SIZE - 1) >> ($b - 1)); + } + + /** + * Right padding with 0 to certain length + * + * @param string $input + * @param int $bytes Length of bytes + * @param bool $isHex Did we provided hex value + * @return string + */ + protected function createByte($input, $bytes = 4, $isHex = true) + { + if ($isHex) { + $byte = $this->hex2bin(str_pad($input, $bytes * 2, '00')); + } else { + $byte = str_pad($input, $bytes, "\x00"); + } + + return $byte; + } + + /** + * Create random bytes + * + * @param $length + * @return string + */ + protected function getRandomBytes($length) + { + $bytes = openssl_random_pseudo_bytes($length, $strong); + + if (false !== $bytes && true === $strong) { + return $bytes; + } + + throw new RuntimeException('OpenSSL did not produce a secure random number.'); + } + + /** ENCRYPTION ALGORITHMS */ + /** + * DES Encryption + * + * @param string $value + * @param string $key + * @return string + */ + protected function desEncrypt($value, $key) + { + $cipher = mcrypt_module_open(MCRYPT_DES, '', 'ecb', ''); + mcrypt_generic_init($cipher, $key, mcrypt_create_iv(mcrypt_enc_get_iv_size($cipher), MCRYPT_DEV_RANDOM)); + + return mcrypt_generic($cipher, $value); + } + + /** + * MD5 Encryption + * + * @param string $key Encryption key + * @param string $msg Message to encrypt + * @return string + */ + protected function md5Encrypt($key, $msg) + { + $blocksize = 64; + if (strlen($key) > $blocksize) { + $key = pack('H*', md5($key)); + } + + $key = str_pad($key, $blocksize, "\0"); + $ipadk = $key ^ str_repeat("\x36", $blocksize); + $opadk = $key ^ str_repeat("\x5c", $blocksize); + + return pack('H*', md5($opadk . pack('H*', md5($ipadk . $msg)))); + } + + /** + * MD4 Encryption + * + * @param string $input + * @return string + * @see http://php.net/manual/en/ref.hash.php + */ + protected function md4Encrypt($input) + { + $input = $this->convertTo16bit($input); + + return function_exists('hash') ? $this->hex2bin(hash('md4', $input)) : mhash(MHASH_MD4, $input); + } + + /** + * Convert UTF-8 to UTF-16 + * + * @param string $input + * @return string + */ + protected function convertTo16bit($input) + { + return iconv('UTF-8', 'UTF-16LE', $input); + } + + /** + * Hex2bin replacement for < PHP 5.4 + * @param string $hex + * @return string Binary + */ + protected function hex2bin($hex) + { + if (function_exists('hex2bin')) { + return hex2bin($hex); + } else { + return pack('H*', $hex); + } + } + + /** + * @param string $message + */ + protected function debug($message) + { + $message = bin2hex($message); + $messageId = substr($message, 16, 8); + echo substr($message, 0, 16) . " NTLMSSP Signature
\n"; + echo $messageId . " Type Indicator
\n"; + + if ($messageId == "02000000") { + $map = array( + 'Challenge', + 'Context', + 'Target Information Security Buffer', + 'Target Name Data', + 'NetBIOS Domain Name', + 'NetBIOS Server Name', + 'DNS Domain Name', + 'DNS Server Name', + 'BLOB', + 'Target Information Terminator', + ); + + $data = $this->parseMessage2($this->hex2bin($message)); + + foreach ($map as $key => $value) { + echo bin2hex($data[$key]) . ' - ' . $data[$key] . ' ||| ' . $value . "
\n"; + } + } elseif ($messageId == "03000000") { + $i = 0; + $data[$i++] = substr($message, 24, 16); + list($lmLength, $lmOffset) = $this->readSecurityBuffer($data[$i - 1]); + + $data[$i++] = substr($message, 40, 16); + list($ntmlLength, $ntmlOffset) = $this->readSecurityBuffer($data[$i - 1]); + + $data[$i++] = substr($message, 56, 16); + list($targetLength, $targetOffset) = $this->readSecurityBuffer($data[$i - 1]); + + $data[$i++] = substr($message, 72, 16); + list($userLength, $userOffset) = $this->readSecurityBuffer($data[$i - 1]); + + $data[$i++] = substr($message, 88, 16); + list($workLength, $workOffset) = $this->readSecurityBuffer($data[$i - 1]); + + $data[$i++] = substr($message, 104, 16); + $data[$i++] = substr($message, 120, 8); + $data[$i++] = substr($message, $targetOffset, $targetLength); + $data[$i++] = substr($message, $userOffset, $userLength); + $data[$i++] = substr($message, $workOffset, $workLength); + $data[$i++] = substr($message, $lmOffset, $lmLength); + $data[$i] = substr($message, $ntmlOffset, $ntmlLength); + + $map = array( + 'LM Response Security Buffer', + 'NTLM Response Security Buffer', + 'Target Name Security Buffer', + 'User Name Security Buffer', + 'Workstation Name Security Buffer', + 'Session Key Security Buffer', + 'Flags', + 'Target Name Data', + 'User Name Data', + 'Workstation Name Data', + 'LM Response Data', + 'NTLM Response Data', + ); + + foreach ($map as $key => $value) { + echo $data[$key] . ' - ' . $this->hex2bin($data[$key]) . ' ||| ' . $value . "
\n"; + } + } + + echo "

"; + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php index ca588eaaa..6b5a9db2b 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php @@ -8,47 +8,45 @@ * file that was distributed with this source code. */ - /** * Handles PLAIN authentication. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Transport_Esmtp_Auth_PlainAuthenticator - implements Swift_Transport_Esmtp_Authenticator +class Swift_Transport_Esmtp_Auth_PlainAuthenticator implements Swift_Transport_Esmtp_Authenticator { - - /** - * Get the name of the AUTH mechanism this Authenticator handles. - * @return string - */ - public function getAuthKeyword() - { - return 'PLAIN'; - } - - /** - * Try to authenticate the user with $username and $password. - * @param Swift_Transport_SmtpAgent $agent - * @param string $username - * @param string $password - * @return boolean - */ - public function authenticate(Swift_Transport_SmtpAgent $agent, - $username, $password) - { - try + /** + * Get the name of the AUTH mechanism this Authenticator handles. + * + * @return string + */ + public function getAuthKeyword() { - $message = base64_encode($username . chr(0) . $username . chr(0) . $password); - $agent->executeCommand(sprintf("AUTH PLAIN %s\r\n", $message), array(235)); - return true; + return 'PLAIN'; } - catch (Swift_TransportException $e) + + /** + * Try to authenticate the user with $username and $password. + * + * @param Swift_Transport_SmtpAgent $agent + * @param string $username + * @param string $password + * + * @return bool + */ + public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password) { - $agent->executeCommand("RSET\r\n", array(250)); - return false; + try { + $message = base64_encode($username . chr(0) . $username . chr(0) . $password); + $agent->executeCommand(sprintf("AUTH PLAIN %s\r\n", $message), array(235)); + + return true; + } catch (Swift_TransportException $e) { + $agent->executeCommand("RSET\r\n", array(250)); + + return false; + } } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php new file mode 100644 index 000000000..de19fc1ba --- /dev/null +++ b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php @@ -0,0 +1,71 @@ + + * $transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 587, 'tls') + * ->setAuthMode('XOAUTH2') + * ->setUsername('YOUR_EMAIL_ADDRESS') + * ->setPassword('YOUR_ACCESS_TOKEN'); + * + * + * @package Swift + * @subpackage Transport + * @author xu.li + * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol + */ +class Swift_Transport_Esmtp_Auth_XOAuth2Authenticator implements Swift_Transport_Esmtp_Authenticator +{ + /** + * Get the name of the AUTH mechanism this Authenticator handles. + * + * @return string + */ + public function getAuthKeyword() + { + return 'XOAUTH2'; + } + + /** + * Try to authenticate the user with $email and $token. + * + * @param Swift_Transport_SmtpAgent $agent + * @param string $email + * @param string $token + * + * @return bool + */ + public function authenticate(Swift_Transport_SmtpAgent $agent, $email, $token) + { + try { + $param = $this->constructXOAuth2Params($email, $token); + $agent->executeCommand("AUTH XOAUTH2 " . $param . "\r\n", array(235)); + + return true; + } catch (Swift_TransportException $e) { + $agent->executeCommand("RSET\r\n", array(250)); + + return false; + } + } + + /** + * Construct the auth parameter + * + * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol#the_sasl_xoauth2_mechanism + */ + protected function constructXOAuth2Params($email, $token) + { + return base64_encode("user=$email\1auth=Bearer $token\1\1"); + } +} diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php index 1d98cd6aa..452ab8204 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php @@ -8,252 +8,261 @@ * file that was distributed with this source code. */ - /** * An ESMTP handler for AUTH support. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Transport_Esmtp_AuthHandler implements Swift_Transport_EsmtpHandler { - - /** - * Authenticators available to process the request. - * @var Swift_Transport_Esmtp_Authenticator[] - * @access private - */ - private $_authenticators = array(); - - /** - * The username for authentication. - * @var string - * @access private - */ - private $_username; - - /** - * The password for authentication. - * @var string - * @access private - */ - private $_password; - - /** - * The auth mode for authentication. - * @var string - * @access private - */ - private $_auth_mode; - - /** - * The ESMTP AUTH parameters available. - * @var string[] - * @access private - */ - private $_esmtpParams = array(); - - /** - * Create a new AuthHandler with $authenticators for support. - * @param Swift_Transport_Esmtp_Authenticator[] $authenticators - */ - public function __construct(array $authenticators) - { - $this->setAuthenticators($authenticators); - } - - /** - * Set the Authenticators which can process a login request. - * @param Swift_Transport_Esmtp_Authenticator[] $authenticators - */ - public function setAuthenticators(array $authenticators) - { - $this->_authenticators = $authenticators; - } - - /** - * Get the Authenticators which can process a login request. - * @return Swift_Transport_Esmtp_Authenticator[] - */ - public function getAuthenticators() - { - return $this->_authenticators; - } - - /** - * Set the username to authenticate with. - * @param string $username - */ - public function setUsername($username) - { - $this->_username = $username; - } - - /** - * Get the username to authenticate with. - * @return string - */ - public function getUsername() - { - return $this->_username; - } - - /** - * Set the password to authenticate with. - * @param string $password - */ - public function setPassword($password) - { - $this->_password = $password; - } - - /** - * Get the password to authenticate with. - * @return string - */ - public function getPassword() - { - return $this->_password; - } - - /** - * Set the auth mode to use to authenticate. - * @param string $mode - */ - public function setAuthMode($mode) - { - $this->_auth_mode = $mode; - } - - /** - * Get the auth mode to use to authenticate. - * @return string - */ - public function getAuthMode() - { - return $this->_auth_mode; - } - - /** - * Get the name of the ESMTP extension this handles. - * @return boolean - */ - public function getHandledKeyword() - { - return 'AUTH'; - } - - /** - * Set the parameters which the EHLO greeting indicated. - * @param string[] $parameters - */ - public function setKeywordParams(array $parameters) - { - $this->_esmtpParams = $parameters; - } - - /** - * Runs immediately after a EHLO has been issued. - * @param Swift_Transport_SmtpAgent $agent to read/write - */ - public function afterEhlo(Swift_Transport_SmtpAgent $agent) - { - if ($this->_username) + /** + * Authenticators available to process the request. + * + * @var Swift_Transport_Esmtp_Authenticator[] + */ + private $_authenticators = array(); + + /** + * The username for authentication. + * + * @var string + */ + private $_username; + + /** + * The password for authentication. + * + * @var string + */ + private $_password; + + /** + * The auth mode for authentication. + * + * @var string + */ + private $_auth_mode; + + /** + * The ESMTP AUTH parameters available. + * + * @var string[] + */ + private $_esmtpParams = array(); + + /** + * Create a new AuthHandler with $authenticators for support. + * + * @param Swift_Transport_Esmtp_Authenticator[] $authenticators + */ + public function __construct(array $authenticators) { - $count = 0; - foreach ($this->_getAuthenticatorsForAgent() as $authenticator) - { - if (in_array(strtolower($authenticator->getAuthKeyword()), - array_map('strtolower', $this->_esmtpParams))) - { - $count++; - if ($authenticator->authenticate($agent, $this->_username, $this->_password)) - { - return; - } + $this->setAuthenticators($authenticators); + } + + /** + * Set the Authenticators which can process a login request. + * + * @param Swift_Transport_Esmtp_Authenticator[] $authenticators + */ + public function setAuthenticators(array $authenticators) + { + $this->_authenticators = $authenticators; + } + + /** + * Get the Authenticators which can process a login request. + * + * @return Swift_Transport_Esmtp_Authenticator[] + */ + public function getAuthenticators() + { + return $this->_authenticators; + } + + /** + * Set the username to authenticate with. + * + * @param string $username + */ + public function setUsername($username) + { + $this->_username = $username; + } + + /** + * Get the username to authenticate with. + * + * @return string + */ + public function getUsername() + { + return $this->_username; + } + + /** + * Set the password to authenticate with. + * + * @param string $password + */ + public function setPassword($password) + { + $this->_password = $password; + } + + /** + * Get the password to authenticate with. + * + * @return string + */ + public function getPassword() + { + return $this->_password; + } + + /** + * Set the auth mode to use to authenticate. + * + * @param string $mode + */ + public function setAuthMode($mode) + { + $this->_auth_mode = $mode; + } + + /** + * Get the auth mode to use to authenticate. + * + * @return string + */ + public function getAuthMode() + { + return $this->_auth_mode; + } + + /** + * Get the name of the ESMTP extension this handles. + * + * @return bool + */ + public function getHandledKeyword() + { + return 'AUTH'; + } + + /** + * Set the parameters which the EHLO greeting indicated. + * + * @param string[] $parameters + */ + public function setKeywordParams(array $parameters) + { + $this->_esmtpParams = $parameters; + } + + /** + * Runs immediately after a EHLO has been issued. + * + * @param Swift_Transport_SmtpAgent $agent to read/write + */ + public function afterEhlo(Swift_Transport_SmtpAgent $agent) + { + if ($this->_username) { + $count = 0; + foreach ($this->_getAuthenticatorsForAgent() as $authenticator) { + if (in_array(strtolower($authenticator->getAuthKeyword()), + array_map('strtolower', $this->_esmtpParams))) + { + $count++; + if ($authenticator->authenticate($agent, $this->_username, $this->_password)) { + return; + } + } + } + throw new Swift_TransportException( + 'Failed to authenticate on SMTP server with username "' . + $this->_username . '" using ' . $count . ' possible authenticators' + ); } - } - throw new Swift_TransportException( - 'Failed to authenticate on SMTP server with username "' . - $this->_username . '" using ' . $count . ' possible authenticators' - ); - } - } - - /** - * Not used. - */ - public function getMailParams() - { - return array(); - } - - /** - * Not used. - */ - public function getRcptParams() - { - return array(); - } - - /** - * Not used. - */ - public function onCommand(Swift_Transport_SmtpAgent $agent, - $command, $codes = array(), &$failedRecipients = null, &$stop = false) - { - } - - /** - * Returns +1, -1 or 0 according to the rules for usort(). - * This method is called to ensure extensions can be execute in an appropriate order. - * @param string $esmtpKeyword to compare with - * @return int - */ - public function getPriorityOver($esmtpKeyword) - { - return 0; - } - - /** - * Returns an array of method names which are exposed to the Esmtp class. - * @return string[] - */ - public function exposeMixinMethods() - { - return array('setUsername', 'getUsername', 'setPassword', 'getPassword', 'setAuthMode', 'getAuthMode'); - } - - /** - * Not used. - */ - public function resetState() - { - } - - // -- Protected methods - - /** - * Returns the authenticator list for the given agent. - * @param Swift_Transport_SmtpAgent $agent - * @return array - * @access protected - */ - protected function _getAuthenticatorsForAgent() - { - if (!$mode = strtolower($this->_auth_mode)) - { - return $this->_authenticators; } - foreach ($this->_authenticators as $authenticator) + /** + * Not used. + */ + public function getMailParams() { - if (strtolower($authenticator->getAuthKeyword()) == $mode) - { - return array($authenticator); - } + return array(); } - throw new Swift_TransportException('Auth mode '.$mode.' is invalid'); - } + /** + * Not used. + */ + public function getRcptParams() + { + return array(); + } + + /** + * Not used. + */ + public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = array(), &$failedRecipients = null, &$stop = false) + { + } + + /** + * Returns +1, -1 or 0 according to the rules for usort(). + * + * This method is called to ensure extensions can be execute in an appropriate order. + * + * @param string $esmtpKeyword to compare with + * + * @return int + */ + public function getPriorityOver($esmtpKeyword) + { + return 0; + } + + /** + * Returns an array of method names which are exposed to the Esmtp class. + * + * @return string[] + */ + public function exposeMixinMethods() + { + return array('setUsername', 'getUsername', 'setPassword', 'getPassword', 'setAuthMode', 'getAuthMode'); + } + + /** + * Not used. + */ + public function resetState() + { + } + + // -- Protected methods + + /** + * Returns the authenticator list for the given agent. + * + * @param Swift_Transport_SmtpAgent $agent + * + * @return array + */ + protected function _getAuthenticatorsForAgent() + { + if (!$mode = strtolower($this->_auth_mode)) { + return $this->_authenticators; + } + + foreach ($this->_authenticators as $authenticator) { + if (strtolower($authenticator->getAuthKeyword()) == $mode) { + return array($authenticator); + } + } + + throw new Swift_TransportException('Auth mode '.$mode.' is invalid'); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php index 4af223eea..c1d4a0470 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php @@ -8,30 +8,30 @@ * file that was distributed with this source code. */ - /** * An Authentication mechanism. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Transport_Esmtp_Authenticator { - - /** - * Get the name of the AUTH mechanism this Authenticator handles. - * @return string - */ - public function getAuthKeyword(); - - /** - * Try to authenticate the user with $username and $password. - * @param Swift_Transport_SmtpAgent $agent - * @param string $username - * @param string $password - * @return boolean - */ - public function authenticate(Swift_Transport_SmtpAgent $agent, - $username, $password); - + /** + * Get the name of the AUTH mechanism this Authenticator handles. + * + * @return string + */ + public function getAuthKeyword(); + + /** + * Try to authenticate the user with $username and $password. + * + * @param Swift_Transport_SmtpAgent $agent + * @param string $username + * @param string $password + * + * @return bool + */ + public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password); } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php b/lib/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php index a09ae1966..83fb71b1e 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php @@ -8,74 +8,81 @@ * file that was distributed with this source code. */ - /** * An ESMTP handler. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Transport_EsmtpHandler { - - /** - * Get the name of the ESMTP extension this handles. - * @return boolean - */ - public function getHandledKeyword(); - - /** - * Set the parameters which the EHLO greeting indicated. - * @param string[] $parameters - */ - public function setKeywordParams(array $parameters); - - /** - * Runs immediately after a EHLO has been issued. - * @param Swift_Transport_SmtpAgent $agent to read/write - */ - public function afterEhlo(Swift_Transport_SmtpAgent $agent); - - /** - * Get params which are appended to MAIL FROM:<>. - * @return string[] - */ - public function getMailParams(); - - /** - * Get params which are appended to RCPT TO:<>. - * @return string[] - */ - public function getRcptParams(); - - /** - * Runs when a command is due to be sent. - * @param Swift_Transport_SmtpAgent $agent to read/write - * @param string $command to send - * @param int[] $codes expected in response - * @param string[] &$failedRecipients - * @param boolean &$stop to be set true if the command is now sent - */ - public function onCommand(Swift_Transport_SmtpAgent $agent, - $command, $codes = array(), &$failedRecipients = null, &$stop = false); - - /** - * Returns +1, -1 or 0 according to the rules for usort(). - * This method is called to ensure extensions can be execute in an appropriate order. - * @param string $esmtpKeyword to compare with - * @return int - */ - public function getPriorityOver($esmtpKeyword); - - /** - * Returns an array of method names which are exposed to the Esmtp class. - * @return string[] - */ - public function exposeMixinMethods(); - - /** - * Tells this handler to clear any buffers and reset its state. - */ - public function resetState(); - + /** + * Get the name of the ESMTP extension this handles. + * + * @return bool + */ + public function getHandledKeyword(); + + /** + * Set the parameters which the EHLO greeting indicated. + * + * @param string[] $parameters + */ + public function setKeywordParams(array $parameters); + + /** + * Runs immediately after a EHLO has been issued. + * + * @param Swift_Transport_SmtpAgent $agent to read/write + */ + public function afterEhlo(Swift_Transport_SmtpAgent $agent); + + /** + * Get params which are appended to MAIL FROM:<>. + * + * @return string[] + */ + public function getMailParams(); + + /** + * Get params which are appended to RCPT TO:<>. + * + * @return string[] + */ + public function getRcptParams(); + + /** + * Runs when a command is due to be sent. + * + * @param Swift_Transport_SmtpAgent $agent to read/write + * @param string $command to send + * @param int[] $codes expected in response + * @param string[] $failedRecipients to collect failures + * @param bool $stop to be set true by-reference if the command is now sent + */ + public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = array(), &$failedRecipients = null, &$stop = false); + + /** + * Returns +1, -1 or 0 according to the rules for usort(). + * + * This method is called to ensure extensions can be execute in an appropriate order. + * + * @param string $esmtpKeyword to compare with + * + * @return int + */ + public function getPriorityOver($esmtpKeyword); + + /** + * Returns an array of method names which are exposed to the Esmtp class. + * + * @return string[] + */ + public function exposeMixinMethods(); + + /** + * Tells this handler to clear any buffers and reset its state. + */ + public function resetState(); } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php b/lib/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php index 9eed84c9f..6ad5b098a 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php @@ -8,346 +8,386 @@ * file that was distributed with this source code. */ - /** * Sends Messages over SMTP with ESMTP support. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Transport_EsmtpTransport - extends Swift_Transport_AbstractSmtpTransport - implements Swift_Transport_SmtpAgent +class Swift_Transport_EsmtpTransport extends Swift_Transport_AbstractSmtpTransport implements Swift_Transport_SmtpAgent { - - /** - * ESMTP extension handlers. - * @var Swift_Transport_EsmtpHandler[] - * @access private - */ - private $_handlers = array(); - - /** - * ESMTP capabilities. - * @var string[] - * @access private - */ - private $_capabilities = array(); - - /** - * Connection buffer parameters. - * @var array - * @access protected - */ - private $_params = array( - 'protocol' => 'tcp', - 'host' => 'localhost', - 'port' => 25, - 'timeout' => 30, - 'blocking' => 1, - 'type' => Swift_Transport_IoBuffer::TYPE_SOCKET - ); - - /** - * Creates a new EsmtpTransport using the given I/O buffer. - * @param Swift_Transport_IoBuffer $buf - * @param Swift_Transport_EsmtpHandler[] $extensionHandlers - * @param Swift_Events_EventDispatcher $dispatcher - */ - public function __construct(Swift_Transport_IoBuffer $buf, - array $extensionHandlers, Swift_Events_EventDispatcher $dispatcher) - { - parent::__construct($buf, $dispatcher); - $this->setExtensionHandlers($extensionHandlers); - } - - /** - * Set the host to connect to. - * @param string $host - */ - public function setHost($host) - { - $this->_params['host'] = $host; - return $this; - } - - /** - * Get the host to connect to. - * @return string - */ - public function getHost() - { - return $this->_params['host']; - } - - /** - * Set the port to connect to. - * @param int $port - */ - public function setPort($port) - { - $this->_params['port'] = (int) $port; - return $this; - } - - /** - * Get the port to connect to. - * @return int - */ - public function getPort() - { - return $this->_params['port']; - } - - /** - * Set the connection timeout. - * @param int $timeout seconds - */ - public function setTimeout($timeout) - { - $this->_params['timeout'] = (int) $timeout; - $this->_buffer->setParam('timeout', (int) $timeout); - return $this; - } - - /** - * Get the connection timeout. - * @return int - */ - public function getTimeout() - { - return $this->_params['timeout']; - } - - /** - * Set the encryption type (tls or ssl) - * @param string $encryption - */ - public function setEncryption($enc) - { - $this->_params['protocol'] = $enc; - return $this; - } - - /** - * Get the encryption type. - * @return string - */ - public function getEncryption() - { - return $this->_params['protocol']; - } - - /** - * Sets the sourceIp - * @param string $source - */ - public function setSourceIp($source) - { - $this->_params['sourceIp']=$source; - return $this; - } + /** + * ESMTP extension handlers. + * + * @var Swift_Transport_EsmtpHandler[] + */ + private $_handlers = array(); - /** - * Returns the ip used to connect to the destination - * @return string - */ - public function getSourceIp() - { - return $this->_params['sourceIp']; - } - - /** - * Set ESMTP extension handlers. - * @param Swift_Transport_EsmtpHandler[] $handlers - */ - public function setExtensionHandlers(array $handlers) - { - $assoc = array(); - foreach ($handlers as $handler) - { - $assoc[$handler->getHandledKeyword()] = $handler; - } - uasort($assoc, array($this, '_sortHandlers')); - $this->_handlers = $assoc; - $this->_setHandlerParams(); - return $this; - } - - /** - * Get ESMTP extension handlers. - * @return Swift_Transport_EsmtpHandler[] - */ - public function getExtensionHandlers() - { - return array_values($this->_handlers); - } - - /** - * Run a command against the buffer, expecting the given response codes. - * If no response codes are given, the response will not be validated. - * If codes are given, an exception will be thrown on an invalid response. - * @param string $command - * @param int[] $codes - * @param string[] &$failures - * @return string - */ - public function executeCommand($command, $codes = array(), &$failures = null) - { - $failures = (array) $failures; - $stopSignal = false; - $response = null; - foreach ($this->_getActiveHandlers() as $handler) - { - $response = $handler->onCommand( - $this, $command, $codes, $failures, $stopSignal + /** + * ESMTP capabilities. + * + * @var string[] + */ + private $_capabilities = array(); + + /** + * Connection buffer parameters. + * + * @var array + */ + private $_params = array( + 'protocol' => 'tcp', + 'host' => 'localhost', + 'port' => 25, + 'timeout' => 30, + 'blocking' => 1, + 'tls' => false, + 'type' => Swift_Transport_IoBuffer::TYPE_SOCKET ); - if ($stopSignal) - { - return $response; - } - } - return parent::executeCommand($command, $codes, $failures); - } - - // -- Mixin invocation code - - /** Mixin handling method for ESMTP handlers */ - public function __call($method, $args) - { - foreach ($this->_handlers as $handler) + + /** + * Creates a new EsmtpTransport using the given I/O buffer. + * + * @param Swift_Transport_IoBuffer $buf + * @param Swift_Transport_EsmtpHandler[] $extensionHandlers + * @param Swift_Events_EventDispatcher $dispatcher + */ + public function __construct(Swift_Transport_IoBuffer $buf, array $extensionHandlers, Swift_Events_EventDispatcher $dispatcher) { - if (in_array(strtolower($method), - array_map('strtolower', (array) $handler->exposeMixinMethods()) - )) - { - $return = call_user_func_array(array($handler, $method), $args); - //Allow fluid method calls - if (is_null($return) && substr($method, 0, 3) == 'set') - { - return $this; - } - else - { - return $return; - } - } - } - trigger_error('Call to undefined method ' . $method, E_USER_ERROR); - } - - // -- Protected methods - - /** Get the params to initialize the buffer */ - protected function _getBufferParams() - { - return $this->_params; - } - - /** Overridden to perform EHLO instead */ - protected function _doHeloCommand() - { - try - { - $response = $this->executeCommand( - sprintf("EHLO %s\r\n", $this->_domain), array(250) - ); - } - catch (Swift_TransportException $e) - { - return parent::_doHeloCommand(); + parent::__construct($buf, $dispatcher); + $this->setExtensionHandlers($extensionHandlers); } - $this->_capabilities = $this->_getCapabilities($response); - $this->_setHandlerParams(); - foreach ($this->_getActiveHandlers() as $handler) + /** + * Set the host to connect to. + * + * @param string $host + * + * @return Swift_Transport_EsmtpTransport + */ + public function setHost($host) { - $handler->afterEhlo($this); + $this->_params['host'] = $host; + + return $this; } - } - - /** Overridden to add Extension support */ - protected function _doMailFromCommand($address) - { - $handlers = $this->_getActiveHandlers(); - $params = array(); - foreach ($handlers as $handler) + + /** + * Get the host to connect to. + * + * @return string + */ + public function getHost() { - $params = array_merge($params, (array) $handler->getMailParams()); + return $this->_params['host']; } - $paramStr = !empty($params) ? ' ' . implode(' ', $params) : ''; - $this->executeCommand( - sprintf("MAIL FROM: <%s>%s\r\n", $address, $paramStr), array(250) - ); - } - - /** Overridden to add Extension support */ - protected function _doRcptToCommand($address) - { - $handlers = $this->_getActiveHandlers(); - $params = array(); - foreach ($handlers as $handler) + + /** + * Set the port to connect to. + * + * @param int $port + * + * @return Swift_Transport_EsmtpTransport + */ + public function setPort($port) { - $params = array_merge($params, (array) $handler->getRcptParams()); + $this->_params['port'] = (int) $port; + + return $this; } - $paramStr = !empty($params) ? ' ' . implode(' ', $params) : ''; - $this->executeCommand( - sprintf("RCPT TO: <%s>%s\r\n", $address, $paramStr), array(250, 251, 252) - ); - } - - // -- Private methods - - /** Determine ESMTP capabilities by function group */ - private function _getCapabilities($ehloResponse) - { - $capabilities = array(); - $ehloResponse = trim($ehloResponse); - $lines = explode("\r\n", $ehloResponse); - array_shift($lines); - foreach ($lines as $line) + + /** + * Get the port to connect to. + * + * @return int + */ + public function getPort() { - if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) - { - $keyword = strtoupper($matches[1]); - $paramStr = strtoupper(ltrim($matches[2], ' =')); - $params = !empty($paramStr) ? explode(' ', $paramStr) : array(); - $capabilities[$keyword] = $params; - } + return $this->_params['port']; } - return $capabilities; - } - - /** Set parameters which are used by each extension handler */ - private function _setHandlerParams() - { - foreach ($this->_handlers as $keyword => $handler) + + /** + * Set the connection timeout. + * + * @param int $timeout seconds + * + * @return Swift_Transport_EsmtpTransport + */ + public function setTimeout($timeout) { - if (array_key_exists($keyword, $this->_capabilities)) - { - $handler->setKeywordParams($this->_capabilities[$keyword]); - } + $this->_params['timeout'] = (int) $timeout; + $this->_buffer->setParam('timeout', (int) $timeout); + + return $this; } - } - - /** Get ESMTP handlers which are currently ok to use */ - private function _getActiveHandlers() - { - $handlers = array(); - foreach ($this->_handlers as $keyword => $handler) + + /** + * Get the connection timeout. + * + * @return int + */ + public function getTimeout() { - if (array_key_exists($keyword, $this->_capabilities)) - { - $handlers[] = $handler; - } + return $this->_params['timeout']; + } + + /** + * Set the encryption type (tls or ssl) + * + * @param string $encryption + * + * @return Swift_Transport_EsmtpTransport + */ + public function setEncryption($encryption) + { + if ('tls' == $encryption) { + $this->_params['protocol'] = 'tcp'; + $this->_params['tls'] = true; + } else { + $this->_params['protocol'] = $encryption; + $this->_params['tls'] = false; + } + + return $this; + } + + /** + * Get the encryption type. + * + * @return string + */ + public function getEncryption() + { + return $this->_params['tls'] ? 'tls' : $this->_params['protocol']; + } + + /** + * Sets the source IP. + * + * @param string $source + * + * @return Swift_Transport_EsmtpTransport + */ + public function setSourceIp($source) + { + $this->_params['sourceIp']=$source; + + return $this; + } + + /** + * Returns the IP used to connect to the destination. + * + * @return string + */ + public function getSourceIp() + { + return $this->_params['sourceIp']; + } + + /** + * Set ESMTP extension handlers. + * + * @param Swift_Transport_EsmtpHandler[] $handlers + * + * @return Swift_Transport_EsmtpTransport + */ + public function setExtensionHandlers(array $handlers) + { + $assoc = array(); + foreach ($handlers as $handler) { + $assoc[$handler->getHandledKeyword()] = $handler; + } + uasort($assoc, array($this, '_sortHandlers')); + $this->_handlers = $assoc; + $this->_setHandlerParams(); + + return $this; + } + + /** + * Get ESMTP extension handlers. + * + * @return Swift_Transport_EsmtpHandler[] + */ + public function getExtensionHandlers() + { + return array_values($this->_handlers); + } + + /** + * Run a command against the buffer, expecting the given response codes. + * + * If no response codes are given, the response will not be validated. + * If codes are given, an exception will be thrown on an invalid response. + * + * @param string $command + * @param int[] $codes + * @param string[] $failures An array of failures by-reference + * + * @return string + */ + public function executeCommand($command, $codes = array(), &$failures = null) + { + $failures = (array) $failures; + $stopSignal = false; + $response = null; + foreach ($this->_getActiveHandlers() as $handler) { + $response = $handler->onCommand( + $this, $command, $codes, $failures, $stopSignal + ); + if ($stopSignal) { + return $response; + } + } + + return parent::executeCommand($command, $codes, $failures); + } + + // -- Mixin invocation code + + /** Mixin handling method for ESMTP handlers */ + public function __call($method, $args) + { + foreach ($this->_handlers as $handler) { + if (in_array(strtolower($method), + array_map('strtolower', (array) $handler->exposeMixinMethods()) + )) + { + $return = call_user_func_array(array($handler, $method), $args); + // Allow fluid method calls + if (is_null($return) && substr($method, 0, 3) == 'set') { + return $this; + } else { + return $return; + } + } + } + trigger_error('Call to undefined method ' . $method, E_USER_ERROR); + } + + // -- Protected methods + + /** Get the params to initialize the buffer */ + protected function _getBufferParams() + { + return $this->_params; + } + + /** Overridden to perform EHLO instead */ + protected function _doHeloCommand() + { + try { + $response = $this->executeCommand( + sprintf("EHLO %s\r\n", $this->_domain), array(250) + ); + } catch (Swift_TransportException $e) { + return parent::_doHeloCommand(); + } + + if ($this->_params['tls']) { + try { + $this->executeCommand("STARTTLS\r\n", array(220)); + + if (!$this->_buffer->startTLS()) { + throw new Swift_TransportException('Unable to connect with TLS encryption'); + } + + try { + $response = $this->executeCommand( + sprintf("EHLO %s\r\n", $this->_domain), array(250) + ); + } catch (Swift_TransportException $e) { + return parent::_doHeloCommand(); + } + } catch (Swift_TransportException $e) { + $this->_throwException($e); + } + } + + $this->_capabilities = $this->_getCapabilities($response); + $this->_setHandlerParams(); + foreach ($this->_getActiveHandlers() as $handler) { + $handler->afterEhlo($this); + } + } + + /** Overridden to add Extension support */ + protected function _doMailFromCommand($address) + { + $handlers = $this->_getActiveHandlers(); + $params = array(); + foreach ($handlers as $handler) { + $params = array_merge($params, (array) $handler->getMailParams()); + } + $paramStr = !empty($params) ? ' ' . implode(' ', $params) : ''; + $this->executeCommand( + sprintf("MAIL FROM: <%s>%s\r\n", $address, $paramStr), array(250) + ); + } + + /** Overridden to add Extension support */ + protected function _doRcptToCommand($address) + { + $handlers = $this->_getActiveHandlers(); + $params = array(); + foreach ($handlers as $handler) { + $params = array_merge($params, (array) $handler->getRcptParams()); + } + $paramStr = !empty($params) ? ' ' . implode(' ', $params) : ''; + $this->executeCommand( + sprintf("RCPT TO: <%s>%s\r\n", $address, $paramStr), array(250, 251, 252) + ); + } + + // -- Private methods + + /** Determine ESMTP capabilities by function group */ + private function _getCapabilities($ehloResponse) + { + $capabilities = array(); + $ehloResponse = trim($ehloResponse); + $lines = explode("\r\n", $ehloResponse); + array_shift($lines); + foreach ($lines as $line) { + if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) { + $keyword = strtoupper($matches[1]); + $paramStr = strtoupper(ltrim($matches[2], ' =')); + $params = !empty($paramStr) ? explode(' ', $paramStr) : array(); + $capabilities[$keyword] = $params; + } + } + + return $capabilities; + } + + /** Set parameters which are used by each extension handler */ + private function _setHandlerParams() + { + foreach ($this->_handlers as $keyword => $handler) { + if (array_key_exists($keyword, $this->_capabilities)) { + $handler->setKeywordParams($this->_capabilities[$keyword]); + } + } + } + + /** Get ESMTP handlers which are currently ok to use */ + private function _getActiveHandlers() + { + $handlers = array(); + foreach ($this->_handlers as $keyword => $handler) { + if (array_key_exists($keyword, $this->_capabilities)) { + $handlers[] = $handler; + } + } + + return $handlers; + } + + /** Custom sort for extension handler ordering */ + private function _sortHandlers($a, $b) + { + return $a->getPriorityOver($b->getHandledKeyword()); } - return $handlers; - } - - /** Custom sort for extension handler ordering */ - private function _sortHandlers($a, $b) - { - return $a->getPriorityOver($b->getHandledKeyword()); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php b/lib/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php index 62bc80bdc..d0d3f69be 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php @@ -8,88 +8,83 @@ * file that was distributed with this source code. */ - /** * Contains a list of redundant Transports so when one fails, the next is used. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Transport_FailoverTransport - extends Swift_Transport_LoadBalancedTransport +class Swift_Transport_FailoverTransport extends Swift_Transport_LoadBalancedTransport { - - /** - * Registered transport curently used. - * @var Swift_Transport - * @access private - */ - private $_currentTransport; - - /** - * Creates a new FailoverTransport. - */ - public function __construct() - { - parent::__construct(); - } - - /** - * Send the given Message. - * Recipient/sender data will be retreived from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * @param Swift_Mime_Message $message - * @param string[] &$failedRecipients to collect failures by-reference - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $maxTransports = count($this->_transports); - $sent = 0; - - for ($i = 0; $i < $maxTransports - && $transport = $this->_getNextTransport(); ++$i) + /** + * Registered transport currently used. + * + * @var Swift_Transport + */ + private $_currentTransport; + + /** + * Creates a new FailoverTransport. + */ + public function __construct() { - try - { - if (!$transport->isStarted()) + parent::__construct(); + } + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * + * @param Swift_Mime_Message $message + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $maxTransports = count($this->_transports); + $sent = 0; + + for ($i = 0; $i < $maxTransports + && $transport = $this->_getNextTransport(); ++$i) { - $transport->start(); + try { + if (!$transport->isStarted()) { + $transport->start(); + } + + return $transport->send($message, $failedRecipients); + } catch (Swift_TransportException $e) { + $this->_killCurrentTransport(); + } } - - return $transport->send($message, $failedRecipients); - } - catch (Swift_TransportException $e) - { - $this->_killCurrentTransport(); - } + + if (count($this->_transports) == 0) { + throw new Swift_TransportException( + 'All Transports in FailoverTransport failed, or no Transports available' + ); + } + + return $sent; } - - if (count($this->_transports) == 0) + + // -- Protected methods + + protected function _getNextTransport() { - throw new Swift_TransportException( - 'All Transports in FailoverTransport failed, or no Transports available' - ); + if (!isset($this->_currentTransport)) { + $this->_currentTransport = parent::_getNextTransport(); + } + + return $this->_currentTransport; } - - return $sent; - } - - // -- Protected methods - - protected function _getNextTransport() - { - if (!isset($this->_currentTransport)) + + protected function _killCurrentTransport() { - $this->_currentTransport = parent::_getNextTransport(); + $this->_currentTransport = null; + parent::_killCurrentTransport(); } - return $this->_currentTransport; - } - - protected function _killCurrentTransport() - { - $this->_currentTransport = null; - parent::_killCurrentTransport(); - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php b/lib/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php index 9a46cd91e..835895118 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php @@ -8,56 +8,62 @@ * file that was distributed with this source code. */ - /** * Buffers input and output to a resource. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -interface Swift_Transport_IoBuffer - extends Swift_InputByteStream, Swift_OutputByteStream +interface Swift_Transport_IoBuffer extends Swift_InputByteStream, Swift_OutputByteStream { - - /** A socket buffer over TCP */ - const TYPE_SOCKET = 0x0001; - - /** A process buffer with I/O support */ - const TYPE_PROCESS = 0x0010; - - /** - * Perform any initialization needed, using the given $params. - * Parameters will vary depending upon the type of IoBuffer used. - * @param array $params - */ - public function initialize(array $params); - - /** - * Set an individual param on the buffer (e.g. switching to SSL). - * @param string $param - * @param mixed $value - */ - public function setParam($param, $value); - - /** - * Perform any shutdown logic needed. - */ - public function terminate(); - - /** - * Set an array of string replacements which should be made on data written - * to the buffer. This could replace LF with CRLF for example. - * @param string[] $replacements - */ - public function setWriteTranslations(array $replacements); - - /** - * Get a line of output (including any CRLF). - * The $sequence number comes from any writes and may or may not be used - * depending upon the implementation. - * @param int $sequence of last write to scan from - * @return string - */ - public function readLine($sequence); - + /** A socket buffer over TCP */ + const TYPE_SOCKET = 0x0001; + + /** A process buffer with I/O support */ + const TYPE_PROCESS = 0x0010; + + /** + * Perform any initialization needed, using the given $params. + * + * Parameters will vary depending upon the type of IoBuffer used. + * + * @param array $params + */ + public function initialize(array $params); + + /** + * Set an individual param on the buffer (e.g. switching to SSL). + * + * @param string $param + * @param mixed $value + */ + public function setParam($param, $value); + + /** + * Perform any shutdown logic needed. + */ + public function terminate(); + + /** + * Set an array of string replacements which should be made on data written + * to the buffer. + * + * This could replace LF with CRLF for example. + * + * @param string[] $replacements + */ + public function setWriteTranslations(array $replacements); + + /** + * Get a line of output (including any CRLF). + * + * The $sequence number comes from any writes and may or may not be used + * depending upon the implementation. + * + * @param int $sequence of last write to scan from + * + * @return string + */ + public function readLine($sequence); } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php b/lib/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php index 05a51c398..7a82632d9 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php @@ -8,178 +8,164 @@ * file that was distributed with this source code. */ - /** - * Redudantly and rotationally uses several Transports when sending. - * - * @package Swift + * Redundantly and rotationally uses several Transports when sending. + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Transport_LoadBalancedTransport implements Swift_Transport { - - /** Transports which are deemed useless */ - private $_deadTransports = array(); - - /** - * The Transports which are used in rotation. - * - * @var array Swift_Transport - * @access protected - */ - protected $_transports = array(); - - /** - * Creates a new LoadBalancedTransport. - */ - public function __construct() - { - } - - /** - * Set $transports to delegate to. - * - * @param array $transports Swift_Transport - */ - public function setTransports(array $transports) - { - $this->_transports = $transports; - $this->_deadTransports = array(); - } - - /** - * Get $transports to delegate to. - * - * @return array Swift_Transport - */ - public function getTransports(array $transports) - { - return array_merge($this->_transports, $this->_deadTransports); - } - - /** - * Test if this Transport mechanism has started. - * - * @return boolean - */ - public function isStarted() - { - return count($this->_transports) > 0; - } - - /** - * Start this Transport mechanism. - */ - public function start() - { - $this->_transports = array_merge($this->_transports, $this->_deadTransports); - } - - /** - * Stop this Transport mechanism. - */ - public function stop() - { - foreach ($this->_transports as $transport) + /** + * Transports which are deemed useless. + * + * @var Swift_Transport[] + */ + private $_deadTransports = array(); + + /** + * The Transports which are used in rotation. + * + * @var Swift_Transport[] + */ + protected $_transports = array(); + + /** + * Creates a new LoadBalancedTransport. + */ + public function __construct() { - $transport->stop(); } - } - - /** - * Send the given Message. - * - * Recipient/sender data will be retreived from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * - * @param Swift_Mime_Message $message - * @param string[] &$failedRecipients to collect failures by-reference - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $maxTransports = count($this->_transports); - $sent = 0; - - for ($i = 0; $i < $maxTransports - && $transport = $this->_getNextTransport(); ++$i) + + /** + * Set $transports to delegate to. + * + * @param Swift_Transport[] $transports + */ + public function setTransports(array $transports) { - try - { - if (!$transport->isStarted()) - { - $transport->start(); + $this->_transports = $transports; + $this->_deadTransports = array(); + } + + /** + * Get $transports to delegate to. + * + * @return Swift_Transport[] + */ + public function getTransports() + { + return array_merge($this->_transports, $this->_deadTransports); + } + + /** + * Test if this Transport mechanism has started. + * + * @return bool + */ + public function isStarted() + { + return count($this->_transports) > 0; + } + + /** + * Start this Transport mechanism. + */ + public function start() + { + $this->_transports = array_merge($this->_transports, $this->_deadTransports); + } + + /** + * Stop this Transport mechanism. + */ + public function stop() + { + foreach ($this->_transports as $transport) { + $transport->stop(); } - if ($sent = $transport->send($message, $failedRecipients)) + } + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * + * @param Swift_Mime_Message $message + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $maxTransports = count($this->_transports); + $sent = 0; + + for ($i = 0; $i < $maxTransports + && $transport = $this->_getNextTransport(); ++$i) { - break; + try { + if (!$transport->isStarted()) { + $transport->start(); + } + if ($sent = $transport->send($message, $failedRecipients)) { + break; + } + } catch (Swift_TransportException $e) { + $this->_killCurrentTransport(); + } } - } - catch (Swift_TransportException $e) - { - $this->_killCurrentTransport(); - } + + if (count($this->_transports) == 0) { + throw new Swift_TransportException( + 'All Transports in LoadBalancedTransport failed, or no Transports available' + ); + } + + return $sent; } - - if (count($this->_transports) == 0) + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) { - throw new Swift_TransportException( - 'All Transports in LoadBalancedTransport failed, or no Transports available' - ); + foreach ($this->_transports as $transport) { + $transport->registerPlugin($plugin); + } } - - return $sent; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - foreach ($this->_transports as $transport) + + // -- Protected methods + + /** + * Rotates the transport list around and returns the first instance. + * + * @return Swift_Transport + */ + protected function _getNextTransport() { - $transport->registerPlugin($plugin); + if ($next = array_shift($this->_transports)) { + $this->_transports[] = $next; + } + + return $next; } - } - - // -- Protected methods - - /** - * Rotates the transport list around and returns the first instance. - * - * @return Swift_Transport - * @access protected - */ - protected function _getNextTransport() - { - if ($next = array_shift($this->_transports)) + + /** + * Tag the currently used (top of stack) transport as dead/useless. + */ + protected function _killCurrentTransport() { - $this->_transports[] = $next; + if ($transport = array_pop($this->_transports)) { + try { + $transport->stop(); + } catch (Exception $e) { + } + $this->_deadTransports[] = $transport; + } } - return $next; - } - - /** - * Tag the currently used (top of stack) transport as dead/useless. - * - * @access protected - */ - protected function _killCurrentTransport() - { - if ($transport = array_pop($this->_transports)) - { - try - { - $transport->stop(); - } - catch (Exception $e) - { - } - $this->_deadTransports[] = $transport; - } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php b/lib/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php index dda882fd1..9103f7943 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php @@ -10,27 +10,25 @@ /** * This interface intercepts calls to the mail() function. - * - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Transport_MailInvoker { - - /** - * Send mail via the mail() function. - * - * This method takes the same arguments as PHP mail(). - * - * @param string $to - * @param string $subject - * @param string $body - * @param string $headers - * @param string $extraParams - * - * @return boolean - */ - public function mail($to, $subject, $body, $headers = null, $extraParams = null); - + /** + * Send mail via the mail() function. + * + * This method takes the same arguments as PHP mail(). + * + * @param string $to + * @param string $subject + * @param string $body + * @param string $headers + * @param string $extraParams + * + * @return bool + */ + public function mail($to, $subject, $body, $headers = null, $extraParams = null); } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/MailTransport.php b/lib/swiftmailer/lib/classes/Swift/Transport/MailTransport.php index 4e8f28b79..0a0ed27be 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/MailTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/MailTransport.php @@ -8,234 +8,224 @@ * file that was distributed with this source code. */ - /** * Sends Messages using the mail() function. - * + * * It is advised that users do not use this transport if at all possible * since a number of plugin features cannot be used in conjunction with this * transport due to the internal interface in PHP itself. - * + * * The level of error reporting with this transport is incredibly weak, again * due to limitations of PHP's internal mail() function. You'll get an * all-or-nothing result from sending. - * - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Transport_MailTransport implements Swift_Transport { + /** Additional parameters to pass to mail() */ + private $_extraParams = '-f%s'; - /** Addtional parameters to pass to mail() */ - private $_extraParams = '-f%s'; - - /** The event dispatcher from the plugin API */ - private $_eventDispatcher; - - /** An invoker that calls the mail() function */ - private $_invoker; - - /** - * Create a new MailTransport with the $log. - * @param Swift_Transport_Log $log - */ - public function __construct(Swift_Transport_MailInvoker $invoker, - Swift_Events_EventDispatcher $eventDispatcher) - { - $this->_invoker = $invoker; - $this->_eventDispatcher = $eventDispatcher; - } - - /** - * Not used. - */ - public function isStarted() - { - return false; - } - - /** - * Not used. - */ - public function start() - { - } - - /** - * Not used. - */ - public function stop() - { - } - - /** - * Set the additional parameters used on the mail() function. - * - * This string is formatted for sprintf() where %s is the sender address. - * - * @param string $params - */ - public function setExtraParams($params) - { - $this->_extraParams = $params; - return $this; - } - - /** - * Get the additional parameters used on the mail() function. - * - * This string is formatted for sprintf() where %s is the sender address. - * - * @return string - */ - public function getExtraParams() - { - return $this->_extraParams; - } - - /** - * Send the given Message. - * - * Recipient/sender data will be retreived from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * - * @param Swift_Mime_Message $message - * @param string[] &$failedRecipients to collect failures by-reference - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $failedRecipients = (array) $failedRecipients; - - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + /** The event dispatcher from the plugin API */ + private $_eventDispatcher; + + /** An invoker that calls the mail() function */ + private $_invoker; + + /** + * Create a new MailTransport with the $log. + * + * @param Swift_Transport_MailInvoker $invoker + * @param Swift_Events_EventDispatcher $eventDispatcher + */ + public function __construct(Swift_Transport_MailInvoker $invoker, Swift_Events_EventDispatcher $eventDispatcher) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) - { - return 0; - } + $this->_invoker = $invoker; + $this->_eventDispatcher = $eventDispatcher; } - - $count = ( - count((array) $message->getTo()) - + count((array) $message->getCc()) - + count((array) $message->getBcc()) - ); - - $toHeader = $message->getHeaders()->get('To'); - $subjectHeader = $message->getHeaders()->get('Subject'); - - $to = $toHeader ? $toHeader->getFieldBody() : ''; - $subject = $subjectHeader ? $subjectHeader->getFieldBody() : ''; - - $reversePath = $this->_getReversePath($message); - - //Remove headers that would otherwise be duplicated - $message->getHeaders()->remove('To'); - $message->getHeaders()->remove('Subject'); - - $messageStr = $message->toString(); - - if ($toHeader) + + /** + * Not used. + */ + public function isStarted() { + return false; + } + + /** + * Not used. + */ + public function start() + { + } + + /** + * Not used. + */ + public function stop() + { + } + + /** + * Set the additional parameters used on the mail() function. + * + * This string is formatted for sprintf() where %s is the sender address. + * + * @param string $params + * + * @return Swift_Transport_MailTransport + */ + public function setExtraParams($params) + { + $this->_extraParams = $params; + + return $this; + } + + /** + * Get the additional parameters used on the mail() function. + * + * This string is formatted for sprintf() where %s is the sender address. + * + * @return string + */ + public function getExtraParams() + { + return $this->_extraParams; + } + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * The return value is the number of recipients who were accepted for delivery. + * + * @param Swift_Mime_Message $message + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $failedRecipients = (array) $failedRecipients; + + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) { + return 0; + } + } + + $count = ( + count((array) $message->getTo()) + + count((array) $message->getCc()) + + count((array) $message->getBcc()) + ); + + $toHeader = $message->getHeaders()->get('To'); + $subjectHeader = $message->getHeaders()->get('Subject'); + + if (!$toHeader) { + throw new Swift_TransportException( + 'Cannot send message without a recipient' + ); + } + $to = $toHeader->getFieldBody(); + $subject = $subjectHeader ? $subjectHeader->getFieldBody() : ''; + + $reversePath = $this->_getReversePath($message); + + // Remove headers that would otherwise be duplicated + $message->getHeaders()->remove('To'); + $message->getHeaders()->remove('Subject'); + + $messageStr = $message->toString(); + $message->getHeaders()->set($toHeader); + $message->getHeaders()->set($subjectHeader); + + // Separate headers from body + if (false !== $endHeaders = strpos($messageStr, "\r\n\r\n")) { + $headers = substr($messageStr, 0, $endHeaders) . "\r\n"; //Keep last EOL + $body = substr($messageStr, $endHeaders + 4); + } else { + $headers = $messageStr . "\r\n"; + $body = ''; + } + + unset($messageStr); + + if ("\r\n" != PHP_EOL) { + // Non-windows (not using SMTP) + $headers = str_replace("\r\n", PHP_EOL, $headers); + $body = str_replace("\r\n", PHP_EOL, $body); + } else { + // Windows, using SMTP + $headers = str_replace("\r\n.", "\r\n..", $headers); + $body = str_replace("\r\n.", "\r\n..", $body); + } + + if ($this->_invoker->mail($to, $subject, $body, $headers, + sprintf($this->_extraParams, $reversePath))) + { + if ($evt) { + $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); + $evt->setFailedRecipients($failedRecipients); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + } else { + $failedRecipients = array_merge( + $failedRecipients, + array_keys((array) $message->getTo()), + array_keys((array) $message->getCc()), + array_keys((array) $message->getBcc()) + ); + + if ($evt) { + $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED); + $evt->setFailedRecipients($failedRecipients); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + $message->generateId(); + + $count = 0; + } + + return $count; } - $message->getHeaders()->set($subjectHeader); - - //Separate headers from body - if (false !== $endHeaders = strpos($messageStr, "\r\n\r\n")) + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) { - $headers = substr($messageStr, 0, $endHeaders) . "\r\n"; //Keep last EOL - $body = substr($messageStr, $endHeaders + 4); + $this->_eventDispatcher->bindEventListener($plugin); } - else + + // -- Private methods + + /** Determine the best-use reverse path for this message */ + private function _getReversePath(Swift_Mime_Message $message) { - $headers = $messageStr . "\r\n"; - $body = ''; + $return = $message->getReturnPath(); + $sender = $message->getSender(); + $from = $message->getFrom(); + $path = null; + if (!empty($return)) { + $path = $return; + } elseif (!empty($sender)) { + $keys = array_keys($sender); + $path = array_shift($keys); + } elseif (!empty($from)) { + $keys = array_keys($from); + $path = array_shift($keys); + } + + return $path; } - - unset($messageStr); - - if ("\r\n" != PHP_EOL) //Non-windows (not using SMTP) - { - $headers = str_replace("\r\n", PHP_EOL, $headers); - $body = str_replace("\r\n", PHP_EOL, $body); - } - else //Windows, using SMTP - { - $headers = str_replace("\r\n.", "\r\n..", $headers); - $body = str_replace("\r\n.", "\r\n..", $body); - } - - if ($this->_invoker->mail($to, $subject, $body, $headers, - sprintf($this->_extraParams, $reversePath))) - { - if ($evt) - { - $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); - $evt->setFailedRecipients($failedRecipients); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - } - else - { - $failedRecipients = array_merge( - $failedRecipients, - array_keys((array) $message->getTo()), - array_keys((array) $message->getCc()), - array_keys((array) $message->getBcc()) - ); - - if ($evt) - { - $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED); - $evt->setFailedRecipients($failedRecipients); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - - $message->generateId(); - - $count = 0; - } - - return $count; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_eventDispatcher->bindEventListener($plugin); - } - - // -- Private methods - - /** Determine the best-use reverse path for this message */ - private function _getReversePath(Swift_Mime_Message $message) - { - $return = $message->getReturnPath(); - $sender = $message->getSender(); - $from = $message->getFrom(); - $path = null; - if (!empty($return)) - { - $path = $return; - } - elseif (!empty($sender)) - { - $keys = array_keys($sender); - $path = array_shift($keys); - } - elseif (!empty($from)) - { - $keys = array_keys($from); - $path = array_shift($keys); - } - return $path; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/NullTransport.php b/lib/swiftmailer/lib/classes/Swift/Transport/NullTransport.php index c60d93881..fcfd9218d 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/NullTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/NullTransport.php @@ -10,81 +10,85 @@ /** * Pretends messages have been sent, but just ignores them. + * * @package Swift * @author Fabien Potencier */ class Swift_Transport_NullTransport implements Swift_Transport { - /** The event dispatcher from the plugin API */ - private $_eventDispatcher; + /** The event dispatcher from the plugin API */ + private $_eventDispatcher; - /** - * Constructor. - */ - public function __construct(Swift_Events_EventDispatcher $eventDispatcher) - { - $this->_eventDispatcher = $eventDispatcher; - } - - /** - * Tests if this Transport mechanism has started. - * - * @return boolean - */ - public function isStarted() - { - return true; - } - - /** - * Starts this Transport mechanism. - */ - public function start() - { - } - - /** - * Stops this Transport mechanism. - */ - public function stop() - { - } - - /** - * Sends the given message. - * - * @param Swift_Mime_Message $message - * @param string[] &$failedRecipients to collect failures by-reference - * - * @return int The number of sent emails - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + /** + * Constructor. + */ + public function __construct(Swift_Events_EventDispatcher $eventDispatcher) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) - { - return 0; - } + $this->_eventDispatcher = $eventDispatcher; } - - if ($evt) + + /** + * Tests if this Transport mechanism has started. + * + * @return bool + */ + public function isStarted() { - $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + return true; + } + + /** + * Starts this Transport mechanism. + */ + public function start() + { + } + + /** + * Stops this Transport mechanism. + */ + public function stop() + { + } + + /** + * Sends the given message. + * + * @param Swift_Mime_Message $message + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int The number of sent emails + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) { + return 0; + } + } + + if ($evt) { + $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + $count = ( + count((array) $message->getTo()) + + count((array) $message->getCc()) + + count((array) $message->getBcc()) + ); + + return $count; + } + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) + { + $this->_eventDispatcher->bindEventListener($plugin); } - - return 0; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_eventDispatcher->bindEventListener($plugin); - } } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php b/lib/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php index 7721409f9..9ce748017 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php @@ -8,162 +8,156 @@ * file that was distributed with this source code. */ - /** - * SendmailTransport for sending mail through a sendmail/postfix (etc..) binary. - * + * SendmailTransport for sending mail through a Sendmail/Postfix (etc..) binary. + * * Supported modes are -bs and -t, with any additional flags desired. * It is advised to use -bs mode since error reporting with -t mode is not * possible. - * - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Transport_SendmailTransport - extends Swift_Transport_AbstractSmtpTransport +class Swift_Transport_SendmailTransport extends Swift_Transport_AbstractSmtpTransport { - - /** - * Connection buffer parameters. - * @var array - * @access protected - */ - private $_params = array( - 'timeout' => 30, - 'blocking' => 1, - 'command' => '/usr/sbin/sendmail -bs', - 'type' => Swift_Transport_IoBuffer::TYPE_PROCESS - ); - - /** - * Create a new SendmailTransport with $buf for I/O. - * @param Swift_Transport_IoBuffer $buf - * @param Swift_Events_EventDispatcher $dispatcher - */ - public function __construct(Swift_Transport_IoBuffer $buf, - Swift_Events_EventDispatcher $dispatcher) - { - parent::__construct($buf, $dispatcher); - } - - /** - * Start the standalone SMTP session if running in -bs mode. - */ - public function start() - { - if (false !== strpos($this->getCommand(), ' -bs')) + /** + * Connection buffer parameters. + * + * @var array + */ + private $_params = array( + 'timeout' => 30, + 'blocking' => 1, + 'command' => '/usr/sbin/sendmail -bs', + 'type' => Swift_Transport_IoBuffer::TYPE_PROCESS + ); + + /** + * Create a new SendmailTransport with $buf for I/O. + * + * @param Swift_Transport_IoBuffer $buf + * @param Swift_Events_EventDispatcher $dispatcher + */ + public function __construct(Swift_Transport_IoBuffer $buf, Swift_Events_EventDispatcher $dispatcher) { - parent::start(); + parent::__construct($buf, $dispatcher); } - } - - /** - * Set the command to invoke. - * If using -t mode you are strongly advised to include -oi or -i in the - * flags. For example: /usr/sbin/sendmail -oi -t - * Swift will append a -f flag if one is not present. - * The recommended mode is "-bs" since it is interactive and failure notifications - * are hence possible. - * @param string $command - */ - public function setCommand($command) - { - $this->_params['command'] = $command; - return $this; - } - - /** - * Get the sendmail command which will be invoked. - * @return string - */ - public function getCommand() - { - return $this->_params['command']; - } - - /** - * Send the given Message. - * Recipient/sender data will be retreived from the Message API. - * The return value is the number of recipients who were accepted for delivery. - * NOTE: If using 'sendmail -t' you will not be aware of any failures until - * they bounce (i.e. send() will always return 100% success). - * @param Swift_Mime_Message $message - * @param string[] &$failedRecipients to collect failures by-reference - * @return int - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - $failedRecipients = (array) $failedRecipients; - $command = $this->getCommand(); - $buffer = $this->getBuffer(); - - if (false !== strpos($command, ' -t')) + + /** + * Start the standalone SMTP session if running in -bs mode. + */ + public function start() { - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) - { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) - { - return 0; + if (false !== strpos($this->getCommand(), ' -bs')) { + parent::start(); } - } - - if (false === strpos($command, ' -f')) - { - $command .= ' -f' . $this->_getReversePath($message); - } - - $buffer->initialize(array_merge($this->_params, array('command' => $command))); - - if (false === strpos($command, ' -i') && false === strpos($command, ' -oi')) - { - $buffer->setWriteTranslations(array("\r\n" => "\n", "\n." => "\n..")); - } - else - { - $buffer->setWriteTranslations(array("\r\n"=>"\n")); - } - - $count = count((array) $message->getTo()) - + count((array) $message->getCc()) - + count((array) $message->getBcc()) - ; - $message->toByteStream($buffer); - $buffer->flushBuffers(); - $buffer->setWriteTranslations(array()); - $buffer->terminate(); - - if ($evt) - { - $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); - $evt->setFailedRecipients($failedRecipients); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); - } - - $message->generateId(); } - elseif (false !== strpos($command, ' -bs')) + + /** + * Set the command to invoke. + * + * If using -t mode you are strongly advised to include -oi or -i in the flags. + * For example: /usr/sbin/sendmail -oi -t + * Swift will append a -f flag if one is not present. + * + * The recommended mode is "-bs" since it is interactive and failure notifications + * are hence possible. + * + * @param string $command + * + * @return Swift_Transport_SendmailTransport + */ + public function setCommand($command) { - $count = parent::send($message, $failedRecipients); + $this->_params['command'] = $command; + + return $this; } - else + + /** + * Get the sendmail command which will be invoked. + * + * @return string + */ + public function getCommand() { - $this->_throwException(new Swift_TransportException( - 'Unsupported sendmail command flags [' . $command . ']. ' . - 'Must be one of "-bs" or "-t" but can include additional flags.' - )); + return $this->_params['command']; + } + + /** + * Send the given Message. + * + * Recipient/sender data will be retrieved from the Message API. + * + * The return value is the number of recipients who were accepted for delivery. + * NOTE: If using 'sendmail -t' you will not be aware of any failures until + * they bounce (i.e. send() will always return 100% success). + * + * @param Swift_Mime_Message $message + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + $failedRecipients = (array) $failedRecipients; + $command = $this->getCommand(); + $buffer = $this->getBuffer(); + + if (false !== strpos($command, ' -t')) { + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) { + return 0; + } + } + + if (false === strpos($command, ' -f')) { + $command .= ' -f' . escapeshellarg($this->_getReversePath($message)); + } + + $buffer->initialize(array_merge($this->_params, array('command' => $command))); + + if (false === strpos($command, ' -i') && false === strpos($command, ' -oi')) { + $buffer->setWriteTranslations(array("\r\n" => "\n", "\n." => "\n..")); + } else { + $buffer->setWriteTranslations(array("\r\n"=>"\n")); + } + + $count = count((array) $message->getTo()) + + count((array) $message->getCc()) + + count((array) $message->getBcc()) + ; + $message->toByteStream($buffer); + $buffer->flushBuffers(); + $buffer->setWriteTranslations(array()); + $buffer->terminate(); + + if ($evt) { + $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); + $evt->setFailedRecipients($failedRecipients); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + $message->generateId(); + } elseif (false !== strpos($command, ' -bs')) { + $count = parent::send($message, $failedRecipients); + } else { + $this->_throwException(new Swift_TransportException( + 'Unsupported sendmail command flags [' . $command . ']. ' . + 'Must be one of "-bs" or "-t" but can include additional flags.' + )); + } + + return $count; + } + + // -- Protected methods + + /** Get the params to initialize the buffer */ + protected function _getBufferParams() + { + return $this->_params; } - - return $count; - } - - // -- Protected methods - - /** Get the params to initialize the buffer */ - protected function _getBufferParams() - { - return $this->_params; - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php b/lib/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php index d91e36e2d..0bf6c160a 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php @@ -1,57 +1,41 @@ . - + * This file is part of SwiftMailer. + * (c) 2004-2009 Chris Corbyn + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ - /** * This is the implementation class for {@link Swift_Transport_MailInvoker}. - * - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_Transport_SimpleMailInvoker implements Swift_Transport_MailInvoker { - - /** - * Send mail via the mail() function. - * - * This method takes the same arguments as PHP mail(). - * - * @param string $to - * @param string $subject - * @param string $body - * @param string $headers - * @param string $extraParams - * - * @return boolean - */ - public function mail($to, $subject, $body, $headers = null, $extraParams = null) - { - if (!ini_get('safe_mode')) + /** + * Send mail via the mail() function. + * + * This method takes the same arguments as PHP mail(). + * + * @param string $to + * @param string $subject + * @param string $body + * @param string $headers + * @param string $extraParams + * + * @return bool + */ + public function mail($to, $subject, $body, $headers = null, $extraParams = null) { - return mail($to, $subject, $body, $headers, $extraParams); + if (!ini_get('safe_mode')) { + return @mail($to, $subject, $body, $headers, $extraParams); + } else { + return @mail($to, $subject, $body, $headers); + } } - else - { - return mail($to, $subject, $body, $headers); - } - } - } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php b/lib/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php index ee9b8ed51..fcbf5e981 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php @@ -10,27 +10,29 @@ /** * Wraps an IoBuffer to send/receive SMTP commands/responses. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ interface Swift_Transport_SmtpAgent { - - /** - * Get the IoBuffer where read/writes are occurring. - * @return Swift_Transport_IoBuffer - */ - public function getBuffer(); - - /** - * Run a command against the buffer, expecting the given response codes. - * If no response codes are given, the response will not be validated. - * If codes are given, an exception will be thrown on an invalid response. - * @param string $command - * @param int[] $codes - * @param string[] &$failures - */ - public function executeCommand($command, $codes = array(), &$failures = null); - + /** + * Get the IoBuffer where read/writes are occurring. + * + * @return Swift_Transport_IoBuffer + */ + public function getBuffer(); + + /** + * Run a command against the buffer, expecting the given response codes. + * + * If no response codes are given, the response will not be validated. + * If codes are given, an exception will be thrown on an invalid response. + * + * @param string $command + * @param int[] $codes + * @param string[] $failures An array of failures by-reference + */ + public function executeCommand($command, $codes = array(), &$failures = null); } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/SpoolTransport.php b/lib/swiftmailer/lib/classes/Swift/Transport/SpoolTransport.php index 61a148497..0fafed72c 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/SpoolTransport.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/SpoolTransport.php @@ -10,106 +10,109 @@ /** * Stores Messages in a queue. + * * @package Swift * @author Fabien Potencier */ class Swift_Transport_SpoolTransport implements Swift_Transport { - /** The spool instance */ - private $_spool; + /** The spool instance */ + private $_spool; - /** The event dispatcher from the plugin API */ - private $_eventDispatcher; + /** The event dispatcher from the plugin API */ + private $_eventDispatcher; - /** - * Constructor. - */ - public function __construct(Swift_Events_EventDispatcher $eventDispatcher, Swift_Spool $spool = null) - { - $this->_eventDispatcher = $eventDispatcher; - $this->_spool = $spool; - } - - /** - * Sets the spool object. - * @param Swift_Spool $spool - */ - public function setSpool(Swift_Spool $spool) - { - $this->_spool = $spool; - return $this; - } - - /** - * Get the spool object. - * @return Swift_Spool - */ - public function getSpool() - { - return $this->_spool; - } - - /** - * Tests if this Transport mechanism has started. - * - * @return boolean - */ - public function isStarted() - { - return true; - } - - /** - * Starts this Transport mechanism. - */ - public function start() - { - } - - /** - * Stops this Transport mechanism. - */ - public function stop() - { - } - - /** - * Sends the given message. - * - * @param Swift_Mime_Message $message - * @param string[] &$failedRecipients to collect failures by-reference - * - * @return int The number of sent emails - */ - public function send(Swift_Mime_Message $message, &$failedRecipients = null) - { - if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) + /** + * Constructor. + */ + public function __construct(Swift_Events_EventDispatcher $eventDispatcher, Swift_Spool $spool = null) { - $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); - if ($evt->bubbleCancelled()) - { - return 0; - } + $this->_eventDispatcher = $eventDispatcher; + $this->_spool = $spool; } - - $success = $this->_spool->queueMessage($message); - - if ($evt) + + /** + * Sets the spool object. + * + * @param Swift_Spool $spool + * + * @return Swift_Transport_SpoolTransport + */ + public function setSpool(Swift_Spool $spool) { - $evt->setResult($success ? Swift_Events_SendEvent::RESULT_SUCCESS : Swift_Events_SendEvent::RESULT_FAILED); - $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + $this->_spool = $spool; + + return $this; + } + + /** + * Get the spool object. + * + * @return Swift_Spool + */ + public function getSpool() + { + return $this->_spool; + } + + /** + * Tests if this Transport mechanism has started. + * + * @return bool + */ + public function isStarted() + { + return true; + } + + /** + * Starts this Transport mechanism. + */ + public function start() + { + } + + /** + * Stops this Transport mechanism. + */ + public function stop() + { + } + + /** + * Sends the given message. + * + * @param Swift_Mime_Message $message + * @param string[] $failedRecipients An array of failures by-reference + * + * @return int The number of sent e-mail's + */ + public function send(Swift_Mime_Message $message, &$failedRecipients = null) + { + if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) { + $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed'); + if ($evt->bubbleCancelled()) { + return 0; + } + } + + $success = $this->_spool->queueMessage($message); + + if ($evt) { + $evt->setResult($success ? Swift_Events_SendEvent::RESULT_SUCCESS : Swift_Events_SendEvent::RESULT_FAILED); + $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed'); + } + + return 1; + } + + /** + * Register a plugin. + * + * @param Swift_Events_EventListener $plugin + */ + public function registerPlugin(Swift_Events_EventListener $plugin) + { + $this->_eventDispatcher->bindEventListener($plugin); } - - return 1; - } - - /** - * Register a plugin. - * - * @param Swift_Events_EventListener $plugin - */ - public function registerPlugin(Swift_Events_EventListener $plugin) - { - $this->_eventDispatcher->bindEventListener($plugin); - } } diff --git a/lib/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php b/lib/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php index b92dea19f..f11e344e6 100644 --- a/lib/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php +++ b/lib/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php @@ -8,329 +8,320 @@ * file that was distributed with this source code. */ - /** * A generic IoBuffer implementation supporting remote sockets and local processes. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ -class Swift_Transport_StreamBuffer - extends Swift_ByteStream_AbstractFilterableInputStream - implements Swift_Transport_IoBuffer +class Swift_Transport_StreamBuffer extends Swift_ByteStream_AbstractFilterableInputStream implements Swift_Transport_IoBuffer { - - /** A primary socket */ - private $_stream; - - /** The input stream */ - private $_in; - - /** The output stream */ - private $_out; - - /** Buffer initialization parameters */ - private $_params = array(); - - /** The ReplacementFilterFactory */ - private $_replacementFactory; - - /** Translations performed on data being streamed into the buffer */ - private $_translations = array(); - - /** - * Create a new StreamBuffer using $replacementFactory for transformations. - * @param Swift_ReplacementFilterFactory $replacementFactory - */ - public function __construct( - Swift_ReplacementFilterFactory $replacementFactory) - { - $this->_replacementFactory = $replacementFactory; - } - - /** - * Perform any initialization needed, using the given $params. - * Parameters will vary depending upon the type of IoBuffer used. - * @param array $params - */ - public function initialize(array $params) - { - $this->_params = $params; - switch ($params['type']) + /** A primary socket */ + private $_stream; + + /** The input stream */ + private $_in; + + /** The output stream */ + private $_out; + + /** Buffer initialization parameters */ + private $_params = array(); + + /** The ReplacementFilterFactory */ + private $_replacementFactory; + + /** Translations performed on data being streamed into the buffer */ + private $_translations = array(); + + /** + * Create a new StreamBuffer using $replacementFactory for transformations. + * + * @param Swift_ReplacementFilterFactory $replacementFactory + */ + public function __construct(Swift_ReplacementFilterFactory $replacementFactory) { - case self::TYPE_PROCESS: - $this->_establishProcessConnection(); - break; - case self::TYPE_SOCKET: - default: - $this->_establishSocketConnection(); - break; + $this->_replacementFactory = $replacementFactory; } - } - - /** - * Set an individual param on the buffer (e.g. switching to SSL). - * @param string $param - * @param mixed $value - */ - public function setParam($param, $value) - { - if (isset($this->_stream)) + + /** + * Perform any initialization needed, using the given $params. + * + * Parameters will vary depending upon the type of IoBuffer used. + * + * @param array $params + */ + public function initialize(array $params) { - switch ($param) - { - case 'protocol': - if (!array_key_exists('protocol', $this->_params) - || $value != $this->_params['protocol']) - { - if ('tls' == $value) - { - stream_socket_enable_crypto( - $this->_stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT - ); + $this->_params = $params; + switch ($params['type']) { + case self::TYPE_PROCESS: + $this->_establishProcessConnection(); + break; + case self::TYPE_SOCKET: + default: + $this->_establishSocketConnection(); + break; + } + } + + /** + * Set an individual param on the buffer (e.g. switching to SSL). + * + * @param string $param + * @param mixed $value + */ + public function setParam($param, $value) + { + if (isset($this->_stream)) { + switch ($param) { + case 'timeout': + if ($this->_stream) { + stream_set_timeout($this->_stream, $value); + } + break; + + case 'blocking': + if ($this->_stream) { + stream_set_blocking($this->_stream, 1); + } + } - } - break; - - case 'timeout': - if ($this->_stream) - { - stream_set_timeout($this->_stream, $value); - } - break; - - case 'blocking': - if ($this->_stream) - { - stream_set_blocking($this->_stream, 1); - } - - } - } - $this->_params[$param] = $value; - } - - /** - * Perform any shutdown logic needed. - */ - public function terminate() - { - if (isset($this->_stream)) - { - switch ($this->_params['type']) - { - case self::TYPE_PROCESS: - fclose($this->_in); - fclose($this->_out); - proc_close($this->_stream); - break; - case self::TYPE_SOCKET: - default: - fclose($this->_stream); - break; - } - } - $this->_stream = null; - $this->_out = null; - $this->_in = null; - } - - /** - * Set an array of string replacements which should be made on data written - * to the buffer. This could replace LF with CRLF for example. - * @param string[] $replacements - */ - public function setWriteTranslations(array $replacements) - { - foreach ($this->_translations as $search => $replace) - { - if (!isset($replacements[$search])) - { - $this->removeFilter($search); - unset($this->_translations[$search]); - } - } - - foreach ($replacements as $search => $replace) - { - if (!isset($this->_translations[$search])) - { - $this->addFilter( - $this->_replacementFactory->createFilter($search, $replace), $search - ); - $this->_translations[$search] = true; - } - } - } - - /** - * Get a line of output (including any CRLF). - * The $sequence number comes from any writes and may or may not be used - * depending upon the implementation. - * @param int $sequence of last write to scan from - * @return string - */ - public function readLine($sequence) - { - if (isset($this->_out) && !feof($this->_out)) - { - $line = fgets($this->_out); - if (strlen($line)==0) - { - $metas = stream_get_meta_data($this->_out); - if ($metas['timed_out']) { - throw new Swift_IoException( - 'Connection to ' . - $this->_getReadConnectionDescription() . - ' Timed Out' - ); } - } - return $line; + $this->_params[$param] = $value; } - } - - /** - * Reads $length bytes from the stream into a string and moves the pointer - * through the stream by $length. If less bytes exist than are requested the - * remaining bytes are given instead. If no bytes are remaining at all, boolean - * false is returned. - * @param int $length - * @return string - */ - public function read($length) - { - if (isset($this->_out) && !feof($this->_out)) + + public function startTLS() { - $ret = fread($this->_out, $length); - if (strlen($ret)==0) - { - $metas = stream_get_meta_data($this->_out); - if ($metas['timed_out']) - { - throw new Swift_IoException( - 'Connection to ' . - $this->_getReadConnectionDescription() . - ' Timed Out' - ); + return stream_socket_enable_crypto($this->_stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + } + + /** + * Perform any shutdown logic needed. + */ + public function terminate() + { + if (isset($this->_stream)) { + switch ($this->_params['type']) { + case self::TYPE_PROCESS: + fclose($this->_in); + fclose($this->_out); + proc_close($this->_stream); + break; + case self::TYPE_SOCKET: + default: + fclose($this->_stream); + break; + } } - } - return $ret; + $this->_stream = null; + $this->_out = null; + $this->_in = null; } - } - - /** Not implemented */ - public function setReadPointer($byteOffset) - { - } - - // -- Protected methods - - /** Flush the stream contents */ - protected function _flush() - { - if (isset($this->_in)) + + /** + * Set an array of string replacements which should be made on data written + * to the buffer. + * + * This could replace LF with CRLF for example. + * + * @param string[] $replacements + */ + public function setWriteTranslations(array $replacements) { - fflush($this->_in); + foreach ($this->_translations as $search => $replace) { + if (!isset($replacements[$search])) { + $this->removeFilter($search); + unset($this->_translations[$search]); + } + } + + foreach ($replacements as $search => $replace) { + if (!isset($this->_translations[$search])) { + $this->addFilter( + $this->_replacementFactory->createFilter($search, $replace), $search + ); + $this->_translations[$search] = true; + } + } } - } - - /** Write this bytes to the stream */ - protected function _commit($bytes) - { - if (isset($this->_in) - && fwrite($this->_in, $bytes)) + + /** + * Get a line of output (including any CRLF). + * + * The $sequence number comes from any writes and may or may not be used + * depending upon the implementation. + * + * @param int $sequence of last write to scan from + * + * @return string + * + * @throws Swift_IoException + */ + public function readLine($sequence) { - return ++$this->_sequence; + if (isset($this->_out) && !feof($this->_out)) { + $line = fgets($this->_out); + if (strlen($line)==0) { + $metas = stream_get_meta_data($this->_out); + if ($metas['timed_out']) { + throw new Swift_IoException( + 'Connection to ' . + $this->_getReadConnectionDescription() . + ' Timed Out' + ); + } + } + + return $line; + } } - } - - // -- Private methods - - /** - * Establishes a connection to a remote server. - * @access private - */ - private function _establishSocketConnection() - { - $host = $this->_params['host']; - if (!empty($this->_params['protocol'])) + + /** + * Reads $length bytes from the stream into a string and moves the pointer + * through the stream by $length. + * + * If less bytes exist than are requested the remaining bytes are given instead. + * If no bytes are remaining at all, boolean false is returned. + * + * @param int $length + * + * @return string|bool + * + * @throws Swift_IoException + */ + public function read($length) { - $host = $this->_params['protocol'] . '://' . $host; + if (isset($this->_out) && !feof($this->_out)) { + $ret = fread($this->_out, $length); + if (strlen($ret)==0) { + $metas = stream_get_meta_data($this->_out); + if ($metas['timed_out']) { + throw new Swift_IoException( + 'Connection to ' . + $this->_getReadConnectionDescription() . + ' Timed Out' + ); + } + } + + return $ret; + } } - $timeout = 15; - if (!empty($this->_params['timeout'])) + + /** Not implemented */ + public function setReadPointer($byteOffset) { - $timeout = $this->_params['timeout']; } - $options = array(); - if (!empty($this->_params['sourceIp'])) + + // -- Protected methods + + /** Flush the stream contents */ + protected function _flush() { - $options['socket']['bindto']=$this->_params['sourceIp'].':0'; + if (isset($this->_in)) { + fflush($this->_in); + } } - if (!$this->_stream = stream_socket_client($host.':'.$this->_params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, stream_context_create($options))) + + /** Write this bytes to the stream */ + protected function _commit($bytes) { - throw new Swift_TransportException( - 'Connection could not be established with host ' . $this->_params['host'] . - ' [' . $errstr . ' #' . $errno . ']' - ); + if (isset($this->_in)) { + $bytesToWrite = strlen($bytes); + $totalBytesWritten = 0; + + while ($totalBytesWritten < $bytesToWrite) { + $bytesWritten = fwrite($this->_in, substr($bytes, $totalBytesWritten)); + if (false === $bytesWritten || 0 === $bytesWritten) { + break; + } + + $totalBytesWritten += $bytesWritten; + } + + if ($totalBytesWritten > 0) { + return ++$this->_sequence; + } + } } - if (!empty($this->_params['blocking'])) + + // -- Private methods + + /** + * Establishes a connection to a remote server. + */ + private function _establishSocketConnection() { - stream_set_blocking($this->_stream, 1); - } - else - { - stream_set_blocking($this->_stream, 0); - } - stream_set_timeout($this->_stream, $timeout); - $this->_in =& $this->_stream; - $this->_out =& $this->_stream; - } - - /** - * Opens a process for input/output. - * @access private - */ - private function _establishProcessConnection() - { - $command = $this->_params['command']; - $descriptorSpec = array( - 0 => array('pipe', 'r'), - 1 => array('pipe', 'w'), - 2 => array('pipe', 'w') - ); - $this->_stream = proc_open($command, $descriptorSpec, $pipes); - stream_set_blocking($pipes[2], 0); - if ($err = stream_get_contents($pipes[2])) - { - throw new Swift_TransportException( - 'Process could not be started [' . $err . ']' - ); - } - $this->_in =& $pipes[0]; - $this->_out =& $pipes[1]; - } - - - private function _getReadConnectionDescription() - { - switch ($this->_params['type']) - { - case self::TYPE_PROCESS: - return 'Process '.$this->_params['command']; - break; - - case self::TYPE_SOCKET: - default: $host = $this->_params['host']; - if (!empty($this->_params['protocol'])) - { - $host = $this->_params['protocol'] . '://' . $host; + if (!empty($this->_params['protocol'])) { + $host = $this->_params['protocol'] . '://' . $host; + } + $timeout = 15; + if (!empty($this->_params['timeout'])) { + $timeout = $this->_params['timeout']; + } + $options = array(); + if (!empty($this->_params['sourceIp'])) { + $options['socket']['bindto']=$this->_params['sourceIp'].':0'; + } + $this->_stream = @stream_socket_client($host.':'.$this->_params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, stream_context_create($options)); + if (false === $this->_stream) { + throw new Swift_TransportException( + 'Connection could not be established with host ' . $this->_params['host'] . + ' [' . $errstr . ' #' . $errno . ']' + ); + } + if (!empty($this->_params['blocking'])) { + stream_set_blocking($this->_stream, 1); + } else { + stream_set_blocking($this->_stream, 0); + } + stream_set_timeout($this->_stream, $timeout); + $this->_in =& $this->_stream; + $this->_out =& $this->_stream; + } + + /** + * Opens a process for input/output. + */ + private function _establishProcessConnection() + { + $command = $this->_params['command']; + $descriptorSpec = array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ); + $this->_stream = proc_open($command, $descriptorSpec, $pipes); + stream_set_blocking($pipes[2], 0); + if ($err = stream_get_contents($pipes[2])) { + throw new Swift_TransportException( + 'Process could not be started [' . $err . ']' + ); + } + $this->_in =& $pipes[0]; + $this->_out =& $pipes[1]; + } + + private function _getReadConnectionDescription() + { + switch ($this->_params['type']) { + case self::TYPE_PROCESS: + return 'Process '.$this->_params['command']; + break; + + case self::TYPE_SOCKET: + default: + $host = $this->_params['host']; + if (!empty($this->_params['protocol'])) { + $host = $this->_params['protocol'] . '://' . $host; + } + $host.=':'.$this->_params['port']; + + return $host; + break; } - $host.=':'.$this->_params['port']; - return $host; - break; } - } } diff --git a/lib/swiftmailer/lib/classes/Swift/TransportException.php b/lib/swiftmailer/lib/classes/Swift/TransportException.php index 7df6e0b4f..48e41d16d 100644 --- a/lib/swiftmailer/lib/classes/Swift/TransportException.php +++ b/lib/swiftmailer/lib/classes/Swift/TransportException.php @@ -8,23 +8,22 @@ * file that was distributed with this source code. */ - /** * TransportException thrown when an error occurs in the Transport subsystem. - * @package Swift + * + * @package Swift * @subpackage Transport - * @author Chris Corbyn + * @author Chris Corbyn */ class Swift_TransportException extends Swift_IoException { - - /** - * Create a new TransportException with $message. - * @param string $message - */ - public function __construct($message) - { - parent::__construct($message); - } - + /** + * Create a new TransportException with $message. + * + * @param string $message + */ + public function __construct($message) + { + parent::__construct($message); + } } diff --git a/lib/swiftmailer/lib/classes/Swift/Validate.php b/lib/swiftmailer/lib/classes/Swift/Validate.php index d21900e22..b6906c0b6 100644 --- a/lib/swiftmailer/lib/classes/Swift/Validate.php +++ b/lib/swiftmailer/lib/classes/Swift/Validate.php @@ -7,32 +7,37 @@ */ /** - * Utility Class allowing users to simply check expressions again Swift Grammar + * Utility Class allowing users to simply check expressions again Swift Grammar. + * * @package Swift - * @author Xavier De Cock + * @author Xavier De Cock */ class Swift_Validate { - /** - * Grammar Object - * @var Swift_Mime_Grammar - */ - private static $grammar = null; - - /** - * Checks if an email matches the current grammars - * @param string $email - */ - public static function email($email) - { - if (self::$grammar===null) + /** + * Grammar Object + * + * @var Swift_Mime_Grammar + */ + private static $grammar = null; + + /** + * Checks if an e-mail address matches the current grammars. + * + * @param string $email + * + * @return bool + */ + public static function email($email) { - self::$grammar = Swift_DependencyContainer::getInstance() - ->lookup('mime.grammar'); + if (self::$grammar===null) { + self::$grammar = Swift_DependencyContainer::getInstance() + ->lookup('mime.grammar'); + } + + return (bool) preg_match( + '/^' . self::$grammar->getDefinition('addr-spec') . '$/D', + $email + ); } - return preg_match( - '/^' . self::$grammar->getDefinition('addr-spec') . '$/D', - $email - ); - } -} \ No newline at end of file +} diff --git a/lib/swiftmailer/lib/dependency_maps/cache_deps.php b/lib/swiftmailer/lib/dependency_maps/cache_deps.php index 605820646..6023448e8 100644 --- a/lib/swiftmailer/lib/dependency_maps/cache_deps.php +++ b/lib/swiftmailer/lib/dependency_maps/cache_deps.php @@ -1,25 +1,23 @@ register('cache') - -> asAliasOf('cache.array') - - -> register('tempdir') - -> asValue('/tmp') - - -> register('cache.null') - -> asSharedInstanceOf('Swift_KeyCache_NullKeyCache') - - -> register('cache.array') - -> asSharedInstanceOf('Swift_KeyCache_ArrayKeyCache') - -> withDependencies(array('cache.inputstream')) - - -> register('cache.disk') - -> asSharedInstanceOf('Swift_KeyCache_DiskKeyCache') - -> withDependencies(array('cache.inputstream', 'tempdir')) - - -> register('cache.inputstream') - -> asNewInstanceOf('Swift_KeyCache_SimpleKeyCacheInputStream') - - ; + ->register('cache') + ->asAliasOf('cache.array') + + ->register('tempdir') + ->asValue('/tmp') + + ->register('cache.null') + ->asSharedInstanceOf('Swift_KeyCache_NullKeyCache') + + ->register('cache.array') + ->asSharedInstanceOf('Swift_KeyCache_ArrayKeyCache') + ->withDependencies(array('cache.inputstream')) + + ->register('cache.disk') + ->asSharedInstanceOf('Swift_KeyCache_DiskKeyCache') + ->withDependencies(array('cache.inputstream', 'tempdir')) + + ->register('cache.inputstream') + ->asNewInstanceOf('Swift_KeyCache_SimpleKeyCacheInputStream') +; diff --git a/lib/swiftmailer/lib/dependency_maps/message_deps.php b/lib/swiftmailer/lib/dependency_maps/message_deps.php index 10f1e0375..64d69d215 100644 --- a/lib/swiftmailer/lib/dependency_maps/message_deps.php +++ b/lib/swiftmailer/lib/dependency_maps/message_deps.php @@ -1,9 +1,9 @@ register('message.message') + ->asNewInstanceOf('Swift_Message') - -> register('message.message') - -> asNewInstanceOf('Swift_Message') - - -> register('message.mimepart') - -> asNewInstanceOf('Swift_Mimepart'); + ->register('message.mimepart') + ->asNewInstanceOf('Swift_MimePart') +; diff --git a/lib/swiftmailer/lib/dependency_maps/mime_deps.php b/lib/swiftmailer/lib/dependency_maps/mime_deps.php index 6d7b30d68..a13472e9b 100644 --- a/lib/swiftmailer/lib/dependency_maps/mime_deps.php +++ b/lib/swiftmailer/lib/dependency_maps/mime_deps.php @@ -3,103 +3,121 @@ require dirname(__FILE__) . '/../mime_types.php'; Swift_DependencyContainer::getInstance() - - -> register('properties.charset') - -> asValue('utf-8') - - -> register('mime.grammar') - -> asSharedInstanceOf('Swift_Mime_Grammar') - - -> register('mime.message') - -> asNewInstanceOf('Swift_Mime_SimpleMessage') - -> withDependencies(array( - 'mime.headerset', - 'mime.qpcontentencoder', - 'cache', - 'mime.grammar', - 'properties.charset' - )) - - -> register('mime.part') - -> asNewInstanceOf('Swift_Mime_MimePart') - -> withDependencies(array( - 'mime.headerset', - 'mime.qpcontentencoder', - 'cache', - 'mime.grammar', - 'properties.charset' - )) - - -> register('mime.attachment') - -> asNewInstanceOf('Swift_Mime_Attachment') - -> withDependencies(array( - 'mime.headerset', - 'mime.base64contentencoder', - 'cache', - 'mime.grammar' - )) - -> addConstructorValue($swift_mime_types) - - -> register('mime.embeddedfile') - -> asNewInstanceOf('Swift_Mime_EmbeddedFile') - -> withDependencies(array( - 'mime.headerset', - 'mime.base64contentencoder', - 'cache', - 'mime.grammar' - )) - -> addConstructorValue($swift_mime_types) - - -> register('mime.headerfactory') - -> asNewInstanceOf('Swift_Mime_SimpleHeaderFactory') - -> withDependencies(array( - 'mime.qpheaderencoder', - 'mime.rfc2231encoder', - 'mime.grammar', - 'properties.charset' + ->register('properties.charset') + ->asValue('utf-8') + + ->register('mime.grammar') + ->asSharedInstanceOf('Swift_Mime_Grammar') + + ->register('mime.message') + ->asNewInstanceOf('Swift_Mime_SimpleMessage') + ->withDependencies(array( + 'mime.headerset', + 'mime.qpcontentencoder', + 'cache', + 'mime.grammar', + 'properties.charset' )) - - -> register('mime.headerset') - -> asNewInstanceOf('Swift_Mime_SimpleHeaderSet') - -> withDependencies(array('mime.headerfactory', 'properties.charset')) - - -> register('mime.qpheaderencoder') - -> asNewInstanceOf('Swift_Mime_HeaderEncoder_QpHeaderEncoder') - -> withDependencies(array('mime.charstream')) - - -> register('mime.charstream') - -> asNewInstanceOf('Swift_CharacterStream_NgCharacterStream') - -> withDependencies(array('mime.characterreaderfactory', 'properties.charset')) - - -> register('mime.bytecanonicalizer') - -> asSharedInstanceOf('Swift_StreamFilters_ByteArrayReplacementFilter') - -> addConstructorValue(array(array(0x0D, 0x0A), array(0x0D), array(0x0A))) - -> addConstructorValue(array(array(0x0A), array(0x0A), array(0x0D, 0x0A))) - - -> register('mime.characterreaderfactory') - -> asSharedInstanceOf('Swift_CharacterReaderFactory_SimpleCharacterReaderFactory') - - -> register('mime.qpcontentencoder') - -> asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder') - -> withDependencies(array('mime.charstream', 'mime.bytecanonicalizer')) - - -> register('mime.7bitcontentencoder') - -> asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder') - -> addConstructorValue('7bit') - -> addConstructorValue(true) - - -> register('mime.8bitcontentencoder') - -> asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder') - -> addConstructorValue('8bit') - -> addConstructorValue(true) - - -> register('mime.base64contentencoder') - -> asSharedInstanceOf('Swift_Mime_ContentEncoder_Base64ContentEncoder') - - -> register('mime.rfc2231encoder') - -> asNewInstanceOf('Swift_Encoder_Rfc2231Encoder') - -> withDependencies(array('mime.charstream')) - - ; - + + ->register('mime.part') + ->asNewInstanceOf('Swift_Mime_MimePart') + ->withDependencies(array( + 'mime.headerset', + 'mime.qpcontentencoder', + 'cache', + 'mime.grammar', + 'properties.charset' + )) + + ->register('mime.attachment') + ->asNewInstanceOf('Swift_Mime_Attachment') + ->withDependencies(array( + 'mime.headerset', + 'mime.base64contentencoder', + 'cache', + 'mime.grammar' + )) + ->addConstructorValue($swift_mime_types) + + ->register('mime.embeddedfile') + ->asNewInstanceOf('Swift_Mime_EmbeddedFile') + ->withDependencies(array( + 'mime.headerset', + 'mime.base64contentencoder', + 'cache', + 'mime.grammar' + )) + ->addConstructorValue($swift_mime_types) + + ->register('mime.headerfactory') + ->asNewInstanceOf('Swift_Mime_SimpleHeaderFactory') + ->withDependencies(array( + 'mime.qpheaderencoder', + 'mime.rfc2231encoder', + 'mime.grammar', + 'properties.charset' + )) + + ->register('mime.headerset') + ->asNewInstanceOf('Swift_Mime_SimpleHeaderSet') + ->withDependencies(array('mime.headerfactory', 'properties.charset')) + + ->register('mime.qpheaderencoder') + ->asNewInstanceOf('Swift_Mime_HeaderEncoder_QpHeaderEncoder') + ->withDependencies(array('mime.charstream')) + + ->register('mime.base64headerencoder') + ->asNewInstanceOf('Swift_Mime_HeaderEncoder_Base64HeaderEncoder') + ->withDependencies(array('mime.charstream')) + + ->register('mime.charstream') + ->asNewInstanceOf('Swift_CharacterStream_NgCharacterStream') + ->withDependencies(array('mime.characterreaderfactory', 'properties.charset')) + + ->register('mime.bytecanonicalizer') + ->asSharedInstanceOf('Swift_StreamFilters_ByteArrayReplacementFilter') + ->addConstructorValue(array(array(0x0D, 0x0A), array(0x0D), array(0x0A))) + ->addConstructorValue(array(array(0x0A), array(0x0A), array(0x0D, 0x0A))) + + ->register('mime.characterreaderfactory') + ->asSharedInstanceOf('Swift_CharacterReaderFactory_SimpleCharacterReaderFactory') + + ->register('mime.safeqpcontentencoder') + ->asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder') + ->withDependencies(array('mime.charstream', 'mime.bytecanonicalizer')) + + ->register('mime.rawcontentencoder') + ->asNewInstanceOf('Swift_Mime_ContentEncoder_RawContentEncoder') + + ->register('mime.nativeqpcontentencoder') + ->withDependencies(array('properties.charset')) + ->asNewInstanceOf('Swift_Mime_ContentEncoder_NativeQpContentEncoder') + + ->register('mime.qpcontentencoderproxy') + ->asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoderProxy') + ->withDependencies(array('mime.safeqpcontentencoder', 'mime.nativeqpcontentencoder', 'properties.charset')) + + ->register('mime.7bitcontentencoder') + ->asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder') + ->addConstructorValue('7bit') + ->addConstructorValue(true) + + ->register('mime.8bitcontentencoder') + ->asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder') + ->addConstructorValue('8bit') + ->addConstructorValue(true) + + ->register('mime.base64contentencoder') + ->asSharedInstanceOf('Swift_Mime_ContentEncoder_Base64ContentEncoder') + + ->register('mime.rfc2231encoder') + ->asNewInstanceOf('Swift_Encoder_Rfc2231Encoder') + ->withDependencies(array('mime.charstream')) + + // As of PHP 5.4.7, the quoted_printable_encode() function behaves correctly. + // see https://github.com/php/php-src/commit/18bb426587d62f93c54c40bf8535eb8416603629 + ->register('mime.qpcontentencoder') + ->asAliasOf(version_compare(phpversion(), '5.4.7', '>=') ? 'mime.qpcontentencoderproxy' : 'mime.safeqpcontentencoder') +; + unset($swift_mime_types); diff --git a/lib/swiftmailer/lib/dependency_maps/transport_deps.php b/lib/swiftmailer/lib/dependency_maps/transport_deps.php index 52c334165..56ca0590f 100644 --- a/lib/swiftmailer/lib/dependency_maps/transport_deps.php +++ b/lib/swiftmailer/lib/dependency_maps/transport_deps.php @@ -1,70 +1,76 @@ register('transport.smtp') - -> asNewInstanceOf('Swift_Transport_EsmtpTransport') - -> withDependencies(array( - 'transport.buffer', - array('transport.authhandler'), - 'transport.eventdispatcher' - )) - - -> register('transport.sendmail') - -> asNewInstanceOf('Swift_Transport_SendmailTransport') - -> withDependencies(array( - 'transport.buffer', - 'transport.eventdispatcher' - )) - - -> register('transport.mail') - -> asNewInstanceOf('Swift_Transport_MailTransport') - -> withDependencies(array('transport.mailinvoker', 'transport.eventdispatcher')) - - -> register('transport.loadbalanced') - -> asNewInstanceOf('Swift_Transport_LoadBalancedTransport') - - -> register('transport.failover') - -> asNewInstanceOf('Swift_Transport_FailoverTransport') - - -> register('transport.spool') - -> asNewInstanceOf('Swift_Transport_SpoolTransport') - -> withDependencies(array('transport.eventdispatcher')) - - -> register('transport.null') - -> asNewInstanceOf('Swift_Transport_NullTransport') - -> withDependencies(array('transport.eventdispatcher')) - - -> register('transport.mailinvoker') - -> asSharedInstanceOf('Swift_Transport_SimpleMailInvoker') - - -> register('transport.buffer') - -> asNewInstanceOf('Swift_Transport_StreamBuffer') - -> withDependencies(array('transport.replacementfactory')) - - -> register('transport.authhandler') - -> asNewInstanceOf('Swift_Transport_Esmtp_AuthHandler') - -> withDependencies(array( - array( - 'transport.crammd5auth', - 'transport.loginauth', - 'transport.plainauth' - ) - )) - - -> register('transport.crammd5auth') - -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_CramMd5Authenticator') - - -> register('transport.loginauth') - -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_LoginAuthenticator') - - -> register('transport.plainauth') - -> asNewInstanceOf('Swift_Transport_Esmtp_Auth_PlainAuthenticator') - - -> register('transport.eventdispatcher') - -> asNewInstanceOf('Swift_Events_SimpleEventDispatcher') - - -> register('transport.replacementfactory') - -> asSharedInstanceOf('Swift_StreamFilters_StringReplacementFilterFactory') - - ; + ->register('transport.smtp') + ->asNewInstanceOf('Swift_Transport_EsmtpTransport') + ->withDependencies(array( + 'transport.buffer', + array('transport.authhandler'), + 'transport.eventdispatcher' + )) + + ->register('transport.sendmail') + ->asNewInstanceOf('Swift_Transport_SendmailTransport') + ->withDependencies(array( + 'transport.buffer', + 'transport.eventdispatcher' + )) + + ->register('transport.mail') + ->asNewInstanceOf('Swift_Transport_MailTransport') + ->withDependencies(array('transport.mailinvoker', 'transport.eventdispatcher')) + + ->register('transport.loadbalanced') + ->asNewInstanceOf('Swift_Transport_LoadBalancedTransport') + + ->register('transport.failover') + ->asNewInstanceOf('Swift_Transport_FailoverTransport') + + ->register('transport.spool') + ->asNewInstanceOf('Swift_Transport_SpoolTransport') + ->withDependencies(array('transport.eventdispatcher')) + + ->register('transport.null') + ->asNewInstanceOf('Swift_Transport_NullTransport') + ->withDependencies(array('transport.eventdispatcher')) + + ->register('transport.mailinvoker') + ->asSharedInstanceOf('Swift_Transport_SimpleMailInvoker') + + ->register('transport.buffer') + ->asNewInstanceOf('Swift_Transport_StreamBuffer') + ->withDependencies(array('transport.replacementfactory')) + + ->register('transport.authhandler') + ->asNewInstanceOf('Swift_Transport_Esmtp_AuthHandler') + ->withDependencies(array( + array( + 'transport.crammd5auth', + 'transport.loginauth', + 'transport.plainauth', + 'transport.ntlmauth', + 'transport.xoauth2auth', + ) + )) + + ->register('transport.crammd5auth') + ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_CramMd5Authenticator') + + ->register('transport.loginauth') + ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_LoginAuthenticator') + + ->register('transport.plainauth') + ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_PlainAuthenticator') + + ->register('transport.xoauth2auth') + ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_XOAuth2Authenticator') + + ->register('transport.ntlmauth') + ->asNewInstanceOf('Swift_Transport_Esmtp_Auth_NTLMAuthenticator') + + ->register('transport.eventdispatcher') + ->asNewInstanceOf('Swift_Events_SimpleEventDispatcher') + + ->register('transport.replacementfactory') + ->asSharedInstanceOf('Swift_StreamFilters_StringReplacementFilterFactory') +; diff --git a/lib/swiftmailer/lib/mime_types.php b/lib/swiftmailer/lib/mime_types.php index 65c9aa077..964c34986 100644 --- a/lib/swiftmailer/lib/mime_types.php +++ b/lib/swiftmailer/lib/mime_types.php @@ -6,71 +6,1002 @@ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. + * + * autogenerated using http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types + * and https://raw.github.com/minad/mimemagic/master/script/freedesktop.org.xml */ /* * List of MIME type automatically detected in Swift Mailer. */ -//You may add or take away what you like (lowercase required) +// You may add or take away what you like (lowercase required) $swift_mime_types = array( - 'aif' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'avi' => 'video/avi', - 'bmp' => 'image/bmp', - 'bz2' => 'application/x-bz2', - 'csv' => 'text/csv', - 'dmg' => 'application/x-apple-diskimage', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'eml' => 'message/rfc822', - 'aps' => 'application/postscript', - 'exe' => 'application/x-ms-dos-executable', - 'flv' => 'video/x-flv', - 'gif' => 'image/gif', - 'gz' => 'application/x-gzip', - 'hqx' => 'application/stuffit', - 'htm' => 'text/html', - 'html' => 'text/html', - 'jar' => 'application/x-java-archive', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'm3u' => 'audio/x-mpegurl', - 'm4a' => 'audio/mp4', - 'mdb' => 'application/x-msaccess', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mov' => 'video/quicktime', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'odg' => 'vnd.oasis.opendocument.graphics', - 'odp' => 'vnd.oasis.opendocument.presentation', - 'odt' => 'vnd.oasis.opendocument.text', - 'ods' => 'vnd.oasis.opendocument.spreadsheet', - 'ogg' => 'audio/ogg', - 'pdf' => 'application/pdf', - 'png' => 'image/png', - 'ppt' => 'application/vnd.ms-powerpoint', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'ps' => 'application/postscript', - 'rar' => 'application/x-rar-compressed', - 'rtf' => 'application/rtf', - 'tar' => 'application/x-tar', - 'sit' => 'application/x-stuffit', - 'svg' => 'image/svg+xml', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'ttf' => 'application/x-font-truetype', - 'txt' => 'text/plain', - 'vcf' => 'text/x-vcard', - 'wav' => 'audio/wav', - 'wma' => 'audio/x-ms-wma', - 'wmv' => 'audio/x-ms-wmv', - 'xls' => 'application/excel', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xml' => 'application/xml', - 'zip' => 'application/zip' -); + '3dml' => 'text/vnd.in3d.3dml', + '3ds' => 'image/x-3ds', + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gpp', + '7z' => 'application/x-7z-compressed', + 'aab' => 'application/x-authorware-bin', + 'aac' => 'audio/x-aac', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abw' => 'application/x-abiword', + 'ac' => 'application/pkix-attr-cert', + 'acc' => 'application/vnd.americandynamics.acc', + 'ace' => 'application/x-ace-compressed', + 'acu' => 'application/vnd.acucobol', + 'acutc' => 'application/vnd.acucorp', + 'adp' => 'audio/adpcm', + 'aep' => 'application/vnd.audiograph', + 'afm' => 'application/x-font-type1', + 'afp' => 'application/vnd.ibm.modcap', + 'ahead' => 'application/vnd.ahead.space', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'air' => 'application/vnd.adobe.air-application-installer-package+zip', + 'ait' => 'application/vnd.dvb.ait', + 'ami' => 'application/vnd.amiga.ami', + 'apk' => 'application/vnd.android.package-archive', + 'appcache' => 'text/cache-manifest', + 'apr' => 'application/vnd.lotus-approach', + 'aps' => 'application/postscript', + 'arc' => 'application/x-freearc', + 'asc' => 'application/pgp-signature', + 'asf' => 'video/x-ms-asf', + 'asm' => 'text/x-asm', + 'aso' => 'application/vnd.accpac.simply.aso', + 'asx' => 'video/x-ms-asf', + 'atc' => 'application/vnd.acucorp', + 'atom' => 'application/atom+xml', + 'atomcat' => 'application/atomcat+xml', + 'atomsvc' => 'application/atomsvc+xml', + 'atx' => 'application/vnd.antix.game-component', + 'au' => 'audio/basic', + 'avi' => 'video/x-msvideo', + 'aw' => 'application/applixware', + 'azf' => 'application/vnd.airzip.filesecure.azf', + 'azs' => 'application/vnd.airzip.filesecure.azs', + 'azw' => 'application/vnd.amazon.ebook', + 'bat' => 'application/x-msdownload', + 'bcpio' => 'application/x-bcpio', + 'bdf' => 'application/x-font-bdf', + 'bdm' => 'application/vnd.syncml.dm+wbxml', + 'bed' => 'application/vnd.realvnc.bed', + 'bh2' => 'application/vnd.fujitsu.oasysprs', + 'bin' => 'application/octet-stream', + 'blb' => 'application/x-blorb', + 'blorb' => 'application/x-blorb', + 'bmi' => 'application/vnd.bmi', + 'bmp' => 'image/bmp', + 'book' => 'application/vnd.framemaker', + 'box' => 'application/vnd.previewsystems.box', + 'boz' => 'application/x-bzip2', + 'bpk' => 'application/octet-stream', + 'btif' => 'image/prs.btif', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/x-c', + 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', + 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', + 'c4d' => 'application/vnd.clonk.c4group', + 'c4f' => 'application/vnd.clonk.c4group', + 'c4g' => 'application/vnd.clonk.c4group', + 'c4p' => 'application/vnd.clonk.c4group', + 'c4u' => 'application/vnd.clonk.c4group', + 'cab' => 'application/vnd.ms-cab-compressed', + 'caf' => 'audio/x-caf', + 'cap' => 'application/vnd.tcpdump.pcap', + 'car' => 'application/vnd.curl.car', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cb7' => 'application/x-cbr', + 'cba' => 'application/x-cbr', + 'cbr' => 'application/x-cbr', + 'cbt' => 'application/x-cbr', + 'cbz' => 'application/x-cbr', + 'cc' => 'text/x-c', + 'cct' => 'application/x-director', + 'ccxml' => 'application/ccxml+xml', + 'cdbcmsg' => 'application/vnd.contact.cmsg', + 'cdf' => 'application/x-netcdf', + 'cdkey' => 'application/vnd.mediastation.cdkey', + 'cdmia' => 'application/cdmi-capability', + 'cdmic' => 'application/cdmi-container', + 'cdmid' => 'application/cdmi-domain', + 'cdmio' => 'application/cdmi-object', + 'cdmiq' => 'application/cdmi-queue', + 'cdx' => 'chemical/x-cdx', + 'cdxml' => 'application/vnd.chemdraw+xml', + 'cdy' => 'application/vnd.cinderella', + 'cer' => 'application/pkix-cert', + 'cfs' => 'application/x-cfs-compressed', + 'cgm' => 'image/cgm', + 'chat' => 'application/x-chat', + 'chm' => 'application/vnd.ms-htmlhelp', + 'chrt' => 'application/vnd.kde.kchart', + 'cif' => 'chemical/x-cif', + 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', + 'cil' => 'application/vnd.ms-artgalry', + 'cla' => 'application/vnd.claymore', + 'class' => 'application/java-vm', + 'clkk' => 'application/vnd.crick.clicker.keyboard', + 'clkp' => 'application/vnd.crick.clicker.palette', + 'clkt' => 'application/vnd.crick.clicker.template', + 'clkw' => 'application/vnd.crick.clicker.wordbank', + 'clkx' => 'application/vnd.crick.clicker', + 'clp' => 'application/x-msclip', + 'cmc' => 'application/vnd.cosmocaller', + 'cmdf' => 'chemical/x-cmdf', + 'cml' => 'chemical/x-cml', + 'cmp' => 'application/vnd.yellowriver-custom-menu', + 'cmx' => 'image/x-cmx', + 'cod' => 'application/vnd.rim.cod', + 'com' => 'application/x-msdownload', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/mac-compactpro', + 'crd' => 'application/x-mscardfile', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'csh' => 'application/x-csh', + 'csml' => 'chemical/x-csml', + 'csp' => 'application/vnd.commonspace', + 'css' => 'text/css', + 'cst' => 'application/x-director', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'curl' => 'text/vnd.curl', + 'cww' => 'application/prs.cww', + 'cxt' => 'application/x-director', + 'cxx' => 'text/x-c', + 'dae' => 'model/vnd.collada+xml', + 'daf' => 'application/vnd.mobius.daf', + 'dart' => 'application/vnd.dart', + 'dataless' => 'application/vnd.fdsn.seed', + 'davmount' => 'application/davmount+xml', + 'dbk' => 'application/docbook+xml', + 'dcr' => 'application/x-director', + 'dcurl' => 'text/vnd.curl.dcurl', + 'dd2' => 'application/vnd.oma.dd2+xml', + 'ddd' => 'application/vnd.fujixerox.ddd', + 'deb' => 'application/x-debian-package', + 'def' => 'text/plain', + 'deploy' => 'application/octet-stream', + 'der' => 'application/x-x509-ca-cert', + 'dfac' => 'application/vnd.dreamfactory', + 'dgc' => 'application/x-dgc-compressed', + 'dic' => 'text/x-c', + 'dir' => 'application/x-director', + 'dis' => 'application/vnd.mobius.dis', + 'dist' => 'application/octet-stream', + 'distz' => 'application/octet-stream', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/x-msdownload', + 'dmg' => 'application/x-apple-diskimage', + 'dmp' => 'application/vnd.tcpdump.pcap', + 'dms' => 'application/octet-stream', + 'dna' => 'application/vnd.dna', + 'doc' => 'application/msword', + 'docm' => 'application/vnd.ms-word.document.macroenabled.12', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot' => 'application/msword', + 'dotm' => 'application/vnd.ms-word.template.macroenabled.12', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'dp' => 'application/vnd.osgi.dp', + 'dpg' => 'application/vnd.dpgraph', + 'dra' => 'audio/vnd.dra', + 'dsc' => 'text/prs.lines.tag', + 'dssc' => 'application/dssc+der', + 'dtb' => 'application/x-dtbook+xml', + 'dtd' => 'application/xml-dtd', + 'dts' => 'audio/vnd.dts', + 'dtshd' => 'audio/vnd.dts.hd', + 'dump' => 'application/octet-stream', + 'dvb' => 'video/vnd.dvb.file', + 'dvi' => 'application/x-dvi', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/vnd.dwg', + 'dxf' => 'image/vnd.dxf', + 'dxp' => 'application/vnd.spotfire.dxp', + 'dxr' => 'application/x-director', + 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', + 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', + 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', + 'ecma' => 'application/ecmascript', + 'edm' => 'application/vnd.novadigm.edm', + 'edx' => 'application/vnd.novadigm.edx', + 'efif' => 'application/vnd.picsel', + 'ei6' => 'application/vnd.pg.osasli', + 'elc' => 'application/octet-stream', + 'emf' => 'application/x-msmetafile', + 'eml' => 'message/rfc822', + 'emma' => 'application/emma+xml', + 'emz' => 'application/x-msmetafile', + 'eol' => 'audio/vnd.digital-winds', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'es3' => 'application/vnd.eszigno3+xml', + 'esa' => 'application/vnd.osgi.subsystem', + 'esf' => 'application/vnd.epson.esf', + 'et3' => 'application/vnd.eszigno3+xml', + 'etx' => 'text/x-setext', + 'eva' => 'application/x-eva', + 'evy' => 'application/x-envoy', + 'exe' => 'application/x-msdownload', + 'exi' => 'application/exi', + 'ext' => 'application/vnd.novadigm.ext', + 'ez' => 'application/andrew-inset', + 'ez2' => 'application/vnd.ezpix-album', + 'ez3' => 'application/vnd.ezpix-package', + 'f' => 'text/x-fortran', + 'f4v' => 'video/x-f4v', + 'f77' => 'text/x-fortran', + 'f90' => 'text/x-fortran', + 'fbs' => 'image/vnd.fastbidsheet', + 'fcdt' => 'application/vnd.adobe.formscentral.fcdt', + 'fcs' => 'application/vnd.isac.fcs', + 'fdf' => 'application/vnd.fdf', + 'fe_launch' => 'application/vnd.denovo.fcselayout-link', + 'fg5' => 'application/vnd.fujitsu.oasysgp', + 'fgd' => 'application/x-director', + 'fh' => 'image/x-freehand', + 'fh4' => 'image/x-freehand', + 'fh5' => 'image/x-freehand', + 'fh7' => 'image/x-freehand', + 'fhc' => 'image/x-freehand', + 'fig' => 'application/x-xfig', + 'flac' => 'audio/x-flac', + 'fli' => 'video/x-fli', + 'flo' => 'application/vnd.micrografx.flo', + 'flv' => 'video/x-flv', + 'flw' => 'application/vnd.kde.kivio', + 'flx' => 'text/vnd.fmi.flexstor', + 'fly' => 'text/vnd.fly', + 'fm' => 'application/vnd.framemaker', + 'fnc' => 'application/vnd.frogans.fnc', + 'for' => 'text/x-fortran', + 'fpx' => 'image/vnd.fpx', + 'frame' => 'application/vnd.framemaker', + 'fsc' => 'application/vnd.fsc.weblaunch', + 'fst' => 'image/vnd.fst', + 'ftc' => 'application/vnd.fluxtime.clip', + 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', + 'fvt' => 'video/vnd.fvt', + 'fxp' => 'application/vnd.adobe.fxp', + 'fxpl' => 'application/vnd.adobe.fxp', + 'fzs' => 'application/vnd.fuzzysheet', + 'g2w' => 'application/vnd.geoplan', + 'g3' => 'image/g3fax', + 'g3w' => 'application/vnd.geospace', + 'gac' => 'application/vnd.groove-account', + 'gam' => 'application/x-tads', + 'gbr' => 'application/rpki-ghostbusters', + 'gca' => 'application/x-gca-compressed', + 'gdl' => 'model/vnd.gdl', + 'geo' => 'application/vnd.dynageo', + 'gex' => 'application/vnd.geometry-explorer', + 'ggb' => 'application/vnd.geogebra.file', + 'ggt' => 'application/vnd.geogebra.tool', + 'ghf' => 'application/vnd.groove-help', + 'gif' => 'image/gif', + 'gim' => 'application/vnd.groove-identity-message', + 'gml' => 'application/gml+xml', + 'gmx' => 'application/vnd.gmx', + 'gnumeric' => 'application/x-gnumeric', + 'gph' => 'application/vnd.flographit', + 'gpx' => 'application/gpx+xml', + 'gqf' => 'application/vnd.grafeq', + 'gqs' => 'application/vnd.grafeq', + 'gram' => 'application/srgs', + 'gramps' => 'application/x-gramps-xml', + 'gre' => 'application/vnd.geometry-explorer', + 'grv' => 'application/vnd.groove-injector', + 'grxml' => 'application/srgs+xml', + 'gsf' => 'application/x-font-ghostscript', + 'gtar' => 'application/x-gtar', + 'gtm' => 'application/vnd.groove-tool-message', + 'gtw' => 'model/vnd.gtw', + 'gv' => 'text/vnd.graphviz', + 'gxf' => 'application/gxf', + 'gxt' => 'application/vnd.geonext', + 'gz' => 'application/x-gzip', + 'h' => 'text/x-c', + 'h261' => 'video/h261', + 'h263' => 'video/h263', + 'h264' => 'video/h264', + 'hal' => 'application/vnd.hal+xml', + 'hbci' => 'application/vnd.hbci', + 'hdf' => 'application/x-hdf', + 'hh' => 'text/x-c', + 'hlp' => 'application/winhlp', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hpid' => 'application/vnd.hp-hpid', + 'hps' => 'application/vnd.hp-hps', + 'hqx' => 'application/mac-binhex40', + 'htke' => 'application/vnd.kenameaapp', + 'htm' => 'text/html', + 'html' => 'text/html', + 'hvd' => 'application/vnd.yamaha.hv-dic', + 'hvp' => 'application/vnd.yamaha.hv-voice', + 'hvs' => 'application/vnd.yamaha.hv-script', + 'i2g' => 'application/vnd.intergeo', + 'icc' => 'application/vnd.iccprofile', + 'ice' => 'x-conference/x-cooltalk', + 'icm' => 'application/vnd.iccprofile', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ief' => 'image/ief', + 'ifb' => 'text/calendar', + 'ifm' => 'application/vnd.shana.informed.formdata', + 'iges' => 'model/iges', + 'igl' => 'application/vnd.igloader', + 'igm' => 'application/vnd.insors.igm', + 'igs' => 'model/iges', + 'igx' => 'application/vnd.micrografx.igx', + 'iif' => 'application/vnd.shana.informed.interchange', + 'imp' => 'application/vnd.accpac.simply.imp', + 'ims' => 'application/vnd.ms-ims', + 'in' => 'text/plain', + 'ink' => 'application/inkml+xml', + 'inkml' => 'application/inkml+xml', + 'install' => 'application/x-install-instructions', + 'iota' => 'application/vnd.astraea-software.iota', + 'ipfix' => 'application/ipfix', + 'ipk' => 'application/vnd.shana.informed.package', + 'irm' => 'application/vnd.ibm.rights-management', + 'irp' => 'application/vnd.irepository.package+xml', + 'iso' => 'application/x-iso9660-image', + 'itp' => 'application/vnd.shana.informed.formtemplate', + 'ivp' => 'application/vnd.immervision-ivp', + 'ivu' => 'application/vnd.immervision-ivu', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'jam' => 'application/vnd.jam', + 'jar' => 'application/java-archive', + 'java' => 'text/x-java-source', + 'jisp' => 'application/vnd.jisp', + 'jlt' => 'application/vnd.hp-jlyt', + 'jnlp' => 'application/x-java-jnlp-file', + 'joda' => 'application/vnd.joost.joda-archive', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpgm' => 'video/jpm', + 'jpgv' => 'video/jpeg', + 'jpm' => 'video/jpm', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'jsonml' => 'application/jsonml+json', + 'kar' => 'audio/midi', + 'karbon' => 'application/vnd.kde.karbon', + 'kfo' => 'application/vnd.kde.kformula', + 'kia' => 'application/vnd.kidspiration', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'kmz' => 'application/vnd.google-earth.kmz', + 'kne' => 'application/vnd.kinar', + 'knp' => 'application/vnd.kinar', + 'kon' => 'application/vnd.kde.kontour', + 'kpr' => 'application/vnd.kde.kpresenter', + 'kpt' => 'application/vnd.kde.kpresenter', + 'kpxx' => 'application/vnd.ds-keypoint', + 'ksp' => 'application/vnd.kde.kspread', + 'ktr' => 'application/vnd.kahootz', + 'ktx' => 'image/ktx', + 'ktz' => 'application/vnd.kahootz', + 'kwd' => 'application/vnd.kde.kword', + 'kwt' => 'application/vnd.kde.kword', + 'lasxml' => 'application/vnd.las.las+xml', + 'latex' => 'application/x-latex', + 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', + 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', + 'les' => 'application/vnd.hhe.lesson-player', + 'lha' => 'application/x-lzh-compressed', + 'link66' => 'application/vnd.route66.link66+xml', + 'list' => 'text/plain', + 'list3820' => 'application/vnd.ibm.modcap', + 'listafp' => 'application/vnd.ibm.modcap', + 'lnk' => 'application/x-ms-shortcut', + 'log' => 'text/plain', + 'lostxml' => 'application/lost+xml', + 'lrf' => 'application/octet-stream', + 'lrm' => 'application/vnd.ms-lrm', + 'ltf' => 'application/vnd.frogans.ltf', + 'lvp' => 'audio/vnd.lucent.voice', + 'lwp' => 'application/vnd.lotus-wordpro', + 'lzh' => 'application/x-lzh-compressed', + 'm13' => 'application/x-msmediaview', + 'm14' => 'application/x-msmediaview', + 'm1v' => 'video/mpeg', + 'm21' => 'application/mp21', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3a' => 'audio/mpeg', + 'm3u' => 'audio/x-mpegurl', + 'm3u8' => 'application/vnd.apple.mpegurl', + 'm4a' => 'audio/mp4', + 'm4u' => 'video/vnd.mpegurl', + 'm4v' => 'video/x-m4v', + 'ma' => 'application/mathematica', + 'mads' => 'application/mads+xml', + 'mag' => 'application/vnd.ecowin.chart', + 'maker' => 'application/vnd.framemaker', + 'man' => 'text/troff', + 'mar' => 'application/octet-stream', + 'mathml' => 'application/mathml+xml', + 'mb' => 'application/mathematica', + 'mbk' => 'application/vnd.mobius.mbk', + 'mbox' => 'application/mbox', + 'mc1' => 'application/vnd.medcalcdata', + 'mcd' => 'application/vnd.mcd', + 'mcurl' => 'text/vnd.curl.mcurl', + 'mdb' => 'application/x-msaccess', + 'mdi' => 'image/vnd.ms-modi', + 'me' => 'text/troff', + 'mesh' => 'model/mesh', + 'meta4' => 'application/metalink4+xml', + 'metalink' => 'application/metalink+xml', + 'mets' => 'application/mets+xml', + 'mfm' => 'application/vnd.mfmp', + 'mft' => 'application/rpki-manifest', + 'mgp' => 'application/vnd.osgeo.mapguide.package', + 'mgz' => 'application/vnd.proteus.magazine', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mie' => 'application/x-mie', + 'mif' => 'application/vnd.mif', + 'mime' => 'message/rfc822', + 'mj2' => 'video/mj2', + 'mjp2' => 'video/mj2', + 'mk3d' => 'video/x-matroska', + 'mka' => 'audio/x-matroska', + 'mks' => 'video/x-matroska', + 'mkv' => 'video/x-matroska', + 'mlp' => 'application/vnd.dolby.mlp', + 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', + 'mmf' => 'application/vnd.smaf', + 'mmr' => 'image/vnd.fujixerox.edmics-mmr', + 'mng' => 'video/x-mng', + 'mny' => 'application/x-msmoney', + 'mobi' => 'application/x-mobipocket-ebook', + 'mods' => 'application/mods+xml', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp21' => 'application/mp21', + 'mp2a' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4s' => 'application/mp4', + 'mp4v' => 'video/mp4', + 'mpc' => 'application/vnd.mophun.certificate', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'mpga' => 'audio/mpeg', + 'mpkg' => 'application/vnd.apple.installer+xml', + 'mpm' => 'application/vnd.blueice.multipass', + 'mpn' => 'application/vnd.mophun.application', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/vnd.ms-project', + 'mpy' => 'application/vnd.ibm.minipay', + 'mqy' => 'application/vnd.mobius.mqy', + 'mrc' => 'application/marc', + 'mrcx' => 'application/marcxml+xml', + 'ms' => 'text/troff', + 'mscml' => 'application/mediaservercontrol+xml', + 'mseed' => 'application/vnd.fdsn.mseed', + 'mseq' => 'application/vnd.mseq', + 'msf' => 'application/vnd.epson.msf', + 'msh' => 'model/mesh', + 'msi' => 'application/x-msdownload', + 'msl' => 'application/vnd.mobius.msl', + 'msty' => 'application/vnd.muvee.style', + 'mts' => 'model/vnd.mts', + 'mus' => 'application/vnd.musician', + 'musicxml' => 'application/vnd.recordare.musicxml+xml', + 'mvb' => 'application/x-msmediaview', + 'mwf' => 'application/vnd.mfer', + 'mxf' => 'application/mxf', + 'mxl' => 'application/vnd.recordare.musicxml', + 'mxml' => 'application/xv+xml', + 'mxs' => 'application/vnd.triscape.mxs', + 'mxu' => 'video/vnd.mpegurl', + 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', + 'n3' => 'text/n3', + 'nb' => 'application/mathematica', + 'nbp' => 'application/vnd.wolfram.player', + 'nc' => 'application/x-netcdf', + 'ncx' => 'application/x-dtbncx+xml', + 'nfo' => 'text/x-nfo', + 'ngdat' => 'application/vnd.nokia.n-gage.data', + 'nitf' => 'application/vnd.nitf', + 'nlu' => 'application/vnd.neurolanguage.nlu', + 'nml' => 'application/vnd.enliven', + 'nnd' => 'application/vnd.noblenet-directory', + 'nns' => 'application/vnd.noblenet-sealer', + 'nnw' => 'application/vnd.noblenet-web', + 'npx' => 'image/vnd.net-fpx', + 'nsc' => 'application/x-conference', + 'nsf' => 'application/vnd.lotus-notes', + 'ntf' => 'application/vnd.nitf', + 'nzb' => 'application/x-nzb', + 'oa2' => 'application/vnd.fujitsu.oasys2', + 'oa3' => 'application/vnd.fujitsu.oasys3', + 'oas' => 'application/vnd.fujitsu.oasys', + 'obd' => 'application/x-msbinder', + 'obj' => 'application/x-tgif', + 'oda' => 'application/oda', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odft' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'oga' => 'audio/ogg', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'omdoc' => 'application/omdoc+xml', + 'onepkg' => 'application/onenote', + 'onetmp' => 'application/onenote', + 'onetoc' => 'application/onenote', + 'onetoc2' => 'application/onenote', + 'opf' => 'application/oebps-package+xml', + 'opml' => 'text/x-opml', + 'oprc' => 'application/vnd.palm', + 'org' => 'application/vnd.lotus-organizer', + 'osf' => 'application/vnd.yamaha.openscoreformat', + 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'otf' => 'application/x-font-otf', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oxps' => 'application/oxps', + 'oxt' => 'application/vnd.openofficeorg.extension', + 'p' => 'text/x-pascal', + 'p10' => 'application/pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7b' => 'application/x-pkcs7-certificates', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'p8' => 'application/pkcs8', + 'pas' => 'text/x-pascal', + 'paw' => 'application/vnd.pawaafile', + 'pbd' => 'application/vnd.powerbuilder6', + 'pbm' => 'image/x-portable-bitmap', + 'pcap' => 'application/vnd.tcpdump.pcap', + 'pcf' => 'application/x-font-pcf', + 'pcl' => 'application/vnd.hp-pcl', + 'pclxl' => 'application/vnd.hp-pclxl', + 'pct' => 'image/x-pict', + 'pcurl' => 'application/vnd.curl.pcurl', + 'pcx' => 'image/x-pcx', + 'pdb' => 'application/vnd.palm', + 'pdf' => 'application/pdf', + 'pfa' => 'application/x-font-type1', + 'pfb' => 'application/x-font-type1', + 'pfm' => 'application/x-font-type1', + 'pfr' => 'application/font-tdpfr', + 'pfx' => 'application/x-pkcs12', + 'pgm' => 'image/x-portable-graymap', + 'pgn' => 'application/x-chess-pgn', + 'pgp' => 'application/pgp-encrypted', + 'php' => 'application/x-php', + 'php3' => 'application/x-php', + 'php4' => 'application/x-php', + 'php5' => 'application/x-php', + 'pic' => 'image/x-pict', + 'pkg' => 'application/octet-stream', + 'pki' => 'application/pkixcmp', + 'pkipath' => 'application/pkix-pkipath', + 'plb' => 'application/vnd.3gpp.pic-bw-large', + 'plc' => 'application/vnd.mobius.plc', + 'plf' => 'application/vnd.pocketlearn', + 'pls' => 'application/pls+xml', + 'pml' => 'application/vnd.ctc-posml', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'portpkg' => 'application/vnd.macports.portpkg', + 'pot' => 'application/vnd.ms-powerpoint', + 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12', + 'ppd' => 'application/vnd.cups-ppd', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/vnd.ms-powerpoint', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'pqa' => 'application/vnd.palm', + 'prc' => 'application/x-mobipocket-ebook', + 'pre' => 'application/vnd.lotus-freelance', + 'prf' => 'application/pics-rules', + 'ps' => 'application/postscript', + 'psb' => 'application/vnd.3gpp.pic-bw-small', + 'psd' => 'image/vnd.adobe.photoshop', + 'psf' => 'application/x-font-linux-psf', + 'pskcxml' => 'application/pskc+xml', + 'ptid' => 'application/vnd.pvi.ptid1', + 'pub' => 'application/x-mspublisher', + 'pvb' => 'application/vnd.3gpp.pic-bw-var', + 'pwn' => 'application/vnd.3m.post-it-notes', + 'pya' => 'audio/vnd.ms-playready.media.pya', + 'pyv' => 'video/vnd.ms-playready.media.pyv', + 'qam' => 'application/vnd.epson.quickanime', + 'qbo' => 'application/vnd.intu.qbo', + 'qfx' => 'application/vnd.intu.qfx', + 'qps' => 'application/vnd.publishare-delta-tree', + 'qt' => 'video/quicktime', + 'qwd' => 'application/vnd.quark.quarkxpress', + 'qwt' => 'application/vnd.quark.quarkxpress', + 'qxb' => 'application/vnd.quark.quarkxpress', + 'qxd' => 'application/vnd.quark.quarkxpress', + 'qxl' => 'application/vnd.quark.quarkxpress', + 'qxt' => 'application/vnd.quark.quarkxpress', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'rar' => 'application/x-rar-compressed', + 'ras' => 'image/x-cmu-raster', + 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', + 'rdf' => 'application/rdf+xml', + 'rdz' => 'application/vnd.data-vision.rdz', + 'rep' => 'application/vnd.businessobjects', + 'res' => 'application/x-dtbresource+xml', + 'rgb' => 'image/x-rgb', + 'rif' => 'application/reginfo+xml', + 'rip' => 'audio/vnd.rip', + 'ris' => 'application/x-research-info-systems', + 'rl' => 'application/resource-lists+xml', + 'rlc' => 'image/vnd.fujixerox.edmics-rlc', + 'rld' => 'application/resource-lists-diff+xml', + 'rm' => 'application/vnd.rn-realmedia', + 'rmi' => 'audio/midi', + 'rmp' => 'audio/x-pn-realaudio-plugin', + 'rms' => 'application/vnd.jcp.javame.midlet-rms', + 'rmvb' => 'application/vnd.rn-realmedia-vbr', + 'rnc' => 'application/relax-ng-compact-syntax', + 'roa' => 'application/rpki-roa', + 'roff' => 'text/troff', + 'rp9' => 'application/vnd.cloanto.rp9', + 'rpss' => 'application/vnd.nokia.radio-presets', + 'rpst' => 'application/vnd.nokia.radio-preset', + 'rq' => 'application/sparql-query', + 'rs' => 'application/rls-services+xml', + 'rsd' => 'application/rsd+xml', + 'rss' => 'application/rss+xml', + 'rtf' => 'application/rtf', + 'rtx' => 'text/richtext', + 's' => 'text/x-asm', + 's3m' => 'audio/s3m', + 'saf' => 'application/vnd.yamaha.smaf-audio', + 'sbml' => 'application/sbml+xml', + 'sc' => 'application/vnd.ibm.secure-container', + 'scd' => 'application/x-msschedule', + 'scm' => 'application/vnd.lotus-screencam', + 'scq' => 'application/scvp-cv-request', + 'scs' => 'application/scvp-cv-response', + 'scurl' => 'text/vnd.curl.scurl', + 'sda' => 'application/vnd.stardivision.draw', + 'sdc' => 'application/vnd.stardivision.calc', + 'sdd' => 'application/vnd.stardivision.impress', + 'sdkd' => 'application/vnd.solent.sdkm+xml', + 'sdkm' => 'application/vnd.solent.sdkm+xml', + 'sdp' => 'application/sdp', + 'sdw' => 'application/vnd.stardivision.writer', + 'see' => 'application/vnd.seemail', + 'seed' => 'application/vnd.fdsn.seed', + 'sema' => 'application/vnd.sema', + 'semd' => 'application/vnd.semd', + 'semf' => 'application/vnd.semf', + 'ser' => 'application/java-serialized-object', + 'setpay' => 'application/set-payment-initiation', + 'setreg' => 'application/set-registration-initiation', + 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', + 'sfs' => 'application/vnd.spotfire.sfs', + 'sfv' => 'text/x-sfv', + 'sgi' => 'image/sgi', + 'sgl' => 'application/vnd.stardivision.writer-global', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'shf' => 'application/shf+xml', + 'sid' => 'image/x-mrsid-image', + 'sig' => 'application/pgp-signature', + 'sil' => 'audio/silk', + 'silo' => 'model/mesh', + 'sis' => 'application/vnd.symbian.install', + 'sisx' => 'application/vnd.symbian.install', + 'sit' => 'application/x-stuffit', + 'sitx' => 'application/x-stuffitx', + 'skd' => 'application/vnd.koan', + 'skm' => 'application/vnd.koan', + 'skp' => 'application/vnd.koan', + 'skt' => 'application/vnd.koan', + 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'slt' => 'application/vnd.epson.salt', + 'sm' => 'application/vnd.stepmania.stepchart', + 'smf' => 'application/vnd.stardivision.math', + 'smi' => 'application/smil+xml', + 'smil' => 'application/smil+xml', + 'smv' => 'video/x-smv', + 'smzip' => 'application/vnd.stepmania.package', + 'snd' => 'audio/basic', + 'snf' => 'application/x-font-snf', + 'so' => 'application/octet-stream', + 'spc' => 'application/x-pkcs7-certificates', + 'spf' => 'application/vnd.yamaha.smaf-phrase', + 'spl' => 'application/x-futuresplash', + 'spot' => 'text/vnd.in3d.spot', + 'spp' => 'application/scvp-vp-response', + 'spq' => 'application/scvp-vp-request', + 'spx' => 'audio/ogg', + 'sql' => 'application/x-sql', + 'src' => 'application/x-wais-source', + 'srt' => 'application/x-subrip', + 'sru' => 'application/sru+xml', + 'srx' => 'application/sparql-results+xml', + 'ssdl' => 'application/ssdl+xml', + 'sse' => 'application/vnd.kodak-descriptor', + 'ssf' => 'application/vnd.epson.ssf', + 'ssml' => 'application/ssml+xml', + 'st' => 'application/vnd.sailingtracker.track', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'std' => 'application/vnd.sun.xml.draw.template', + 'stf' => 'application/vnd.wt.stf', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'stk' => 'application/hyperstudio', + 'stl' => 'application/vnd.ms-pki.stl', + 'str' => 'application/vnd.pg.format', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'sub' => 'text/vnd.dvb.subtitle', + 'sus' => 'application/vnd.sus-calendar', + 'susp' => 'application/vnd.sus-calendar', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svc' => 'application/vnd.dvb.service', + 'svd' => 'application/vnd.svd', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + 'swa' => 'application/x-director', + 'swf' => 'application/x-shockwave-flash', + 'swi' => 'application/vnd.aristanetworks.swi', + 'sxc' => 'application/vnd.sun.xml.calc', + 'sxd' => 'application/vnd.sun.xml.draw', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sxm' => 'application/vnd.sun.xml.math', + 'sxw' => 'application/vnd.sun.xml.writer', + 't' => 'text/troff', + 't3' => 'application/x-t3vm-image', + 'taglet' => 'application/vnd.mynfc', + 'tao' => 'application/vnd.tao.intent-module-archive', + 'tar' => 'application/x-tar', + 'tcap' => 'application/vnd.3gpp2.tcap', + 'tcl' => 'application/x-tcl', + 'teacher' => 'application/vnd.smart.teacher', + 'tei' => 'application/tei+xml', + 'teicorpus' => 'application/tei+xml', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'text/plain', + 'tfi' => 'application/thraud+xml', + 'tfm' => 'application/x-tex-tfm', + 'tga' => 'image/x-tga', + 'thmx' => 'application/vnd.ms-officetheme', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tmo' => 'application/vnd.tmobile-livetv', + 'torrent' => 'application/x-bittorrent', + 'tpl' => 'application/vnd.groove-tool-template', + 'tpt' => 'application/vnd.trid.tpt', + 'tr' => 'text/troff', + 'tra' => 'application/vnd.trueapp', + 'trm' => 'application/x-msterminal', + 'tsd' => 'application/timestamped-data', + 'tsv' => 'text/tab-separated-values', + 'ttc' => 'application/x-font-ttf', + 'ttf' => 'application/x-font-ttf', + 'ttl' => 'text/turtle', + 'twd' => 'application/vnd.simtech-mindmapper', + 'twds' => 'application/vnd.simtech-mindmapper', + 'txd' => 'application/vnd.genomatix.tuxedo', + 'txf' => 'application/vnd.mobius.txf', + 'txt' => 'text/plain', + 'u32' => 'application/x-authorware-bin', + 'udeb' => 'application/x-debian-package', + 'ufd' => 'application/vnd.ufdl', + 'ufdl' => 'application/vnd.ufdl', + 'ulx' => 'application/x-glulx', + 'umj' => 'application/vnd.umajin', + 'unityweb' => 'application/vnd.unity', + 'uoml' => 'application/vnd.uoml+xml', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'urls' => 'text/uri-list', + 'ustar' => 'application/x-ustar', + 'utz' => 'application/vnd.uiq.theme', + 'uu' => 'text/x-uuencode', + 'uva' => 'audio/vnd.dece.audio', + 'uvd' => 'application/vnd.dece.data', + 'uvf' => 'application/vnd.dece.data', + 'uvg' => 'image/vnd.dece.graphic', + 'uvh' => 'video/vnd.dece.hd', + 'uvi' => 'image/vnd.dece.graphic', + 'uvm' => 'video/vnd.dece.mobile', + 'uvp' => 'video/vnd.dece.pd', + 'uvs' => 'video/vnd.dece.sd', + 'uvt' => 'application/vnd.dece.ttml+xml', + 'uvu' => 'video/vnd.uvvu.mp4', + 'uvv' => 'video/vnd.dece.video', + 'uvva' => 'audio/vnd.dece.audio', + 'uvvd' => 'application/vnd.dece.data', + 'uvvf' => 'application/vnd.dece.data', + 'uvvg' => 'image/vnd.dece.graphic', + 'uvvh' => 'video/vnd.dece.hd', + 'uvvi' => 'image/vnd.dece.graphic', + 'uvvm' => 'video/vnd.dece.mobile', + 'uvvp' => 'video/vnd.dece.pd', + 'uvvs' => 'video/vnd.dece.sd', + 'uvvt' => 'application/vnd.dece.ttml+xml', + 'uvvu' => 'video/vnd.uvvu.mp4', + 'uvvv' => 'video/vnd.dece.video', + 'uvvx' => 'application/vnd.dece.unspecified', + 'uvvz' => 'application/vnd.dece.zip', + 'uvx' => 'application/vnd.dece.unspecified', + 'uvz' => 'application/vnd.dece.zip', + 'vcard' => 'text/vcard', + 'vcd' => 'application/x-cdlink', + 'vcf' => 'text/x-vcard', + 'vcg' => 'application/vnd.groove-vcard', + 'vcs' => 'text/x-vcalendar', + 'vcx' => 'application/vnd.vcx', + 'vis' => 'application/vnd.visionary', + 'viv' => 'video/vnd.vivo', + 'vob' => 'video/x-ms-vob', + 'vor' => 'application/vnd.stardivision.writer', + 'vox' => 'application/x-authorware-bin', + 'vrml' => 'model/vrml', + 'vsd' => 'application/vnd.visio', + 'vsf' => 'application/vnd.vsf', + 'vss' => 'application/vnd.visio', + 'vst' => 'application/vnd.visio', + 'vsw' => 'application/vnd.visio', + 'vtu' => 'model/vnd.vtu', + 'vxml' => 'application/voicexml+xml', + 'w3d' => 'application/x-director', + 'wad' => 'application/x-doom', + 'wav' => 'audio/x-wav', + 'wax' => 'audio/x-ms-wax', + 'wbmp' => 'image/vnd.wap.wbmp', + 'wbs' => 'application/vnd.criticaltools.wbs+xml', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wcm' => 'application/vnd.ms-works', + 'wdb' => 'application/vnd.ms-works', + 'wdp' => 'image/vnd.ms-photo', + 'weba' => 'audio/webm', + 'webm' => 'video/webm', + 'webp' => 'image/webp', + 'wg' => 'application/vnd.pmi.widget', + 'wgt' => 'application/widget', + 'wks' => 'application/vnd.ms-works', + 'wm' => 'video/x-ms-wm', + 'wma' => 'audio/x-ms-wma', + 'wmd' => 'application/x-ms-wmd', + 'wmf' => 'application/x-msmetafile', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wmz' => 'application/x-msmetafile', + 'woff' => 'application/font-woff', + 'wpd' => 'application/vnd.wordperfect', + 'wpl' => 'application/vnd.ms-wpl', + 'wps' => 'application/vnd.ms-works', + 'wqd' => 'application/vnd.wqd', + 'wri' => 'application/x-mswrite', + 'wrl' => 'model/vrml', + 'wsdl' => 'application/wsdl+xml', + 'wspolicy' => 'application/wspolicy+xml', + 'wtb' => 'application/vnd.webturbo', + 'wvx' => 'video/x-ms-wvx', + 'x32' => 'application/x-authorware-bin', + 'x3d' => 'model/x3d+xml', + 'x3db' => 'model/x3d+binary', + 'x3dbz' => 'model/x3d+binary', + 'x3dv' => 'model/x3d+vrml', + 'x3dvz' => 'model/x3d+vrml', + 'x3dz' => 'model/x3d+xml', + 'xaml' => 'application/xaml+xml', + 'xap' => 'application/x-silverlight-app', + 'xar' => 'application/vnd.xara', + 'xbap' => 'application/x-ms-xbap', + 'xbd' => 'application/vnd.fujixerox.docuworks.binder', + 'xbm' => 'image/x-xbitmap', + 'xdf' => 'application/xcap-diff+xml', + 'xdm' => 'application/vnd.syncml.dm+xml', + 'xdp' => 'application/vnd.adobe.xdp+xml', + 'xdssc' => 'application/dssc+xml', + 'xdw' => 'application/vnd.fujixerox.docuworks', + 'xenc' => 'application/xenc+xml', + 'xer' => 'application/patch-ops-error+xml', + 'xfdf' => 'application/vnd.adobe.xfdf', + 'xfdl' => 'application/vnd.xfdl', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xhvml' => 'application/xv+xml', + 'xif' => 'image/vnd.xiff', + 'xla' => 'application/vnd.ms-excel', + 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12', + 'xlc' => 'application/vnd.ms-excel', + 'xlf' => 'application/x-xliff+xml', + 'xlm' => 'application/vnd.ms-excel', + 'xls' => 'application/vnd.ms-excel', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xlt' => 'application/vnd.ms-excel', + 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'xlw' => 'application/vnd.ms-excel', + 'xm' => 'audio/xm', + 'xml' => 'application/xml', + 'xo' => 'application/vnd.olpc-sugar', + 'xop' => 'application/xop+xml', + 'xpi' => 'application/x-xpinstall', + 'xpl' => 'application/xproc+xml', + 'xpm' => 'image/x-xpixmap', + 'xpr' => 'application/vnd.is-xpr', + 'xps' => 'application/vnd.ms-xpsdocument', + 'xpw' => 'application/vnd.intercon.formnet', + 'xpx' => 'application/vnd.intercon.formnet', + 'xsl' => 'application/xml', + 'xslt' => 'application/xslt+xml', + 'xsm' => 'application/vnd.syncml+xml', + 'xspf' => 'application/xspf+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'xvm' => 'application/xv+xml', + 'xvml' => 'application/xv+xml', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-xyz', + 'xz' => 'application/x-xz', + 'yang' => 'application/yang', + 'yin' => 'application/yin+xml', + 'z1' => 'application/x-zmachine', + 'z2' => 'application/x-zmachine', + 'z3' => 'application/x-zmachine', + 'z4' => 'application/x-zmachine', + 'z5' => 'application/x-zmachine', + 'z6' => 'application/x-zmachine', + 'z7' => 'application/x-zmachine', + 'z8' => 'application/x-zmachine', + 'zaz' => 'application/vnd.zzazz.deck+xml', + 'zip' => 'application/zip', + 'zir' => 'application/vnd.zul', + 'zirz' => 'application/vnd.zul', + 'zmm' => 'application/vnd.handheld-entertainment+xml', + '123' => 'application/vnd.lotus-1-2-3' +); \ No newline at end of file diff --git a/lib/swiftmailer/lib/preferences.php b/lib/swiftmailer/lib/preferences.php index da9602f6e..422394370 100644 --- a/lib/swiftmailer/lib/preferences.php +++ b/lib/swiftmailer/lib/preferences.php @@ -6,17 +6,30 @@ /* */ /****************************************************************************/ -// Sets the default charset so that setCharset() is not needed elsewhere -Swift_Preferences::getInstance()->setCharset('utf-8'); +$preferences = Swift_Preferences::getInstance(); -// Without these lines the default caching mechanism is "array" but this uses -// a lot of memory. -// If possible, use a disk cache to enable attaching large attachments etc -if (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir())) -{ - Swift_Preferences::getInstance() - -> setTempDir(sys_get_temp_dir()) - -> setCacheType('disk'); +// Sets the default charset so that setCharset() is not needed elsewhere +$preferences->setCharset('utf-8'); + +// Without these lines the default caching mechanism is "array" but this uses a lot of memory. +// If possible, use a disk cache to enable attaching large attachments etc. +// You can override the default temporary directory by setting the TMPDIR environment variable. + +// The @ operator in front of is_writable calls is to avoid PHP warnings +// when using open_basedir +$tmp = getenv('TMPDIR'); +if ($tmp && @is_writable($tmp)) { + $preferences + ->setTempDir($tmp) + ->setCacheType('disk'); +} elseif (function_exists('sys_get_temp_dir') && @is_writable(sys_get_temp_dir())) { + $preferences + ->setTempDir(sys_get_temp_dir()) + ->setCacheType('disk'); } -Swift_Preferences::getInstance()->setQPDotEscape(false); +// this should only be done when Swiftmailer won't use the native QP content encoder +// see mime_deps.php +if (version_compare(phpversion(), '5.4.7', '<')) { + $preferences->setQPDotEscape(false); +} diff --git a/lib/swiftmailer/lib/swift_init.php b/lib/swiftmailer/lib/swift_init.php index 77807676a..5c80b05c1 100644 --- a/lib/swiftmailer/lib/swift_init.php +++ b/lib/swiftmailer/lib/swift_init.php @@ -12,16 +12,17 @@ * Dependency injection initialization for Swift Mailer. */ -if (defined('SWIFT_INIT_LOADED')) - return; +if (defined('SWIFT_INIT_LOADED')) { + return; +} define('SWIFT_INIT_LOADED', true); -//Load in dependency maps +// Load in dependency maps require dirname(__FILE__) . '/dependency_maps/cache_deps.php'; require dirname(__FILE__) . '/dependency_maps/mime_deps.php'; require dirname(__FILE__) . '/dependency_maps/message_deps.php'; require dirname(__FILE__) . '/dependency_maps/transport_deps.php'; -//Load in global library preferences +// Load in global library preferences require dirname(__FILE__) . '/preferences.php'; diff --git a/lib/swiftmailer/lib/swift_required.php b/lib/swiftmailer/lib/swift_required.php index aba342a2e..d64d26ed6 100644 --- a/lib/swiftmailer/lib/swift_required.php +++ b/lib/swiftmailer/lib/swift_required.php @@ -12,16 +12,19 @@ * Autoloader and dependency injection initialization for Swift Mailer. */ -if (defined('SWIFT_REQUIRED_LOADED')) - return; +if (class_exists('Swift', false)) { + return; +} -define('SWIFT_REQUIRED_LOADED', true); - -//Load Swift utility class +// Load Swift utility class require dirname(__FILE__) . '/classes/Swift.php'; -//Start the autoloader -Swift::registerAutoload(); +if (!function_exists('_swiftmailer_init')) { + function _swiftmailer_init() + { + require dirname(__FILE__) . '/swift_init.php'; + } +} -//Load the init script to set up dependency injection -require dirname(__FILE__) . '/swift_init.php'; +// Start the autoloader and lazy-load the init script to set up dependency injection +Swift::registerAutoload('_swiftmailer_init'); diff --git a/lib/swiftmailer/lib/swift_required_pear.php b/lib/swiftmailer/lib/swift_required_pear.php index cf7261a8e..05acc3237 100644 --- a/lib/swiftmailer/lib/swift_required_pear.php +++ b/lib/swiftmailer/lib/swift_required_pear.php @@ -12,16 +12,19 @@ * Autoloader and dependency injection initialization for Swift Mailer. */ -if (defined('SWIFT_REQUIRED_LOADED')) - return; +if (class_exists('Swift', false)) { + return; +} -define('SWIFT_REQUIRED_LOADED', true); - -//Load Swift utility class +// Load Swift utility class require dirname(__FILE__) . '/Swift.php'; -//Start the autoloader -Swift::registerAutoload(); +if (!function_exists('_swiftmailer_init')) { + function _swiftmailer_init() + { + require dirname(__FILE__) . '/swift_init.php'; + } +} -//Load the init script to set up dependency injection -require dirname(__FILE__) . '/swift_init.php'; +// Start the autoloader and lazy-load the init script to set up dependency injection +Swift::registerAutoload('_swiftmailer_init');