From 4861b21b7037a6c4e4ee7a6df69462a830219b6f Mon Sep 17 00:00:00 2001 From: wilsonge Date: Sat, 19 Dec 2015 02:10:28 +0000 Subject: [PATCH] Update PHPMailer to 5.2.14 --- .gitignore | 2 + administrator/components/com_admin/script.php | 1 + composer.json | 2 +- composer.lock | 26 +- libraries/vendor/composer/ClassLoader.php | 6 +- .../vendor/composer/autoload_classmap.php | 4 + libraries/vendor/composer/autoload_files.php | 6 +- libraries/vendor/composer/autoload_real.php | 12 +- libraries/vendor/composer/installed.json | 118 +- libraries/vendor/phpmailer/phpmailer/VERSION | 1 + .../phpmailer/phpmailer/class.phpmailer.php | 1161 ++++-- .../phpmailer/class.phpmaileroauth.php | 196 + .../phpmailer/class.phpmaileroauthgoogle.php | 76 + .../vendor/phpmailer/phpmailer/class.pop3.php | 84 +- .../vendor/phpmailer/phpmailer/class.smtp.php | 365 +- .../vendor/phpmailer/phpmailer/composer.lock | 3458 +++++++++++++++++ .../phpmailer/extras/EasyPeasyICS.php | 214 +- .../phpmailer/extras/class.html2text.php | 677 ---- .../phpmailer/phpmailer/extras/htmlfilter.php | 768 ++-- .../phpmailer/extras/ntlm_sasl_client.php | 332 +- 20 files changed, 5797 insertions(+), 1712 deletions(-) create mode 100644 libraries/vendor/phpmailer/phpmailer/VERSION create mode 100644 libraries/vendor/phpmailer/phpmailer/class.phpmaileroauth.php create mode 100644 libraries/vendor/phpmailer/phpmailer/class.phpmaileroauthgoogle.php create mode 100644 libraries/vendor/phpmailer/phpmailer/composer.lock delete mode 100644 libraries/vendor/phpmailer/phpmailer/extras/class.html2text.php diff --git a/.gitignore b/.gitignore index d6e79cd498759..7df8f0215e4b2 100644 --- a/.gitignore +++ b/.gitignore @@ -106,6 +106,8 @@ Desktop.ini /libraries/vendor/phpmailer/phpmailer/composer.json /libraries/vendor/phpmailer/phpmailer/README.md /libraries/vendor/phpmailer/phpmailer/travis.phpunit.xml.dist +/libraries/vendor/phpmailer/phpmailer/extras/README.md +/libraries/vendor/phpmailer/phpmailer/get_oauth_token.php /libraries/vendor/psr/log/Psr/Log/Test /libraries/vendor/psr/log/.gitignore /libraries/vendor/psr/log/composer.json diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php index 2762b5a6dbb36..7d38b791e02c5 100644 --- a/administrator/components/com_admin/script.php +++ b/administrator/components/com_admin/script.php @@ -1471,6 +1471,7 @@ public function deleteUnexistingFiles() '/libraries/vendor/symfony/yaml/Symfony/Component', '/libraries/vendor/symfony/yaml/Symfony', '/administrator/components/com_tags/helpers', + '/libraries/vendor/phpmailer/phpmailer/extras/class.html2text.php', ); jimport('joomla.filesystem.file'); diff --git a/composer.json b/composer.json index b0ba2e5eb802d..9e1cac2f0d7eb 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "ircmaxell/password-compat": "1.*", "leafo/lessphp": "0.3.9", "paragonie/random_compat": "~1.0", - "phpmailer/phpmailer": "5.2.9", + "phpmailer/phpmailer": "5.2.14", "symfony/polyfill-php56": "~1.0", "symfony/yaml": "2.*" }, diff --git a/composer.lock b/composer.lock index 3931b1ce3a8a3..3da1e6518d629 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "95f124c32e010ff993d660ee0c98188b", - "content-hash": "49979472d61e44eba9b2d42a6ab04886", + "hash": "684c7db12dc7f9de7e939f46930cd9be", + "content-hash": "3fe2809a805463b5353fd2cf269e2ee6", "packages": [ { "name": "ircmaxell/password-compat", @@ -650,16 +650,16 @@ }, { "name": "phpmailer/phpmailer", - "version": "v5.2.9", + "version": "v5.2.14", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "73b61679809615850706f1dbf88e6df2ddc05745" + "reference": "e774bc9152de85547336e22b8926189e582ece95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/73b61679809615850706f1dbf88e6df2ddc05745", - "reference": "73b61679809615850706f1dbf88e6df2ddc05745", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e774bc9152de85547336e22b8926189e582ece95", + "reference": "e774bc9152de85547336e22b8926189e582ece95", "shasum": "" }, "require": { @@ -667,14 +667,22 @@ }, "require-dev": { "phpdocumentor/phpdocumentor": "*", - "phpunit/phpunit": "4.1.*" + "phpunit/phpunit": "4.7.*" + }, + "suggest": { + "league/oauth2-client": "Needed for XOAUTH2 authentication", + "league/oauth2-google": "Needed for Gmail XOAUTH2" }, "type": "library", "autoload": { "classmap": [ "class.phpmailer.php", + "class.phpmaileroauth.php", + "class.phpmaileroauthgoogle.php", + "class.smtp.php", "class.pop3.php", - "class.smtp.php" + "extras/EasyPeasyICS.php", + "extras/ntlm_sasl_client.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -699,7 +707,7 @@ } ], "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "time": "2014-09-26 18:33:30" + "time": "2015-11-01 10:15:28" }, { "name": "psr/log", diff --git a/libraries/vendor/composer/ClassLoader.php b/libraries/vendor/composer/ClassLoader.php index 5e1469e8307d9..990cfdcfa2296 100644 --- a/libraries/vendor/composer/ClassLoader.php +++ b/libraries/vendor/composer/ClassLoader.php @@ -13,9 +13,7 @@ namespace Composer\Autoload; /** - * ClassLoader implements a PSR-0 class loader - * - * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. * * $loader = new \Composer\Autoload\ClassLoader(); * @@ -39,6 +37,8 @@ * * @author Fabien Potencier * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ */ class ClassLoader { diff --git a/libraries/vendor/composer/autoload_classmap.php b/libraries/vendor/composer/autoload_classmap.php index 531fe8d2b3285..d6330d2166453 100644 --- a/libraries/vendor/composer/autoload_classmap.php +++ b/libraries/vendor/composer/autoload_classmap.php @@ -7,8 +7,11 @@ return array( 'CallbackFilterIterator' => $vendorDir . '/joomla/compat/src/CallbackFilterIterator.php', + 'EasyPeasyICS' => $vendorDir . '/phpmailer/phpmailer/extras/EasyPeasyICS.php', 'JsonSerializable' => $vendorDir . '/joomla/compat/src/JsonSerializable.php', 'PHPMailer' => $vendorDir . '/phpmailer/phpmailer/class.phpmailer.php', + 'PHPMailerOAuth' => $vendorDir . '/phpmailer/phpmailer/class.phpmaileroauth.php', + 'PHPMailerOAuthGoogle' => $vendorDir . '/phpmailer/phpmailer/class.phpmaileroauthgoogle.php', 'POP3' => $vendorDir . '/phpmailer/phpmailer/class.pop3.php', 'SMTP' => $vendorDir . '/phpmailer/phpmailer/class.smtp.php', 'lessc' => $vendorDir . '/leafo/lessphp/lessc.inc.php', @@ -16,5 +19,6 @@ 'lessc_formatter_compressed' => $vendorDir . '/leafo/lessphp/lessc.inc.php', 'lessc_formatter_lessjs' => $vendorDir . '/leafo/lessphp/lessc.inc.php', 'lessc_parser' => $vendorDir . '/leafo/lessphp/lessc.inc.php', + 'ntlm_sasl_client_class' => $vendorDir . '/phpmailer/phpmailer/extras/ntlm_sasl_client.php', 'phpmailerException' => $vendorDir . '/phpmailer/phpmailer/class.phpmailer.php', ); diff --git a/libraries/vendor/composer/autoload_files.php b/libraries/vendor/composer/autoload_files.php index a896f89286bfb..b36e7f98276f5 100644 --- a/libraries/vendor/composer/autoload_files.php +++ b/libraries/vendor/composer/autoload_files.php @@ -6,7 +6,7 @@ $baseDir = dirname(dirname($vendorDir)); return array( - $vendorDir . '/ircmaxell/password-compat/lib/password.php', - $vendorDir . '/paragonie/random_compat/lib/random.php', - $vendorDir . '/symfony/polyfill-php56/bootstrap.php', + 'e40631d46120a9c38ea139981f8dab26' => $vendorDir . '/ircmaxell/password-compat/lib/password.php', + '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php', + 'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php', ); diff --git a/libraries/vendor/composer/autoload_real.php b/libraries/vendor/composer/autoload_real.php index 024522060c11a..191a3f253b576 100644 --- a/libraries/vendor/composer/autoload_real.php +++ b/libraries/vendor/composer/autoload_real.php @@ -41,15 +41,19 @@ public static function getLoader() $loader->register(true); $includeFiles = require __DIR__ . '/autoload_files.php'; - foreach ($includeFiles as $file) { - composerRequire0efb534ee20646bcb987f4359c38b3aa($file); + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire0efb534ee20646bcb987f4359c38b3aa($fileIdentifier, $file); } return $loader; } } -function composerRequire0efb534ee20646bcb987f4359c38b3aa($file) +function composerRequire0efb534ee20646bcb987f4359c38b3aa($fileIdentifier, $file) { - require $file; + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } } diff --git a/libraries/vendor/composer/installed.json b/libraries/vendor/composer/installed.json index 88428164adc47..1eaea909a2c74 100644 --- a/libraries/vendor/composer/installed.json +++ b/libraries/vendor/composer/installed.json @@ -215,61 +215,6 @@ "password" ] }, - { - "name": "phpmailer/phpmailer", - "version": "v5.2.9", - "version_normalized": "5.2.9.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "73b61679809615850706f1dbf88e6df2ddc05745" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/73b61679809615850706f1dbf88e6df2ddc05745", - "reference": "73b61679809615850706f1dbf88e6df2ddc05745", - "shasum": "" - }, - "require": { - "php": ">=5.0.0" - }, - "require-dev": { - "phpdocumentor/phpdocumentor": "*", - "phpunit/phpunit": "4.1.*" - }, - "time": "2014-09-26 18:33:30", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "class.phpmailer.php", - "class.pop3.php", - "class.smtp.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1" - ], - "authors": [ - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP" - }, { "name": "joomla/utilities", "version": "1.3.3", @@ -925,5 +870,68 @@ "portable", "shim" ] + }, + { + "name": "phpmailer/phpmailer", + "version": "v5.2.14", + "version_normalized": "5.2.14.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "e774bc9152de85547336e22b8926189e582ece95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e774bc9152de85547336e22b8926189e582ece95", + "reference": "e774bc9152de85547336e22b8926189e582ece95", + "shasum": "" + }, + "require": { + "php": ">=5.0.0" + }, + "require-dev": { + "phpdocumentor/phpdocumentor": "*", + "phpunit/phpunit": "4.7.*" + }, + "suggest": { + "league/oauth2-client": "Needed for XOAUTH2 authentication", + "league/oauth2-google": "Needed for Gmail XOAUTH2" + }, + "time": "2015-11-01 10:15:28", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "class.phpmailer.php", + "class.phpmaileroauth.php", + "class.phpmaileroauthgoogle.php", + "class.smtp.php", + "class.pop3.php", + "extras/EasyPeasyICS.php", + "extras/ntlm_sasl_client.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP" } ] diff --git a/libraries/vendor/phpmailer/phpmailer/VERSION b/libraries/vendor/phpmailer/phpmailer/VERSION new file mode 100644 index 0000000000000..ba678f2d2cf28 --- /dev/null +++ b/libraries/vendor/phpmailer/phpmailer/VERSION @@ -0,0 +1 @@ +5.2.14 \ No newline at end of file diff --git a/libraries/vendor/phpmailer/phpmailer/class.phpmailer.php b/libraries/vendor/phpmailer/phpmailer/class.phpmailer.php index cd102a285944f..e4dd00bf39eaa 100644 --- a/libraries/vendor/phpmailer/phpmailer/class.phpmailer.php +++ b/libraries/vendor/phpmailer/phpmailer/class.phpmailer.php @@ -29,65 +29,66 @@ class PHPMailer { /** * The PHPMailer Version number. - * @type string + * @var string */ - public $Version = '5.2.9'; + public $Version = '5.2.14'; /** * Email priority. - * Options: 1 = High, 3 = Normal, 5 = low. - * @type integer + * Options: null (default), 1 = High, 3 = Normal, 5 = low. + * When null, the header is not set at all. + * @var integer */ - public $Priority = 3; + public $Priority = null; /** * The character set of the message. - * @type string + * @var string */ public $CharSet = 'iso-8859-1'; /** * The MIME Content-type of the message. - * @type string + * @var string */ public $ContentType = 'text/plain'; /** * The message encoding. * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable". - * @type string + * @var string */ public $Encoding = '8bit'; /** * Holds the most recent mailer error message. - * @type string + * @var string */ public $ErrorInfo = ''; /** * The From email address for the message. - * @type string + * @var string */ public $From = 'root@localhost'; /** * The From name of the message. - * @type string + * @var string */ public $FromName = 'Root User'; /** * The Sender email (Return-Path) of the message. * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. - * @type string + * @var string */ public $Sender = ''; /** * The Return-Path of the message. * If empty, it will be set to either From or Sender. - * @type string + * @var string * @deprecated Email senders should never set a return-path header; * it's the receiver's job (RFC5321 section 4.4), so this no longer does anything. * @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference @@ -96,14 +97,14 @@ class PHPMailer /** * The Subject of the message. - * @type string + * @var string */ public $Subject = ''; /** * An HTML or plain text message body. * If HTML then call isHTML(true). - * @type string + * @var string */ public $Body = ''; @@ -112,7 +113,7 @@ class PHPMailer * This body can be read by mail clients that do not have HTML email * capability such as mutt & Eudora. * Clients that can read HTML will view the normal Body. - * @type string + * @var string */ public $AltBody = ''; @@ -122,91 +123,92 @@ class PHPMailer * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/ * @link http://kigkonsult.se/iCalcreator/ - * @type string + * @var string */ public $Ical = ''; /** * The complete compiled MIME message body. * @access protected - * @type string + * @var string */ protected $MIMEBody = ''; /** * The complete compiled MIME message headers. - * @type string + * @var string * @access protected */ protected $MIMEHeader = ''; /** * Extra headers that createHeader() doesn't fold in. - * @type string + * @var string * @access protected */ protected $mailHeader = ''; /** * Word-wrap the message body to this number of chars. - * @type integer + * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance. + * @var integer */ public $WordWrap = 0; /** * Which method to use to send mail. * Options: "mail", "sendmail", or "smtp". - * @type string + * @var string */ public $Mailer = 'mail'; /** * The path to the sendmail program. - * @type string + * @var string */ public $Sendmail = '/usr/sbin/sendmail'; /** * Whether mail() uses a fully sendmail-compatible MTA. * One which supports sendmail's "-oi -f" options. - * @type boolean + * @var boolean */ public $UseSendmailOptions = true; /** * Path to PHPMailer plugins. * Useful if the SMTP class is not in the PHP include path. - * @type string + * @var string * @deprecated Should not be needed now there is an autoloader. */ public $PluginDir = ''; /** - * The email address that a reading confirmation should be sent to. - * @type string + * The email address that a reading confirmation should be sent to, also known as read receipt. + * @var string */ public $ConfirmReadingTo = ''; /** - * The hostname to use in Message-Id and Received headers - * and as default HELO string. - * If empty, the value returned - * by SERVER_NAME is used or 'localhost.localdomain'. - * @type string + * The hostname to use in the Message-ID header and as default HELO string. + * If empty, PHPMailer attempts to find one with, in order, + * $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value + * 'localhost.localdomain'. + * @var string */ public $Hostname = ''; /** - * An ID to be used in the Message-Id header. + * An ID to be used in the Message-ID header. * If empty, a unique id will be generated. - * @type string + * @var string */ public $MessageID = ''; /** * The message Date to be used in the Date header. * If empty, the current date will be added. - * @type string + * @var string */ public $MessageDate = ''; @@ -219,79 +221,95 @@ class PHPMailer * You can also specify encryption type, for example: * (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465"). * Hosts will be tried in order. - * @type string + * @var string */ public $Host = 'localhost'; /** * The default SMTP server port. - * @type integer + * @var integer * @TODO Why is this needed when the SMTP class takes care of it? */ public $Port = 25; /** * The SMTP HELO of the message. - * Default is $Hostname. - * @type string + * Default is $Hostname. If $Hostname is empty, PHPMailer attempts to find + * one with the same method described above for $Hostname. + * @var string * @see PHPMailer::$Hostname */ public $Helo = ''; /** - * The secure connection prefix. - * Options: "", "ssl" or "tls" - * @type string + * What kind of encryption to use on the SMTP connection. + * Options: '', 'ssl' or 'tls' + * @var string */ public $SMTPSecure = ''; + /** + * Whether to enable TLS encryption automatically if a server supports it, + * even if `SMTPSecure` is not set to 'tls'. + * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid. + * @var boolean + */ + public $SMTPAutoTLS = true; + /** * Whether to use SMTP authentication. * Uses the Username and Password properties. - * @type boolean + * @var boolean * @see PHPMailer::$Username * @see PHPMailer::$Password */ public $SMTPAuth = false; + /** + * Options array passed to stream_context_create when connecting via SMTP. + * @var array + */ + public $SMTPOptions = array(); + /** * SMTP username. - * @type string + * @var string */ public $Username = ''; /** * SMTP password. - * @type string + * @var string */ public $Password = ''; /** * SMTP auth type. * Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5 - * @type string + * @var string */ public $AuthType = ''; /** * SMTP realm. * Used for NTLM auth - * @type string + * @var string */ public $Realm = ''; /** * SMTP workstation. * Used for NTLM auth - * @type string + * @var string */ public $Workstation = ''; /** * The SMTP server timeout in seconds. - * @type integer + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 + * @var integer */ - public $Timeout = 10; + public $Timeout = 300; /** * SMTP class debug output mode. @@ -302,7 +320,7 @@ class PHPMailer * * `2` Data and commands * * `3` As 2 plus connection status * * `4` Low-level data output - * @type integer + * @var integer * @see SMTP::$do_debug */ public $SMTPDebug = 0; @@ -318,7 +336,7 @@ class PHPMailer * * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";}; * - * @type string|callable + * @var string|callable * @see SMTP::$Debugoutput */ public $Debugoutput = 'echo'; @@ -327,20 +345,20 @@ class PHPMailer * Whether to keep SMTP connection open after each message. * If this is set to true then to close the connection * requires an explicit call to smtpClose(). - * @type boolean + * @var boolean */ public $SMTPKeepAlive = false; /** * Whether to split multiple to addresses into multiple messages * or send them all in one message. - * @type boolean + * @var boolean */ public $SingleTo = false; /** * Storage for addresses when SingleTo is enabled. - * @type array + * @var array * @TODO This should really not be public */ public $SingleToArray = array(); @@ -348,15 +366,15 @@ class PHPMailer /** * Whether to generate VERP addresses on send. * Only applicable when sending via SMTP. - * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path + * @link https://en.wikipedia.org/wiki/Variable_envelope_return_path * @link http://www.postfix.org/VERP_README.html Postfix VERP info - * @type boolean + * @var boolean */ public $do_verp = false; /** * Whether to allow sending messages with an empty body. - * @type boolean + * @var boolean */ public $AllowEmpty = false; @@ -364,40 +382,40 @@ class PHPMailer * The default line ending. * @note The default remains "\n". We force CRLF where we know * it must be used via self::CRLF. - * @type string + * @var string */ public $LE = "\n"; /** * DKIM selector. - * @type string + * @var string */ public $DKIM_selector = ''; /** * DKIM Identity. * Usually the email address used as the source of the email - * @type string + * @var string */ public $DKIM_identity = ''; /** * DKIM passphrase. * Used if your key is encrypted. - * @type string + * @var string */ public $DKIM_passphrase = ''; /** * DKIM signing domain name. * @example 'example.com' - * @type string + * @var string */ public $DKIM_domain = ''; /** * DKIM private key file path. - * @type string + * @var string */ public $DKIM_private = ''; @@ -417,138 +435,175 @@ class PHPMailer * string $subject the subject * string $body the email body * string $from email address of sender - * @type string + * @var string */ public $action_function = ''; /** - * What to use in the X-Mailer header. - * Options: null for default, whitespace for none, or a string to use - * @type string + * What to put in the X-Mailer header. + * Options: An empty string for PHPMailer default, whitespace for none, or a string to use + * @var string */ public $XMailer = ''; /** * An instance of the SMTP sender class. - * @type SMTP + * @var SMTP * @access protected */ protected $smtp = null; /** - * The array of 'to' addresses. - * @type array + * The array of 'to' names and addresses. + * @var array * @access protected */ protected $to = array(); /** - * The array of 'cc' addresses. - * @type array + * The array of 'cc' names and addresses. + * @var array * @access protected */ protected $cc = array(); /** - * The array of 'bcc' addresses. - * @type array + * The array of 'bcc' names and addresses. + * @var array * @access protected */ protected $bcc = array(); /** * The array of reply-to names and addresses. - * @type array + * @var array * @access protected */ protected $ReplyTo = array(); /** * An array of all kinds of addresses. - * Includes all of $to, $cc, $bcc, $replyto - * @type array + * Includes all of $to, $cc, $bcc + * @var array * @access protected + * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc */ protected $all_recipients = array(); + /** + * An array of names and addresses queued for validation. + * In send(), valid and non duplicate entries are moved to $all_recipients + * and one of $to, $cc, or $bcc. + * This array is used only for addresses with IDN. + * @var array + * @access protected + * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc + * @see PHPMailer::$all_recipients + */ + protected $RecipientsQueue = array(); + + /** + * An array of reply-to names and addresses queued for validation. + * In send(), valid and non duplicate entries are moved to $ReplyTo. + * This array is used only for addresses with IDN. + * @var array + * @access protected + * @see PHPMailer::$ReplyTo + */ + protected $ReplyToQueue = array(); + /** * The array of attachments. - * @type array + * @var array * @access protected */ protected $attachment = array(); /** * The array of custom headers. - * @type array + * @var array * @access protected */ protected $CustomHeader = array(); /** * The most recent Message-ID (including angular brackets). - * @type string + * @var string * @access protected */ protected $lastMessageID = ''; /** * The message's MIME type. - * @type string + * @var string * @access protected */ protected $message_type = ''; /** * The array of MIME boundary strings. - * @type array + * @var array * @access protected */ protected $boundary = array(); /** * The array of available languages. - * @type array + * @var array * @access protected */ protected $language = array(); /** * The number of errors encountered. - * @type integer + * @var integer * @access protected */ protected $error_count = 0; /** * The S/MIME certificate file path. - * @type string + * @var string * @access protected */ protected $sign_cert_file = ''; /** * The S/MIME key file path. - * @type string + * @var string * @access protected */ protected $sign_key_file = ''; + /** + * The optional S/MIME extra certificates ("CA Chain") file path. + * @var string + * @access protected + */ + protected $sign_extracerts_file = ''; + /** * The S/MIME password for the key. * Used only if the key is encrypted. - * @type string + * @var string * @access protected */ protected $sign_key_pass = ''; /** * Whether to throw exceptions for errors. - * @type boolean + * @var boolean * @access protected */ protected $exceptions = false; + /** + * Unique ID used for message ID and boundaries. + * @var string + * @access protected + */ + protected $uniqueid = ''; + /** * Error severity: message only, continue processing. */ @@ -569,13 +624,19 @@ class PHPMailer */ const CRLF = "\r\n"; + /** + * The maximum line length allowed by RFC 2822 section 2.1.1 + * @var integer + */ + const MAX_LINE_LENGTH = 998; + /** * Constructor. * @param boolean $exceptions Should we throw external exceptions? */ public function __construct($exceptions = false) { - $this->exceptions = ($exceptions == true); + $this->exceptions = (boolean)$exceptions; } /** @@ -583,7 +644,8 @@ public function __construct($exceptions = false) */ public function __destruct() { - if ($this->Mailer == 'smtp') { //close any open SMTP connection nicely + //Close any open SMTP connection nicely + if ($this->Mailer == 'smtp') { $this->smtpClose(); } } @@ -629,7 +691,8 @@ protected function edebug($str) if ($this->SMTPDebug <= 0) { return; } - if (is_callable($this->Debugoutput)) { + //Avoid clash with built-in function names + if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) { call_user_func($this->Debugoutput, $str, $this->SMTPDebug); return; } @@ -725,55 +788,101 @@ public function isQmail() /** * Add a "To" address. - * @param string $address + * @param string $address The email address to send to * @param string $name - * @return boolean true on success, false if address already used + * @return boolean true on success, false if address already used or invalid in some way */ public function addAddress($address, $name = '') { - return $this->addAnAddress('to', $address, $name); + return $this->addOrEnqueueAnAddress('to', $address, $name); } /** * Add a "CC" address. * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer. - * @param string $address + * @param string $address The email address to send to * @param string $name - * @return boolean true on success, false if address already used + * @return boolean true on success, false if address already used or invalid in some way */ public function addCC($address, $name = '') { - return $this->addAnAddress('cc', $address, $name); + return $this->addOrEnqueueAnAddress('cc', $address, $name); } /** * Add a "BCC" address. * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer. - * @param string $address + * @param string $address The email address to send to * @param string $name - * @return boolean true on success, false if address already used + * @return boolean true on success, false if address already used or invalid in some way */ public function addBCC($address, $name = '') { - return $this->addAnAddress('bcc', $address, $name); + return $this->addOrEnqueueAnAddress('bcc', $address, $name); } /** - * Add a "Reply-to" address. - * @param string $address + * Add a "Reply-To" address. + * @param string $address The email address to reply to * @param string $name - * @return boolean + * @return boolean true on success, false if address already used or invalid in some way */ public function addReplyTo($address, $name = '') { - return $this->addAnAddress('Reply-To', $address, $name); + return $this->addOrEnqueueAnAddress('Reply-To', $address, $name); } /** - * Add an address to one of the recipient arrays. - * Addresses that have been added already return false, but do not throw exceptions - * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo' - * @param string $address The email address to send to + * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer + * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still + * be modified after calling this function), addition of such addresses is delayed until send(). + * Addresses that have been added already return false, but do not throw exceptions. + * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo' + * @param string $address The email address to send, resp. to reply to + * @param string $name + * @throws phpmailerException + * @return boolean true on success, false if address already used or invalid in some way + * @access protected + */ + protected function addOrEnqueueAnAddress($kind, $address, $name) + { + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (($pos = strrpos($address, '@')) === false) { + // At-sign is misssing. + $error_message = $this->lang('invalid_address') . $address; + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new phpmailerException($error_message); + } + return false; + } + $params = array($kind, $address, $name); + // Enqueue addresses with IDN until we know the PHPMailer::$CharSet. + if ($this->has8bitChars(substr($address, ++$pos)) and $this->idnSupported()) { + if ($kind != 'Reply-To') { + if (!array_key_exists($address, $this->RecipientsQueue)) { + $this->RecipientsQueue[$address] = $params; + return true; + } + } else { + if (!array_key_exists($address, $this->ReplyToQueue)) { + $this->ReplyToQueue[$address] = $params; + return true; + } + } + return false; + } + // Immediately add standard addresses without IDN. + return call_user_func_array(array($this, 'addAnAddress'), $params); + } + + /** + * Add an address to one of the recipient arrays or to the ReplyTo array. + * Addresses that have been added already return false, but do not throw exceptions. + * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo' + * @param string $address The email address to send, resp. to reply to * @param string $name * @throws phpmailerException * @return boolean true on success, false if address already used or invalid in some way @@ -781,26 +890,26 @@ public function addReplyTo($address, $name = '') */ protected function addAnAddress($kind, $address, $name = '') { - if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) { - $this->setError($this->lang('Invalid recipient array') . ': ' . $kind); - $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind); + if (!in_array($kind, array('to', 'cc', 'bcc', 'Reply-To'))) { + $error_message = $this->lang('Invalid recipient kind: ') . $kind; + $this->setError($error_message); + $this->edebug($error_message); if ($this->exceptions) { - throw new phpmailerException('Invalid recipient array: ' . $kind); + throw new phpmailerException($error_message); } return false; } - $address = trim($address); - $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim if (!$this->validateAddress($address)) { - $this->setError($this->lang('invalid_address') . ': ' . $address); - $this->edebug($this->lang('invalid_address') . ': ' . $address); + $error_message = $this->lang('invalid_address') . $address; + $this->setError($error_message); + $this->edebug($error_message); if ($this->exceptions) { - throw new phpmailerException($this->lang('invalid_address') . ': ' . $address); + throw new phpmailerException($error_message); } return false; } if ($kind != 'Reply-To') { - if (!isset($this->all_recipients[strtolower($address)])) { + if (!array_key_exists(strtolower($address), $this->all_recipients)) { array_push($this->$kind, array($address, $name)); $this->all_recipients[strtolower($address)] = true; return true; @@ -814,6 +923,61 @@ protected function addAnAddress($kind, $address, $name = '') return false; } + /** + * Parse and validate a string containing one or more RFC822-style comma-separated email addresses + * of the form "display name
" into an array of name/address pairs. + * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available. + * Note that quotes in the name part are removed. + * @param string $addrstr The address list string + * @param bool $useimap Whether to use the IMAP extension to parse the list + * @return array + * @link http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation + */ + public function parseAddresses($addrstr, $useimap = true) + { + $addresses = array(); + if ($useimap and function_exists('imap_rfc822_parse_adrlist')) { + //Use this built-in parser if it's available + $list = imap_rfc822_parse_adrlist($addrstr, ''); + foreach ($list as $address) { + if ($address->host != '.SYNTAX-ERROR.') { + if ($this->validateAddress($address->mailbox . '@' . $address->host)) { + $addresses[] = array( + 'name' => (property_exists($address, 'personal') ? $address->personal : ''), + 'address' => $address->mailbox . '@' . $address->host + ); + } + } + } + } else { + //Use this simpler parser + $list = explode(',', $addrstr); + foreach ($list as $address) { + $address = trim($address); + //Is there a separate name part? + if (strpos($address, '<') === false) { + //No separate name, just use the whole thing + if ($this->validateAddress($address)) { + $addresses[] = array( + 'name' => '', + 'address' => $address + ); + } + } else { + list($name, $email) = explode('<', $address); + $email = trim(str_replace('>', '', $email)); + if ($this->validateAddress($email)) { + $addresses[] = array( + 'name' => trim(str_replace(array('"', "'"), '', $name)), + 'address' => $email + ); + } + } + } + } + return $addresses; + } + /** * Set the From and FromName properties. * @param string $address @@ -826,11 +990,15 @@ public function setFrom($address, $name = '', $auto = true) { $address = trim($address); $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim - if (!$this->validateAddress($address)) { - $this->setError($this->lang('invalid_address') . ': ' . $address); - $this->edebug($this->lang('invalid_address') . ': ' . $address); + // Don't validate now addresses with IDN. Will be done in send(). + if (($pos = strrpos($address, '@')) === false or + (!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and + !$this->validateAddress($address)) { + $error_message = $this->lang('invalid_address') . $address; + $this->setError($error_message); + $this->edebug($error_message); if ($this->exceptions) { - throw new phpmailerException($this->lang('invalid_address') . ': ' . $address); + throw new phpmailerException($error_message); } return false; } @@ -860,10 +1028,10 @@ public function getLastMessageID() * Check that a string looks like an email address. * @param string $address The email address to check * @param string $patternselect A selector for the validation pattern to use : - * * `auto` Pick strictest one automatically; + * * `auto` Pick best pattern automatically; * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14; * * `pcre` Use old PCRE implementation; - * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; same as pcre8 but does not allow 'dotless' domains; + * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. * * `noregex` Don't use a regex: super fast, really dumb. * @return boolean @@ -872,6 +1040,10 @@ public function getLastMessageID() */ public static function validateAddress($address, $patternselect = 'auto') { + //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321 + if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) { + return false; + } if (!$patternselect or $patternselect == 'auto') { //Check this constant first so it works when extension_loaded() is disabled by safe mode //Constant was added in PHP 5.2.4 @@ -951,6 +1123,48 @@ public static function validateAddress($address, $patternselect = 'auto') } } + /** + * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the + * "intl" and "mbstring" PHP extensions. + * @return bool "true" if required functions for IDN support are present + */ + public function idnSupported() + { + // @TODO: Write our own "idn_to_ascii" function for PHP <= 5.2. + return function_exists('idn_to_ascii') and function_exists('mb_convert_encoding'); + } + + /** + * Converts IDN in given email address to its ASCII form, also known as punycode, if possible. + * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet. + * This function silently returns unmodified address if: + * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form) + * - Conversion to punycode is impossible (e.g. required PHP functions are not available) + * or fails for any reason (e.g. domain has characters not allowed in an IDN) + * @see PHPMailer::$CharSet + * @param string $address The email address to convert + * @return string The encoded address in ASCII form + */ + public function punyencodeAddress($address) + { + // Verify we have required functions, CharSet, and at-sign. + if ($this->idnSupported() and + !empty($this->CharSet) and + ($pos = strrpos($address, '@')) !== false) { + $domain = substr($address, ++$pos); + // Verify CharSet string is a valid one, and domain properly encoded in this CharSet. + if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) { + $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet); + if (($punycode = defined('INTL_IDNA_VARIANT_UTS46') ? + idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) : + idn_to_ascii($domain)) !== false) { + return substr($address, 0, $pos) . $punycode; + } + } + } + return $address; + } + /** * Create a message and send it. * Uses the sending method specified by $Mailer. @@ -982,25 +1196,54 @@ public function send() public function preSend() { try { + $this->error_count = 0; // Reset errors $this->mailHeader = ''; + + // Dequeue recipient and Reply-To addresses with IDN + foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) { + $params[1] = $this->punyencodeAddress($params[1]); + call_user_func_array(array($this, 'addAnAddress'), $params); + } if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL); } + // Validate From, Sender, and ConfirmReadingTo addresses + foreach (array('From', 'Sender', 'ConfirmReadingTo') as $address_kind) { + $this->$address_kind = trim($this->$address_kind); + if (empty($this->$address_kind)) { + continue; + } + $this->$address_kind = $this->punyencodeAddress($this->$address_kind); + if (!$this->validateAddress($this->$address_kind)) { + $error_message = $this->lang('invalid_address') . $this->$address_kind; + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new phpmailerException($error_message); + } + return false; + } + } + // Set whether the message is multipart/alternative if (!empty($this->AltBody)) { $this->ContentType = 'multipart/alternative'; } - $this->error_count = 0; // reset errors $this->setMessageType(); // Refuse to send an empty message unless we are specifically allowing it if (!$this->AllowEmpty and empty($this->Body)) { throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL); } - $this->MIMEHeader = $this->createHeader(); + // Create body before headers in case body makes changes to headers (e.g. altering transfer encoding) + $this->MIMEHeader = ''; $this->MIMEBody = $this->createBody(); + // createBody may have added some headers, so retain them + $tempheaders = $this->MIMEHeader; + $this->MIMEHeader = $this->createHeader(); + $this->MIMEHeader .= $tempheaders; // To capture the complete message when using mail(), create // an extra header list which createHeader() doesn't fold in @@ -1020,7 +1263,6 @@ public function preSend() if (!empty($this->DKIM_domain) && !empty($this->DKIM_private) && !empty($this->DKIM_selector) - && !empty($this->DKIM_domain) && file_exists($this->DKIM_private)) { $header_dkim = $this->DKIM_Add( $this->MIMEHeader . $this->mailHeader, @@ -1031,7 +1273,6 @@ public function preSend() str_replace("\r\n", "\n", $header_dkim) . self::CRLF; } return true; - } catch (phpmailerException $exc) { $this->setError($exc->getMessage()); if ($this->exceptions) { @@ -1101,7 +1342,7 @@ protected function sendmailSend($header, $body) $sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail)); } } - if ($this->SingleTo === true) { + if ($this->SingleTo) { foreach ($this->SingleToArray as $toAddr) { if (!@$mail = popen($sendmail, 'w')) { throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); @@ -1130,7 +1371,15 @@ protected function sendmailSend($header, $body) fputs($mail, $header); fputs($mail, $body); $result = pclose($mail); - $this->doCallback(($result == 0), $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From); + $this->doCallback( + ($result == 0), + $this->to, + $this->cc, + $this->bcc, + $this->Subject, + $body, + $this->From + ); if ($result != 0) { throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); } @@ -1165,7 +1414,7 @@ protected function mailSend($header, $body) ini_set('sendmail_from', $this->Sender); } $result = false; - if ($this->SingleTo === true && count($toArr) > 1) { + if ($this->SingleTo && count($toArr) > 1) { foreach ($toArr as $toAddr) { $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params); $this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From); @@ -1211,58 +1460,51 @@ public function getSMTPInstance() protected function smtpSend($header, $body) { $bad_rcpt = array(); - - if (!$this->smtpConnect()) { + if (!$this->smtpConnect($this->SMTPOptions)) { throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); } - $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; + if ('' == $this->Sender) { + $smtp_from = $this->From; + } else { + $smtp_from = $this->Sender; + } if (!$this->smtp->mail($smtp_from)) { $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL); } // Attempt to send to all recipients - foreach ($this->to as $to) { - if (!$this->smtp->recipient($to[0])) { - $bad_rcpt[] = $to[0]; - $isSent = false; - } else { - $isSent = true; - } - $this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From); - } - foreach ($this->cc as $cc) { - if (!$this->smtp->recipient($cc[0])) { - $bad_rcpt[] = $cc[0]; - $isSent = false; - } else { - $isSent = true; - } - $this->doCallback($isSent, array(), array($cc[0]), array(), $this->Subject, $body, $this->From); - } - foreach ($this->bcc as $bcc) { - if (!$this->smtp->recipient($bcc[0])) { - $bad_rcpt[] = $bcc[0]; - $isSent = false; - } else { - $isSent = true; + foreach (array($this->to, $this->cc, $this->bcc) as $togroup) { + foreach ($togroup as $to) { + if (!$this->smtp->recipient($to[0])) { + $error = $this->smtp->getError(); + $bad_rcpt[] = array('to' => $to[0], 'error' => $error['detail']); + $isSent = false; + } else { + $isSent = true; + } + $this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From); } - $this->doCallback($isSent, array(), array(), array($bcc[0]), $this->Subject, $body, $this->From); } // Only send the DATA command if we have viable recipients if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) { throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL); } - if ($this->SMTPKeepAlive == true) { + if ($this->SMTPKeepAlive) { $this->smtp->reset(); } else { $this->smtp->quit(); $this->smtp->close(); } - if (count($bad_rcpt) > 0) { // Create error message for any bad addresses + //Create error message for any bad addresses + if (count($bad_rcpt) > 0) { + $errstr = ''; + foreach ($bad_rcpt as $bad) { + $errstr .= $bad['to'] . ': ' . $bad['error']; + } throw new phpmailerException( - $this->lang('recipients_failed') . implode(', ', $bad_rcpt), + $this->lang('recipients_failed') . $errstr, self::STOP_CONTINUE ); } @@ -1308,13 +1550,24 @@ public function smtpConnect($options = array()) // The host string prefix can temporarily override the current setting for SMTPSecure // If it's not specified, the default value is used $prefix = ''; + $secure = $this->SMTPSecure; $tls = ($this->SMTPSecure == 'tls'); - if ($hostinfo[2] == 'ssl' or ($hostinfo[2] == '' and $this->SMTPSecure == 'ssl')) { + if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) { $prefix = 'ssl://'; - $tls = false; // Can't have SSL and TLS at once + $tls = false; // Can't have SSL and TLS at the same time + $secure = 'ssl'; } elseif ($hostinfo[2] == 'tls') { $tls = true; // tls doesn't use a prefix + $secure = 'tls'; + } + //Do we need the OpenSSL extension? + $sslext = defined('OPENSSL_ALGO_SHA1'); + if ('tls' === $secure or 'ssl' === $secure) { + //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled + if (!$sslext) { + throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL); + } } $host = $hostinfo[3]; $port = $this->Port; @@ -1330,7 +1583,14 @@ public function smtpConnect($options = array()) $hello = $this->serverHostname(); } $this->smtp->hello($hello); - + //Automatically enable TLS encryption if: + // * it's not disabled + // * we have openssl extension + // * we are not already using SSL + // * the server offers STARTTLS + if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) { + $tls = true; + } if ($tls) { if (!$this->smtp->startTLS()) { throw new phpmailerException($this->lang('connect_host')); @@ -1353,6 +1613,7 @@ public function smtpConnect($options = array()) return true; } catch (phpmailerException $exc) { $lastexception = $exc; + $this->edebug($exc->getMessage()); // We must have connected, but then failed TLS or Auth, so close connection nicely $this->smtp->quit(); } @@ -1404,14 +1665,15 @@ public function setLanguage($langcode = 'en', $lang_path = '') 'file_open' => 'File Error: Could not open file: ', 'from_failed' => 'The following From address failed: ', 'instantiate' => 'Could not instantiate mail function.', - 'invalid_address' => 'Invalid address', + 'invalid_address' => 'Invalid address: ', 'mailer_not_supported' => ' mailer is not supported.', 'provide_address' => 'You must provide at least one recipient email address.', 'recipients_failed' => 'SMTP Error: The following recipients failed: ', 'signing' => 'Signing Error: ', 'smtp_connect_failed' => 'SMTP connect() failed.', 'smtp_error' => 'SMTP server error: ', - 'variable_set' => 'Cannot set or reset variable: ' + 'variable_set' => 'Cannot set or reset variable: ', + 'extension_missing' => 'Extension missing: ' ); if (empty($lang_path)) { // Calculate an absolute path so it can work if CWD is not here @@ -1419,18 +1681,19 @@ public function setLanguage($langcode = 'en', $lang_path = '') } $foundlang = true; $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php'; - if ($langcode != 'en') { // There is no English translation file + // There is no English translation file + if ($langcode != 'en') { // Make sure language file path is readable if (!is_readable($lang_file)) { $foundlang = false; } else { // Overwrite language-specific strings. - // This way we'll never have missing translations. + // This way we'll never have missing translation keys. $foundlang = include $lang_file; } } $this->language = $PHPMAILER_LANG; - return ($foundlang == true); // Returns false if language not found + return (boolean)$foundlang; // Returns false if language not found } /** @@ -1492,7 +1755,11 @@ public function addrFormat($addr) */ public function wrapText($message, $length, $qp_mode = false) { - $soft_break = ($qp_mode) ? sprintf(' =%s', $this->LE) : $this->LE; + if ($qp_mode) { + $soft_break = sprintf(' =%s', $this->LE); + } else { + $soft_break = $this->LE; + } // If utf-8 encoding is used, we will need to make sure we don't // split multibyte characters when we wrap $is_utf8 = (strtolower($this->CharSet) == 'utf-8'); @@ -1500,20 +1767,23 @@ public function wrapText($message, $length, $qp_mode = false) $crlflen = strlen(self::CRLF); $message = $this->fixEOL($message); + //Remove a trailing line break if (substr($message, -$lelen) == $this->LE) { $message = substr($message, 0, -$lelen); } - $line = explode($this->LE, $message); // Magic. We know fixEOL uses $LE + //Split message into lines + $lines = explode($this->LE, $message); + //Message will be rebuilt in here $message = ''; - for ($i = 0; $i < count($line); $i++) { - $line_part = explode(' ', $line[$i]); + foreach ($lines as $line) { + $words = explode(' ', $line); $buf = ''; - for ($e = 0; $e < count($line_part); $e++) { - $word = $line_part[$e]; + $firstword = true; + foreach ($words as $word) { if ($qp_mode and (strlen($word) > $length)) { $space_left = $length - strlen($buf) - $crlflen; - if ($e != 0) { + if (!$firstword) { if ($space_left > 20) { $len = $space_left; if ($is_utf8) { @@ -1555,13 +1825,17 @@ public function wrapText($message, $length, $qp_mode = false) } } else { $buf_o = $buf; - $buf .= ($e == 0) ? $word : (' ' . $word); + if (!$firstword) { + $buf .= ' '; + } + $buf .= $word; if (strlen($buf) > $length and $buf_o != '') { $message .= $buf_o . $soft_break; $buf = $word; } } + $firstword = false; } $message .= $buf . self::CRLF; } @@ -1571,11 +1845,11 @@ public function wrapText($message, $length, $qp_mode = false) /** * Find the last character boundary prior to $maxLength in a utf-8 - * quoted (printable) encoded string. + * quoted-printable encoded string. * Original written by Colin Brown. * @access public * @param string $encodedText utf-8 QP text - * @param integer $maxLength find last character boundary prior to this length + * @param integer $maxLength Find the last character boundary prior to this length * @return integer */ public function utf8CharBoundary($encodedText, $maxLength) @@ -1585,22 +1859,26 @@ public function utf8CharBoundary($encodedText, $maxLength) while (!$foundSplitPos) { $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); $encodedCharPos = strpos($lastChunk, '='); - if ($encodedCharPos !== false) { + if (false !== $encodedCharPos) { // Found start of encoded character byte within $lookBack block. // Check the encoded byte value (the 2 chars after the '=') $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); $dec = hexdec($hex); - if ($dec < 128) { // Single byte character. + if ($dec < 128) { + // Single byte character. // If the encoded char was found at pos 0, it will fit // otherwise reduce maxLength to start of the encoded char - $maxLength = ($encodedCharPos == 0) ? $maxLength : - $maxLength - ($lookBack - $encodedCharPos); + if ($encodedCharPos > 0) { + $maxLength = $maxLength - ($lookBack - $encodedCharPos); + } $foundSplitPos = true; - } elseif ($dec >= 192) { // First byte of a multi byte character + } elseif ($dec >= 192) { + // First byte of a multi byte character // Reduce maxLength to split at start of character $maxLength = $maxLength - ($lookBack - $encodedCharPos); $foundSplitPos = true; - } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back + } elseif ($dec < 192) { + // Middle byte of a multi byte character, look further back $lookBack += 3; } } else { @@ -1612,7 +1890,10 @@ public function utf8CharBoundary($encodedText, $maxLength) } /** - * Set the body wrapping. + * Apply word wrapping to the message body. + * Wraps the message body to the number of chars set in the WordWrap property. + * You should only do this to plain-text bodies as wrapping HTML tags may break them. + * This is called automatically by createBody(), so you don't need to call it yourself. * @access public * @return void */ @@ -1644,20 +1925,13 @@ public function createHeader() { $result = ''; - // Set the boundaries - $uniq_id = md5(uniqid(time())); - $this->boundary[1] = 'b1_' . $uniq_id; - $this->boundary[2] = 'b2_' . $uniq_id; - $this->boundary[3] = 'b3_' . $uniq_id; - if ($this->MessageDate == '') { $this->MessageDate = self::rfcDate(); } $result .= $this->headerLine('Date', $this->MessageDate); - // To be created automatically by mail() - if ($this->SingleTo === true) { + if ($this->SingleTo) { if ($this->Mailer != 'mail') { foreach ($this->to as $toaddr) { $this->SingleToArray[] = $this->addrFormat($toaddr); @@ -1701,14 +1975,16 @@ public function createHeader() if ($this->MessageID != '') { $this->lastMessageID = $this->MessageID; } else { - $this->lastMessageID = sprintf('<%s@%s>', $uniq_id, $this->ServerHostname()); + $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname()); + } + $result .= $this->headerLine('Message-ID', $this->lastMessageID); + if (!is_null($this->Priority)) { + $result .= $this->headerLine('X-Priority', $this->Priority); } - $result .= $this->HeaderLine('Message-ID', $this->lastMessageID); - $result .= $this->headerLine('X-Priority', $this->Priority); if ($this->XMailer == '') { $result .= $this->headerLine( 'X-Mailer', - 'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer/)' + 'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer)' ); } else { $myXmailer = trim($this->XMailer); @@ -1718,14 +1994,14 @@ public function createHeader() } if ($this->ConfirmReadingTo != '') { - $result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); + $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>'); } // Add custom headers - for ($index = 0; $index < count($this->CustomHeader); $index++) { + foreach ($this->CustomHeader as $header) { $result .= $this->headerLine( - trim($this->CustomHeader[$index][0]), - $this->encodeHeader(trim($this->CustomHeader[$index][1])) + trim($header[0]), + $this->encodeHeader(trim($header[1])) ); } if (!$this->sign_key_file) { @@ -1801,7 +2077,6 @@ public function getSentMIMEMessage() return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody; } - /** * Assemble the message body. * Returns an empty string on failure. @@ -1812,6 +2087,11 @@ public function getSentMIMEMessage() public function createBody() { $body = ''; + //Create unique IDs and preset boundaries + $this->uniqueid = md5(uniqid(time())); + $this->boundary[1] = 'b1_' . $this->uniqueid; + $this->boundary[2] = 'b2_' . $this->uniqueid; + $this->boundary[3] = 'b3_' . $this->uniqueid; if ($this->sign_key_file) { $body .= $this->getMailMIME() . $this->LE; @@ -1821,30 +2101,48 @@ public function createBody() $bodyEncoding = $this->Encoding; $bodyCharSet = $this->CharSet; + //Can we do a 7-bit downgrade? if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) { $bodyEncoding = '7bit'; $bodyCharSet = 'us-ascii'; } + //If lines are too long, and we're not already using an encoding that will shorten them, + //change to quoted-printable transfer encoding + if ('base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) { + $this->Encoding = 'quoted-printable'; + $bodyEncoding = 'quoted-printable'; + } + $altBodyEncoding = $this->Encoding; $altBodyCharSet = $this->CharSet; + //Can we do a 7-bit downgrade? if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) { $altBodyEncoding = '7bit'; $altBodyCharSet = 'us-ascii'; } + //If lines are too long, change to quoted-printable transfer encoding + if (self::hasLineLongerThanMax($this->AltBody)) { + $altBodyEncoding = 'quoted-printable'; + } + //Use this as a preamble in all multipart message types + $mimepre = "This is a multi-part message in MIME format." . $this->LE . $this->LE; switch ($this->message_type) { case 'inline': + $body .= $mimepre; $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); $body .= $this->LE . $this->LE; $body .= $this->attachAll('inline', $this->boundary[1]); break; case 'attach': + $body .= $mimepre; $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); $body .= $this->LE . $this->LE; $body .= $this->attachAll('attachment', $this->boundary[1]); break; case 'inline_attach': + $body .= $mimepre; $body .= $this->textLine('--' . $this->boundary[1]); $body .= $this->headerLine('Content-Type', 'multipart/related;'); $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); @@ -1857,6 +2155,7 @@ public function createBody() $body .= $this->attachAll('attachment', $this->boundary[1]); break; case 'alt': + $body .= $mimepre; $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding); $body .= $this->encodeString($this->AltBody, $altBodyEncoding); $body .= $this->LE . $this->LE; @@ -1871,6 +2170,7 @@ public function createBody() $body .= $this->endBoundary($this->boundary[1]); break; case 'alt_inline': + $body .= $mimepre; $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding); $body .= $this->encodeString($this->AltBody, $altBodyEncoding); $body .= $this->LE . $this->LE; @@ -1886,6 +2186,7 @@ public function createBody() $body .= $this->endBoundary($this->boundary[1]); break; case 'alt_attach': + $body .= $mimepre; $body .= $this->textLine('--' . $this->boundary[1]); $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); @@ -1901,6 +2202,7 @@ public function createBody() $body .= $this->attachAll('attachment', $this->boundary[1]); break; case 'alt_inline_attach': + $body .= $mimepre; $body .= $this->textLine('--' . $this->boundary[1]); $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); @@ -1932,23 +2234,42 @@ public function createBody() } elseif ($this->sign_key_file) { try { if (!defined('PKCS7_TEXT')) { - throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.'); + throw new phpmailerException($this->lang('extension_missing') . 'openssl'); } // @TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1 $file = tempnam(sys_get_temp_dir(), 'mail'); - file_put_contents($file, $body); // @TODO check this worked + if (false === file_put_contents($file, $body)) { + throw new phpmailerException($this->lang('signing') . ' Could not write temp file'); + } $signed = tempnam(sys_get_temp_dir(), 'signed'); - if (@openssl_pkcs7_sign( - $file, - $signed, - 'file://' . realpath($this->sign_cert_file), - array('file://' . realpath($this->sign_key_file), $this->sign_key_pass), - null - ) - ) { + //Workaround for PHP bug https://bugs.php.net/bug.php?id=69197 + if (empty($this->sign_extracerts_file)) { + $sign = @openssl_pkcs7_sign( + $file, + $signed, + 'file://' . realpath($this->sign_cert_file), + array('file://' . realpath($this->sign_key_file), $this->sign_key_pass), + null + ); + } else { + $sign = @openssl_pkcs7_sign( + $file, + $signed, + 'file://' . realpath($this->sign_cert_file), + array('file://' . realpath($this->sign_key_file), $this->sign_key_pass), + null, + PKCS7_DETACHED, + $this->sign_extracerts_file + ); + } + if ($sign) { @unlink($file); $body = file_get_contents($signed); @unlink($signed); + //The message returned by openssl contains both headers and body, so need to split them up + $parts = explode("\n\n", $body, 2); + $this->MIMEHeader .= $parts[0] . $this->LE . $this->LE; + $body = $parts[1]; } else { @unlink($file); @unlink($signed); @@ -2154,18 +2475,27 @@ protected function attachAll($disposition_type, $boundary) $type = $attachment[4]; $disposition = $attachment[6]; $cid = $attachment[7]; - if ($disposition == 'inline' && isset($cidUniq[$cid])) { + if ($disposition == 'inline' && array_key_exists($cid, $cidUniq)) { continue; } $cidUniq[$cid] = true; $mime[] = sprintf('--%s%s', $boundary, $this->LE); - $mime[] = sprintf( - 'Content-Type: %s; name="%s"%s', - $type, - $this->encodeHeader($this->secureHeader($name)), - $this->LE - ); + //Only include a filename property if we have one + if (!empty($name)) { + $mime[] = sprintf( + 'Content-Type: %s; name="%s"%s', + $type, + $this->encodeHeader($this->secureHeader($name)), + $this->LE + ); + } else { + $mime[] = sprintf( + 'Content-Type: %s%s', + $type, + $this->LE + ); + } // RFC1341 part 5 says 7bit is assumed if not specified if ($encoding != '7bit') { $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE); @@ -2189,12 +2519,20 @@ protected function attachAll($disposition_type, $boundary) $this->LE . $this->LE ); } else { - $mime[] = sprintf( - 'Content-Disposition: %s; filename=%s%s', - $disposition, - $encoded_name, - $this->LE . $this->LE - ); + if (!empty($encoded_name)) { + $mime[] = sprintf( + 'Content-Disposition: %s; filename=%s%s', + $disposition, + $encoded_name, + $this->LE . $this->LE + ); + } else { + $mime[] = sprintf( + 'Content-Disposition: %s%s', + $disposition, + $this->LE . $this->LE + ); + } } } else { $mime[] = $this->LE; @@ -2228,7 +2566,6 @@ protected function attachAll($disposition_type, $boundary) * @param string $path The full path to the file * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' * @throws phpmailerException - * @see EncodeFile(encodeFile * @access protected * @return string */ @@ -2246,7 +2583,7 @@ protected function encodeFile($path, $encoding = 'base64') //Doesn't exist in PHP 5.4, but we don't need to check because //get_magic_quotes_runtime always returns false in 5.4+ //so it will never get here - ini_set('magic_quotes_runtime', 0); + ini_set('magic_quotes_runtime', false); } } $file_buffer = file_get_contents($path); @@ -2255,7 +2592,7 @@ protected function encodeFile($path, $encoding = 'base64') if (version_compare(PHP_VERSION, '5.3.0', '<')) { set_magic_quotes_runtime($magic_quotes); } else { - ini_set('magic_quotes_runtime', ($magic_quotes?'1':'0')); + ini_set('magic_quotes_runtime', $magic_quotes); } } return $file_buffer; @@ -2335,7 +2672,8 @@ public function encodeHeader($str, $position = 'text') break; } - if ($matchcount == 0) { // There are no chars that need encoding + //There are no chars that need encoding + if ($matchcount == 0) { return ($str); } @@ -2445,8 +2783,9 @@ public function base64EncodeWrapMB($str, $linebreak = null) */ public function encodeQP($string, $line_max = 76) { - if (function_exists('quoted_printable_encode')) { // Use native function if it's available (>= PHP5.3) - return $this->fixEOL(quoted_printable_encode($string)); + // Use native function if it's available (>= PHP5.3) + if (function_exists('quoted_printable_encode')) { + return quoted_printable_encode($string); } // Fall back to a pure PHP implementation $string = str_replace( @@ -2454,8 +2793,7 @@ public function encodeQP($string, $line_max = 76) array(' ', "\r\n=2E", "\r\n", '='), rawurlencode($string) ); - $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string); - return $this->fixEOL($string); + return preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string); } /** @@ -2512,7 +2850,7 @@ public function encodeQ($str, $position = 'text') // If the string contains an '=', make sure it's the first thing we replace // so as to avoid double-encoding $eqkey = array_search('=', $matches[0]); - if ($eqkey !== false) { + if (false !== $eqkey) { unset($matches[0][$eqkey]); array_unshift($matches[0], '='); } @@ -2524,7 +2862,6 @@ public function encodeQ($str, $position = 'text') return str_replace(' ', '_', $encoded); } - /** * Add a string or binary attachment (non-filesystem). * This method can be used to attach ascii or binary data, @@ -2563,7 +2900,7 @@ public function addStringAttachment( /** * Add an embedded (inline) attachment from a file. * This can include images, sounds, and just about any other document type. - * These differ from 'regular' attachmants in that they are intended to be + * These differ from 'regular' attachments in that they are intended to be * displayed inline with the message, not just attached for download. * This is used in HTML messages that embed the images * the HTML refers to using the $cid value. @@ -2630,7 +2967,7 @@ public function addStringEmbeddedImage( $disposition = 'inline' ) { // If a MIME type is not specified, try to work it out from the name - if ($type == '') { + if ($type == '' and !empty($name)) { $type = self::filenameToType($name); } @@ -2686,6 +3023,22 @@ public function alternativeExists() return !empty($this->AltBody); } + /** + * Clear queued addresses of given kind. + * @access protected + * @param string $kind 'to', 'cc', or 'bcc' + * @return void + */ + public function clearQueuedAddresses($kind) + { + $RecipientsQueue = $this->RecipientsQueue; + foreach ($RecipientsQueue as $address => $params) { + if ($params[0] == $kind) { + unset($this->RecipientsQueue[$address]); + } + } + } + /** * Clear all To recipients. * @return void @@ -2696,6 +3049,7 @@ public function clearAddresses() unset($this->all_recipients[strtolower($to[0])]); } $this->to = array(); + $this->clearQueuedAddresses('to'); } /** @@ -2708,6 +3062,7 @@ public function clearCCs() unset($this->all_recipients[strtolower($cc[0])]); } $this->cc = array(); + $this->clearQueuedAddresses('cc'); } /** @@ -2720,6 +3075,7 @@ public function clearBCCs() unset($this->all_recipients[strtolower($bcc[0])]); } $this->bcc = array(); + $this->clearQueuedAddresses('bcc'); } /** @@ -2729,6 +3085,7 @@ public function clearBCCs() public function clearReplyTos() { $this->ReplyTo = array(); + $this->ReplyToQueue = array(); } /** @@ -2741,6 +3098,7 @@ public function clearAllRecipients() $this->cc = array(); $this->bcc = array(); $this->all_recipients = array(); + $this->RecipientsQueue = array(); } /** @@ -2772,8 +3130,17 @@ protected function setError($msg) $this->error_count++; if ($this->Mailer == 'smtp' and !is_null($this->smtp)) { $lasterror = $this->smtp->getError(); - if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) { - $msg .= '

' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "

\n"; + if (!empty($lasterror['error'])) { + $msg .= $this->lang('smtp_error') . $lasterror['error']; + if (!empty($lasterror['detail'])) { + $msg .= ' Detail: '. $lasterror['detail']; + } + if (!empty($lasterror['smtp_code'])) { + $msg .= ' SMTP code: ' . $lasterror['smtp_code']; + } + if (!empty($lasterror['smtp_code_ex'])) { + $msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex']; + } } } $this->ErrorInfo = $msg; @@ -2826,10 +3193,17 @@ protected function lang($key) $this->setLanguage('en'); // set the default language } - if (isset($this->language[$key])) { + if (array_key_exists($key, $this->language)) { + if ($key == 'smtp_connect_failed') { + //Include a link to troubleshooting docs on SMTP connection failure + //this is by far the biggest cause of support questions + //but it's usually not PHPMailer's fault. + return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting'; + } return $this->language[$key]; } else { - return 'Language string failed to load: ' . $key; + //Return the key as a fallback + return $key; } } @@ -2880,6 +3254,15 @@ public function addCustomHeader($name, $value = null) } } + /** + * Returns all custom headers. + * @return array + */ + public function getCustomHeaders() + { + return $this->CustomHeader; + } + /** * Create a message from an HTML string. * Automatically makes modifications for inline images and backgrounds @@ -2888,13 +3271,14 @@ public function addCustomHeader($name, $value = null) * @access public * @param string $message HTML message string * @param string $basedir baseline directory for path - * @param boolean $advanced Whether to use the advanced HTML to text converter + * @param boolean|callable $advanced Whether to use the internal HTML to text converter + * or your own custom converter @see PHPMailer::html2text() * @return string $message */ public function msgHTML($message, $basedir = '', $advanced = false) { preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images); - if (isset($images[2])) { + if (array_key_exists(2, $images)) { foreach ($images[2] as $imgindex => $url) { // Convert data URIs into embedded images if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) { @@ -2905,15 +3289,16 @@ public function msgHTML($message, $basedir = '', $advanced = false) $data = rawurldecode($data); } $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2 - if ($this->addStringEmbeddedImage($data, $cid, '', 'base64', $match[1])) { - $message = preg_replace( - '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui', + if ($this->addStringEmbeddedImage($data, $cid, 'embed' . $imgindex, 'base64', $match[1])) { + $message = str_replace( + $images[0][$imgindex], $images[1][$imgindex] . '="cid:' . $cid . '"', $message ); } - } elseif (!preg_match('#^[A-z]+://#', $url)) { + } elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[A-z]+://#', $url)) { // Do not change urls for absolute images (thanks to corvuscorax) + // Do not change urls that are already inline images $filename = basename($url); $directory = dirname($url); if ($directory == '.') { @@ -2931,7 +3316,7 @@ public function msgHTML($message, $basedir = '', $advanced = false) $cid, $filename, 'base64', - self::_mime_types(self::mb_pathinfo($filename, PATHINFO_EXTENSION)) + self::_mime_types((string)self::mb_pathinfo($filename, PATHINFO_EXTENSION)) ) ) { $message = preg_replace( @@ -2956,16 +3341,28 @@ public function msgHTML($message, $basedir = '', $advanced = false) /** * Convert an HTML string into plain text. + * This is used by msgHTML(). + * Note - older versions of this function used a bundled advanced converter + * which was been removed for license reasons in #232 + * Example usage: + * + * // Use default conversion + * $plain = $mail->html2text($html); + * // Use your own custom converter + * $plain = $mail->html2text($html, function($html) { + * $converter = new MyHtml2text($html); + * return $converter->get_text(); + * }); + * * @param string $html The HTML text to convert - * @param boolean $advanced Should this use the more complex html2text converter or just a simple one? + * @param boolean|callable $advanced Any boolean value to use the internal converter, + * or provide your own callable for custom conversion. * @return string */ public function html2text($html, $advanced = false) { - if ($advanced) { - require_once 'extras/class.html2text.php'; - $htmlconverter = new html2text($html); - return $htmlconverter->get_text(); + if (is_callable($advanced)) { + return call_user_func($advanced, $html); } return html_entity_decode( trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))), @@ -2984,96 +3381,109 @@ public function html2text($html, $advanced = false) public static function _mime_types($ext = '') { $mimes = array( - 'xl' => 'application/excel', - 'hqx' => 'application/mac-binhex40', - 'cpt' => 'application/mac-compactpro', - 'bin' => 'application/macbinary', - 'doc' => 'application/msword', - 'word' => 'application/msword', + 'xl' => 'application/excel', + 'js' => 'application/javascript', + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'bin' => 'application/macbinary', + 'doc' => 'application/msword', + 'word' => 'application/msword', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'class' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'dms' => 'application/octet-stream', - 'exe' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'psd' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'so' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => 'application/pdf', - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => 'application/vnd.ms-excel', - 'ppt' => 'application/vnd.ms-powerpoint', + 'dll' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'psd' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'so' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', 'wbxml' => 'application/vnd.wap.wbxml', - 'wmlc' => 'application/vnd.wap.wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'php3' => 'application/x-httpd-php', - 'php4' => 'application/x-httpd-php', - 'php' => 'application/x-httpd-php', + 'wmlc' => 'application/vnd.wap.wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'php3' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php' => 'application/x-httpd-php', 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => 'application/x-javascript', - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => 'application/x-tar', - 'xht' => 'application/xhtml+xml', + 'phps' => 'application/x-httpd-php-source', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'xht' => 'application/xhtml+xml', 'xhtml' => 'application/xhtml+xml', - 'zip' => 'application/zip', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mp2' => 'audio/mpeg', - 'mp3' => 'audio/mpeg', - 'mpga' => 'audio/mpeg', - 'aif' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'wav' => 'audio/x-wav', - 'bmp' => 'image/bmp', - 'gif' => 'image/gif', - 'jpeg' => 'image/jpeg', - 'jpe' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'png' => 'image/png', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'eml' => 'message/rfc822', - 'css' => 'text/css', - 'html' => 'text/html', - 'htm' => 'text/html', + 'zip' => 'application/zip', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mpga' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'wav' => 'audio/x-wav', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'png' => 'image/png', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'eml' => 'message/rfc822', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', 'shtml' => 'text/html', - 'log' => 'text/plain', - 'text' => 'text/plain', - 'txt' => 'text/plain', - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'vcf' => 'text/vcard', + 'log' => 'text/plain', + 'text' => 'text/plain', + 'txt' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'vcf' => 'text/vcard', 'vcard' => 'text/vcard', - 'xml' => 'text/xml', - 'xsl' => 'text/xml', - 'mpeg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mov' => 'video/quicktime', - 'qt' => 'video/quicktime', - 'rv' => 'video/vnd.rn-realvideo', - 'avi' => 'video/x-msvideo', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mov' => 'video/quicktime', + 'qt' => 'video/quicktime', + 'rv' => 'video/vnd.rn-realvideo', + 'avi' => 'video/x-msvideo', 'movie' => 'video/x-sgi-movie' ); - return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]: 'application/octet-stream'); + if (array_key_exists(strtolower($ext), $mimes)) { + return $mimes[strtolower($ext)]; + } + return 'application/octet-stream'; } /** @@ -3087,7 +3497,7 @@ public static function filenameToType($filename) { // In case the path is a URL, strip any query string before getting extension $qpos = strpos($filename, '?'); - if ($qpos !== false) { + if (false !== $qpos) { $filename = substr($filename, 0, $qpos); } $pathinfo = self::mb_pathinfo($filename); @@ -3143,33 +3553,27 @@ public static function mb_pathinfo($path, $options = null) /** * Set or reset instance properties. - * + * You should avoid this function - it's more verbose, less efficient, more error-prone and + * harder to debug than setting properties directly. * Usage Example: - * $page->set('X-Priority', '3'); - * + * `$mail->set('SMTPSecure', 'tls');` + * is the same as: + * `$mail->SMTPSecure = 'tls';` * @access public - * @param string $name - * @param mixed $value - * NOTE: will not work with arrays, there are no arrays to set/reset - * @throws phpmailerException + * @param string $name The property name to set + * @param mixed $value The value to set the property to * @return boolean - * @TODO Should this not be using __set() magic function? + * @TODO Should this not be using the __set() magic function? */ public function set($name, $value = '') { - try { - if (isset($this->$name)) { - $this->$name = $value; - } else { - throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL); - } - } catch (Exception $exc) { - $this->setError($exc->getMessage()); - if ($exc->getCode() == self::STOP_CRITICAL) { - return false; - } + if (property_exists($this, $name)) { + $this->$name = $value; + return true; + } else { + $this->setError($this->lang('variable_set') . $name); + return false; } - return true; } /** @@ -3198,19 +3602,20 @@ public static function normalizeBreaks($text, $breaktype = "\r\n") return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text); } - /** * Set the public and private key files and password for S/MIME signing. * @access public * @param string $cert_filename * @param string $key_filename * @param string $key_pass Password for private key + * @param string $extracerts_filename Optional path to chain certificate */ - public function sign($cert_filename, $key_filename, $key_pass) + public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '') { $this->sign_cert_file = $cert_filename; $this->sign_key_file = $key_filename; $this->sign_key_pass = $key_pass; + $this->sign_extracerts_file = $extracerts_filename; } /** @@ -3244,7 +3649,7 @@ public function DKIM_Sign($signHeader) { if (!defined('PKCS7_TEXT')) { if ($this->exceptions) { - throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.'); + throw new phpmailerException($this->lang('extension_missing') . 'openssl'); } return ''; } @@ -3328,8 +3733,8 @@ public function DKIM_Add($headers_line, $subject, $body) $to_header = $header; $current = 'to_header'; } else { - if ($current && strpos($header, ' =?') === 0) { - $current .= $header; + if (!empty($$current) && strpos($header, ' =?') === 0) { + $$current .= $header; } else { $current = ''; } @@ -3345,7 +3750,11 @@ public function DKIM_Add($headers_line, $subject, $body) $body = $this->DKIM_BodyC($body); $DKIMlen = strlen($body); // Length of body $DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1 hash of body - $ident = ($this->DKIM_identity == '') ? '' : ' i=' . $this->DKIM_identity . ';'; + if ('' == $this->DKIM_identity) { + $ident = ''; + } else { + $ident = ' i=' . $this->DKIM_identity . ';'; + } $dkimhdrs = 'DKIM-Signature: v=1; a=' . $DKIMsignatureType . '; q=' . $DKIMquery . '; l=' . @@ -3361,14 +3770,30 @@ public function DKIM_Add($headers_line, $subject, $body) "\tbh=" . $DKIMb64 . ";\r\n" . "\tb="; $toSign = $this->DKIM_HeaderC( - $from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs + $from_header . "\r\n" . + $to_header . "\r\n" . + $subject_header . "\r\n" . + $dkimhdrs ); $signed = $this->DKIM_Sign($toSign); return $dkimhdrs . $signed . "\r\n"; } + /** + * Detect if a string contains a line longer than the maximum line length allowed. + * @param string $str + * @return boolean + * @static + */ + public static function hasLineLongerThanMax($str) + { + //+2 to include CRLF line break for a 1000 total + return (boolean)preg_match('/^(.{'.(self::MAX_LINE_LENGTH + 2).',})/m', $str); + } + /** * Allows for public read access to 'to' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ @@ -3379,6 +3804,7 @@ public function getToAddresses() /** * Allows for public read access to 'cc' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ @@ -3389,6 +3815,7 @@ public function getCcAddresses() /** * Allows for public read access to 'bcc' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ @@ -3399,6 +3826,7 @@ public function getBccAddresses() /** * Allows for public read access to 'ReplyTo' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ @@ -3409,6 +3837,7 @@ public function getReplyToAddresses() /** * Allows for public read access to 'all_recipients' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ diff --git a/libraries/vendor/phpmailer/phpmailer/class.phpmaileroauth.php b/libraries/vendor/phpmailer/phpmailer/class.phpmaileroauth.php new file mode 100644 index 0000000000000..f9cd7b42a5608 --- /dev/null +++ b/libraries/vendor/phpmailer/phpmailer/class.phpmaileroauth.php @@ -0,0 +1,196 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2014 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** + * PHPMailerOAuth - PHPMailer subclass adding OAuth support. + * @package PHPMailer + * @author @sherryl4george + * @author Marcus Bointon (@Synchro) + */ +class PHPMailerOAuth extends PHPMailer +{ + /** + * The OAuth user's email address + * @var string + */ + public $oauthUserEmail = ''; + + /** + * The OAuth refresh token + * @var string + */ + public $oauthRefreshToken = ''; + + /** + * The OAuth client ID + * @var string + */ + public $oauthClientId = ''; + + /** + * The OAuth client secret + * @var string + */ + public $oauthClientSecret = ''; + + /** + * An instance of the PHPMailerOAuthGoogle class. + * @var PHPMailerOAuthGoogle + * @access protected + */ + protected $oauth = null; + + /** + * Get a PHPMailerOAuthGoogle instance to use. + * @return PHPMailerOAuthGoogle + */ + public function getOAUTHInstance() + { + if (!is_object($this->oauth)) { + $this->oauth = new PHPMailerOAuthGoogle( + $this->oauthUserEmail, + $this->oauthClientSecret, + $this->oauthClientId, + $this->oauthRefreshToken + ); + } + return $this->oauth; + } + + /** + * Initiate a connection to an SMTP server. + * Overrides the original smtpConnect method to add support for OAuth. + * @param array $options An array of options compatible with stream_context_create() + * @uses SMTP + * @access public + * @return bool + */ + public function smtpConnect($options = array()) + { + if (is_null($this->smtp)) { + $this->smtp = $this->getSMTPInstance(); + } + + if (is_null($this->oauth)) { + $this->oauth = $this->getOAUTHInstance(); + } + + // Already connected? + if ($this->smtp->connected()) { + return true; + } + + $this->smtp->setTimeout($this->Timeout); + $this->smtp->setDebugLevel($this->SMTPDebug); + $this->smtp->setDebugOutput($this->Debugoutput); + $this->smtp->setVerp($this->do_verp); + $hosts = explode(';', $this->Host); + $lastexception = null; + + foreach ($hosts as $hostentry) { + $hostinfo = array(); + if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) { + // Not a valid host entry + continue; + } + // $hostinfo[2]: optional ssl or tls prefix + // $hostinfo[3]: the hostname + // $hostinfo[4]: optional port number + // The host string prefix can temporarily override the current setting for SMTPSecure + // If it's not specified, the default value is used + $prefix = ''; + $secure = $this->SMTPSecure; + $tls = ($this->SMTPSecure == 'tls'); + if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) { + $prefix = 'ssl://'; + $tls = false; // Can't have SSL and TLS at the same time + $secure = 'ssl'; + } elseif ($hostinfo[2] == 'tls') { + $tls = true; + // tls doesn't use a prefix + $secure = 'tls'; + } + //Do we need the OpenSSL extension? + $sslext = defined('OPENSSL_ALGO_SHA1'); + if ('tls' === $secure or 'ssl' === $secure) { + //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled + if (!$sslext) { + throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL); + } + } + $host = $hostinfo[3]; + $port = $this->Port; + $tport = (integer)$hostinfo[4]; + if ($tport > 0 and $tport < 65536) { + $port = $tport; + } + if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) { + try { + if ($this->Helo) { + $hello = $this->Helo; + } else { + $hello = $this->serverHostname(); + } + $this->smtp->hello($hello); + //Automatically enable TLS encryption if: + // * it's not disabled + // * we have openssl extension + // * we are not already using SSL + // * the server offers STARTTLS + if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) { + $tls = true; + } + if ($tls) { + if (!$this->smtp->startTLS()) { + throw new phpmailerException($this->lang('connect_host')); + } + // We must resend HELO after tls negotiation + $this->smtp->hello($hello); + } + if ($this->SMTPAuth) { + if (!$this->smtp->authenticate( + $this->Username, + $this->Password, + $this->AuthType, + $this->Realm, + $this->Workstation, + $this->oauth + ) + ) { + throw new phpmailerException($this->lang('authenticate')); + } + } + return true; + } catch (phpmailerException $exc) { + $lastexception = $exc; + $this->edebug($exc->getMessage()); + // We must have connected, but then failed TLS or Auth, so close connection nicely + $this->smtp->quit(); + } + } + } + // If we get here, all connection attempts have failed, so close connection hard + $this->smtp->close(); + // As we've caught all exceptions, just report whatever the last one was + if ($this->exceptions and !is_null($lastexception)) { + throw $lastexception; + } + return false; + } +} diff --git a/libraries/vendor/phpmailer/phpmailer/class.phpmaileroauthgoogle.php b/libraries/vendor/phpmailer/phpmailer/class.phpmaileroauthgoogle.php new file mode 100644 index 0000000000000..ab6292b82f301 --- /dev/null +++ b/libraries/vendor/phpmailer/phpmailer/class.phpmaileroauthgoogle.php @@ -0,0 +1,76 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2014 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** + * PHPMailerOAuthGoogle - Wrapper for League OAuth2 Google provider. + * @package PHPMailer + * @author @sherryl4george + * @author Marcus Bointon (@Synchro) + * @link https://github.com/thephpleague/oauth2-client + */ +class PHPMailerOAuthGoogle +{ + private $oauthUserEmail = ''; + private $oauthRefreshToken = ''; + private $oauthClientId = ''; + private $oauthClientSecret = ''; + + /** + * @param string $UserEmail + * @param string $ClientSecret + * @param string $ClientId + * @param string $RefreshToken + */ + public function __construct( + $UserEmail, + $ClientSecret, + $ClientId, + $RefreshToken + ) { + $this->oauthClientId = $ClientId; + $this->oauthClientSecret = $ClientSecret; + $this->oauthRefreshToken = $RefreshToken; + $this->oauthUserEmail = $UserEmail; + } + + private function getProvider() { + return new League\OAuth2\Client\Provider\Google([ + 'clientId' => $this->oauthClientId, + 'clientSecret' => $this->oauthClientSecret + ]); + } + + private function getGrant() + { + return new \League\OAuth2\Client\Grant\RefreshToken(); + } + + private function getToken() + { + $provider = $this->getProvider(); + $grant = $this->getGrant(); + return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]); + } + + public function getOauth64() + { + $token = $this->getToken(); + return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001"); + } +} diff --git a/libraries/vendor/phpmailer/phpmailer/class.pop3.php b/libraries/vendor/phpmailer/phpmailer/class.pop3.php index 9d3e7bdccba5a..403b573eb3710 100644 --- a/libraries/vendor/phpmailer/phpmailer/class.pop3.php +++ b/libraries/vendor/phpmailer/phpmailer/class.pop3.php @@ -31,28 +31,28 @@ class POP3 { /** * The POP3 PHPMailer Version number. - * @type string + * @var string * @access public */ - public $Version = '5.2.9'; + public $Version = '5.2.14'; /** * Default POP3 port number. - * @type integer + * @var integer * @access public */ public $POP3_PORT = 110; /** * Default timeout in seconds. - * @type integer + * @var integer * @access public */ public $POP3_TIMEOUT = 30; /** * POP3 Carriage Return + Line Feed. - * @type string + * @var string * @access public * @deprecated Use the constant instead */ @@ -61,66 +61,66 @@ class POP3 /** * Debug display level. * Options: 0 = no, 1+ = yes - * @type integer + * @var integer * @access public */ public $do_debug = 0; /** * POP3 mail server hostname. - * @type string + * @var string * @access public */ public $host; /** * POP3 port number. - * @type integer + * @var integer * @access public */ public $port; /** * POP3 Timeout Value in seconds. - * @type integer + * @var integer * @access public */ public $tval; /** * POP3 username - * @type string + * @var string * @access public */ public $username; /** * POP3 password. - * @type string + * @var string * @access public */ public $password; /** * Resource handle for the POP3 connection socket. - * @type resource - * @access private + * @var resource + * @access protected */ - private $pop_conn; + protected $pop_conn; /** * Are we connected? - * @type boolean - * @access private + * @var boolean + * @access protected */ - private $connected = false; + protected $connected = false; /** * Error container. - * @type array - * @access private + * @var array + * @access protected */ - private $errors = array(); + protected $errors = array(); /** * Line break constant @@ -130,8 +130,8 @@ class POP3 /** * Simple static wrapper for all-in-one POP before SMTP * @param $host - * @param boolean $port - * @param boolean $tval + * @param integer|boolean $port The port number to connect to + * @param integer|boolean $timeout The timeout value * @param string $username * @param string $password * @param integer $debug_level @@ -140,13 +140,13 @@ class POP3 public static function popBeforeSmtp( $host, $port = false, - $tval = false, + $timeout = false, $username = '', $password = '', $debug_level = 0 ) { $pop = new POP3; - return $pop->authorise($host, $port, $tval, $username, $password, $debug_level); + return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level); } /** @@ -166,13 +166,13 @@ public function authorise($host, $port = false, $timeout = false, $username = '' { $this->host = $host; // If no port value provided, use default - if ($port === false) { + if (false === $port) { $this->port = $this->POP3_PORT; } else { $this->port = (integer)$port; } // If no timeout value provided, use default - if ($timeout === false) { + if (false === $timeout) { $this->tval = $this->POP3_TIMEOUT; } else { $this->tval = (integer)$timeout; @@ -215,7 +215,7 @@ public function connect($host, $port = false, $tval = 30) //Rather than suppress it with @fsockopen, capture it cleanly instead set_error_handler(array($this, 'catchWarning')); - if ($port === false) { + if (false === $port) { $port = $this->POP3_PORT; } @@ -231,7 +231,7 @@ public function connect($host, $port = false, $tval = 30) restore_error_handler(); // Did we connect? - if ($this->pop_conn === false) { + if (false === $this->pop_conn) { // It would appear not... $this->setError(array( 'error' => "Failed to connect to server $host on port $port", @@ -310,9 +310,9 @@ public function disconnect() * $size is the maximum number of bytes to retrieve * @param integer $size * @return string - * @access private + * @access protected */ - private function getResponse($size = 128) + protected function getResponse($size = 128) { $response = fgets($this->pop_conn, $size); if ($this->do_debug >= 1) { @@ -325,9 +325,9 @@ private function getResponse($size = 128) * Send raw data to the POP3 server. * @param string $string * @return integer - * @access private + * @access protected */ - private function sendString($string) + protected function sendString($string) { if ($this->pop_conn) { if ($this->do_debug >= 2) { //Show client messages when debug >= 2 @@ -343,9 +343,9 @@ private function sendString($string) * Looks for for +OK or -ERR. * @param string $string * @return boolean - * @access private + * @access protected */ - private function checkResponse($string) + protected function checkResponse($string) { if (substr($string, 0, 3) !== '+OK') { $this->setError(array( @@ -363,8 +363,9 @@ private function checkResponse($string) * Add an error to the internal error store. * Also display debug output if it's enabled. * @param $error + * @access protected */ - private function setError($error) + protected function setError($error) { $this->errors[] = $error; if ($this->do_debug >= 1) { @@ -376,15 +377,24 @@ private function setError($error) } } + /** + * Get an array of error messages, if any. + * @return array + */ + public function getErrors() + { + return $this->errors; + } + /** * POP3 connection error handler. * @param integer $errno * @param string $errstr * @param string $errfile * @param integer $errline - * @access private + * @access protected */ - private function catchWarning($errno, $errstr, $errfile, $errline) + protected function catchWarning($errno, $errstr, $errfile, $errline) { $this->setError(array( 'error' => "Connecting to the POP3 server raised a PHP warning: ", diff --git a/libraries/vendor/phpmailer/phpmailer/class.smtp.php b/libraries/vendor/phpmailer/phpmailer/class.smtp.php index 9d1f2283ddb3f..2e32e2fce00ea 100644 --- a/libraries/vendor/phpmailer/phpmailer/class.smtp.php +++ b/libraries/vendor/phpmailer/phpmailer/class.smtp.php @@ -21,32 +21,32 @@ * PHPMailer RFC821 SMTP email transport class. * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server. * @package PHPMailer - * @author Chris Ryan + * @author Chris Ryan * @author Marcus Bointon */ class SMTP { /** * The PHPMailer SMTP version number. - * @type string + * @var string */ - const VERSION = '5.2.9'; + const VERSION = '5.2.14'; /** * SMTP line break constant. - * @type string + * @var string */ const CRLF = "\r\n"; /** * The SMTP port to use if one is not specified. - * @type integer + * @var integer */ const DEFAULT_SMTP_PORT = 25; /** * The maximum line length allowed by RFC 2822 section 2.1.1 - * @type integer + * @var integer */ const MAX_LINE_LENGTH = 998; @@ -77,15 +77,15 @@ class SMTP /** * The PHPMailer SMTP Version number. - * @type string + * @var string * @deprecated Use the `VERSION` constant instead * @see SMTP::VERSION */ - public $Version = '5.2.9'; + public $Version = '5.2.14'; /** * SMTP server port number. - * @type integer + * @var integer * @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead * @see SMTP::DEFAULT_SMTP_PORT */ @@ -93,7 +93,7 @@ class SMTP /** * SMTP reply line ending. - * @type string + * @var string * @deprecated Use the `CRLF` constant instead * @see SMTP::CRLF */ @@ -107,7 +107,7 @@ class SMTP * * self::DEBUG_SERVER (`2`) Client commands and server responses * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages - * @type integer + * @var integer */ public $do_debug = self::DEBUG_OFF; @@ -122,7 +122,7 @@ class SMTP * * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";}; * - * @type string|callable + * @var string|callable */ public $Debugoutput = 'echo'; @@ -130,7 +130,7 @@ class SMTP * Whether to use VERP. * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path * @link http://www.postfix.org/VERP_README.html Info on VERP - * @type boolean + * @var boolean */ public $do_verp = false; @@ -139,38 +139,55 @@ class SMTP * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure. * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2 - * @type integer + * @var integer */ public $Timeout = 300; /** - * The SMTP timelimit value for reads, in seconds. - * @type integer + * How long to wait for commands to complete, in seconds. + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 + * @var integer */ - public $Timelimit = 30; + public $Timelimit = 300; /** * The socket for the server connection. - * @type resource + * @var resource */ protected $smtp_conn; /** - * Error message, if any, for the last call. - * @type array + * Error information, if any, for the last SMTP command. + * @var array */ - protected $error = array(); + protected $error = array( + 'error' => '', + 'detail' => '', + 'smtp_code' => '', + 'smtp_code_ex' => '' + ); /** * The reply the server sent to us for HELO. * If null, no HELO string has yet been received. - * @type string|null + * @var string|null */ protected $helo_rply = null; + /** + * The set of SMTP extensions sent in reply to EHLO command. + * Indexes of the array are extension names. + * Value at index 'HELO' or 'EHLO' (according to command that was sent) + * represents the server name. In case of HELO it is the only element of the array. + * Other values can be boolean TRUE or an array containing extension options. + * If null, no HELO/EHLO string has yet been received. + * @var array|null + */ + protected $server_caps = null; + /** * The most recent reply received from the server. - * @type string + * @var string */ protected $last_reply = ''; @@ -187,7 +204,8 @@ protected function edebug($str, $level = 0) if ($level > $this->do_debug) { return; } - if (is_callable($this->Debugoutput)) { + //Avoid clash with built-in function names + if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) { call_user_func($this->Debugoutput, $str, $this->do_debug); return; } @@ -235,11 +253,11 @@ public function connect($host, $port = null, $timeout = 30, $options = array()) $streamok = function_exists('stream_socket_client'); } // Clear errors to avoid confusion - $this->error = array(); + $this->setError(''); // Make sure we are __not__ connected if ($this->connected()) { // Already connected, generate error - $this->error = array('error' => 'Already connected to a server'); + $this->setError('Already connected to a server'); return false; } if (empty($port)) { @@ -247,7 +265,7 @@ public function connect($host, $port = null, $timeout = 30, $options = array()) } // Connect to the SMTP server $this->edebug( - "Connection: opening to $host:$port, t=$timeout, opt=".var_export($options, true), + "Connection: opening to $host:$port, timeout=$timeout, options=".var_export($options, true), self::DEBUG_CONNECTION ); $errno = 0; @@ -279,10 +297,10 @@ public function connect($host, $port = null, $timeout = 30, $options = array()) } // Verify we connected properly if (!is_resource($this->smtp_conn)) { - $this->error = array( - 'error' => 'Failed to connect to server', - 'errno' => $errno, - 'errstr' => $errstr + $this->setError( + 'Failed to connect to server', + $errno, + $errstr ); $this->edebug( 'SMTP ERROR: ' . $this->error['error'] @@ -296,7 +314,8 @@ public function connect($host, $port = null, $timeout = 30, $options = array()) // Windows does not have support for this timeout function if (substr(PHP_OS, 0, 3) != 'WIN') { $max = ini_get('max_execution_time'); - if ($max != 0 && $timeout > $max) { // Don't bother if unlimited + // Don't bother if unlimited + if ($max != 0 && $timeout > $max) { @set_time_limit($timeout); } stream_set_timeout($this->smtp_conn, $timeout, 0); @@ -332,22 +351,62 @@ public function startTLS() * Perform SMTP authentication. * Must be run after hello(). * @see hello() - * @param string $username The user name - * @param string $password The password - * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5) - * @param string $realm The auth realm for NTLM + * @param string $username The user name + * @param string $password The password + * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2) + * @param string $realm The auth realm for NTLM * @param string $workstation The auth workstation for NTLM - * @access public - * @return boolean True if successfully authenticated. + * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth) + * @return bool True if successfully authenticated.* @access public */ public function authenticate( $username, $password, - $authtype = 'LOGIN', + $authtype = null, $realm = '', - $workstation = '' + $workstation = '', + $OAuth = null ) { - if (empty($authtype)) { + if (!$this->server_caps) { + $this->setError('Authentication is not allowed before HELO/EHLO'); + return false; + } + + if (array_key_exists('EHLO', $this->server_caps)) { + // SMTP extensions are available. Let's try to find a proper authentication method + + if (!array_key_exists('AUTH', $this->server_caps)) { + $this->setError('Authentication is not allowed at this stage'); + // 'at this stage' means that auth may be allowed after the stage changes + // e.g. after STARTTLS + return false; + } + + self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL); + self::edebug( + 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']), + self::DEBUG_LOWLEVEL + ); + + if (empty($authtype)) { + foreach (array('LOGIN', 'CRAM-MD5', 'NTLM', 'PLAIN', 'XOAUTH2') as $method) { + if (in_array($method, $this->server_caps['AUTH'])) { + $authtype = $method; + break; + } + } + if (empty($authtype)) { + $this->setError('No supported authentication methods found'); + return false; + } + self::edebug('Auth method selected: '.$authtype, self::DEBUG_LOWLEVEL); + } + + if (!in_array($authtype, $this->server_caps['AUTH'])) { + $this->setError("The requested authentication method \"$authtype\" is not supported by the server"); + return false; + } + } elseif (empty($authtype)) { $authtype = 'LOGIN'; } switch ($authtype) { @@ -378,6 +437,19 @@ public function authenticate( return false; } break; + case 'XOAUTH2': + //If the OAuth Instance is not set. Can be a case when PHPMailer is used + //instead of PHPMailerOAuth + if (is_null($OAuth)) { + return false; + } + $oauth = $OAuth->getOauth64(); + + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { + return false; + } + break; case 'NTLM': /* * ntlm_sasl_client.php @@ -388,11 +460,11 @@ public function authenticate( * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication */ require_once 'extras/ntlm_sasl_client.php'; - $temp = new stdClass(); + $temp = new stdClass; $ntlm_client = new ntlm_sasl_client_class; //Check that functions are available if (!$ntlm_client->Initialize($temp)) { - $this->error = array('error' => $temp->error); + $this->setError($temp->error); $this->edebug( 'You need to enable some modules in your php.ini file: ' . $this->error['error'], @@ -441,6 +513,9 @@ public function authenticate( // send encoded credentials return $this->sendCommand('Username', base64_encode($response), 235); + default: + $this->setError("Authentication method \"$authtype\" is not supported"); + return false; } return true; } @@ -513,7 +588,8 @@ public function connected() */ public function close() { - $this->error = array(); + $this->setError(''); + $this->server_caps = null; $this->helo_rply = null; if (is_resource($this->smtp_conn)) { // close the connection and cleanup @@ -537,9 +613,11 @@ public function close() */ public function data($msg_data) { + //This will use the standard timelimit if (!$this->sendCommand('DATA', 'DATA', 354)) { return false; } + /* The server is ready to accept data! * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF) * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into @@ -567,13 +645,14 @@ public function data($msg_data) if ($in_headers and $line == '') { $in_headers = false; } - // ok we need to break this line up into several smaller lines - //This is a small micro-optimisation: isset($str[$len]) is equivalent to (strlen($str) > $len) + //Break this line up into several smaller lines if it's too long + //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len), while (isset($line[self::MAX_LINE_LENGTH])) { //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on //so as to avoid breaking in the middle of a word $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' '); - if (!$pos) { //Deliberately matches both false and 0 + //Deliberately matches both false and 0 + if (!$pos) { //No nice break found, add a hard break $pos = self::MAX_LINE_LENGTH - 1; $lines_out[] = substr($line, 0, $pos); @@ -584,16 +663,14 @@ public function data($msg_data) //Move along by the amount we dealt with $line = substr($line, $pos + 1); } - /* If processing headers add a LWSP-char to the front of new line - * RFC822 section 3.1.1 - */ + //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1 if ($in_headers) { $line = "\t" . $line; } } $lines_out[] = $line; - // Send the lines to the server + //Send the lines to the server foreach ($lines_out as $line_out) { //RFC2821 section 4.5.2 if (!empty($line_out) and $line_out[0] == '.') { @@ -603,8 +680,14 @@ public function data($msg_data) } } - // Message data has been sent, complete the command - return $this->sendCommand('DATA END', '.', 250); + //Message data has been sent, complete the command + //Increase timelimit for end of DATA command + $savetimelimit = $this->Timelimit; + $this->Timelimit = $this->Timelimit * 2; + $result = $this->sendCommand('DATA END', '.', 250); + //Restore timelimit + $this->Timelimit = $savetimelimit; + return $result; } /** @@ -619,7 +702,7 @@ public function data($msg_data) */ public function hello($host = '') { - // Try extended hello first (RFC 2821) + //Try extended hello first (RFC 2821) return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host)); } @@ -636,9 +719,56 @@ protected function sendHello($hello, $host) { $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250); $this->helo_rply = $this->last_reply; + if ($noerror) { + $this->parseHelloFields($hello); + } else { + $this->server_caps = null; + } return $noerror; } + /** + * Parse a reply to HELO/EHLO command to discover server extensions. + * In case of HELO, the only parameter that can be discovered is a server name. + * @access protected + * @param string $type - 'HELO' or 'EHLO' + */ + protected function parseHelloFields($type) + { + $this->server_caps = array(); + $lines = explode("\n", $this->last_reply); + + foreach ($lines as $n => $s) { + //First 4 chars contain response code followed by - or space + $s = trim(substr($s, 4)); + if (empty($s)) { + continue; + } + $fields = explode(' ', $s); + if (!empty($fields)) { + if (!$n) { + $name = $type; + $fields = $fields[0]; + } else { + $name = array_shift($fields); + switch ($name) { + case 'SIZE': + $fields = ($fields ? $fields[0] : 0); + break; + case 'AUTH': + if (!is_array($fields)) { + $fields = array(); + } + break; + default: + $fields = true; + } + } + $this->server_caps[$name] = $fields; + } + } + } + /** * Send an SMTP MAIL command. * Starts a mail transaction from the email address specified in @@ -684,15 +814,15 @@ public function quit($close_on_error = true) * Sets the TO argument to $toaddr. * Returns true if the recipient was accepted false if it was rejected. * Implements from rfc 821: RCPT TO: - * @param string $toaddr The address the message is being sent to + * @param string $address The address the message is being sent to * @access public * @return boolean */ - public function recipient($toaddr) + public function recipient($address) { return $this->sendCommand( 'RCPT TO', - 'RCPT TO:<' . $toaddr . '>', + 'RCPT TO:<' . $address . '>', array(250, 251) ); } @@ -711,32 +841,52 @@ public function reset() /** * Send a command to an SMTP server and check its return code. - * @param string $command The command name - not sent to the server + * @param string $command The command name - not sent to the server * @param string $commandstring The actual command to send - * @param integer|array $expect One or more expected integer success codes + * @param integer|array $expect One or more expected integer success codes * @access protected * @return boolean True on success. */ protected function sendCommand($command, $commandstring, $expect) { if (!$this->connected()) { - $this->error = array( - 'error' => "Called $command without being connected" - ); + $this->setError("Called $command without being connected"); + return false; + } + //Reject line breaks in all commands + if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) { + $this->setError("Command '$command' contained line breaks"); return false; } $this->client_send($commandstring . self::CRLF); $this->last_reply = $this->get_lines(); - $code = substr($this->last_reply, 0, 3); + // Fetch SMTP code and possible error code explanation + $matches = array(); + if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) { + $code = $matches[1]; + $code_ex = (count($matches) > 2 ? $matches[2] : null); + // Cut off error code from each response line + $detail = preg_replace( + "/{$code}[ -]".($code_ex ? str_replace('.', '\\.', $code_ex).' ' : '')."/m", + '', + $this->last_reply + ); + } else { + // Fall back to simple parsing if regex fails + $code = substr($this->last_reply, 0, 3); + $code_ex = null; + $detail = substr($this->last_reply, 4); + } $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); if (!in_array($code, (array)$expect)) { - $this->error = array( - 'error' => "$command command failed", - 'smtp_code' => $code, - 'detail' => substr($this->last_reply, 4) + $this->setError( + "$command command failed", + $detail, + $code, + $code_ex ); $this->edebug( 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply, @@ -745,7 +895,7 @@ protected function sendCommand($command, $commandstring, $expect) return false; } - $this->error = array(); + $this->setError(''); return true; } @@ -800,9 +950,7 @@ public function noop() */ public function turn() { - $this->error = array( - 'error' => 'The SMTP TURN command is not implemented' - ); + $this->setError('The SMTP TURN command is not implemented'); $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT); return false; } @@ -829,6 +977,57 @@ public function getError() return $this->error; } + /** + * Get SMTP extensions available on the server + * @access public + * @return array|null + */ + public function getServerExtList() + { + return $this->server_caps; + } + + /** + * A multipurpose method + * The method works in three ways, dependent on argument value and current state + * 1. HELO/EHLO was not sent - returns null and set up $this->error + * 2. HELO was sent + * $name = 'HELO': returns server name + * $name = 'EHLO': returns boolean false + * $name = any string: returns null and set up $this->error + * 3. EHLO was sent + * $name = 'HELO'|'EHLO': returns server name + * $name = any string: if extension $name exists, returns boolean True + * or its options. Otherwise returns boolean False + * In other words, one can use this method to detect 3 conditions: + * - null returned: handshake was not or we don't know about ext (refer to $this->error) + * - false returned: the requested feature exactly not exists + * - positive value returned: the requested feature exists + * @param string $name Name of SMTP extension or 'HELO'|'EHLO' + * @return mixed + */ + public function getServerExt($name) + { + if (!$this->server_caps) { + $this->setError('No HELO/EHLO was sent'); + return null; + } + + // the tight logic knot ;) + if (!array_key_exists($name, $this->server_caps)) { + if ($name == 'HELO') { + return $this->server_caps['EHLO']; + } + if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) { + return false; + } + $this->setError('HELO handshake was used. Client knows nothing about server extensions'); + return null; + } + + return $this->server_caps[$name]; + } + /** * Get the last reply from the server. * @access public @@ -862,10 +1061,9 @@ protected function get_lines() } while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { $str = @fgets($this->smtp_conn, 515); - $this->edebug("SMTP -> get_lines(): \$data was \"$data\"", self::DEBUG_LOWLEVEL); - $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL); - $data .= $str; $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL); + $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL); + $data .= $str; // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen if ((isset($str[3]) and $str[3] == ' ')) { break; @@ -910,9 +1108,26 @@ public function getVerp() return $this->do_verp; } + /** + * Set error messages and codes. + * @param string $message The error message + * @param string $detail Further detail on the error + * @param string $smtp_code An associated SMTP error code + * @param string $smtp_code_ex Extended SMTP code + */ + protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '') + { + $this->error = array( + 'error' => $message, + 'detail' => $detail, + 'smtp_code' => $smtp_code, + 'smtp_code_ex' => $smtp_code_ex + ); + } + /** * Set debug output method. - * @param string $method The function/method to use for debugging output. + * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it. */ public function setDebugOutput($method = 'echo') { diff --git a/libraries/vendor/phpmailer/phpmailer/composer.lock b/libraries/vendor/phpmailer/phpmailer/composer.lock new file mode 100644 index 0000000000000..15a841d8a35eb --- /dev/null +++ b/libraries/vendor/phpmailer/phpmailer/composer.lock @@ -0,0 +1,3458 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "0eb36ae77d61050323a94e312176ea66", + "packages": [], + "packages-dev": [ + { + "name": "cilex/cilex", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/Cilex/Cilex.git", + "reference": "7acd965a609a56d0345e8b6071c261fbdb926cb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Cilex/Cilex/zipball/7acd965a609a56d0345e8b6071c261fbdb926cb5", + "reference": "7acd965a609a56d0345e8b6071c261fbdb926cb5", + "shasum": "" + }, + "require": { + "cilex/console-service-provider": "1.*", + "php": ">=5.3.3", + "pimple/pimple": "~1.0", + "symfony/finder": "~2.1", + "symfony/process": "~2.1" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*", + "symfony/validator": "~2.1" + }, + "suggest": { + "monolog/monolog": ">=1.0.0", + "symfony/validator": ">=1.0.0", + "symfony/yaml": ">=1.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Cilex": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "description": "The PHP micro-framework for Command line tools based on the Symfony2 Components", + "homepage": "http://cilex.github.com", + "keywords": [ + "cli", + "microframework" + ], + "time": "2014-03-29 14:03:13" + }, + { + "name": "cilex/console-service-provider", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Cilex/console-service-provider.git", + "reference": "25ee3d1875243d38e1a3448ff94bdf944f70d24e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Cilex/console-service-provider/zipball/25ee3d1875243d38e1a3448ff94bdf944f70d24e", + "reference": "25ee3d1875243d38e1a3448ff94bdf944f70d24e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "pimple/pimple": "1.*@dev", + "symfony/console": "~2.1" + }, + "require-dev": { + "cilex/cilex": "1.*@dev", + "silex/silex": "1.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Cilex\\Provider\\Console": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "description": "Console Service Provider", + "keywords": [ + "cilex", + "console", + "pimple", + "service-provider", + "silex" + ], + "time": "2012-12-19 10:50:58" + }, + { + "name": "container-interop/container-interop", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "time": "2014-12-30 15:22:37" + }, + { + "name": "doctrine/annotations", + "version": "v1.2.7", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": ">=5.3.2" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Annotations\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2015-08-31 12:32:49" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09 13:34:57" + }, + { + "name": "erusev/parsedown", + "version": "1.5.4", + "source": { + "type": "git", + "url": "https://github.com/erusev/parsedown.git", + "reference": "0e89e3714bda18973184d30646306bb0a482bd96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/0e89e3714bda18973184d30646306bb0a482bd96", + "reference": "0e89e3714bda18973184d30646306bb0a482bd96", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Parsedown": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "description": "Parser for Markdown.", + "homepage": "http://parsedown.org", + "keywords": [ + "markdown", + "parser" + ], + "time": "2015-08-03 09:24:05" + }, + { + "name": "herrera-io/json", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/kherge-abandoned/php-json.git", + "reference": "60c696c9370a1e5136816ca557c17f82a6fa83f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kherge-abandoned/php-json/zipball/60c696c9370a1e5136816ca557c17f82a6fa83f1", + "reference": "60c696c9370a1e5136816ca557c17f82a6fa83f1", + "shasum": "" + }, + "require": { + "ext-json": "*", + "justinrainbow/json-schema": ">=1.0,<2.0-dev", + "php": ">=5.3.3", + "seld/jsonlint": ">=1.0,<2.0-dev" + }, + "require-dev": { + "herrera-io/phpunit-test-case": "1.*", + "mikey179/vfsstream": "1.1.0", + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "files": [ + "src/lib/json_version.php" + ], + "psr-0": { + "Herrera\\Json": "src/lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kevin Herrera", + "email": "kevin@herrera.io", + "homepage": "http://kevin.herrera.io/", + "role": "Developer" + } + ], + "description": "A library for simplifying JSON linting and validation.", + "homepage": "http://herrera-io.github.com/php-json", + "keywords": [ + "json", + "lint", + "schema", + "validate" + ], + "time": "2013-10-30 16:51:34" + }, + { + "name": "herrera-io/phar-update", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/kherge-abandoned/php-phar-update.git", + "reference": "00a79e1d5b8cf3c080a2e3becf1ddf7a7fea025b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kherge-abandoned/php-phar-update/zipball/00a79e1d5b8cf3c080a2e3becf1ddf7a7fea025b", + "reference": "00a79e1d5b8cf3c080a2e3becf1ddf7a7fea025b", + "shasum": "" + }, + "require": { + "herrera-io/json": "1.*", + "kherge/version": "1.*", + "php": ">=5.3.3" + }, + "require-dev": { + "herrera-io/phpunit-test-case": "1.*", + "mikey179/vfsstream": "1.1.0", + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "files": [ + "src/lib/constants.php" + ], + "psr-0": { + "Herrera\\Phar\\Update": "src/lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kevin Herrera", + "email": "kevin@herrera.io", + "homepage": "http://kevin.herrera.io/", + "role": "Developer" + } + ], + "description": "A library for self-updating Phars.", + "homepage": "http://herrera-io.github.com/php-phar-update", + "keywords": [ + "phar", + "update" + ], + "time": "2013-10-30 17:23:01" + }, + { + "name": "jms/metadata", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/metadata.git", + "reference": "22b72455559a25777cfd28c4ffda81ff7639f353" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/22b72455559a25777cfd28c4ffda81ff7639f353", + "reference": "22b72455559a25777cfd28c4ffda81ff7639f353", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "doctrine/cache": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Metadata\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache" + ], + "authors": [ + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "Class/method/property metadata management in PHP", + "keywords": [ + "annotations", + "metadata", + "xml", + "yaml" + ], + "time": "2014-07-12 07:13:19" + }, + { + "name": "jms/parser-lib", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/parser-lib.git", + "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/parser-lib/zipball/c509473bc1b4866415627af0e1c6cc8ac97fa51d", + "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d", + "shasum": "" + }, + "require": { + "phpoption/phpoption": ">=0.9,<2.0-dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "JMS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "description": "A library for easily creating recursive-descent parsers.", + "time": "2012-11-18 18:08:43" + }, + { + "name": "jms/serializer", + "version": "0.16.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/serializer.git", + "reference": "c8a171357ca92b6706e395c757f334902d430ea9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/c8a171357ca92b6706e395c757f334902d430ea9", + "reference": "c8a171357ca92b6706e395c757f334902d430ea9", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "jms/metadata": "~1.1", + "jms/parser-lib": "1.*", + "php": ">=5.3.2", + "phpcollection/phpcollection": "~0.1" + }, + "require-dev": { + "doctrine/orm": "~2.1", + "doctrine/phpcr-odm": "~1.0.1", + "jackalope/jackalope-doctrine-dbal": "1.0.*", + "propel/propel1": "~1.7", + "symfony/filesystem": "2.*", + "symfony/form": "~2.1", + "symfony/translation": "~2.0", + "symfony/validator": "~2.0", + "symfony/yaml": "2.*", + "twig/twig": ">=1.8,<2.0-dev" + }, + "suggest": { + "symfony/yaml": "Required if you'd like to serialize data to YAML format." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.15-dev" + } + }, + "autoload": { + "psr-0": { + "JMS\\Serializer": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.", + "homepage": "http://jmsyst.com/libs/serializer", + "keywords": [ + "deserialization", + "jaxb", + "json", + "serialization", + "xml" + ], + "time": "2014-03-18 08:39:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "1.4.4", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "8dc9b9d85ab639ca60ab4608b34c1279d6ae7bce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/8dc9b9d85ab639ca60ab4608b34c1279d6ae7bce", + "reference": "8dc9b9d85ab639ca60ab4608b34c1279d6ae7bce", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "json-schema/json-schema-test-suite": "1.1.0", + "phpdocumentor/phpdocumentor": "~2", + "phpunit/phpunit": "~3.7" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "JsonSchema": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2015-07-14 16:29:50" + }, + { + "name": "kherge/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/kherge-abandoned/Version.git", + "reference": "f07cf83f8ce533be8f93d2893d96d674bbeb7e30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kherge-abandoned/Version/zipball/f07cf83f8ce533be8f93d2893d96d674bbeb7e30", + "reference": "f07cf83f8ce533be8f93d2893d96d674bbeb7e30", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "KevinGH\\Version": "src/lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kevin Herrera", + "email": "me@kevingh.com", + "homepage": "http://www.kevingh.com/" + } + ], + "description": "A parsing and comparison library for semantic versioning.", + "homepage": "http://github.com/kherge/Version", + "time": "2012-08-16 17:13:03" + }, + { + "name": "monolog/monolog", + "version": "1.17.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/0524c87587ab85bc4c2d6f5b41253ccb930a5422", + "reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "raven/raven": "~0.11", + "ruflin/elastica": ">=0.90 <3.0", + "swiftmailer/swiftmailer": "~5.3", + "videlalvaro/php-amqplib": "~2.4" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "raven/raven": "Allow sending log messages to a Sentry server", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.16.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2015-08-31 09:17:37" + }, + { + "name": "nikic/php-parser", + "version": "v0.9.5", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ef70767475434bdb3615b43c327e2cae17ef12eb", + "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9-dev" + } + }, + "autoload": { + "psr-0": { + "PHPParser": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2014-07-23 18:24:17" + }, + { + "name": "phpcollection/phpcollection", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-collection.git", + "reference": "b8bf55a0a929ca43b01232b36719f176f86c7e83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-collection/zipball/b8bf55a0a929ca43b01232b36719f176f86c7e83", + "reference": "b8bf55a0a929ca43b01232b36719f176f86c7e83", + "shasum": "" + }, + "require": { + "phpoption/phpoption": "1.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + }, + "autoload": { + "psr-0": { + "PhpCollection": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "General-Purpose Collection Library for PHP", + "keywords": [ + "collection", + "list", + "map", + "sequence", + "set" + ], + "time": "2014-03-11 13:46:42" + }, + { + "name": "phpdocumentor/fileset", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/Fileset.git", + "reference": "bfa78d8fa9763dfce6d0e5d3730c1d8ab25d34b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/Fileset/zipball/bfa78d8fa9763dfce6d0e5d3730c1d8ab25d34b0", + "reference": "bfa78d8fa9763dfce6d0e5d3730c1d8ab25d34b0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/finder": "~2.1" + }, + "require-dev": { + "phpunit/phpunit": "~3.7" + }, + "type": "library", + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/", + "tests/unit/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Fileset component for collecting a set of files given directories and file paths", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "files", + "fileset", + "phpdoc" + ], + "time": "2013-08-06 21:07:42" + }, + { + "name": "phpdocumentor/graphviz", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/GraphViz.git", + "reference": "aa243118c8a055fc853c02802e8503c5435862f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/GraphViz/zipball/aa243118c8a055fc853c02802e8503c5435862f7", + "reference": "aa243118c8a055fc853c02802e8503c5435862f7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~3.7" + }, + "type": "library", + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/", + "tests/unit" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2014-07-19 06:52:59" + }, + { + "name": "phpdocumentor/phpdocumentor", + "version": "v2.8.5", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/phpDocumentor2.git", + "reference": "adfb4affa80e8cc0134616f2d2d264dd25c243eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/phpDocumentor2/zipball/adfb4affa80e8cc0134616f2d2d264dd25c243eb", + "reference": "adfb4affa80e8cc0134616f2d2d264dd25c243eb", + "shasum": "" + }, + "require": { + "cilex/cilex": "~1.0", + "erusev/parsedown": "~1.0", + "herrera-io/phar-update": "1.0.3", + "jms/serializer": "~0.12", + "monolog/monolog": "~1.6", + "php": ">=5.3.3", + "phpdocumentor/fileset": "~1.0", + "phpdocumentor/graphviz": "~1.0", + "phpdocumentor/reflection": "~1.0", + "phpdocumentor/reflection-docblock": "~2.0", + "symfony/config": "~2.3", + "symfony/console": "~2.3", + "symfony/event-dispatcher": "~2.1", + "symfony/process": "~2.0", + "symfony/stopwatch": "~2.3", + "symfony/validator": "~2.2", + "twig/twig": "~1.3", + "zendframework/zend-cache": "~2.1", + "zendframework/zend-config": "~2.1", + "zendframework/zend-filter": "~2.1", + "zendframework/zend-i18n": "~2.1", + "zendframework/zend-serializer": "~2.1", + "zendframework/zend-servicemanager": "~2.1", + "zendframework/zend-stdlib": "~2.1", + "zetacomponents/document": ">=1.3.1" + }, + "require-dev": { + "behat/behat": "~3.0", + "mikey179/vfsstream": "~1.2", + "mockery/mockery": "~0.9@dev", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.4", + "symfony/expression-language": "~2.4" + }, + "suggest": { + "ext-twig": "Enabling the twig extension improves the generation of twig based templates.", + "ext-xslcache": "Enabling the XSLCache extension improves the generation of xml based templates." + }, + "bin": [ + "bin/phpdoc.php", + "bin/phpdoc" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "2.9-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/", + "tests/unit/" + ], + "Cilex\\Provider": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Documentation Generator for PHP", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "api", + "application", + "dga", + "documentation", + "phpdoc" + ], + "time": "2015-07-28 06:36:40" + }, + { + "name": "phpdocumentor/reflection", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/Reflection.git", + "reference": "fc40c3f604ac2287eb5c314174d5109b2c699372" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/fc40c3f604ac2287eb5c314174d5109b2c699372", + "reference": "fc40c3f604ac2287eb5c314174d5109b2c699372", + "shasum": "" + }, + "require": { + "nikic/php-parser": "~0.9.4", + "php": ">=5.3.3", + "phpdocumentor/reflection-docblock": "~2.0", + "psr/log": "~1.0" + }, + "require-dev": { + "behat/behat": "~2.4", + "mockery/mockery": "~0.8", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/", + "tests/unit/", + "tests/mocks/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Reflection library to do Static Analysis for PHP Projects", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2014-11-14 11:43:04" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03 12:10:50" + }, + { + "name": "phpoption/phpoption", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "94e644f7d2051a5f0fcf77d81605f152eecff0ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/94e644f7d2051a5f0fcf77d81605f152eecff0ed", + "reference": "94e644f7d2051a5f0fcf77d81605f152eecff0ed", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-0": { + "PhpOption\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "time": "2015-07-25 16:39:46" + }, + { + "name": "phpspec/prophecy", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", + "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2015-08-13 10:07:40" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c", + "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2015-08-04 03:42:39" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2015-06-21 13:08:43" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21 13:50:34" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2015-06-21 08:01:12" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3ab72c62e550370a6cd5dc873e1a04ab57562f5b", + "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-08-16 08:51:00" + }, + { + "name": "phpunit/phpunit", + "version": "4.7.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "9b97f9d807b862c2de2a36e86690000801c85724" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b97f9d807b862c2de2a36e86690000801c85724", + "reference": "9b97f9d807b862c2de2a36e86690000801c85724", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "~1.3,>=1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": ">=1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.2", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2015-07-13 11:28:34" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "5e2645ad49d196e020b85598d7c97e482725786a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5e2645ad49d196e020b85598d7c97e482725786a", + "reference": "5e2645ad49d196e020b85598d7c97e482725786a", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2015-08-19 09:14:08" + }, + { + "name": "pimple/pimple", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d", + "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ], + "time": "2013-11-22 08:30:29" + }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2012-12-21 11:40:51" + }, + { + "name": "sebastian/comparator", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-07-26 15:48:44" + }, + { + "name": "sebastian/diff", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-02-22 15:13:53" + }, + { + "name": "sebastian/environment", + "version": "1.3.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", + "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2015-08-03 06:14:51" + }, + { + "name": "sebastian/exporter", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "7ae5513327cb536431847bcc0c10edba2701064e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", + "reference": "7ae5513327cb536431847bcc0c10edba2701064e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2015-06-21 07:55:53" + }, + { + "name": "sebastian/global-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2014-10-06 09:23:50" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-06-21 08:04:50" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2015-06-21 13:59:46" + }, + { + "name": "seld/jsonlint", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/863ae85c6d3ef60ca49cb12bd051c4a0648c40c4", + "reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2015-01-04 21:18:15" + }, + { + "name": "symfony/config", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Config.git", + "reference": "6c905bbed1e728226de656e4c07d620dfe9e80d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Config/zipball/6c905bbed1e728226de656e4c07d620dfe9e80d9", + "reference": "6c905bbed1e728226de656e4c07d620dfe9e80d9", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/filesystem": "~2.3" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2015-07-09 16:07:40" + }, + { + "name": "symfony/console", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e", + "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2015-07-28 15:18:12" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/9310b5f9a87ec2ea75d20fec0b0017c77c66dac3", + "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.6", + "symfony/expression-language": "~2.6", + "symfony/phpunit-bridge": "~2.7", + "symfony/stopwatch": "~2.3" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2015-06-18 19:21:56" + }, + { + "name": "symfony/filesystem", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Filesystem.git", + "reference": "2d7b2ddaf3f548f4292df49a99d19c853d43f0b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/2d7b2ddaf3f548f4292df49a99d19c853d43f0b8", + "reference": "2d7b2ddaf3f548f4292df49a99d19c853d43f0b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2015-07-09 16:07:40" + }, + { + "name": "symfony/finder", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/ae0f363277485094edc04c9f3cbe595b183b78e4", + "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2015-07-09 16:07:40" + }, + { + "name": "symfony/process", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Process.git", + "reference": "48aeb0e48600321c272955132d7606ab0a49adb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Process/zipball/48aeb0e48600321c272955132d7606ab0a49adb3", + "reference": "48aeb0e48600321c272955132d7606ab0a49adb3", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2015-07-01 11:25:50" + }, + { + "name": "symfony/stopwatch", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Stopwatch.git", + "reference": "b07a866719bbac5294c67773340f97b871733310" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/b07a866719bbac5294c67773340f97b871733310", + "reference": "b07a866719bbac5294c67773340f97b871733310", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2015-07-01 18:23:16" + }, + { + "name": "symfony/translation", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Translation.git", + "reference": "c8dc34cc936152c609cdd722af317e4239d10dd6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Translation/zipball/c8dc34cc936152c609cdd722af317e4239d10dd6", + "reference": "c8dc34cc936152c609cdd722af317e4239d10dd6", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.7", + "symfony/intl": "~2.3", + "symfony/phpunit-bridge": "~2.7", + "symfony/yaml": "~2.2" + }, + "suggest": { + "psr/log": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com", + "time": "2015-07-09 16:07:40" + }, + { + "name": "symfony/validator", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Validator.git", + "reference": "646df03e635a8a232804274401449ccdf5f03cad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Validator/zipball/646df03e635a8a232804274401449ccdf5f03cad", + "reference": "646df03e635a8a232804274401449ccdf5f03cad", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/translation": "~2.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "egulias/email-validator": "~1.2,>=1.2.1", + "symfony/config": "~2.2", + "symfony/expression-language": "~2.4", + "symfony/http-foundation": "~2.1", + "symfony/intl": "~2.3", + "symfony/phpunit-bridge": "~2.7", + "symfony/property-access": "~2.3", + "symfony/yaml": "~2.0,>=2.0.5" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "egulias/email-validator": "Strict (RFC compliant) email validation", + "symfony/config": "", + "symfony/expression-language": "For using the 2.4 Expression validator", + "symfony/http-foundation": "", + "symfony/intl": "", + "symfony/property-access": "For using the 2.4 Validator API", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Validator\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Validator Component", + "homepage": "https://symfony.com", + "time": "2015-07-31 06:49:15" + }, + { + "name": "symfony/yaml", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "71340e996171474a53f3d29111d046be4ad8a0ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff", + "reference": "71340e996171474a53f3d29111d046be4ad8a0ff", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2015-07-28 14:07:07" + }, + { + "name": "twig/twig", + "version": "v1.21.1", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "ca8d3aa90b6a01c82e07909fe815d6b443e75a23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ca8d3aa90b6a01c82e07909fe815d6b443e75a23", + "reference": "ca8d3aa90b6a01c82e07909fe815d6b443e75a23", + "shasum": "" + }, + "require": { + "php": ">=5.2.7" + }, + "require-dev": { + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.21-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + }, + { + "name": "Twig Team", + "homepage": "http://twig.sensiolabs.org/contributors", + "role": "Contributors" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ], + "time": "2015-08-26 08:58:31" + }, + { + "name": "zendframework/zend-cache", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-cache.git", + "reference": "325afc68d4381cf8b95288ebb9b1d38dc32ed579" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-cache/zipball/325afc68d4381cf8b95288ebb9b1d38dc32ed579", + "reference": "325afc68d4381cf8b95288ebb9b1d38dc32ed579", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "zendframework/zend-eventmanager": "~2.5", + "zendframework/zend-serializer": "~2.5", + "zendframework/zend-servicemanager": "~2.5", + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-session": "~2.5" + }, + "suggest": { + "ext-apcu": "APCU, to use the APC storage adapter", + "ext-dba": "DBA, to use the DBA storage adapter", + "ext-memcache": "Memcache >= 2.0.0 to use the Memcache storage adapter", + "ext-memcached": "Memcached >= 1.0.0 to use the Memcached storage adapter", + "ext-mongo": "Mongo, to use MongoDb storage adapter", + "ext-redis": "Redis, to use Redis storage adapter", + "ext-wincache": "WinCache, to use the WinCache storage adapter", + "ext-xcache": "XCache, to use the XCache storage adapter", + "mongofill/mongofill": "Alternative to ext-mongo - a pure PHP implementation designed as a drop in replacement", + "zendframework/zend-serializer": "Zend\\Serializer component", + "zendframework/zend-session": "Zend\\Session component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a generic way to cache any data", + "homepage": "https://github.com/zendframework/zend-cache", + "keywords": [ + "cache", + "zf2" + ], + "time": "2015-07-16 18:44:41" + }, + { + "name": "zendframework/zend-config", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-config.git", + "reference": "ec49b1df1bdd9772df09dc2f612fbfc279bf4c27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-config/zipball/ec49b1df1bdd9772df09dc2f612fbfc279bf4c27", + "reference": "ec49b1df1bdd9772df09dc2f612fbfc279bf4c27", + "shasum": "" + }, + "require": { + "php": ">=5.3.23", + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-filter": "~2.5", + "zendframework/zend-i18n": "~2.5", + "zendframework/zend-json": "~2.5", + "zendframework/zend-mvc": "~2.5", + "zendframework/zend-servicemanager": "~2.5" + }, + "suggest": { + "zendframework/zend-filter": "Zend\\Filter component", + "zendframework/zend-i18n": "Zend\\I18n component", + "zendframework/zend-json": "Zend\\Json to use the Json reader or writer classes", + "zendframework/zend-servicemanager": "Zend\\ServiceManager for use with the Config Factory to retrieve reader and writer instances" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Config\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a nested object property based user interface for accessing this configuration data within application code", + "homepage": "https://github.com/zendframework/zend-config", + "keywords": [ + "config", + "zf2" + ], + "time": "2015-06-03 15:32:00" + }, + { + "name": "zendframework/zend-eventmanager", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-eventmanager.git", + "reference": "135af03d07fd048c322259aab6611d2be290475c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/135af03d07fd048c322259aab6611d2be290475c", + "reference": "135af03d07fd048c322259aab6611d2be290475c", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\EventManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-eventmanager", + "keywords": [ + "eventmanager", + "zf2" + ], + "time": "2015-07-16 19:00:49" + }, + { + "name": "zendframework/zend-filter", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-filter.git", + "reference": "93e6990a198e6cdd811064083acac4693f4b29ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/93e6990a198e6cdd811064083acac4693f4b29ae", + "reference": "93e6990a198e6cdd811064083acac4693f4b29ae", + "shasum": "" + }, + "require": { + "php": ">=5.3.23", + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-config": "~2.5", + "zendframework/zend-crypt": "~2.5", + "zendframework/zend-i18n": "~2.5", + "zendframework/zend-loader": "~2.5", + "zendframework/zend-servicemanager": "~2.5", + "zendframework/zend-uri": "~2.5" + }, + "suggest": { + "zendframework/zend-crypt": "Zend\\Crypt component", + "zendframework/zend-i18n": "Zend\\I18n component", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component", + "zendframework/zend-uri": "Zend\\Uri component for UriNormalize filter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Filter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a set of commonly needed data filters", + "homepage": "https://github.com/zendframework/zend-filter", + "keywords": [ + "filter", + "zf2" + ], + "time": "2015-06-03 15:32:01" + }, + { + "name": "zendframework/zend-i18n", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-i18n.git", + "reference": "509271eb7947e4aabebfc376104179cffea42696" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/509271eb7947e4aabebfc376104179cffea42696", + "reference": "509271eb7947e4aabebfc376104179cffea42696", + "shasum": "" + }, + "require": { + "php": ">=5.3.23", + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-cache": "~2.5", + "zendframework/zend-config": "~2.5", + "zendframework/zend-eventmanager": "~2.5", + "zendframework/zend-filter": "~2.5", + "zendframework/zend-servicemanager": "~2.5", + "zendframework/zend-validator": "~2.5", + "zendframework/zend-view": "~2.5" + }, + "suggest": { + "ext-intl": "Required for most features of Zend\\I18n; included in default builds of PHP", + "zendframework/zend-cache": "Zend\\Cache component", + "zendframework/zend-config": "Zend\\Config component", + "zendframework/zend-eventmanager": "You should install this package to use the events in the translator", + "zendframework/zend-filter": "You should install this package to use the provided filters", + "zendframework/zend-resources": "Translation resources", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component", + "zendframework/zend-validator": "You should install this package to use the provided validators", + "zendframework/zend-view": "You should install this package to use the provided view helpers" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\I18n\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-i18n", + "keywords": [ + "i18n", + "zf2" + ], + "time": "2015-06-03 15:32:01" + }, + { + "name": "zendframework/zend-json", + "version": "2.5.2", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-json.git", + "reference": "4a3add6505fd8618728239d8ce35f182dfbdac02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-json/zipball/4a3add6505fd8618728239d8ce35f182dfbdac02", + "reference": "4a3add6505fd8618728239d8ce35f182dfbdac02", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-http": "~2.5", + "zendframework/zend-server": "~2.5", + "zendframework/zendxml": "~1.0" + }, + "suggest": { + "zendframework/zend-http": "Zend\\Http component", + "zendframework/zend-server": "Zend\\Server component", + "zendframework/zendxml": "To support Zend\\Json\\Json::fromXml() usage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Json\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP", + "homepage": "https://github.com/zendframework/zend-json", + "keywords": [ + "json", + "zf2" + ], + "time": "2015-08-05 14:45:17" + }, + { + "name": "zendframework/zend-math", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-math.git", + "reference": "9f02a1ac4d3374d3332c80f9215deec9c71558fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-math/zipball/9f02a1ac4d3374d3332c80f9215deec9c71558fc", + "reference": "9f02a1ac4d3374d3332c80f9215deec9c71558fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.23" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "ircmaxell/random-lib": "~1.1", + "phpunit/phpunit": "~4.0", + "zendframework/zend-servicemanager": "~2.5" + }, + "suggest": { + "ext-bcmath": "If using the bcmath functionality", + "ext-gmp": "If using the gmp functionality", + "ircmaxell/random-lib": "Fallback random byte generator for Zend\\Math\\Rand if OpenSSL/Mcrypt extensions are unavailable", + "zendframework/zend-servicemanager": ">= current version, if using the BigInteger::factory functionality" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-math", + "keywords": [ + "math", + "zf2" + ], + "time": "2015-06-03 15:32:02" + }, + { + "name": "zendframework/zend-serializer", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-serializer.git", + "reference": "b7208eb17dc4a4fb3a660b85e6c4af035eeed40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-serializer/zipball/b7208eb17dc4a4fb3a660b85e6c4af035eeed40c", + "reference": "b7208eb17dc4a4fb3a660b85e6c4af035eeed40c", + "shasum": "" + }, + "require": { + "php": ">=5.3.23", + "zendframework/zend-json": "~2.5", + "zendframework/zend-math": "~2.5", + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-servicemanager": "~2.5" + }, + "suggest": { + "zendframework/zend-servicemanager": "To support plugin manager support" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Serializer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides an adapter based interface to simply generate storable representation of PHP types by different facilities, and recover", + "homepage": "https://github.com/zendframework/zend-serializer", + "keywords": [ + "serializer", + "zf2" + ], + "time": "2015-06-03 15:32:02" + }, + { + "name": "zendframework/zend-servicemanager", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-servicemanager.git", + "reference": "1dc33f23bd0a7f4d8ba743b915fae523d356027a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/1dc33f23bd0a7f4d8ba743b915fae523d356027a", + "reference": "1dc33f23bd0a7f4d8ba743b915fae523d356027a", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "~1.0", + "php": ">=5.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-di": "~2.5", + "zendframework/zend-mvc": "~2.5" + }, + "suggest": { + "ocramius/proxy-manager": "ProxyManager 0.5.* to handle lazy initialization of services", + "zendframework/zend-di": "Zend\\Di component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\ServiceManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-servicemanager", + "keywords": [ + "servicemanager", + "zf2" + ], + "time": "2015-07-23 21:49:08" + }, + { + "name": "zendframework/zend-stdlib", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-stdlib.git", + "reference": "a35758803fc9051ec1aff43989e679b6b451b1b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/a35758803fc9051ec1aff43989e679b6b451b1b4", + "reference": "a35758803fc9051ec1aff43989e679b6b451b1b4", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-config": "~2.5", + "zendframework/zend-eventmanager": "~2.5", + "zendframework/zend-filter": "~2.5", + "zendframework/zend-inputfilter": "~2.5", + "zendframework/zend-serializer": "~2.5", + "zendframework/zend-servicemanager": "~2.5" + }, + "suggest": { + "zendframework/zend-eventmanager": "To support aggregate hydrator usage", + "zendframework/zend-filter": "To support naming strategy hydrator usage", + "zendframework/zend-serializer": "Zend\\Serializer component", + "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Stdlib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-stdlib", + "keywords": [ + "stdlib", + "zf2" + ], + "time": "2015-07-21 17:08:05" + }, + { + "name": "zetacomponents/base", + "version": "1.9", + "source": { + "type": "git", + "url": "https://github.com/zetacomponents/Base.git", + "reference": "f20df24e8de3e48b6b69b2503f917e457281e687" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zetacomponents/Base/zipball/f20df24e8de3e48b6b69b2503f917e457281e687", + "reference": "f20df24e8de3e48b6b69b2503f917e457281e687", + "shasum": "" + }, + "require-dev": { + "zetacomponents/unit-test": "*" + }, + "type": "library", + "autoload": { + "classmap": [ + "src" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Sergey Alexeev" + }, + { + "name": "Sebastian Bergmann" + }, + { + "name": "Jan Borsodi" + }, + { + "name": "Raymond Bosman" + }, + { + "name": "Frederik Holljen" + }, + { + "name": "Kore Nordmann" + }, + { + "name": "Derick Rethans" + }, + { + "name": "Vadym Savchuk" + }, + { + "name": "Tobias Schlitt" + }, + { + "name": "Alexandru Stanoi" + } + ], + "description": "The Base package provides the basic infrastructure that all packages rely on. Therefore every component relies on this package.", + "homepage": "https://github.com/zetacomponents", + "time": "2014-09-19 03:28:34" + }, + { + "name": "zetacomponents/document", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/zetacomponents/Document.git", + "reference": "688abfde573cf3fe0730f82538fbd7aa9fc95bc8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zetacomponents/Document/zipball/688abfde573cf3fe0730f82538fbd7aa9fc95bc8", + "reference": "688abfde573cf3fe0730f82538fbd7aa9fc95bc8", + "shasum": "" + }, + "require": { + "zetacomponents/base": "*" + }, + "require-dev": { + "zetacomponents/unit-test": "dev-master" + }, + "type": "library", + "autoload": { + "classmap": [ + "src" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Sebastian Bergmann" + }, + { + "name": "Kore Nordmann" + }, + { + "name": "Derick Rethans" + }, + { + "name": "Tobias Schlitt" + }, + { + "name": "Alexandru Stanoi" + } + ], + "description": "The Document components provides a general conversion framework for different semantic document markup languages like XHTML, Docbook, RST and similar.", + "homepage": "https://github.com/zetacomponents", + "time": "2013-12-19 11:40:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.0.0" + }, + "platform-dev": [] +} diff --git a/libraries/vendor/phpmailer/phpmailer/extras/EasyPeasyICS.php b/libraries/vendor/phpmailer/phpmailer/extras/EasyPeasyICS.php index f076895588f8d..d8bfcfae65957 100644 --- a/libraries/vendor/phpmailer/phpmailer/extras/EasyPeasyICS.php +++ b/libraries/vendor/phpmailer/phpmailer/extras/EasyPeasyICS.php @@ -1,90 +1,148 @@ + * @author Manuel Reinhard + * + * Built with inspiration from + * http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355 + * History: + * 2010/12/17 - Manuel Reinhard - when it all started + * 2014 PHPMailer project becomes maintainer + */ -/* ------------------------------------------------------------------------ */ -/* EasyPeasyICS -/* ------------------------------------------------------------------------ */ -/* Manuel Reinhard, manu@sprain.ch -/* Twitter: @sprain -/* Web: www.sprain.ch -/* -/* Built with inspiration by -/" http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355 -/* ------------------------------------------------------------------------ */ -/* History: -/* 2010/12/17 - Manuel Reinhard - when it all started -/* ------------------------------------------------------------------------ */ +/** + * Class EasyPeasyICS. + * Simple ICS data generator + * @package phpmailer + * @subpackage easypeasyics + */ +class EasyPeasyICS +{ + /** + * The name of the calendar + * @var string + */ + protected $calendarName; + /** + * The array of events to add to this calendar + * @var array + */ + protected $events = array(); -class EasyPeasyICS { + /** + * Constructor + * @param string $calendarName + */ + public function __construct($calendarName = "") + { + $this->calendarName = $calendarName; + } - protected $calendarName; - protected $events = array(); - + /** + * Add an event to this calendar. + * @param string $start The start date and time as a unix timestamp + * @param string $end The end date and time as a unix timestamp + * @param string $summary A summary or title for the event + * @param string $description A description of the event + * @param string $url A URL for the event + * @param string $uid A unique identifier for the event - generated automatically if not provided + * @return array An array of event details, including any generated UID + */ + public function addEvent($start, $end, $summary = '', $description = '', $url = '', $uid = '') + { + if (empty($uid)) { + $uid = md5(uniqid(mt_rand(), true)) . '@EasyPeasyICS'; + } + $event = array( + 'start' => gmdate('Ymd', $start) . 'T' . gmdate('His', $start) . 'Z', + 'end' => gmdate('Ymd', $end) . 'T' . gmdate('His', $end) . 'Z', + 'summary' => $summary, + 'description' => $description, + 'url' => $url, + 'uid' => $uid + ); + $this->events[] = $event; + return $event; + } - /** - * Constructor - * @param string $calendarName - */ - public function __construct($calendarName=""){ - $this->calendarName = $calendarName; - }//function + /** + * @return array Get the array of events. + */ + public function getEvents() + { + return $this->events; + } + /** + * Clear all events. + */ + public function clearEvents() + { + $this->events = array(); + } - /** - * Add event to calendar - * @param string $calendarName - */ - public function addEvent($start, $end, $summary="", $description="", $url=""){ - $this->events[] = array( - "start" => $start, - "end" => $end, - "summary" => $summary, - "description" => $description, - "url" => $url - ); - }//function - - - public function render($output = true){ - - //start Variable - $ics = ""; - - //Add header - $ics .= "BEGIN:VCALENDAR + /** + * Get the name of the calendar. + * @return string + */ + public function getName() + { + return $this->calendarName; + } + + /** + * Set the name of the calendar. + * @param $name + */ + public function setName($name) + { + $this->calendarName = $name; + } + + /** + * Render and optionally output a vcal string. + * @param bool $output Whether to output the calendar data directly (the default). + * @return string The complete rendered vlal + */ + public function render($output = true) + { + //Add header + $ics = 'BEGIN:VCALENDAR METHOD:PUBLISH VERSION:2.0 -X-WR-CALNAME:".$this->calendarName." -PRODID:-//hacksw/handcal//NONSGML v1.0//EN"; - - //Add events - foreach($this->events as $event){ - $ics .= " -BEGIN:VEVENT -UID:". md5(uniqid(mt_rand(), true)) ."@EasyPeasyICS.php -DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z -DTSTART:".gmdate('Ymd', $event["start"])."T".gmdate('His', $event["start"])."Z -DTEND:".gmdate('Ymd', $event["end"])."T".gmdate('His', $event["end"])."Z -SUMMARY:".str_replace("\n", "\\n", $event['summary'])." -DESCRIPTION:".str_replace("\n", "\\n", $event['description'])." -URL;VALUE=URI:".$event['url']." -END:VEVENT"; - }//foreach - - - //Footer - $ics .= " -END:VCALENDAR"; +X-WR-CALNAME:' . $this->calendarName . ' +PRODID:-//hacksw/handcal//NONSGML v1.0//EN'; + //Add events + foreach ($this->events as $event) { + $ics .= ' +BEGIN:VEVENT +UID:' . $event['uid'] . ' +DTSTAMP:' . gmdate('Ymd') . 'T' . gmdate('His') . 'Z +DTSTART:' . $event['start'] . ' +DTEND:' . $event['end'] . ' +SUMMARY:' . str_replace("\n", "\\n", $event['summary']) . ' +DESCRIPTION:' . str_replace("\n", "\\n", $event['description']) . ' +URL;VALUE=URI:' . $event['url'] . ' +END:VEVENT'; + } - if ($output) { - //Output - header('Content-type: text/calendar; charset=utf-8'); - header('Content-Disposition: inline; filename='.$this->calendarName.'.ics'); - echo $ics; - } else { - return $ics; - } - - }//function + //Add footer + $ics .= ' +END:VCALENDAR'; -}//class \ No newline at end of file + if ($output) { + //Output + $filename = $this->calendarName; + //Filename needs quoting if it contains spaces + if (strpos($filename, ' ') !== false) { + $filename = '"'.$filename.'"'; + } + header('Content-type: text/calendar; charset=utf-8'); + header('Content-Disposition: inline; filename=' . $filename . '.ics'); + echo $ics; + } + return $ics; + } +} diff --git a/libraries/vendor/phpmailer/phpmailer/extras/class.html2text.php b/libraries/vendor/phpmailer/phpmailer/extras/class.html2text.php deleted file mode 100644 index 20609919b4a91..0000000000000 --- a/libraries/vendor/phpmailer/phpmailer/extras/class.html2text.php +++ /dev/null @@ -1,677 +0,0 @@ - * - * * - * This script is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * The GNU General Public License can be found at * - * http://www.gnu.org/copyleft/gpl.html. * - * * - * This script is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - *************************************************************************/ - -/** - * Converts HTML to formatted plain text - */ -class Html2Text -{ - /** - * Contains the HTML content to convert. - * - * @type string - */ - protected $html; - - /** - * Contains the converted, formatted text. - * - * @type string - */ - protected $text; - - /** - * Maximum width of the formatted text, in columns. - * - * Set this value to 0 (or less) to ignore word wrapping - * and not constrain text to a fixed-width column. - * - * @type integer - */ - protected $width = 70; - - /** - * List of preg* regular expression patterns to search for, - * used in conjunction with $replace. - * - * @type array - * @see $replace - */ - protected $search = array( - "/\r/", // Non-legal carriage return - "/[\n\t]+/", // Newlines and tabs - '/]*>.*?<\/head>/i', // - '/]*>.*?<\/script>/i', //