Ticket #25560: ticket-25560-phpmailer-minimal.patch
File ticket-25560-phpmailer-minimal.patch, 450.1 KB (added by , 11 years ago) |
---|
-
new file src/wp-includes/PHPMailer/.gitignore
diff --git src/wp-includes/PHPMailer/.gitignore src/wp-includes/PHPMailer/.gitignore new file mode 100644 index 0000000..88d2922
- + 1 docs/phpdoc/ 2 test/message.txt 3 test/testbootstrap.php 4 .idea -
new file src/wp-includes/PHPMailer/.travis.yml
diff --git src/wp-includes/PHPMailer/.travis.yml src/wp-includes/PHPMailer/.travis.yml new file mode 100644 index 0000000..28f0099
- + 1 language: php 2 php: 3 - 5.5 4 - 5.4 5 - 5.3 6 before_install: 7 - sudo apt-get update -qq 8 - sudo apt-get install -y -qq postfix 9 before_script: 10 - sudo service postfix stop 11 - smtp-sink -d "%d.%H.%M.%S" localhost:2500 1000 & 12 - cd test 13 - cp testbootstrap-dist.php testbootstrap.php 14 - chmod +x fakesendmail.sh 15 - sudo mkdir -p /var/qmail/bin 16 - sudo cp fakesendmail.sh /var/qmail/bin/sendmail 17 - sudo cp fakesendmail.sh /usr/sbin/sendmail 18 - echo 'sendmail_path = "/usr/sbin/sendmail -t -i "' | sudo tee "/home/travis/.phpenv/versions/`php -i|grep "PHP Version"|head -n 1|grep -o -P '\d+\.\d+\.\d+.*'`/etc/conf.d/sendmail.ini" 19 script: 20 - phpunit phpmailerTest -
new file src/wp-includes/PHPMailer/LICENSE
diff --git src/wp-includes/PHPMailer/LICENSE src/wp-includes/PHPMailer/LICENSE new file mode 100644 index 0000000..8e0763d
- + 1 GNU LESSER GENERAL PUBLIC LICENSE 2 Version 2.1, February 1999 3 4 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 Everyone is permitted to copy and distribute verbatim copies 7 of this license document, but changing it is not allowed. 8 9 [This is the first released version of the Lesser GPL. It also counts 10 as the successor of the GNU Library Public License, version 2, hence 11 the version number 2.1.] 12 13 Preamble 14 15 The licenses for most software are designed to take away your 16 freedom to share and change it. By contrast, the GNU General Public 17 Licenses are intended to guarantee your freedom to share and change 18 free software--to make sure the software is free for all its users. 19 20 This license, the Lesser General Public License, applies to some 21 specially designated software packages--typically libraries--of the 22 Free Software Foundation and other authors who decide to use it. You 23 can use it too, but we suggest you first think carefully about whether 24 this license or the ordinary General Public License is the better 25 strategy to use in any particular case, based on the explanations below. 26 27 When we speak of free software, we are referring to freedom of use, 28 not price. Our General Public Licenses are designed to make sure that 29 you have the freedom to distribute copies of free software (and charge 30 for this service if you wish); that you receive source code or can get 31 it if you want it; that you can change the software and use pieces of 32 it in new free programs; and that you are informed that you can do 33 these things. 34 35 To protect your rights, we need to make restrictions that forbid 36 distributors to deny you these rights or to ask you to surrender these 37 rights. These restrictions translate to certain responsibilities for 38 you if you distribute copies of the library or if you modify it. 39 40 For example, if you distribute copies of the library, whether gratis 41 or for a fee, you must give the recipients all the rights that we gave 42 you. You must make sure that they, too, receive or can get the source 43 code. If you link other code with the library, you must provide 44 complete object files to the recipients, so that they can relink them 45 with the library after making changes to the library and recompiling 46 it. And you must show them these terms so they know their rights. 47 48 We protect your rights with a two-step method: (1) we copyright the 49 library, and (2) we offer you this license, which gives you legal 50 permission to copy, distribute and/or modify the library. 51 52 To protect each distributor, we want to make it very clear that 53 there is no warranty for the free library. Also, if the library is 54 modified by someone else and passed on, the recipients should know 55 that what they have is not the original version, so that the original 56 author's reputation will not be affected by problems that might be 57 introduced by others. 58 59 Finally, software patents pose a constant threat to the existence of 60 any free program. We wish to make sure that a company cannot 61 effectively restrict the users of a free program by obtaining a 62 restrictive license from a patent holder. Therefore, we insist that 63 any patent license obtained for a version of the library must be 64 consistent with the full freedom of use specified in this license. 65 66 Most GNU software, including some libraries, is covered by the 67 ordinary GNU General Public License. This license, the GNU Lesser 68 General Public License, applies to certain designated libraries, and 69 is quite different from the ordinary General Public License. We use 70 this license for certain libraries in order to permit linking those 71 libraries into non-free programs. 72 73 When a program is linked with a library, whether statically or using 74 a shared library, the combination of the two is legally speaking a 75 combined work, a derivative of the original library. The ordinary 76 General Public License therefore permits such linking only if the 77 entire combination fits its criteria of freedom. The Lesser General 78 Public License permits more lax criteria for linking other code with 79 the library. 80 81 We call this license the "Lesser" General Public License because it 82 does Less to protect the user's freedom than the ordinary General 83 Public License. It also provides other free software developers Less 84 of an advantage over competing non-free programs. These disadvantages 85 are the reason we use the ordinary General Public License for many 86 libraries. However, the Lesser license provides advantages in certain 87 special circumstances. 88 89 For example, on rare occasions, there may be a special need to 90 encourage the widest possible use of a certain library, so that it becomes 91 a de-facto standard. To achieve this, non-free programs must be 92 allowed to use the library. A more frequent case is that a free 93 library does the same job as widely used non-free libraries. In this 94 case, there is little to gain by limiting the free library to free 95 software only, so we use the Lesser General Public License. 96 97 In other cases, permission to use a particular library in non-free 98 programs enables a greater number of people to use a large body of 99 free software. For example, permission to use the GNU C Library in 100 non-free programs enables many more people to use the whole GNU 101 operating system, as well as its variant, the GNU/Linux operating 102 system. 103 104 Although the Lesser General Public License is Less protective of the 105 users' freedom, it does ensure that the user of a program that is 106 linked with the Library has the freedom and the wherewithal to run 107 that program using a modified version of the Library. 108 109 The precise terms and conditions for copying, distribution and 110 modification follow. Pay close attention to the difference between a 111 "work based on the library" and a "work that uses the library". The 112 former contains code derived from the library, whereas the latter must 113 be combined with the library in order to run. 114 115 GNU LESSER GENERAL PUBLIC LICENSE 116 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 118 0. This License Agreement applies to any software library or other 119 program which contains a notice placed by the copyright holder or 120 other authorized party saying it may be distributed under the terms of 121 this Lesser General Public License (also called "this License"). 122 Each licensee is addressed as "you". 123 124 A "library" means a collection of software functions and/or data 125 prepared so as to be conveniently linked with application programs 126 (which use some of those functions and data) to form executables. 127 128 The "Library", below, refers to any such software library or work 129 which has been distributed under these terms. A "work based on the 130 Library" means either the Library or any derivative work under 131 copyright law: that is to say, a work containing the Library or a 132 portion of it, either verbatim or with modifications and/or translated 133 straightforwardly into another language. (Hereinafter, translation is 134 included without limitation in the term "modification".) 135 136 "Source code" for a work means the preferred form of the work for 137 making modifications to it. For a library, complete source code means 138 all the source code for all modules it contains, plus any associated 139 interface definition files, plus the scripts used to control compilation 140 and installation of the library. 141 142 Activities other than copying, distribution and modification are not 143 covered by this License; they are outside its scope. The act of 144 running a program using the Library is not restricted, and output from 145 such a program is covered only if its contents constitute a work based 146 on the Library (independent of the use of the Library in a tool for 147 writing it). Whether that is true depends on what the Library does 148 and what the program that uses the Library does. 149 150 1. You may copy and distribute verbatim copies of the Library's 151 complete source code as you receive it, in any medium, provided that 152 you conspicuously and appropriately publish on each copy an 153 appropriate copyright notice and disclaimer of warranty; keep intact 154 all the notices that refer to this License and to the absence of any 155 warranty; and distribute a copy of this License along with the 156 Library. 157 158 You may charge a fee for the physical act of transferring a copy, 159 and you may at your option offer warranty protection in exchange for a 160 fee. 161 162 2. You may modify your copy or copies of the Library or any portion 163 of it, thus forming a work based on the Library, and copy and 164 distribute such modifications or work under the terms of Section 1 165 above, provided that you also meet all of these conditions: 166 167 a) The modified work must itself be a software library. 168 169 b) You must cause the files modified to carry prominent notices 170 stating that you changed the files and the date of any change. 171 172 c) You must cause the whole of the work to be licensed at no 173 charge to all third parties under the terms of this License. 174 175 d) If a facility in the modified Library refers to a function or a 176 table of data to be supplied by an application program that uses 177 the facility, other than as an argument passed when the facility 178 is invoked, then you must make a good faith effort to ensure that, 179 in the event an application does not supply such function or 180 table, the facility still operates, and performs whatever part of 181 its purpose remains meaningful. 182 183 (For example, a function in a library to compute square roots has 184 a purpose that is entirely well-defined independent of the 185 application. Therefore, Subsection 2d requires that any 186 application-supplied function or table used by this function must 187 be optional: if the application does not supply it, the square 188 root function must still compute square roots.) 189 190 These requirements apply to the modified work as a whole. If 191 identifiable sections of that work are not derived from the Library, 192 and can be reasonably considered independent and separate works in 193 themselves, then this License, and its terms, do not apply to those 194 sections when you distribute them as separate works. But when you 195 distribute the same sections as part of a whole which is a work based 196 on the Library, the distribution of the whole must be on the terms of 197 this License, whose permissions for other licensees extend to the 198 entire whole, and thus to each and every part regardless of who wrote 199 it. 200 201 Thus, it is not the intent of this section to claim rights or contest 202 your rights to work written entirely by you; rather, the intent is to 203 exercise the right to control the distribution of derivative or 204 collective works based on the Library. 205 206 In addition, mere aggregation of another work not based on the Library 207 with the Library (or with a work based on the Library) on a volume of 208 a storage or distribution medium does not bring the other work under 209 the scope of this License. 210 211 3. You may opt to apply the terms of the ordinary GNU General Public 212 License instead of this License to a given copy of the Library. To do 213 this, you must alter all the notices that refer to this License, so 214 that they refer to the ordinary GNU General Public License, version 2, 215 instead of to this License. (If a newer version than version 2 of the 216 ordinary GNU General Public License has appeared, then you can specify 217 that version instead if you wish.) Do not make any other change in 218 these notices. 219 220 Once this change is made in a given copy, it is irreversible for 221 that copy, so the ordinary GNU General Public License applies to all 222 subsequent copies and derivative works made from that copy. 223 224 This option is useful when you wish to copy part of the code of 225 the Library into a program that is not a library. 226 227 4. You may copy and distribute the Library (or a portion or 228 derivative of it, under Section 2) in object code or executable form 229 under the terms of Sections 1 and 2 above provided that you accompany 230 it with the complete corresponding machine-readable source code, which 231 must be distributed under the terms of Sections 1 and 2 above on a 232 medium customarily used for software interchange. 233 234 If distribution of object code is made by offering access to copy 235 from a designated place, then offering equivalent access to copy the 236 source code from the same place satisfies the requirement to 237 distribute the source code, even though third parties are not 238 compelled to copy the source along with the object code. 239 240 5. A program that contains no derivative of any portion of the 241 Library, but is designed to work with the Library by being compiled or 242 linked with it, is called a "work that uses the Library". Such a 243 work, in isolation, is not a derivative work of the Library, and 244 therefore falls outside the scope of this License. 245 246 However, linking a "work that uses the Library" with the Library 247 creates an executable that is a derivative of the Library (because it 248 contains portions of the Library), rather than a "work that uses the 249 library". The executable is therefore covered by this License. 250 Section 6 states terms for distribution of such executables. 251 252 When a "work that uses the Library" uses material from a header file 253 that is part of the Library, the object code for the work may be a 254 derivative work of the Library even though the source code is not. 255 Whether this is true is especially significant if the work can be 256 linked without the Library, or if the work is itself a library. The 257 threshold for this to be true is not precisely defined by law. 258 259 If such an object file uses only numerical parameters, data 260 structure layouts and accessors, and small macros and small inline 261 functions (ten lines or less in length), then the use of the object 262 file is unrestricted, regardless of whether it is legally a derivative 263 work. (Executables containing this object code plus portions of the 264 Library will still fall under Section 6.) 265 266 Otherwise, if the work is a derivative of the Library, you may 267 distribute the object code for the work under the terms of Section 6. 268 Any executables containing that work also fall under Section 6, 269 whether or not they are linked directly with the Library itself. 270 271 6. As an exception to the Sections above, you may also combine or 272 link a "work that uses the Library" with the Library to produce a 273 work containing portions of the Library, and distribute that work 274 under terms of your choice, provided that the terms permit 275 modification of the work for the customer's own use and reverse 276 engineering for debugging such modifications. 277 278 You must give prominent notice with each copy of the work that the 279 Library is used in it and that the Library and its use are covered by 280 this License. You must supply a copy of this License. If the work 281 during execution displays copyright notices, you must include the 282 copyright notice for the Library among them, as well as a reference 283 directing the user to the copy of this License. Also, you must do one 284 of these things: 285 286 a) Accompany the work with the complete corresponding 287 machine-readable source code for the Library including whatever 288 changes were used in the work (which must be distributed under 289 Sections 1 and 2 above); and, if the work is an executable linked 290 with the Library, with the complete machine-readable "work that 291 uses the Library", as object code and/or source code, so that the 292 user can modify the Library and then relink to produce a modified 293 executable containing the modified Library. (It is understood 294 that the user who changes the contents of definitions files in the 295 Library will not necessarily be able to recompile the application 296 to use the modified definitions.) 297 298 b) Use a suitable shared library mechanism for linking with the 299 Library. A suitable mechanism is one that (1) uses at run time a 300 copy of the library already present on the user's computer system, 301 rather than copying library functions into the executable, and (2) 302 will operate properly with a modified version of the library, if 303 the user installs one, as long as the modified version is 304 interface-compatible with the version that the work was made with. 305 306 c) Accompany the work with a written offer, valid for at 307 least three years, to give the same user the materials 308 specified in Subsection 6a, above, for a charge no more 309 than the cost of performing this distribution. 310 311 d) If distribution of the work is made by offering access to copy 312 from a designated place, offer equivalent access to copy the above 313 specified materials from the same place. 314 315 e) verify that the user has already received a copy of these 316 materials or that you have already sent this user a copy. 317 318 For an executable, the required form of the "work that uses the 319 Library" must include any data and utility programs needed for 320 reproducing the executable from it. However, as a special exception, 321 the materials to be distributed need not include anything that is 322 normally distributed (in either source or binary form) with the major 323 components (compiler, kernel, and so on) of the operating system on 324 which the executable runs, unless that component itself accompanies 325 the executable. 326 327 It may happen that this requirement contradicts the license 328 restrictions of other proprietary libraries that do not normally 329 accompany the operating system. Such a contradiction means you cannot 330 use both them and the Library together in an executable that you 331 distribute. 332 333 7. You may place library facilities that are a work based on the 334 Library side-by-side in a single library together with other library 335 facilities not covered by this License, and distribute such a combined 336 library, provided that the separate distribution of the work based on 337 the Library and of the other library facilities is otherwise 338 permitted, and provided that you do these two things: 339 340 a) Accompany the combined library with a copy of the same work 341 based on the Library, uncombined with any other library 342 facilities. This must be distributed under the terms of the 343 Sections above. 344 345 b) Give prominent notice with the combined library of the fact 346 that part of it is a work based on the Library, and explaining 347 where to find the accompanying uncombined form of the same work. 348 349 8. You may not copy, modify, sublicense, link with, or distribute 350 the Library except as expressly provided under this License. Any 351 attempt otherwise to copy, modify, sublicense, link with, or 352 distribute the Library is void, and will automatically terminate your 353 rights under this License. However, parties who have received copies, 354 or rights, from you under this License will not have their licenses 355 terminated so long as such parties remain in full compliance. 356 357 9. You are not required to accept this License, since you have not 358 signed it. However, nothing else grants you permission to modify or 359 distribute the Library or its derivative works. These actions are 360 prohibited by law if you do not accept this License. Therefore, by 361 modifying or distributing the Library (or any work based on the 362 Library), you indicate your acceptance of this License to do so, and 363 all its terms and conditions for copying, distributing or modifying 364 the Library or works based on it. 365 366 10. Each time you redistribute the Library (or any work based on the 367 Library), the recipient automatically receives a license from the 368 original licensor to copy, distribute, link with or modify the Library 369 subject to these terms and conditions. You may not impose any further 370 restrictions on the recipients' exercise of the rights granted herein. 371 You are not responsible for enforcing compliance by third parties with 372 this License. 373 374 11. If, as a consequence of a court judgment or allegation of patent 375 infringement or for any other reason (not limited to patent issues), 376 conditions are imposed on you (whether by court order, agreement or 377 otherwise) that contradict the conditions of this License, they do not 378 excuse you from the conditions of this License. If you cannot 379 distribute so as to satisfy simultaneously your obligations under this 380 License and any other pertinent obligations, then as a consequence you 381 may not distribute the Library at all. For example, if a patent 382 license would not permit royalty-free redistribution of the Library by 383 all those who receive copies directly or indirectly through you, then 384 the only way you could satisfy both it and this License would be to 385 refrain entirely from distribution of the Library. 386 387 If any portion of this section is held invalid or unenforceable under any 388 particular circumstance, the balance of the section is intended to apply, 389 and the section as a whole is intended to apply in other circumstances. 390 391 It is not the purpose of this section to induce you to infringe any 392 patents or other property right claims or to contest validity of any 393 such claims; this section has the sole purpose of protecting the 394 integrity of the free software distribution system which is 395 implemented by public license practices. Many people have made 396 generous contributions to the wide range of software distributed 397 through that system in reliance on consistent application of that 398 system; it is up to the author/donor to decide if he or she is willing 399 to distribute software through any other system and a licensee cannot 400 impose that choice. 401 402 This section is intended to make thoroughly clear what is believed to 403 be a consequence of the rest of this License. 404 405 12. If the distribution and/or use of the Library is restricted in 406 certain countries either by patents or by copyrighted interfaces, the 407 original copyright holder who places the Library under this License may add 408 an explicit geographical distribution limitation excluding those countries, 409 so that distribution is permitted only in or among countries not thus 410 excluded. In such case, this License incorporates the limitation as if 411 written in the body of this License. 412 413 13. The Free Software Foundation may publish revised and/or new 414 versions of the Lesser General Public License from time to time. 415 Such new versions will be similar in spirit to the present version, 416 but may differ in detail to address new problems or concerns. 417 418 Each version is given a distinguishing version number. If the Library 419 specifies a version number of this License which applies to it and 420 "any later version", you have the option of following the terms and 421 conditions either of that version or of any later version published by 422 the Free Software Foundation. If the Library does not specify a 423 license version number, you may choose any version ever published by 424 the Free Software Foundation. 425 426 14. If you wish to incorporate parts of the Library into other free 427 programs whose distribution conditions are incompatible with these, 428 write to the author to ask for permission. For software which is 429 copyrighted by the Free Software Foundation, write to the Free 430 Software Foundation; we sometimes make exceptions for this. Our 431 decision will be guided by the two goals of preserving the free status 432 of all derivatives of our free software and of promoting the sharing 433 and reuse of software generally. 434 435 NO WARRANTY 436 437 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 447 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 DAMAGES. 457 458 END OF TERMS AND CONDITIONS 459 460 How to Apply These Terms to Your New Libraries 461 462 If you develop a new library, and you want it to be of the greatest 463 possible use to the public, we recommend making it free software that 464 everyone can redistribute and change. You can do so by permitting 465 redistribution under these terms (or, alternatively, under the terms of the 466 ordinary General Public License). 467 468 To apply these terms, attach the following notices to the library. It is 469 safest to attach them to the start of each source file to most effectively 470 convey the exclusion of warranty; and each file should have at least the 471 "copyright" line and a pointer to where the full notice is found. 472 473 <one line to give the library's name and a brief idea of what it does.> 474 Copyright (C) <year> <name of author> 475 476 This library is free software; you can redistribute it and/or 477 modify it under the terms of the GNU Lesser General Public 478 License as published by the Free Software Foundation; either 479 version 2.1 of the License, or (at your option) any later version. 480 481 This library is distributed in the hope that it will be useful, 482 but WITHOUT ANY WARRANTY; without even the implied warranty of 483 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 Lesser General Public License for more details. 485 486 You should have received a copy of the GNU Lesser General Public 487 License along with this library; if not, write to the Free Software 488 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 489 490 Also add information on how to contact you by electronic and paper mail. 491 492 You should also get your employer (if you work as a programmer) or your 493 school, if any, to sign a "copyright disclaimer" for the library, if 494 necessary. Here is a sample; alter the names: 495 496 Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 499 <signature of Ty Coon>, 1 April 1990 500 Ty Coon, President of Vice 501 502 That's all there is to it! 503 504 -
new file src/wp-includes/PHPMailer/PHPMailerAutoload.php
diff --git src/wp-includes/PHPMailer/PHPMailerAutoload.php src/wp-includes/PHPMailer/PHPMailerAutoload.php new file mode 100644 index 0000000..46db5bd
- + 1 <?php 2 /** 3 * PHPMailer SPL autoloader. 4 * PHP Version 5.0.0 5 * @package PHPMailer 6 * @link https://github.com/PHPMailer/PHPMailer/ 7 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk> 8 * @author Jim Jagielski (jimjag) <jimjag@gmail.com> 9 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> 10 * @author Brent R. Matzelle (original founder) 11 * @copyright 2013 Marcus Bointon 12 * @copyright 2010 - 2012 Jim Jagielski 13 * @copyright 2004 - 2009 Andy Prevost 14 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License 15 * @note This program is distributed in the hope that it will be useful - WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. 18 */ 19 20 /** 21 * PHPMailer SPL autoloader. 22 * @param string $classname The name of the class to load 23 */ 24 function PHPMailerAutoload($classname) 25 { 26 //Can't use __DIR__ as it's only in PHP 5.3+ 27 $filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php'; 28 if (is_readable($filename)) { 29 require $filename; 30 } 31 } 32 33 spl_autoload_register('PHPMailerAutoload'); -
new file src/wp-includes/PHPMailer/README.md
diff --git src/wp-includes/PHPMailer/README.md src/wp-includes/PHPMailer/README.md new file mode 100644 index 0000000..de76a76
- + 1 # PHPMailer - A full-featured email creation and transfer class for PHP 2 3 Build status: [![Build Status](https://travis-ci.org/Synchro/PHPMailer.png)](https://travis-ci.org/Synchro/PHPMailer) 4 5 ## Class Features 6 7 - Probably the world's most popular code for sending email from PHP! 8 - Used by many open-source projects: Drupal, SugarCRM, Yii, Joomla! and many more 9 - Integrated SMTP support - send without a local mail server 10 - send emails with multiple TOs, CCs, BCCs and REPLY-TOs 11 - Multipart/alternative emails for mail clients that do not read HTML email 12 - Support for 8bit, base64, binary, and quoted-printable encoding 13 - SMTP authentication with LOGIN, PLAIN, NTLM and CRAM-MD5 mechanisms 14 - Native language support 15 - Compatible with PHP 5.0 and later 16 - Much more! 17 18 ## Why you might need it 19 20 Many PHP developers utilize email in their code. The only PHP function that supports this is the mail() function. However, it does not provide any assistance for making use of popular features such as HTML-based emails and attachments. 21 22 Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules - the vast majority of code that you'll find online that uses the mail() function directly is just plain wrong! 23 *Please* don't be tempted to do it yourself - if you don't use PHPMailer, there are many other excellent libraries that you should look at before rolling your own - try SwiftMailer, Zend_Mail, eZcomponents etc. 24 25 The PHP mail() function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD and OS X platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server. 26 27 ## License 28 29 This software is licenced under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html). Please read LICENSE for information on the 30 software availability and distribution. 31 32 ## Installation 33 34 PHPMailer is available via [Composer/Packagist](https://packagist.org/packages/phpmailer/phpmailer). Alternatively, just copy the contents of the PHPMailer folder into somewhere that's in your PHP `include_path` setting. If you don't speak git or just want a tarball, click the 'zip' button at the top of the page in GitHub. 35 36 37 ## A Simple Example 38 39 ```php 40 <?php 41 require 'class.phpmailer.php'; 42 43 $mail = new PHPMailer; 44 45 $mail->isSMTP(); // Set mailer to use SMTP 46 $mail->Host = 'smtp1.example.com;smtp2.example.com'; // Specify main and backup server 47 $mail->SMTPAuth = true; // Enable SMTP authentication 48 $mail->Username = 'jswan'; // SMTP username 49 $mail->Password = 'secret'; // SMTP password 50 $mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted 51 52 $mail->From = 'from@example.com'; 53 $mail->FromName = 'Mailer'; 54 $mail->addAddress('josh@example.net', 'Josh Adams'); // Add a recipient 55 $mail->addAddress('ellen@example.com'); // Name is optional 56 $mail->addReplyTo('info@example.com', 'Information'); 57 $mail->addCC('cc@example.com'); 58 $mail->addBCC('bcc@example.com'); 59 60 $mail->WordWrap = 50; // Set word wrap to 50 characters 61 $mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments 62 $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name 63 $mail->isHTML(true); // Set email format to HTML 64 65 $mail->Subject = 'Here is the subject'; 66 $mail->Body = 'This is the HTML message body <b>in bold!</b>'; 67 $mail->AltBody = 'This is the body in plain text for non-HTML mail clients'; 68 69 if(!$mail->send()) { 70 echo 'Message could not be sent.'; 71 echo 'Mailer Error: ' . $mail->ErrorInfo; 72 exit; 73 } 74 75 echo 'Message has been sent'; 76 ``` 77 78 You'll find plenty more to play with in the `examples` folder. 79 80 That's it. You should now be ready to use PHPMailer! 81 82 ## Localization 83 PHPMailer defaults to English, but in the `languages` folder you'll find numerous translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this: 84 85 ```php 86 // To load the French version 87 $mail->setLanguage('fr', '/optional/path/to/language/directory/'); 88 ``` 89 90 ## Documentation 91 92 You'll find some basic user-level docs in the docs folder, and you can generate complete API-level documentation using the `generatedocs.sh` shell script in the docs folder, though you'll need to install [PHPDocumentor](http://www.phpdoc.org) first. 93 94 ## Tests 95 96 You'll find a PHPUnit test script in the `test` folder. 97 98 Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.png)](https://travis-ci.org/PHPMailer/PHPMailer) 99 100 If this isn't passing, is there something you can do to help? 101 102 ## Contributing 103 104 Please submit bug reports, suggestions and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues). 105 106 We're particularly interested in fixing edge-cases, expanding test coverage and updating translations. 107 108 With the move to the PHPMailer GitHub organisation, you'll need to update any remote URLs referencing the old GitHub location with a command like this from within your clone: 109 110 `git remote set-url upstream https://github.com/PHPMailer/PHPMailer.git` 111 112 Please *don't* use the SourceForge or Google Code projects any more. 113 114 ## Changelog 115 116 See [changelog](changelog.md). 117 118 ## History 119 - PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](http://sourceforge.net/projects/phpmailer/). 120 - Marcus Bointon (coolbru on SF) and Andy Prevost (codeworxtech) took over the project in 2004. 121 - Became an Apache incubator project on Google Code in 2010, managed by Jim Jagielski. 122 - Marcus created his fork on [GitHub](https://github.com/Synchro/PHPMailer). 123 - Jim and Marcus decide to join forces and use GitHub as the canonical and official repo for PHPMailer. 124 - PHPMailer moves to the [PHPMailer organisation](https://github.com/PHPMailer) on GitHub. 125 126 ### What's changed since moving from SourceForge? 127 - Official successor to the SourceForge and Google Code projects. 128 - Test suite. 129 - Continuous integration with Travis-CI. 130 - Composer support. 131 - Rolling releases. 132 - Additional languages and language strings. 133 - CRAM-MD5 authentication support. 134 - Preserves full repo history of authors, commits and branches from the original SourceForge project. -
new file src/wp-includes/PHPMailer/changelog.md
diff --git src/wp-includes/PHPMailer/changelog.md src/wp-includes/PHPMailer/changelog.md new file mode 100644 index 0000000..4caa777
- + 1 # ChangeLog 2 3 ## Version 5.2.7 (September 12th 2013) 4 * Add Ukranian translation from @Krezalis 5 * Support for do_verp 6 * Fix bug in CRAM-MD5 AUTH 7 * Propagate Debugoutput option to SMTP class (@Reblutus) 8 * Determine MIME type of attachments automatically 9 * Add cross-platform, multibyte-safe pathinfo replacement (with tests) and use it 10 * Add a new 'html' Debugoutput type 11 * Clean up SMTP debug output, remove embedded HTML 12 * Some small changes in header formatting to improve IETF msglint test results 13 * Update test_script to use some recently changed features, rename to code_generator 14 * Generated code actually works! 15 * Update SyntaxHighlighter 16 * Major overhaul and cleanup of example code 17 * New PHPMailer graphic 18 * msgHTML now uses RFC2392-compliant content ids 19 * Add line break normalization function and use it in msgHTML 20 * Don't set unnecessary reply-to addresses 21 * Make fakesendmail.sh a bit cleaner and safer 22 * Set a content-transfer-encoding on multiparts (fixes msglint error) 23 * Fix cid generation in msgHTML (Thanks to @digitalthought) 24 * Fix handling of multiple SMTP servers (Thanks to @NanoCaiordo) 25 * SMTP->connect() now supports stream context options (Thanks to @stanislavdavid) 26 * Add support for iCal event alternatives (Thanks to @reblutus) 27 * Update to Polish language file (Thanks to Krzysztof Kowalewski) 28 * Update to Norwegian language file (Thanks to @datagutten) 29 * Update to Hungarian language file (Thanks to @dominicus-75) 30 * Add Persian/Farsi translation from @jaii 31 * Make SMTPDebug property type match type in SMTP class 32 * Add unit tests for DKIM 33 * Major refactor of SMTP class 34 * Reformat to PSR-2 coding standard 35 * Introduce autoloader 36 * Allow overriding of SMTP class 37 * Overhaul of PHPDocs 38 * Fix broken Q-encoding 39 * Czech language update (Thanks to @nemelu) 40 * Removal of excess blank lines in messages 41 * Added fake POP server and unit tests for POP-before-SMTP 42 43 ## Version 5.2.6 (April 11th 2013) 44 * Reflect move to PHPMailer GitHub organisation at https://github.com/PHPMailer/PHPMailer 45 * Fix unbumped version numbers 46 * Update packagist.org with new location 47 * Clean up Changelog 48 49 ## Version 5.2.5 (April 6th 2013) 50 * First official release after move from Google Code 51 * Fixes for qmail when sending via mail() 52 * Merge in changes from Google code 5.2.4 release 53 * Minor coding standards cleanup in SMTP class 54 * Improved unit tests, now tests S/MIME signing 55 * Travis-CI support on GitHub, runs tests with fake SMTP server 56 57 ## Version 5.2.4 (February 19, 2013) 58 * Fix tag and version bug. 59 * un-deprecate isSMTP(), isMail(), IsSendmail() and isQmail(). 60 * Numerous translation updates 61 62 ## Version 5.2.3 (February 8, 2013) 63 * Fix issue with older PCREs and ValidateAddress() (Bugz: 124) 64 * Add CRAM-MD5 authentication, thanks to Elijah madden, https://github.com/okonomiyaki3000 65 * Replacement of obsolete Quoted-Printable encoder with a much better implementation 66 * Composer package definition 67 * New language added: Hebrew 68 69 ## Version 5.2.2 (December 3, 2012) 70 * Some fixes and syncs from https://github.com/Synchro/PHPMailer 71 * Add Slovak translation, thanks to Michal Tinka 72 73 ## Version 5.2.2-rc2 (November 6, 2012) 74 * Fix SMTP server rotation (Bugz: 118) 75 * Allow override of autogen'ed 'Date' header (for Drupal's 76 og_mailinglist module) 77 * No whitespace after '-f' option (Bugz: 116) 78 * Work around potential warning (Bugz: 114) 79 80 ## Version 5.2.2-rc1 (September 28, 2012) 81 * Header encoding works with long lines (Bugz: 93) 82 * Turkish language update (Bugz: 94) 83 * undefined $pattern in EncodeQ bug squashed (Bugz: 98) 84 * use of mail() in safe_mode now works (Bugz: 96) 85 * ValidateAddress() now 'public static' so people can override the 86 default and use their own validation scheme. 87 * ValidateAddress() no longer uses broken FILTER_VALIDATE_EMAIL 88 * Added in AUTH PLAIN SMTP authentication 89 90 ## Version 5.2.2-beta2 (August 17, 2012) 91 * Fixed Postfix VERP support (Bugz: 92) 92 * Allow action_function callbacks to pass/use 93 the From address (passed as final param) 94 * Prevent inf look for get_lines() (Bugz: 77) 95 * New public var ($UseSendmailOptions). Only pass sendmail() 96 options iff we really are using sendmail or something sendmail 97 compatible. (Bugz: 75) 98 * default setting for LE returned to "\n" due to popular demand. 99 100 ## Version 5.2.2-beta1 (July 13, 2012) 101 * Expose PreSend() and PostSend() as public methods to allow 102 for more control if serializing message sending. 103 * GetSentMIMEMessage() only constructs the message copy when 104 needed. Save memory. 105 * Only pass params to mail() if the underlying MTA is 106 "sendmail" (as defined as "having the string sendmail 107 in its pathname") [#69] 108 * Attachments now work with Amazon SES and others [Bugz#70] 109 * Debug output now sent to stdout (via echo) or error_log [Bugz#5] 110 * New var: Debugoutput (for above) [Bugz#5] 111 * SMTP reads now Timeout aware (new var: Timeout=15) [Bugz#71] 112 * SMTP reads now can have a Timelimit associated with them 113 (new var: Timelimit=30)[Bugz#71] 114 * Fix quoting issue associated with charsets 115 * default setting for LE is now RFC compliant: "\r\n" 116 * Return-Path can now be user defined (new var: ReturnPath) 117 (the default is "" which implies no change from previous 118 behavior, which was to use either From or Sender) [Bugz#46] 119 * X-Mailer header can now be disabled (by setting to a 120 whitespace string, eg " ") [Bugz#66] 121 * Bugz closed: #68, #60, #42, #43, #59, #55, #66, #48, #49, 122 #52, #31, #41, #5. #70, #69 123 124 ## Version 5.2.1 (January 16, 2012) 125 * Closed several bugs#5 126 * Performance improvements 127 * MsgHTML() now returns the message as required. 128 * New method: GetSentMIMEMessage() (returns full copy of sent message) 129 130 ## Version 5.2 (July 19, 2011) 131 * protected MIME body and header 132 * better DKIM DNS Resource Record support 133 * better aly handling 134 * htmlfilter class added to extras 135 * moved to Apache Extras 136 137 ## Version 5.1 (October 20, 2009) 138 * fixed filename issue with AddStringAttachment (thanks to Tony) 139 * fixed "SingleTo" property, now works with Senmail, Qmail, and SMTP in 140 addition to PHP mail() 141 * added DKIM digital signing functionality, new properties: 142 - DKIM_domain (sets the domain name) 143 - DKIM_private (holds DKIM private key) 144 - DKIM_passphrase (holds your DKIM passphrase) 145 - DKIM_selector (holds the DKIM "selector") 146 - DKIM_identity (holds the identifying email address) 147 * added callback function support 148 - callback function parameters include: 149 result, to, cc, bcc, subject and body 150 - see the test/test_callback.php file for usage. 151 * added "auto" identity functionality 152 - can automatically add: 153 - Return-path (if Sender not set) 154 - Reply-To (if ReplyTo not set) 155 - can be disabled: 156 - $mail->SetFrom('yourname@yourdomain.com','First Last',false); 157 - or by adding the $mail->Sender and/or $mail->ReplyTo properties 158 159 Note: "auto" identity added to help with emails ending up in spam or junk boxes because of missing headers 160 161 ## Version 5.0.2 (May 24, 2009) 162 * Fix for missing attachments when inline graphics are present 163 * Fix for missing Cc in header when using SMTP (mail was sent, 164 but not displayed in header -- Cc receiver only saw email To: 165 line and no Cc line, but did get the email (To receiver 166 saw same) 167 168 ## Version 5.0.1 (April 05, 2009) 169 * Temporary fix for missing attachments 170 171 ## Version 5.0.0 (April 02, 2009) 172 With the release of this version, we are initiating a new version numbering 173 system to differentiate from the PHP4 version of PHPMailer. 174 Most notable in this release is fully object oriented code. 175 176 ### class.smtp.php: 177 * Refactored class.smtp.php to support new exception handling 178 * code size reduced from 29.2 Kb to 25.6 Kb 179 * Removed unnecessary functions from class.smtp.php: 180 - public function Expand($name) { 181 - public function Help($keyword="") { 182 - public function Noop() { 183 - public function Send($from) { 184 - public function SendOrMail($from) { 185 - public function Verify($name) { 186 187 ### class.phpmailer.php: 188 * Refactored class.phpmailer.php with new exception handling 189 * Changed processing functionality of Sendmail and Qmail so they cannot be 190 inadvertently used 191 * removed getFile() function, just became a simple wrapper for 192 file_get_contents() 193 * added check for PHP version (will gracefully exit if not at least PHP 5.0) 194 * enhanced code to check if an attachment source is the same as an embedded or 195 inline graphic source to eliminate duplicate attachments 196 197 ### New /test_script 198 We have written a test script you can use to test the script as part of your 199 installation. Once you press submit, the test script will send a multi-mime 200 email with either the message you type in or an HTML email with an inline 201 graphic. Two attachments are included in the email (one of the attachments 202 is also the inline graphic so you can see that only one copy of the graphic 203 is sent in the email). The test script will also display the functional 204 script that you can copy/paste to your editor to duplicate the functionality. 205 206 ### New examples 207 All new examples in both basic and advanced modes. Advanced examples show 208 Exception handling. 209 210 ### PHPDocumentator (phpdocs) documentation for PHPMailer version 5.0.0 211 All new documentation 212 213 ## Version 2.3 (November 06, 2008) 214 * added Arabic language (many thanks to Bahjat Al Mostafa) 215 * removed English language from language files and made it a default within 216 class.phpmailer.php - if no language is found, it will default to use 217 the english language translation 218 * fixed public/private declarations 219 * corrected line 1728, $basedir to $directory 220 * added $sign_cert_file to avoid improper duplicate use of $sign_key_file 221 * corrected $this->Hello on line 612 to $this->Helo 222 * changed default of $LE to "\r\n" to comply with RFC 2822. Can be set by the user 223 if default is not acceptable 224 * removed trim() from return results in EncodeQP 225 * /test and three files it contained are removed from version 2.3 226 * fixed phpunit.php for compliance with PHP5 227 * changed $this->AltBody = $textMsg; to $this->AltBody = html_entity_decode($textMsg); 228 * We have removed the /phpdoc from the downloads. All documentation is now on 229 the http://phpmailer.codeworxtech.com website. 230 231 ## Version 2.2.1 () July 19 2008 232 * fixed line 1092 in class.smtp.php (my apologies, error on my part) 233 234 ## Version 2.2 () July 15 2008 235 * Fixed redirect issue (display of UTF-8 in thank you redirect) 236 * fixed error in getResponse function declaration (class.pop3.php) 237 * PHPMailer now PHP6 compliant 238 * fixed line 1092 in class.smtp.php (endless loop from missing = sign) 239 240 ## Version 2.1 (Wed, June 04 2008) 241 NOTE: WE HAVE A NEW LANGUAGE VARIABLE FOR DIGITALLY SIGNED S/MIME EMAILS. IF YOU CAN HELP WITH LANGUAGES OTHER THAN ENGLISH AND SPANISH, IT WOULD BE APPRECIATED. 242 243 * added S/MIME functionality (ability to digitally sign emails) 244 BIG THANKS TO "sergiocambra" for posting this patch back in November 2007. 245 The "Signed Emails" functionality adds the Sign method to pass the private key 246 filename and the password to read it, and then email will be sent with 247 content-type multipart/signed and with the digital signature attached. 248 * fully compatible with E_STRICT error level 249 - Please note: 250 In about half the test environments this development version was subjected 251 to, an error was thrown for the date() functions used (line 1565 and 1569). 252 This is NOT a PHPMailer error, it is the result of an incorrectly configured 253 PHP5 installation. The fix is to modify your 'php.ini' file and include the 254 date.timezone = America/New York 255 directive, to your own server timezone 256 - If you do get this error, and are unable to access your php.ini file: 257 In your PHP script, add 258 `date_default_timezone_set('America/Toronto');` 259 - do not try to use 260 `$myVar = date_default_timezone_get();` 261 as a test, it will throw an error. 262 * added ability to define path (mainly for embedded images) 263 function `MsgHTML($message,$basedir='')` ... where: 264 `$basedir` is the fully qualified path 265 * fixed `MsgHTML()` function: 266 - Embedded Images where images are specified by `<protocol>://` will not be altered or embedded 267 * fixed the return value of SMTP exit code ( pclose ) 268 * addressed issue of multibyte characters in subject line and truncating 269 * added ability to have user specified Message ID 270 (default is still that PHPMailer create a unique Message ID) 271 * corrected unidentified message type to 'application/octet-stream' 272 * fixed chunk_split() multibyte issue (thanks to Colin Brown, et al). 273 * added check for added attachments 274 * enhanced conversion of HTML to text in MsgHTML (thanks to "brunny") 275 276 ## Version 2.1.0beta2 (Sun, Dec 02 2007) 277 * implemented updated EncodeQP (thanks to coolbru, aka Marcus Bointon) 278 * finished all testing, all known bugs corrected, enhancements tested 279 280 Note: will NOT work with PHP4. 281 282 Please note, this is BETA software **DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS; INTENDED STRICTLY FOR TESTING** 283 284 ## Version 2.1.0beta1 285 Please note, this is BETA software 286 ** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS 287 INTENDED STRICTLY FOR TESTING 288 289 ## Version 2.0.0 rc2 (Fri, Nov 16 2007), interim release 290 * implements new property to control VERP in class.smtp.php 291 example (requires instantiating class.smtp.php): 292 $mail->do_verp = true; 293 * POP-before-SMTP functionality included, thanks to Richard Davey 294 (see class.pop3.php & pop3_before_smtp_test.php for examples) 295 * included example showing how to use PHPMailer with GMAIL 296 * fixed the missing Cc in SendMail() and Mail() 297 298 ****************** 299 A note on sending bulk emails: 300 301 If the email you are sending is not personalized, consider using the 302 "undisclosed-recipient:;" strategy. That is, put all of your recipients 303 in the Bcc field and set the To field to "undisclosed-recipients:;". 304 It's a lot faster (only one send) and saves quite a bit on resources. 305 Contrary to some opinions, this will not get you listed in spam engines - 306 it's a legitimate way for you to send emails. 307 308 A partial example for use with PHPMailer: 309 310 ``` 311 $mail->AddAddress("undisclosed-recipients:;"); 312 $mail->AddBCC("email1@anydomain.com,email2@anyotherdomain.com,email3@anyalternatedomain.com"); 313 ``` 314 315 Many email service providers restrict the number of emails that can be sent 316 in any given time period. Often that is between 50 - 60 emails maximum 317 per hour or per send session. 318 319 If that's the case, then break up your Bcc lists into chunks that are one 320 less than your limit, and put a pause in your script. 321 ******************* 322 323 ## Version 2.0.0 rc1 (Thu, Nov 08 2007), interim release 324 * dramatically simplified using inline graphics ... it's fully automated and requires no user input 325 * added automatic document type detection for attachments and pictures 326 * added MsgHTML() function to replace Body tag for HTML emails 327 * fixed the SendMail security issues (input validation vulnerability) 328 * enhanced the AddAddresses functionality so that the "Name" portion is used in the email address 329 * removed the need to use the AltBody method (set from the HTML, or default text used) 330 * set the PHP Mail() function as the default (still support SendMail, SMTP Mail) 331 * removed the need to set the IsHTML property (set automatically) 332 * added Estonian language file by Indrek Päri 333 * added header injection patch 334 * added "set" method to permit users to create their own pseudo-properties like 'X-Headers', etc. 335 example of use: 336 337 ``` 338 $mail->set('X-Priority', '3'); 339 $mail->set('X-MSMail-Priority', 'Normal'); 340 ``` 341 342 * fixed warning message in SMTP get_lines method 343 * added TLS/SSL SMTP support. Example of use: 344 345 ``` 346 $mail = new PHPMailer(); 347 $mail->Mailer = "smtp"; 348 $mail->Host = "smtp.example.com"; 349 $mail->SMTPSecure = "tls"; // option 350 //$mail->SMTPSecure = "ssl"; // option 351 ... 352 $mail->Send(); 353 ``` 354 355 * PHPMailer has been tested with PHP4 (4.4.7) and PHP5 (5.2.7) 356 * Works with PHP installed as a module or as CGI-PHP 357 NOTE: will NOT work with PHP5 in E_STRICT error mode 358 359 ## Version 1.73 (Sun, Jun 10 2005) 360 * Fixed denial of service bug: http://www.cybsec.com/vuln/PHPMailer-DOS.pdf 361 * Now has a total of 20 translations 362 * Fixed alt attachments bug: http://tinyurl.com/98u9k 363 364 ## Version 1.72 (Wed, May 25 2004) 365 * Added Dutch, Swedish, Czech, Norwegian, and Turkish translations. 366 * Received: Removed this method because spam filter programs like 367 SpamAssassin reject this header. 368 * Fixed error count bug. 369 * SetLanguage default is now "language/". 370 * Fixed magic_quotes_runtime bug. 371 372 ## Version 1.71 (Tue, Jul 28 2003) 373 * Made several speed enhancements 374 * Added German and Italian translation files 375 * Fixed HELO/AUTH bugs on keep-alive connects 376 * Now provides an error message if language file does not load 377 * Fixed attachment EOL bug 378 * Updated some unclear documentation 379 * Added additional tests and improved others 380 381 ## Version 1.70 (Mon, Jun 20 2003) 382 * Added SMTP keep-alive support 383 * Added IsError method for error detection 384 * Added error message translation support (SetLanguage) 385 * Refactored many methods to increase library performance 386 * Hello now sends the newer EHLO message before HELO as per RFC 2821 387 * Removed the boundary class and replaced it with GetBoundary 388 * Removed queue support methods 389 * New $Hostname variable 390 * New Message-ID header 391 * Received header reformat 392 * Helo variable default changed to $Hostname 393 * Removed extra spaces in Content-Type definition (#667182) 394 * Return-Path should be set to Sender when set 395 * Adds Q or B encoding to headers when necessary 396 * quoted-encoding should now encode NULs \000 397 * Fixed encoding of body/AltBody (#553370) 398 * Adds "To: undisclosed-recipients:;" when all recipients are hidden (BCC) 399 * Multiple bug fixes 400 401 ## Version 1.65 (Fri, Aug 09 2002) 402 * Fixed non-visible attachment bug (#585097) for Outlook 403 * SMTP connections are now closed after each transaction 404 * Fixed SMTP::Expand return value 405 * Converted SMTP class documentation to phpDocumentor format 406 407 ## Version 1.62 (Wed, Jun 26 2002) 408 * Fixed multi-attach bug 409 * Set proper word wrapping 410 * Reduced memory use with attachments 411 * Added more debugging 412 * Changed documentation to phpDocumentor format 413 414 ## Version 1.60 (Sat, Mar 30 2002) 415 * Sendmail pipe and address patch (Christian Holtje) 416 * Added embedded image and read confirmation support (A. Ognio) 417 * Added unit tests 418 * Added SMTP timeout support (*nix only) 419 * Added possibly temporary PluginDir variable for SMTP class 420 * Added LE message line ending variable 421 * Refactored boundary and attachment code 422 * Eliminated SMTP class warnings 423 * Added SendToQueue method for future queuing support 424 425 ## Version 1.54 (Wed, Dec 19 2001) 426 * Add some queuing support code 427 * Fixed a pesky multi/alt bug 428 * Messages are no longer forced to have "To" addresses 429 430 ## Version 1.50 (Thu, Nov 08 2001) 431 * Fix extra lines when not using SMTP mailer 432 * Set WordWrap variable to int with a zero default 433 434 ## Version 1.47 (Tue, Oct 16 2001) 435 * Fixed Received header code format 436 * Fixed AltBody order error 437 * Fixed alternate port warning 438 439 ## Version 1.45 (Tue, Sep 25 2001) 440 * Added enhanced SMTP debug support 441 * Added support for multiple ports on SMTP 442 * Added Received header for tracing 443 * Fixed AddStringAttachment encoding 444 * Fixed possible header name quote bug 445 * Fixed wordwrap() trim bug 446 * Couple other small bug fixes 447 448 ## Version 1.41 (Wed, Aug 22 2001) 449 * Fixed AltBody bug w/o attachments 450 * Fixed rfc_date() for certain mail servers 451 452 ## Version 1.40 (Sun, Aug 12 2001) 453 * Added multipart/alternative support (AltBody) 454 * Documentation update 455 * Fixed bug in Mercury MTA 456 457 ## Version 1.29 (Fri, Aug 03 2001) 458 * Added AddStringAttachment() method 459 * Added SMTP authentication support 460 461 ## Version 1.28 (Mon, Jul 30 2001) 462 * Fixed a typo in SMTP class 463 * Fixed header issue with Imail (win32) SMTP server 464 * Made fopen() calls for attachments use "rb" to fix win32 error 465 466 ## Version 1.25 (Mon, Jul 02 2001) 467 * Added RFC 822 date fix (Patrice) 468 * Added improved error handling by adding a $ErrorInfo variable 469 * Removed MailerDebug variable (obsolete with new error handler) 470 471 ## Version 1.20 (Mon, Jun 25 2001) 472 * Added quoted-printable encoding (Patrice) 473 * Set Version as public and removed PrintVersion() 474 * Changed phpdoc to only display public variables and methods 475 476 ## Version 1.19 (Thu, Jun 21 2001) 477 * Fixed MS Mail header bug 478 * Added fix for Bcc problem with mail(). *Does not work on Win32* 479 (See PHP bug report: http://www.php.net/bugs.php?id=11616) 480 * mail() no longer passes a fifth parameter when not needed 481 482 ## Version 1.15 (Fri, Jun 15 2001) 483 Note: these changes contributed by Patrice Fournier 484 * Changed all remaining \n to \r\n 485 * Bcc: header no longer writen to message except 486 when sent directly to sendmail 487 * Added a small message to non-MIME compliant mail reader 488 * Added Sender variable to change the Sender email 489 used in -f for sendmail/mail and in 'MAIL FROM' for smtp mode 490 * Changed boundary setting to a place it will be set only once 491 * Removed transfer encoding for whole message when using multipart 492 * Message body now uses Encoding in multipart messages 493 * Can set encoding and type to attachments 7bit, 8bit 494 and binary attachment are sent as is, base64 are encoded 495 * Can set Encoding to base64 to send 8 bits body 496 through 7 bits servers 497 498 ## Version 1.10 (Tue, Jun 12 2001) 499 * Fixed win32 mail header bug (printed out headers in message body) 500 501 ## Version 1.09 (Fri, Jun 08 2001) 502 * Changed date header to work with Netscape mail programs 503 * Altered phpdoc documentation 504 505 ## Version 1.08 (Tue, Jun 05 2001) 506 * Added enhanced error-checking 507 * Added phpdoc documentation to source 508 509 ## Version 1.06 (Fri, Jun 01 2001) 510 * Added optional name for file attachments 511 512 ## Version 1.05 (Tue, May 29 2001) 513 * Code cleanup 514 * Eliminated sendmail header warning message 515 * Fixed possible SMTP error 516 517 ## Version 1.03 (Thu, May 24 2001) 518 * Fixed problem where qmail sends out duplicate messages 519 520 ## Version 1.02 (Wed, May 23 2001) 521 * Added multiple recipient and attachment Clear* methods 522 * Added Sendmail public variable 523 * Fixed problem with loading SMTP library multiple times 524 525 ## Version 0.98 (Tue, May 22 2001) 526 * Fixed problem with redundant mail hosts sending out multiple messages 527 * Added additional error handler code 528 * Added AddCustomHeader() function 529 * Added support for Microsoft mail client headers (affects priority) 530 * Fixed small bug with Mailer variable 531 * Added PrintVersion() function 532 533 ## Version 0.92 (Tue, May 15 2001) 534 * Changed file names to class.phpmailer.php and class.smtp.php to match 535 current PHP class trend. 536 * Fixed problem where body not being printed when a message is attached 537 * Several small bug fixes 538 539 ## Version 0.90 (Tue, April 17 2001) 540 * Initial public release -
new file src/wp-includes/PHPMailer/class.phpmailer.php
diff --git src/wp-includes/PHPMailer/class.phpmailer.php src/wp-includes/PHPMailer/class.phpmailer.php new file mode 100644 index 0000000..fe37a93
- + 1 <?php 2 /** 3 * PHPMailer - PHP email creation and transport class. 4 * PHP Version 5.0.0 5 * Version 5.2.7 6 * @package PHPMailer 7 * @link https://github.com/PHPMailer/PHPMailer/ 8 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk> 9 * @author Jim Jagielski (jimjag) <jimjag@gmail.com> 10 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> 11 * @author Brent R. Matzelle (original founder) 12 * @copyright 2013 Marcus Bointon 13 * @copyright 2010 - 2012 Jim Jagielski 14 * @copyright 2004 - 2009 Andy Prevost 15 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License 16 * @note This program is distributed in the hope that it will be useful - WITHOUT 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * FITNESS FOR A PARTICULAR PURPOSE. 19 */ 20 21 if (version_compare(PHP_VERSION, '5.0.0', '<')) { 22 exit("Sorry, PHPMailer will only run on PHP version 5 or greater!\n"); 23 } 24 25 /** 26 * PHPMailer - PHP email creation and transport class. 27 * PHP Version 5.0.0 28 * @package PHPMailer 29 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk> 30 * @author Jim Jagielski (jimjag) <jimjag@gmail.com> 31 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> 32 * @author Brent R. Matzelle (original founder) 33 * @copyright 2013 Marcus Bointon 34 * @copyright 2010 - 2012 Jim Jagielski 35 * @copyright 2004 - 2009 Andy Prevost 36 */ 37 class PHPMailer 38 { 39 /** 40 * The PHPMailer Version number. 41 * @type string 42 */ 43 public $Version = '5.2.7'; 44 45 /** 46 * Email priority. 47 * Options: 1 = High, 3 = Normal, 5 = low. 48 * @type int 49 */ 50 public $Priority = 3; 51 52 /** 53 * The character set of the message. 54 * @type string 55 */ 56 public $CharSet = 'iso-8859-1'; 57 58 /** 59 * The MIME Content-type of the message. 60 * @type string 61 */ 62 public $ContentType = 'text/plain'; 63 64 /** 65 * The message encoding. 66 * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable". 67 * @type string 68 */ 69 public $Encoding = '8bit'; 70 71 /** 72 * Holds the most recent mailer error message. 73 * @type string 74 */ 75 public $ErrorInfo = ''; 76 77 /** 78 * The From email address for the message. 79 * @type string 80 */ 81 public $From = 'root@localhost'; 82 83 /** 84 * The From name of the message. 85 * @type string 86 */ 87 public $FromName = 'Root User'; 88 89 /** 90 * The Sender email (Return-Path) of the message. 91 * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. 92 * @type string 93 */ 94 public $Sender = ''; 95 96 /** 97 * The Return-Path of the message. 98 * If empty, it will be set to either From or Sender. 99 * @type string 100 */ 101 public $ReturnPath = ''; 102 103 /** 104 * The Subject of the message. 105 * @type string 106 */ 107 public $Subject = ''; 108 109 /** 110 * An HTML or plain text message body. 111 * If HTML then call isHTML(true). 112 * @type string 113 */ 114 public $Body = ''; 115 116 /** 117 * The plain-text message body. 118 * This body can be read by mail clients that do not have HTML email 119 * capability such as mutt & Eudora. 120 * Clients that can read HTML will view the normal Body. 121 * @type string 122 */ 123 public $AltBody = ''; 124 125 /** 126 * An iCal message part body. 127 * Only supported in simple alt or alt_inline message types 128 * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator 129 * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/ 130 * @link http://kigkonsult.se/iCalcreator/ 131 * @type string 132 */ 133 public $Ical = ''; 134 135 /** 136 * The complete compiled MIME message body. 137 * @access protected 138 * @type string 139 */ 140 protected $MIMEBody = ''; 141 142 /** 143 * The complete compiled MIME message headers. 144 * @type string 145 * @access protected 146 */ 147 protected $MIMEHeader = ''; 148 149 /** 150 * Extra headers that createHeader() doesn't fold in. 151 * @type string 152 * @access protected 153 */ 154 protected $mailHeader = ''; 155 156 /** 157 * Word-wrap the message body to this number of chars. 158 * @type int 159 */ 160 public $WordWrap = 0; 161 162 /** 163 * Which method to use to send mail. 164 * Options: "mail", "sendmail", or "smtp". 165 * @type string 166 */ 167 public $Mailer = 'mail'; 168 169 /** 170 * The path to the sendmail program. 171 * @type string 172 */ 173 public $Sendmail = '/usr/sbin/sendmail'; 174 175 /** 176 * Whether mail() uses a fully sendmail-compatible MTA. 177 * One which supports sendmail's "-oi -f" options. 178 * @type bool 179 */ 180 public $UseSendmailOptions = true; 181 182 /** 183 * Path to PHPMailer plugins. 184 * Useful if the SMTP class is not in the PHP include path. 185 * @type string 186 * @deprecated Should not be needed now there is an autoloader. 187 */ 188 public $PluginDir = ''; 189 190 /** 191 * The email address that a reading confirmation should be sent to. 192 * @type string 193 */ 194 public $ConfirmReadingTo = ''; 195 196 /** 197 * The hostname to use in Message-Id and Received headers 198 * and as default HELO string. 199 * If empty, the value returned 200 * by SERVER_NAME is used or 'localhost.localdomain'. 201 * @type string 202 */ 203 public $Hostname = ''; 204 205 /** 206 * An ID to be used in the Message-Id header. 207 * If empty, a unique id will be generated. 208 * @type string 209 */ 210 public $MessageID = ''; 211 212 /** 213 * The message Date to be used in the Date header. 214 * If empty, the current date will be added. 215 * @type string 216 */ 217 public $MessageDate = ''; 218 219 /** 220 * SMTP hosts. 221 * Either a single hostname or multiple semicolon-delimited hostnames. 222 * You can also specify a different port 223 * for each host by using this format: [hostname:port] 224 * (e.g. "smtp1.example.com:25;smtp2.example.com"). 225 * Hosts will be tried in order. 226 * @type string 227 */ 228 public $Host = 'localhost'; 229 230 /** 231 * The default SMTP server port. 232 * @type int 233 * @Todo Why is this needed when the SMTP class takes care of it? 234 */ 235 public $Port = 25; 236 237 /** 238 * The SMTP HELO of the message. 239 * Default is $Hostname. 240 * @type string 241 * @see PHPMailer::$Hostname 242 */ 243 public $Helo = ''; 244 245 /** 246 * The secure connection prefix. 247 * Options: "", "ssl" or "tls" 248 * @type string 249 */ 250 public $SMTPSecure = ''; 251 252 /** 253 * Whether to use SMTP authentication. 254 * Uses the Username and Password properties. 255 * @type bool 256 * @see PHPMailer::$Username 257 * @see PHPMailer::$Password 258 */ 259 public $SMTPAuth = false; 260 261 /** 262 * SMTP username. 263 * @type string 264 */ 265 public $Username = ''; 266 267 /** 268 * SMTP password. 269 * @type string 270 */ 271 public $Password = ''; 272 273 /** 274 * SMTP auth type. 275 * Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5 276 * @type string 277 */ 278 public $AuthType = ''; 279 280 /** 281 * SMTP realm. 282 * Used for NTLM auth 283 * @type string 284 */ 285 public $Realm = ''; 286 287 /** 288 * SMTP workstation. 289 * Used for NTLM auth 290 * @type string 291 */ 292 public $Workstation = ''; 293 294 /** 295 * The SMTP server timeout in seconds. 296 * @type int 297 */ 298 public $Timeout = 10; 299 300 /** 301 * SMTP class debug output mode. 302 * Options: 0 = off, 1 = commands, 2 = commands and data 303 * @type int 304 * @see SMTP::$do_debug 305 */ 306 public $SMTPDebug = 0; 307 308 /** 309 * The function/method to use for debugging output. 310 * Options: "echo" or "error_log" 311 * @type string 312 * @see SMTP::$Debugoutput 313 */ 314 public $Debugoutput = "echo"; 315 316 /** 317 * Whether to keep SMTP connection open after each message. 318 * If this is set to true then to close the connection 319 * requires an explicit call to smtpClose(). 320 * @type bool 321 */ 322 public $SMTPKeepAlive = false; 323 324 /** 325 * Whether to split multiple to addresses into multiple messages 326 * or send them all in one message. 327 * @type bool 328 */ 329 public $SingleTo = false; 330 331 /** 332 * Storage for addresses when SingleTo is enabled. 333 * @type array 334 * @todo This should really not be public 335 */ 336 public $SingleToArray = array(); 337 338 /** 339 * Whether to generate VERP addresses on send. 340 * Only applicable when sending via SMTP. 341 * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path 342 * @type bool 343 */ 344 public $do_verp = false; 345 346 /** 347 * Whether to allow sending messages with an empty body. 348 * @type bool 349 */ 350 public $AllowEmpty = false; 351 352 /** 353 * The default line ending. 354 * @note The default remains "\n". We force CRLF where we know 355 * it must be used via self::CRLF. 356 * @type string 357 */ 358 public $LE = "\n"; 359 360 /** 361 * DKIM selector. 362 * @type string 363 */ 364 public $DKIM_selector = ''; 365 366 /** 367 * DKIM Identity. 368 * Usually the email address used as the source of the email 369 * @type string 370 */ 371 public $DKIM_identity = ''; 372 373 /** 374 * DKIM passphrase. 375 * Used if your key is encrypted. 376 * @type string 377 */ 378 public $DKIM_passphrase = ''; 379 380 /** 381 * DKIM signing domain name. 382 * @example 'example.com' 383 * @type string 384 */ 385 public $DKIM_domain = ''; 386 387 /** 388 * DKIM private key file path. 389 * @type string 390 */ 391 public $DKIM_private = ''; 392 393 /** 394 * Callback Action function name. 395 * 396 * The function that handles the result of the send email action. 397 * It is called out by send() for each email sent. 398 * 399 * Value can be: 400 * - 'function_name' for function names 401 * - 'Class::Method' for static method calls 402 * - array($object, 'Method') for calling methods on $object 403 * See http://php.net/is_callable manual page for more details. 404 * 405 * Parameters: 406 * bool $result result of the send action 407 * string $to email address of the recipient 408 * string $cc cc email addresses 409 * string $bcc bcc email addresses 410 * string $subject the subject 411 * string $body the email body 412 * string $from email address of sender 413 * 414 * @type string 415 */ 416 public $action_function = ''; 417 418 /** 419 * What to use in the X-Mailer header. 420 * Options: null for default, whitespace for none, or a string to use 421 * @type string 422 */ 423 public $XMailer = ''; 424 425 /** 426 * An instance of the SMTP sender class. 427 * @type SMTP 428 * @access protected 429 */ 430 protected $smtp = null; 431 432 /** 433 * The array of 'to' addresses. 434 * @type array 435 * @access protected 436 */ 437 protected $to = array(); 438 439 /** 440 * The array of 'cc' addresses. 441 * @type array 442 * @access protected 443 */ 444 protected $cc = array(); 445 446 /** 447 * The array of 'bcc' addresses. 448 * @type array 449 * @access protected 450 */ 451 protected $bcc = array(); 452 453 /** 454 * The array of reply-to names and addresses. 455 * @type array 456 * @access protected 457 */ 458 protected $ReplyTo = array(); 459 460 /** 461 * An array of all kinds of addresses. 462 * Includes all of $to, $cc, $bcc, $replyto 463 * @type array 464 * @access protected 465 */ 466 protected $all_recipients = array(); 467 468 /** 469 * The array of attachments. 470 * @type array 471 * @access protected 472 */ 473 protected $attachment = array(); 474 475 /** 476 * The array of custom headers. 477 * @type array 478 * @access protected 479 */ 480 protected $CustomHeader = array(); 481 482 /** 483 * The most recent Message-ID (including angular brackets). 484 * @type string 485 * @access protected 486 */ 487 protected $lastMessageID = ''; 488 489 /** 490 * The message's MIME type. 491 * @type string 492 * @access protected 493 */ 494 protected $message_type = ''; 495 496 /** 497 * The array of MIME boundary strings. 498 * @type array 499 * @access protected 500 */ 501 protected $boundary = array(); 502 503 /** 504 * The array of available languages. 505 * @type array 506 * @access protected 507 */ 508 protected $language = array(); 509 510 /** 511 * The number of errors encountered. 512 * @type integer 513 * @access protected 514 */ 515 protected $error_count = 0; 516 517 /** 518 * The S/MIME certificate file path. 519 * @type string 520 * @access protected 521 */ 522 protected $sign_cert_file = ''; 523 524 /** 525 * The S/MIME key file path. 526 * @type string 527 * @access protected 528 */ 529 protected $sign_key_file = ''; 530 531 /** 532 * The S/MIME password for the key. 533 * Used only if the key is encrypted. 534 * @type string 535 * @access protected 536 */ 537 protected $sign_key_pass = ''; 538 539 /** 540 * Whether to throw exceptions for errors. 541 * @type bool 542 * @access protected 543 */ 544 protected $exceptions = false; 545 546 /** 547 * Error severity: message only, continue processing 548 */ 549 const STOP_MESSAGE = 0; 550 551 /** 552 * Error severity: message, likely ok to continue processing 553 */ 554 const STOP_CONTINUE = 1; 555 556 /** 557 * Error severity: message, plus full stop, critical error reached 558 */ 559 const STOP_CRITICAL = 2; 560 561 /** 562 * SMTP RFC standard line ending 563 */ 564 const CRLF = "\r\n"; 565 566 /** 567 * Constructor 568 * @param bool $exceptions Should we throw external exceptions? 569 */ 570 public function __construct($exceptions = false) 571 { 572 $this->exceptions = ($exceptions == true); 573 //Make sure our autoloader is loaded 574 if (!in_array('PHPMailerAutoload', spl_autoload_functions())) { 575 require 'PHPMailerAutoload.php'; 576 } 577 } 578 579 /** 580 * Destructor. 581 */ 582 public function __destruct() 583 { 584 if ($this->Mailer == 'smtp') { //close any open SMTP connection nicely 585 $this->smtpClose(); 586 } 587 } 588 589 /** 590 * Call mail() in a safe_mode-aware fashion. 591 * Also, unless sendmail_path points to sendmail (or something that 592 * claims to be sendmail), don't pass params (not a perfect fix, 593 * but it will do) 594 * @param string $to To 595 * @param string $subject Subject 596 * @param string $body Message Body 597 * @param string $header Additional Header(s) 598 * @param string $params Params 599 * @access private 600 * @return bool 601 */ 602 private function mailPassthru($to, $subject, $body, $header, $params) 603 { 604 if (ini_get('safe_mode') || !($this->UseSendmailOptions)) { 605 $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header); 606 } else { 607 $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header, $params); 608 } 609 return $rt; 610 } 611 612 /** 613 * Output debugging info via user-defined method. 614 * Only if debug output is enabled. 615 * @see PHPMailer::$Debugoutput 616 * @see PHPMailer::$SMTPDebug 617 * @param string $str 618 */ 619 protected function edebug($str) 620 { 621 if (!$this->SMTPDebug) { 622 return; 623 } 624 switch ($this->Debugoutput) { 625 case 'error_log': 626 error_log($str); 627 break; 628 case 'html': 629 //Cleans up output a bit for a better looking display that's HTML-safe 630 echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, $this->CharSet) . "<br>\n"; 631 break; 632 case 'echo': 633 default: 634 //Just echoes exactly what was received 635 echo $str; 636 } 637 } 638 639 /** 640 * Sets message type to HTML or plain. 641 * @param bool $ishtml True for HTML mode. 642 * @return void 643 */ 644 public function isHTML($ishtml = true) 645 { 646 if ($ishtml) { 647 $this->ContentType = 'text/html'; 648 } else { 649 $this->ContentType = 'text/plain'; 650 } 651 } 652 653 /** 654 * Send messages using SMTP. 655 * @return void 656 */ 657 public function isSMTP() 658 { 659 $this->Mailer = 'smtp'; 660 } 661 662 /** 663 * Send messages using PHP's mail() function. 664 * @return void 665 */ 666 public function isMail() 667 { 668 $this->Mailer = 'mail'; 669 } 670 671 /** 672 * Send messages using $Sendmail. 673 * @return void 674 */ 675 public function isSendmail() 676 { 677 if (!stristr(ini_get('sendmail_path'), 'sendmail')) { 678 $this->Sendmail = '/var/qmail/bin/sendmail'; 679 } 680 $this->Mailer = 'sendmail'; 681 } 682 683 /** 684 * Send messages using qmail. 685 * @return void 686 */ 687 public function isQmail() 688 { 689 if (stristr(ini_get('sendmail_path'), 'qmail')) { 690 $this->Sendmail = '/var/qmail/bin/sendmail'; 691 } 692 $this->Mailer = 'sendmail'; 693 } 694 695 /** 696 * Add a "To" address. 697 * @param string $address 698 * @param string $name 699 * @return bool true on success, false if address already used 700 */ 701 public function addAddress($address, $name = '') 702 { 703 return $this->addAnAddress('to', $address, $name); 704 } 705 706 /** 707 * Add a "CC" address. 708 * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer. 709 * @param string $address 710 * @param string $name 711 * @return bool true on success, false if address already used 712 */ 713 public function addCC($address, $name = '') 714 { 715 return $this->addAnAddress('cc', $address, $name); 716 } 717 718 /** 719 * Add a "BCC" address. 720 * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer. 721 * @param string $address 722 * @param string $name 723 * @return bool true on success, false if address already used 724 */ 725 public function addBCC($address, $name = '') 726 { 727 return $this->addAnAddress('bcc', $address, $name); 728 } 729 730 /** 731 * Add a "Reply-to" address. 732 * @param string $address 733 * @param string $name 734 * @return bool 735 */ 736 public function addReplyTo($address, $name = '') 737 { 738 return $this->addAnAddress('Reply-To', $address, $name); 739 } 740 741 /** 742 * Add an address to one of the recipient arrays. 743 * Addresses that have been added already return false, but do not throw exceptions 744 * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo' 745 * @param string $address The email address to send to 746 * @param string $name 747 * @throws phpmailerException 748 * @return bool true on success, false if address already used or invalid in some way 749 * @access protected 750 */ 751 protected function addAnAddress($kind, $address, $name = '') 752 { 753 if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) { 754 $this->setError($this->lang('Invalid recipient array') . ': ' . $kind); 755 if ($this->exceptions) { 756 throw new phpmailerException('Invalid recipient array: ' . $kind); 757 } 758 $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind); 759 return false; 760 } 761 $address = trim($address); 762 $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim 763 if (!$this->validateAddress($address)) { 764 $this->setError($this->lang('invalid_address') . ': ' . $address); 765 if ($this->exceptions) { 766 throw new phpmailerException($this->lang('invalid_address') . ': ' . $address); 767 } 768 $this->edebug($this->lang('invalid_address') . ': ' . $address); 769 return false; 770 } 771 if ($kind != 'Reply-To') { 772 if (!isset($this->all_recipients[strtolower($address)])) { 773 array_push($this->$kind, array($address, $name)); 774 $this->all_recipients[strtolower($address)] = true; 775 return true; 776 } 777 } else { 778 if (!array_key_exists(strtolower($address), $this->ReplyTo)) { 779 $this->ReplyTo[strtolower($address)] = array($address, $name); 780 return true; 781 } 782 } 783 return false; 784 } 785 786 /** 787 * Set the From and FromName properties. 788 * @param string $address 789 * @param string $name 790 * @param bool $auto Whether to also set the Sender address, defaults to true 791 * @throws phpmailerException 792 * @return bool 793 */ 794 public function setFrom($address, $name = '', $auto = true) 795 { 796 $address = trim($address); 797 $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim 798 if (!$this->validateAddress($address)) { 799 $this->setError($this->lang('invalid_address') . ': ' . $address); 800 if ($this->exceptions) { 801 throw new phpmailerException($this->lang('invalid_address') . ': ' . $address); 802 } 803 $this->edebug($this->lang('invalid_address') . ': ' . $address); 804 return false; 805 } 806 $this->From = $address; 807 $this->FromName = $name; 808 if ($auto) { 809 if (empty($this->Sender)) { 810 $this->Sender = $address; 811 } 812 } 813 return true; 814 } 815 816 /** 817 * Return the Message-ID header of the last email. 818 * Technically this is the value from the last time the headers were created, 819 * but it's also the message ID of the last sent message except in 820 * pathological cases. 821 * @return string 822 */ 823 public function getLastMessageID() 824 { 825 return $this->lastMessageID; 826 } 827 828 /** 829 * Check that a string looks like an email address. 830 * @param string $address The email address to check 831 * @param string $patternselect A selector for the validation pattern to use : 832 * 'auto' - pick best one automatically; 833 * 'pcre8' - use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14; 834 * 'pcre' - use old PCRE implementation; 835 * 'php' - use PHP built-in FILTER_VALIDATE_EMAIL; faster, less thorough; 836 * 'noregex' - super fast, really dumb. 837 * @return bool 838 * @static 839 * @access public 840 */ 841 public static function validateAddress($address, $patternselect = 'auto') 842 { 843 if ($patternselect == 'auto') { 844 if (defined( 845 'PCRE_VERSION' 846 ) 847 ) { //Check this instead of extension_loaded so it works when that function is disabled 848 if (version_compare(PCRE_VERSION, '8.0') >= 0) { 849 $patternselect = 'pcre8'; 850 } else { 851 $patternselect = 'pcre'; 852 } 853 } else { 854 //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension 855 if (version_compare(PHP_VERSION, '5.2.0') >= 0) { 856 $patternselect = 'php'; 857 } else { 858 $patternselect = 'noregex'; 859 } 860 } 861 } 862 switch ($patternselect) { 863 case 'pcre8': 864 /** 865 * Conforms to RFC5322: Uses *correct* regex on which FILTER_VALIDATE_EMAIL is 866 * based; So why not use FILTER_VALIDATE_EMAIL? Because it was broken to 867 * not allow a@b type valid addresses :( 868 * @link http://squiloople.com/2009/12/20/email-address-validation/ 869 * @copyright 2009-2010 Michael Rushton 870 * Feel free to use and redistribute this code. But please keep this copyright notice. 871 */ 872 return (bool)preg_match( 873 '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . 874 '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' . 875 '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' . 876 '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' . 877 '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' . 878 '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' . 879 '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' . 880 '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' . 881 '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', 882 $address 883 ); 884 break; 885 case 'pcre': 886 //An older regex that doesn't need a recent PCRE 887 return (bool)preg_match( 888 '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' . 889 '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' . 890 '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' . 891 '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' . 892 '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' . 893 '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' . 894 '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' . 895 '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' . 896 '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' . 897 '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD', 898 $address 899 ); 900 break; 901 case 'php': 902 default: 903 return (bool)filter_var($address, FILTER_VALIDATE_EMAIL); 904 break; 905 case 'noregex': 906 //No PCRE! Do something _very_ approximate! 907 //Check the address is 3 chars or longer and contains an @ that's not the first or last char 908 return (strlen($address) >= 3 909 and strpos($address, '@') >= 1 910 and strpos($address, '@') != strlen($address) - 1); 911 break; 912 } 913 } 914 915 /** 916 * Create a message and send it. 917 * Uses the sending method specified by $Mailer. 918 * Returns false on error - Use the ErrorInfo variable to view description of the error. 919 * @throws phpmailerException 920 * @return bool 921 */ 922 public function send() 923 { 924 try { 925 if (!$this->preSend()) { 926 return false; 927 } 928 return $this->postSend(); 929 } catch (phpmailerException $e) { 930 $this->mailHeader = ''; 931 $this->setError($e->getMessage()); 932 if ($this->exceptions) { 933 throw $e; 934 } 935 return false; 936 } 937 } 938 939 /** 940 * Prepare a message for sending. 941 * @throws phpmailerException 942 * @return bool 943 */ 944 public function preSend() 945 { 946 try { 947 $this->mailHeader = ""; 948 if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { 949 throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL); 950 } 951 952 // Set whether the message is multipart/alternative 953 if (!empty($this->AltBody)) { 954 $this->ContentType = 'multipart/alternative'; 955 } 956 957 $this->error_count = 0; // reset errors 958 $this->setMessageType(); 959 // Refuse to send an empty message unless we are specifically allowing it 960 if (!$this->AllowEmpty and empty($this->Body)) { 961 throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL); 962 } 963 964 $this->MIMEHeader = $this->createHeader(); 965 $this->MIMEBody = $this->createBody(); 966 967 // To capture the complete message when using mail(), create 968 // an extra header list which createHeader() doesn't fold in 969 if ($this->Mailer == 'mail') { 970 if (count($this->to) > 0) { 971 $this->mailHeader .= $this->addrAppend("To", $this->to); 972 } else { 973 $this->mailHeader .= $this->headerLine("To", "undisclosed-recipients:;"); 974 } 975 $this->mailHeader .= $this->headerLine( 976 'Subject', 977 $this->encodeHeader($this->secureHeader(trim($this->Subject))) 978 ); 979 } 980 981 // Sign with DKIM if enabled 982 if (!empty($this->DKIM_domain) 983 && !empty($this->DKIM_private) 984 && !empty($this->DKIM_selector) 985 && !empty($this->DKIM_domain) 986 && file_exists($this->DKIM_private)) { 987 $header_dkim = $this->DKIM_Add( 988 $this->MIMEHeader . $this->mailHeader, 989 $this->encodeHeader($this->secureHeader($this->Subject)), 990 $this->MIMEBody 991 ); 992 $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF . 993 str_replace("\r\n", "\n", $header_dkim) . self::CRLF; 994 } 995 return true; 996 997 } catch (phpmailerException $e) { 998 $this->setError($e->getMessage()); 999 if ($this->exceptions) { 1000 throw $e; 1001 } 1002 return false; 1003 } 1004 } 1005 1006 /** 1007 * Actually send a message. 1008 * Send the email via the selected mechanism 1009 * @throws phpmailerException 1010 * @return bool 1011 */ 1012 public function postSend() 1013 { 1014 try { 1015 // Choose the mailer and send through it 1016 switch ($this->Mailer) { 1017 case 'sendmail': 1018 return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody); 1019 case 'smtp': 1020 return $this->smtpSend($this->MIMEHeader, $this->MIMEBody); 1021 case 'mail': 1022 return $this->mailSend($this->MIMEHeader, $this->MIMEBody); 1023 default: 1024 return $this->mailSend($this->MIMEHeader, $this->MIMEBody); 1025 } 1026 } catch (phpmailerException $e) { 1027 $this->setError($e->getMessage()); 1028 if ($this->exceptions) { 1029 throw $e; 1030 } 1031 $this->edebug($e->getMessage() . "\n"); 1032 } 1033 return false; 1034 } 1035 1036 /** 1037 * Send mail using the $Sendmail program. 1038 * @param string $header The message headers 1039 * @param string $body The message body 1040 * @see PHPMailer::$Sendmail 1041 * @throws phpmailerException 1042 * @access protected 1043 * @return bool 1044 */ 1045 protected function sendmailSend($header, $body) 1046 { 1047 if ($this->Sender != '') { 1048 $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); 1049 } else { 1050 $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); 1051 } 1052 if ($this->SingleTo === true) { 1053 foreach ($this->SingleToArray as $val) { 1054 if (!@$mail = popen($sendmail, 'w')) { 1055 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); 1056 } 1057 fputs($mail, "To: " . $val . "\n"); 1058 fputs($mail, $header); 1059 fputs($mail, $body); 1060 $result = pclose($mail); 1061 // implement call back function if it exists 1062 $isSent = ($result == 0) ? 1 : 0; 1063 $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From); 1064 if ($result != 0) { 1065 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); 1066 } 1067 } 1068 } else { 1069 if (!@$mail = popen($sendmail, 'w')) { 1070 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); 1071 } 1072 fputs($mail, $header); 1073 fputs($mail, $body); 1074 $result = pclose($mail); 1075 // implement call back function if it exists 1076 $isSent = ($result == 0) ? 1 : 0; 1077 $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From); 1078 if ($result != 0) { 1079 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); 1080 } 1081 } 1082 return true; 1083 } 1084 1085 /** 1086 * Send mail using the PHP mail() function. 1087 * @param string $header The message headers 1088 * @param string $body The message body 1089 * @link http://www.php.net/manual/en/book.mail.php 1090 * @throws phpmailerException 1091 * @access protected 1092 * @return bool 1093 */ 1094 protected function mailSend($header, $body) 1095 { 1096 $toArr = array(); 1097 foreach ($this->to as $t) { 1098 $toArr[] = $this->addrFormat($t); 1099 } 1100 $to = implode(', ', $toArr); 1101 1102 if (empty($this->Sender)) { 1103 $params = " "; 1104 } else { 1105 $params = sprintf("-f%s", $this->Sender); 1106 } 1107 if ($this->Sender != '' and !ini_get('safe_mode')) { 1108 $old_from = ini_get('sendmail_from'); 1109 ini_set('sendmail_from', $this->Sender); 1110 } 1111 $rt = false; 1112 if ($this->SingleTo === true && count($toArr) > 1) { 1113 foreach ($toArr as $val) { 1114 $rt = $this->mailPassthru($val, $this->Subject, $body, $header, $params); 1115 // implement call back function if it exists 1116 $isSent = ($rt == 1) ? 1 : 0; 1117 $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From); 1118 } 1119 } else { 1120 $rt = $this->mailPassthru($to, $this->Subject, $body, $header, $params); 1121 // implement call back function if it exists 1122 $isSent = ($rt == 1) ? 1 : 0; 1123 $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body, $this->From); 1124 } 1125 if (isset($old_from)) { 1126 ini_set('sendmail_from', $old_from); 1127 } 1128 if (!$rt) { 1129 throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL); 1130 } 1131 return true; 1132 } 1133 1134 /** 1135 * Get an instance to use for SMTP operations. 1136 * Override this function to load your own SMTP implementation 1137 * @return SMTP 1138 */ 1139 public function getSMTPInstance() 1140 { 1141 if (!is_object($this->smtp)) { 1142 $this->smtp = new SMTP; 1143 } 1144 return $this->smtp; 1145 } 1146 1147 /** 1148 * Send mail via SMTP. 1149 * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. 1150 * Uses the PHPMailerSMTP class by default. 1151 * @see PHPMailer::getSMTPInstance() to use a different class. 1152 * @param string $header The message headers 1153 * @param string $body The message body 1154 * @throws phpmailerException 1155 * @uses SMTP 1156 * @access protected 1157 * @return bool 1158 */ 1159 protected function smtpSend($header, $body) 1160 { 1161 $bad_rcpt = array(); 1162 1163 if (!$this->smtpConnect()) { 1164 throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); 1165 } 1166 $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; 1167 if (!$this->smtp->mail($smtp_from)) { 1168 $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); 1169 throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL); 1170 } 1171 1172 // Attempt to send attach all recipients 1173 foreach ($this->to as $to) { 1174 if (!$this->smtp->recipient($to[0])) { 1175 $bad_rcpt[] = $to[0]; 1176 $isSent = 0; 1177 } else { 1178 $isSent = 1; 1179 } 1180 $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body, $this->From); 1181 } 1182 foreach ($this->cc as $cc) { 1183 if (!$this->smtp->recipient($cc[0])) { 1184 $bad_rcpt[] = $cc[0]; 1185 $isSent = 0; 1186 } else { 1187 $isSent = 1; 1188 } 1189 $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body, $this->From); 1190 } 1191 foreach ($this->bcc as $bcc) { 1192 if (!$this->smtp->recipient($bcc[0])) { 1193 $bad_rcpt[] = $bcc[0]; 1194 $isSent = 0; 1195 } else { 1196 $isSent = 1; 1197 } 1198 $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body, $this->From); 1199 } 1200 1201 if (count($bad_rcpt) > 0) { //Create error message for any bad addresses 1202 throw new phpmailerException($this->lang('recipients_failed') . implode(', ', $bad_rcpt)); 1203 } 1204 if (!$this->smtp->data($header . $body)) { 1205 throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL); 1206 } 1207 if ($this->SMTPKeepAlive == true) { 1208 $this->smtp->reset(); 1209 } else { 1210 $this->smtp->quit(); 1211 $this->smtp->close(); 1212 } 1213 return true; 1214 } 1215 1216 /** 1217 * Initiate a connection to an SMTP server. 1218 * Returns false if the operation failed. 1219 * @param array $options An array of options compatible with stream_context_create() 1220 * @uses SMTP 1221 * @access public 1222 * @throws phpmailerException 1223 * @return bool 1224 */ 1225 public function smtpConnect($options = array()) 1226 { 1227 if (is_null($this->smtp)) { 1228 $this->smtp = $this->getSMTPInstance(); 1229 } 1230 1231 //Already connected? 1232 if ($this->smtp->connected()) { 1233 return true; 1234 } 1235 1236 $this->smtp->setTimeout($this->Timeout); 1237 $this->smtp->setDebugLevel($this->SMTPDebug); 1238 $this->smtp->setDebugOutput($this->Debugoutput); 1239 $this->smtp->setVerp($this->do_verp); 1240 $tls = ($this->SMTPSecure == 'tls'); 1241 $ssl = ($this->SMTPSecure == 'ssl'); 1242 $hosts = explode(';', $this->Host); 1243 $lastexception = null; 1244 1245 foreach ($hosts as $hostentry) { 1246 $hostinfo = array(); 1247 $host = $hostentry; 1248 $port = $this->Port; 1249 if (preg_match( 1250 '/^(.+):([0-9]+)$/', 1251 $hostentry, 1252 $hostinfo 1253 ) 1254 ) { //If $hostentry contains 'address:port', override default 1255 $host = $hostinfo[1]; 1256 $port = $hostinfo[2]; 1257 } 1258 if ($this->smtp->connect(($ssl ? 'ssl://' : '') . $host, $port, $this->Timeout, $options)) { 1259 try { 1260 if ($this->Helo) { 1261 $hello = $this->Helo; 1262 } else { 1263 $hello = $this->serverHostname(); 1264 } 1265 $this->smtp->hello($hello); 1266 1267 if ($tls) { 1268 if (!$this->smtp->startTLS()) { 1269 throw new phpmailerException($this->lang('connect_host')); 1270 } 1271 //We must resend HELO after tls negotiation 1272 $this->smtp->hello($hello); 1273 } 1274 if ($this->SMTPAuth) { 1275 if (!$this->smtp->authenticate( 1276 $this->Username, 1277 $this->Password, 1278 $this->AuthType, 1279 $this->Realm, 1280 $this->Workstation 1281 ) 1282 ) { 1283 throw new phpmailerException($this->lang('authenticate')); 1284 } 1285 } 1286 return true; 1287 } catch (phpmailerException $e) { 1288 $lastexception = $e; 1289 //We must have connected, but then failed TLS or Auth, so close connection nicely 1290 $this->smtp->quit(); 1291 } 1292 } 1293 } 1294 //If we get here, all connection attempts have failed, so close connection hard 1295 $this->smtp->close(); 1296 //As we've caught all exceptions, just report whatever the last one was 1297 if ($this->exceptions and !is_null($lastexception)) { 1298 throw $lastexception; 1299 } 1300 return false; 1301 } 1302 1303 /** 1304 * Close the active SMTP session if one exists. 1305 * @return void 1306 */ 1307 public function smtpClose() 1308 { 1309 if ($this->smtp !== null) { 1310 if ($this->smtp->connected()) { 1311 $this->smtp->quit(); 1312 $this->smtp->close(); 1313 } 1314 } 1315 } 1316 1317 /** 1318 * Set the language for error messages. 1319 * Returns false if it cannot load the language file. 1320 * The default language is English. 1321 * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr") 1322 * @param string $lang_path Path to the language file directory, with trailing separator (slash) 1323 * @return bool 1324 * @access public 1325 */ 1326 public function setLanguage($langcode = 'en', $lang_path = 'language/') 1327 { 1328 //Define full set of translatable strings 1329 $PHPMAILER_LANG = array( 1330 'authenticate' => 'SMTP Error: Could not authenticate.', 1331 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', 1332 'data_not_accepted' => 'SMTP Error: data not accepted.', 1333 'empty_message' => 'Message body empty', 1334 'encoding' => 'Unknown encoding: ', 1335 'execute' => 'Could not execute: ', 1336 'file_access' => 'Could not access file: ', 1337 'file_open' => 'File Error: Could not open file: ', 1338 'from_failed' => 'The following From address failed: ', 1339 'instantiate' => 'Could not instantiate mail function.', 1340 'invalid_address' => 'Invalid address', 1341 'mailer_not_supported' => ' mailer is not supported.', 1342 'provide_address' => 'You must provide at least one recipient email address.', 1343 'recipients_failed' => 'SMTP Error: The following recipients failed: ', 1344 'signing' => 'Signing Error: ', 1345 'smtp_connect_failed' => 'SMTP connect() failed.', 1346 'smtp_error' => 'SMTP server error: ', 1347 'variable_set' => 'Cannot set or reset variable: ' 1348 ); 1349 //Overwrite language-specific strings. 1350 //This way we'll never have missing translations - no more "language string failed to load"! 1351 $l = true; 1352 if ($langcode != 'en') { //There is no English translation file 1353 $l = @include $lang_path . 'phpmailer.lang-' . $langcode . '.php'; 1354 } 1355 $this->language = $PHPMAILER_LANG; 1356 return ($l == true); //Returns false if language not found 1357 } 1358 1359 /** 1360 * Get the array of strings for the current language. 1361 * @return array 1362 */ 1363 public function getTranslations() 1364 { 1365 return $this->language; 1366 } 1367 1368 /** 1369 * Create recipient headers. 1370 * @access public 1371 * @param string $type 1372 * @param array $addr An array of recipient, 1373 * where each recipient is a 2-element indexed array with element 0 containing an address 1374 * and element 1 containing a name, like: 1375 * array(array('joe@example.com', 'Joe User'), array('zoe@example.com', 'Zoe User')) 1376 * @return string 1377 */ 1378 public function addrAppend($type, $addr) 1379 { 1380 $addresses = array(); 1381 foreach ($addr as $a) { 1382 $addresses[] = $this->addrFormat($a); 1383 } 1384 return $type . ': ' . implode(', ', $addresses) . $this->LE; 1385 } 1386 1387 /** 1388 * Format an address for use in a message header. 1389 * @access public 1390 * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name 1391 * like array('joe@example.com', 'Joe User') 1392 * @return string 1393 */ 1394 public function addrFormat($addr) 1395 { 1396 if (empty($addr[1])) { // No name provided 1397 return $this->secureHeader($addr[0]); 1398 } else { 1399 return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . " <" . $this->secureHeader( 1400 $addr[0] 1401 ) . ">"; 1402 } 1403 } 1404 1405 /** 1406 * Word-wrap message. 1407 * For use with mailers that do not automatically perform wrapping 1408 * and for quoted-printable encoded messages. 1409 * Original written by philippe. 1410 * @param string $message The message to wrap 1411 * @param integer $length The line length to wrap to 1412 * @param bool $qp_mode Whether to run in Quoted-Printable mode 1413 * @access public 1414 * @return string 1415 */ 1416 public function wrapText($message, $length, $qp_mode = false) 1417 { 1418 $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; 1419 // If utf-8 encoding is used, we will need to make sure we don't 1420 // split multibyte characters when we wrap 1421 $is_utf8 = (strtolower($this->CharSet) == "utf-8"); 1422 $lelen = strlen($this->LE); 1423 $crlflen = strlen(self::CRLF); 1424 1425 $message = $this->fixEOL($message); 1426 if (substr($message, -$lelen) == $this->LE) { 1427 $message = substr($message, 0, -$lelen); 1428 } 1429 1430 $line = explode($this->LE, $message); // Magic. We know fixEOL uses $LE 1431 $message = ''; 1432 for ($i = 0; $i < count($line); $i++) { 1433 $line_part = explode(' ', $line[$i]); 1434 $buf = ''; 1435 for ($e = 0; $e < count($line_part); $e++) { 1436 $word = $line_part[$e]; 1437 if ($qp_mode and (strlen($word) > $length)) { 1438 $space_left = $length - strlen($buf) - $crlflen; 1439 if ($e != 0) { 1440 if ($space_left > 20) { 1441 $len = $space_left; 1442 if ($is_utf8) { 1443 $len = $this->utf8CharBoundary($word, $len); 1444 } elseif (substr($word, $len - 1, 1) == "=") { 1445 $len--; 1446 } elseif (substr($word, $len - 2, 1) == "=") { 1447 $len -= 2; 1448 } 1449 $part = substr($word, 0, $len); 1450 $word = substr($word, $len); 1451 $buf .= ' ' . $part; 1452 $message .= $buf . sprintf("=%s", self::CRLF); 1453 } else { 1454 $message .= $buf . $soft_break; 1455 } 1456 $buf = ''; 1457 } 1458 while (strlen($word) > 0) { 1459 if ($length <= 0) { 1460 break; 1461 } 1462 $len = $length; 1463 if ($is_utf8) { 1464 $len = $this->utf8CharBoundary($word, $len); 1465 } elseif (substr($word, $len - 1, 1) == "=") { 1466 $len--; 1467 } elseif (substr($word, $len - 2, 1) == "=") { 1468 $len -= 2; 1469 } 1470 $part = substr($word, 0, $len); 1471 $word = substr($word, $len); 1472 1473 if (strlen($word) > 0) { 1474 $message .= $part . sprintf("=%s", self::CRLF); 1475 } else { 1476 $buf = $part; 1477 } 1478 } 1479 } else { 1480 $buf_o = $buf; 1481 $buf .= ($e == 0) ? $word : (' ' . $word); 1482 1483 if (strlen($buf) > $length and $buf_o != '') { 1484 $message .= $buf_o . $soft_break; 1485 $buf = $word; 1486 } 1487 } 1488 } 1489 $message .= $buf . self::CRLF; 1490 } 1491 1492 return $message; 1493 } 1494 1495 /** 1496 * Find the last character boundary prior to $maxLength in a utf-8 1497 * quoted (printable) encoded string. 1498 * Original written by Colin Brown. 1499 * @access public 1500 * @param string $encodedText utf-8 QP text 1501 * @param int $maxLength find last character boundary prior to this length 1502 * @return int 1503 */ 1504 public function utf8CharBoundary($encodedText, $maxLength) 1505 { 1506 $foundSplitPos = false; 1507 $lookBack = 3; 1508 while (!$foundSplitPos) { 1509 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); 1510 $encodedCharPos = strpos($lastChunk, "="); 1511 if ($encodedCharPos !== false) { 1512 // Found start of encoded character byte within $lookBack block. 1513 // Check the encoded byte value (the 2 chars after the '=') 1514 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); 1515 $dec = hexdec($hex); 1516 if ($dec < 128) { // Single byte character. 1517 // If the encoded char was found at pos 0, it will fit 1518 // otherwise reduce maxLength to start of the encoded char 1519 $maxLength = ($encodedCharPos == 0) ? $maxLength : 1520 $maxLength - ($lookBack - $encodedCharPos); 1521 $foundSplitPos = true; 1522 } elseif ($dec >= 192) { // First byte of a multi byte character 1523 // Reduce maxLength to split at start of character 1524 $maxLength = $maxLength - ($lookBack - $encodedCharPos); 1525 $foundSplitPos = true; 1526 } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back 1527 $lookBack += 3; 1528 } 1529 } else { 1530 // No encoded character found 1531 $foundSplitPos = true; 1532 } 1533 } 1534 return $maxLength; 1535 } 1536 1537 1538 /** 1539 * Set the body wrapping. 1540 * @access public 1541 * @return void 1542 */ 1543 public function setWordWrap() 1544 { 1545 if ($this->WordWrap < 1) { 1546 return; 1547 } 1548 1549 switch ($this->message_type) { 1550 case 'alt': 1551 case 'alt_inline': 1552 case 'alt_attach': 1553 case 'alt_inline_attach': 1554 $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap); 1555 break; 1556 default: 1557 $this->Body = $this->wrapText($this->Body, $this->WordWrap); 1558 break; 1559 } 1560 } 1561 1562 /** 1563 * Assemble message headers. 1564 * @access public 1565 * @return string The assembled headers 1566 */ 1567 public function createHeader() 1568 { 1569 $result = ''; 1570 1571 // Set the boundaries 1572 $uniq_id = md5(uniqid(time())); 1573 $this->boundary[1] = 'b1_' . $uniq_id; 1574 $this->boundary[2] = 'b2_' . $uniq_id; 1575 $this->boundary[3] = 'b3_' . $uniq_id; 1576 1577 if ($this->MessageDate == '') { 1578 $result .= $this->headerLine('Date', self::rfcDate()); 1579 } else { 1580 $result .= $this->headerLine('Date', $this->MessageDate); 1581 } 1582 1583 if ($this->ReturnPath) { 1584 $result .= $this->headerLine('Return-Path', '<' . trim($this->ReturnPath) . '>'); 1585 } elseif ($this->Sender == '') { 1586 $result .= $this->headerLine('Return-Path', '<' . trim($this->From) . '>'); 1587 } else { 1588 $result .= $this->headerLine('Return-Path', '<' . trim($this->Sender) . '>'); 1589 } 1590 1591 // To be created automatically by mail() 1592 if ($this->Mailer != 'mail') { 1593 if ($this->SingleTo === true) { 1594 foreach ($this->to as $t) { 1595 $this->SingleToArray[] = $this->addrFormat($t); 1596 } 1597 } else { 1598 if (count($this->to) > 0) { 1599 $result .= $this->addrAppend('To', $this->to); 1600 } elseif (count($this->cc) == 0) { 1601 $result .= $this->headerLine('To', 'undisclosed-recipients:;'); 1602 } 1603 } 1604 } 1605 1606 $result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName))); 1607 1608 // sendmail and mail() extract Cc from the header before sending 1609 if (count($this->cc) > 0) { 1610 $result .= $this->addrAppend('Cc', $this->cc); 1611 } 1612 1613 // sendmail and mail() extract Bcc from the header before sending 1614 if ((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { 1615 $result .= $this->addrAppend('Bcc', $this->bcc); 1616 } 1617 1618 if (count($this->ReplyTo) > 0) { 1619 $result .= $this->addrAppend('Reply-To', $this->ReplyTo); 1620 } 1621 1622 // mail() sets the subject itself 1623 if ($this->Mailer != 'mail') { 1624 $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); 1625 } 1626 1627 if ($this->MessageID != '') { 1628 $this->lastMessageID = $this->MessageID; 1629 } else { 1630 $this->lastMessageID = sprintf("<%s@%s>", $uniq_id, $this->ServerHostname()); 1631 } 1632 $result .= $this->HeaderLine('Message-ID', $this->lastMessageID); 1633 $result .= $this->headerLine('X-Priority', $this->Priority); 1634 if ($this->XMailer == '') { 1635 $result .= $this->headerLine( 1636 'X-Mailer', 1637 'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer/)' 1638 ); 1639 } else { 1640 $myXmailer = trim($this->XMailer); 1641 if ($myXmailer) { 1642 $result .= $this->headerLine('X-Mailer', $myXmailer); 1643 } 1644 } 1645 1646 if ($this->ConfirmReadingTo != '') { 1647 $result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); 1648 } 1649 1650 // Add custom headers 1651 for ($index = 0; $index < count($this->CustomHeader); $index++) { 1652 $result .= $this->headerLine( 1653 trim($this->CustomHeader[$index][0]), 1654 $this->encodeHeader(trim($this->CustomHeader[$index][1])) 1655 ); 1656 } 1657 if (!$this->sign_key_file) { 1658 $result .= $this->headerLine('MIME-Version', '1.0'); 1659 $result .= $this->getMailMIME(); 1660 } 1661 1662 return $result; 1663 } 1664 1665 /** 1666 * Get the message MIME type headers. 1667 * @access public 1668 * @return string 1669 */ 1670 public function getMailMIME() 1671 { 1672 $result = ''; 1673 switch ($this->message_type) { 1674 case 'inline': 1675 $result .= $this->headerLine('Content-Type', 'multipart/related;'); 1676 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); 1677 break; 1678 case 'attach': 1679 case 'inline_attach': 1680 case 'alt_attach': 1681 case 'alt_inline_attach': 1682 $result .= $this->headerLine('Content-Type', 'multipart/mixed;'); 1683 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); 1684 break; 1685 case 'alt': 1686 case 'alt_inline': 1687 $result .= $this->headerLine('Content-Type', 'multipart/alternative;'); 1688 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); 1689 break; 1690 default: 1691 // Catches case 'plain': and case '': 1692 $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet); 1693 break; 1694 } 1695 //RFC1341 part 5 says 7bit is assumed if not specified 1696 if ($this->Encoding != '7bit') { 1697 $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding); 1698 } 1699 1700 if ($this->Mailer != 'mail') { 1701 $result .= $this->LE; 1702 } 1703 1704 return $result; 1705 } 1706 1707 /** 1708 * Returns the whole MIME message. 1709 * Includes complete headers and body. 1710 * Only valid post PreSend(). 1711 * @see PHPMailer::PreSend() 1712 * @access public 1713 * @return string 1714 */ 1715 public function getSentMIMEMessage() 1716 { 1717 return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody; 1718 } 1719 1720 1721 /** 1722 * Assemble the message body. 1723 * Returns an empty string on failure. 1724 * @access public 1725 * @throws phpmailerException 1726 * @return string The assembled message body 1727 */ 1728 public function createBody() 1729 { 1730 $body = ''; 1731 1732 if ($this->sign_key_file) { 1733 $body .= $this->getMailMIME() . $this->LE; 1734 } 1735 1736 $this->setWordWrap(); 1737 1738 switch ($this->message_type) { 1739 case 'inline': 1740 $body .= $this->getBoundary($this->boundary[1], '', '', ''); 1741 $body .= $this->encodeString($this->Body, $this->Encoding); 1742 $body .= $this->LE . $this->LE; 1743 $body .= $this->attachAll('inline', $this->boundary[1]); 1744 break; 1745 case 'attach': 1746 $body .= $this->getBoundary($this->boundary[1], '', '', ''); 1747 $body .= $this->encodeString($this->Body, $this->Encoding); 1748 $body .= $this->LE . $this->LE; 1749 $body .= $this->attachAll('attachment', $this->boundary[1]); 1750 break; 1751 case 'inline_attach': 1752 $body .= $this->textLine('--' . $this->boundary[1]); 1753 $body .= $this->headerLine('Content-Type', 'multipart/related;'); 1754 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); 1755 $body .= $this->LE; 1756 $body .= $this->getBoundary($this->boundary[2], '', '', ''); 1757 $body .= $this->encodeString($this->Body, $this->Encoding); 1758 $body .= $this->LE . $this->LE; 1759 $body .= $this->attachAll('inline', $this->boundary[2]); 1760 $body .= $this->LE; 1761 $body .= $this->attachAll('attachment', $this->boundary[1]); 1762 break; 1763 case 'alt': 1764 $body .= $this->getBoundary($this->boundary[1], '', 'text/plain', ''); 1765 $body .= $this->encodeString($this->AltBody, $this->Encoding); 1766 $body .= $this->LE . $this->LE; 1767 $body .= $this->getBoundary($this->boundary[1], '', 'text/html', ''); 1768 $body .= $this->encodeString($this->Body, $this->Encoding); 1769 $body .= $this->LE . $this->LE; 1770 if (!empty($this->Ical)) { 1771 $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', ''); 1772 $body .= $this->encodeString($this->Ical, $this->Encoding); 1773 $body .= $this->LE . $this->LE; 1774 } 1775 $body .= $this->endBoundary($this->boundary[1]); 1776 break; 1777 case 'alt_inline': 1778 $body .= $this->getBoundary($this->boundary[1], '', 'text/plain', ''); 1779 $body .= $this->encodeString($this->AltBody, $this->Encoding); 1780 $body .= $this->LE . $this->LE; 1781 $body .= $this->textLine('--' . $this->boundary[1]); 1782 $body .= $this->headerLine('Content-Type', 'multipart/related;'); 1783 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); 1784 $body .= $this->LE; 1785 $body .= $this->getBoundary($this->boundary[2], '', 'text/html', ''); 1786 $body .= $this->encodeString($this->Body, $this->Encoding); 1787 $body .= $this->LE . $this->LE; 1788 $body .= $this->attachAll('inline', $this->boundary[2]); 1789 $body .= $this->LE; 1790 $body .= $this->endBoundary($this->boundary[1]); 1791 break; 1792 case 'alt_attach': 1793 $body .= $this->textLine('--' . $this->boundary[1]); 1794 $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); 1795 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); 1796 $body .= $this->LE; 1797 $body .= $this->getBoundary($this->boundary[2], '', 'text/plain', ''); 1798 $body .= $this->encodeString($this->AltBody, $this->Encoding); 1799 $body .= $this->LE . $this->LE; 1800 $body .= $this->getBoundary($this->boundary[2], '', 'text/html', ''); 1801 $body .= $this->encodeString($this->Body, $this->Encoding); 1802 $body .= $this->LE . $this->LE; 1803 $body .= $this->endBoundary($this->boundary[2]); 1804 $body .= $this->LE; 1805 $body .= $this->attachAll('attachment', $this->boundary[1]); 1806 break; 1807 case 'alt_inline_attach': 1808 $body .= $this->textLine('--' . $this->boundary[1]); 1809 $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); 1810 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); 1811 $body .= $this->LE; 1812 $body .= $this->getBoundary($this->boundary[2], '', 'text/plain', ''); 1813 $body .= $this->encodeString($this->AltBody, $this->Encoding); 1814 $body .= $this->LE . $this->LE; 1815 $body .= $this->textLine('--' . $this->boundary[2]); 1816 $body .= $this->headerLine('Content-Type', 'multipart/related;'); 1817 $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"'); 1818 $body .= $this->LE; 1819 $body .= $this->getBoundary($this->boundary[3], '', 'text/html', ''); 1820 $body .= $this->encodeString($this->Body, $this->Encoding); 1821 $body .= $this->LE . $this->LE; 1822 $body .= $this->attachAll('inline', $this->boundary[3]); 1823 $body .= $this->LE; 1824 $body .= $this->endBoundary($this->boundary[2]); 1825 $body .= $this->LE; 1826 $body .= $this->attachAll('attachment', $this->boundary[1]); 1827 break; 1828 default: 1829 // catch case 'plain' and case '' 1830 $body .= $this->encodeString($this->Body, $this->Encoding); 1831 break; 1832 } 1833 1834 if ($this->isError()) { 1835 $body = ''; 1836 } elseif ($this->sign_key_file) { 1837 try { 1838 if (!defined('PKCS7_TEXT')) { 1839 throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.'); 1840 } 1841 $file = tempnam(sys_get_temp_dir(), 'mail'); 1842 file_put_contents($file, $body); //TODO check this worked 1843 $signed = tempnam(sys_get_temp_dir(), 'signed'); 1844 if (@openssl_pkcs7_sign( 1845 $file, 1846 $signed, 1847 'file://' . realpath($this->sign_cert_file), 1848 array('file://' . realpath($this->sign_key_file), $this->sign_key_pass), 1849 null 1850 ) 1851 ) { 1852 @unlink($file); 1853 $body = file_get_contents($signed); 1854 @unlink($signed); 1855 } else { 1856 @unlink($file); 1857 @unlink($signed); 1858 throw new phpmailerException($this->lang('signing') . openssl_error_string()); 1859 } 1860 } catch (phpmailerException $e) { 1861 $body = ''; 1862 if ($this->exceptions) { 1863 throw $e; 1864 } 1865 } 1866 } 1867 return $body; 1868 } 1869 1870 /** 1871 * Return the start of a message boundary. 1872 * @access protected 1873 * @param string $boundary 1874 * @param string $charSet 1875 * @param string $contentType 1876 * @param string $encoding 1877 * @return string 1878 */ 1879 protected function getBoundary($boundary, $charSet, $contentType, $encoding) 1880 { 1881 $result = ''; 1882 if ($charSet == '') { 1883 $charSet = $this->CharSet; 1884 } 1885 if ($contentType == '') { 1886 $contentType = $this->ContentType; 1887 } 1888 if ($encoding == '') { 1889 $encoding = $this->Encoding; 1890 } 1891 $result .= $this->textLine('--' . $boundary); 1892 $result .= sprintf("Content-Type: %s; charset=%s", $contentType, $charSet); 1893 $result .= $this->LE; 1894 $result .= $this->headerLine('Content-Transfer-Encoding', $encoding); 1895 $result .= $this->LE; 1896 1897 return $result; 1898 } 1899 1900 /** 1901 * Return the end of a message boundary. 1902 * @access protected 1903 * @param string $boundary 1904 * @return string 1905 */ 1906 protected function endBoundary($boundary) 1907 { 1908 return $this->LE . '--' . $boundary . '--' . $this->LE; 1909 } 1910 1911 /** 1912 * Set the message type. 1913 * PHPMailer only supports some preset message types, 1914 * not arbitrary MIME structures. 1915 * @access protected 1916 * @return void 1917 */ 1918 protected function setMessageType() 1919 { 1920 $this->message_type = array(); 1921 if ($this->alternativeExists()) { 1922 $this->message_type[] = "alt"; 1923 } 1924 if ($this->inlineImageExists()) { 1925 $this->message_type[] = "inline"; 1926 } 1927 if ($this->attachmentExists()) { 1928 $this->message_type[] = "attach"; 1929 } 1930 $this->message_type = implode("_", $this->message_type); 1931 if ($this->message_type == "") { 1932 $this->message_type = "plain"; 1933 } 1934 } 1935 1936 /** 1937 * Format a header line. 1938 * @access public 1939 * @param string $name 1940 * @param string $value 1941 * @return string 1942 */ 1943 public function headerLine($name, $value) 1944 { 1945 return $name . ': ' . $value . $this->LE; 1946 } 1947 1948 /** 1949 * Return a formatted mail line. 1950 * @access public 1951 * @param string $value 1952 * @return string 1953 */ 1954 public function textLine($value) 1955 { 1956 return $value . $this->LE; 1957 } 1958 1959 /** 1960 * Add an attachment from a path on the filesystem. 1961 * Returns false if the file could not be found or read. 1962 * @param string $path Path to the attachment. 1963 * @param string $name Overrides the attachment name. 1964 * @param string $encoding File encoding (see $Encoding). 1965 * @param string $type File extension (MIME) type. 1966 * @param string $disposition Disposition to use 1967 * @throws phpmailerException 1968 * @return bool 1969 */ 1970 public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment') 1971 { 1972 try { 1973 if (!@is_file($path)) { 1974 throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE); 1975 } 1976 1977 //If a MIME type is not specified, try to work it out from the file name 1978 if ($type == '') { 1979 $type = self::filenameToType($path); 1980 } 1981 1982 $filename = basename($path); 1983 if ($name == '') { 1984 $name = $filename; 1985 } 1986 1987 $this->attachment[] = array( 1988 0 => $path, 1989 1 => $filename, 1990 2 => $name, 1991 3 => $encoding, 1992 4 => $type, 1993 5 => false, // isStringAttachment 1994 6 => $disposition, 1995 7 => 0 1996 ); 1997 1998 } catch (phpmailerException $e) { 1999 $this->setError($e->getMessage()); 2000 if ($this->exceptions) { 2001 throw $e; 2002 } 2003 $this->edebug($e->getMessage() . "\n"); 2004 return false; 2005 } 2006 return true; 2007 } 2008 2009 /** 2010 * Return the array of attachments. 2011 * @return array 2012 */ 2013 public function getAttachments() 2014 { 2015 return $this->attachment; 2016 } 2017 2018 /** 2019 * Attach all file, string, and binary attachments to the message. 2020 * Returns an empty string on failure. 2021 * @access protected 2022 * @param string $disposition_type 2023 * @param string $boundary 2024 * @return string 2025 */ 2026 protected function attachAll($disposition_type, $boundary) 2027 { 2028 // Return text of body 2029 $mime = array(); 2030 $cidUniq = array(); 2031 $incl = array(); 2032 2033 // Add all attachments 2034 foreach ($this->attachment as $attachment) { 2035 // Check if it is a valid disposition_filter 2036 if ($attachment[6] == $disposition_type) { 2037 // Check for string attachment 2038 $string = ''; 2039 $path = ''; 2040 $bString = $attachment[5]; 2041 if ($bString) { 2042 $string = $attachment[0]; 2043 } else { 2044 $path = $attachment[0]; 2045 } 2046 2047 $inclhash = md5(serialize($attachment)); 2048 if (in_array($inclhash, $incl)) { 2049 continue; 2050 } 2051 $incl[] = $inclhash; 2052 $name = $attachment[2]; 2053 $encoding = $attachment[3]; 2054 $type = $attachment[4]; 2055 $disposition = $attachment[6]; 2056 $cid = $attachment[7]; 2057 if ($disposition == 'inline' && isset($cidUniq[$cid])) { 2058 continue; 2059 } 2060 $cidUniq[$cid] = true; 2061 2062 $mime[] = sprintf("--%s%s", $boundary, $this->LE); 2063 $mime[] = sprintf( 2064 "Content-Type: %s; name=\"%s\"%s", 2065 $type, 2066 $this->encodeHeader($this->secureHeader($name)), 2067 $this->LE 2068 ); 2069 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); 2070 2071 if ($disposition == 'inline') { 2072 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); 2073 } 2074 2075 // If a filename contains any of these chars, it should be quoted, 2076 // but not otherwise: RFC2183 & RFC2045 5.1 2077 // Fixes a warning in IETF's msglint MIME checker 2078 // Allow for bypassing the Content-Disposition header totally 2079 if (!(empty($disposition))) { 2080 if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $name)) { 2081 $mime[] = sprintf( 2082 "Content-Disposition: %s; filename=\"%s\"%s", 2083 $disposition, 2084 $this->encodeHeader($this->secureHeader($name)), 2085 $this->LE . $this->LE 2086 ); 2087 } else { 2088 $mime[] = sprintf( 2089 "Content-Disposition: %s; filename=%s%s", 2090 $disposition, 2091 $this->encodeHeader($this->secureHeader($name)), 2092 $this->LE . $this->LE 2093 ); 2094 } 2095 } else { 2096 $mime[] = $this->LE; 2097 } 2098 2099 // Encode as string attachment 2100 if ($bString) { 2101 $mime[] = $this->encodeString($string, $encoding); 2102 if ($this->isError()) { 2103 return ''; 2104 } 2105 $mime[] = $this->LE . $this->LE; 2106 } else { 2107 $mime[] = $this->encodeFile($path, $encoding); 2108 if ($this->isError()) { 2109 return ''; 2110 } 2111 $mime[] = $this->LE . $this->LE; 2112 } 2113 } 2114 } 2115 2116 $mime[] = sprintf("--%s--%s", $boundary, $this->LE); 2117 2118 return implode("", $mime); 2119 } 2120 2121 /** 2122 * Encode a file attachment in requested format. 2123 * Returns an empty string on failure. 2124 * @param string $path The full path to the file 2125 * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' 2126 * @throws phpmailerException 2127 * @see EncodeFile(encodeFile 2128 * @access protected 2129 * @return string 2130 */ 2131 protected function encodeFile($path, $encoding = 'base64') 2132 { 2133 try { 2134 if (!is_readable($path)) { 2135 throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE); 2136 } 2137 $magic_quotes = get_magic_quotes_runtime(); 2138 if ($magic_quotes) { 2139 if (version_compare(PHP_VERSION, '5.3.0', '<')) { 2140 set_magic_quotes_runtime(0); 2141 } else { 2142 ini_set('magic_quotes_runtime', 0); 2143 } 2144 } 2145 $file_buffer = file_get_contents($path); 2146 $file_buffer = $this->encodeString($file_buffer, $encoding); 2147 if ($magic_quotes) { 2148 if (version_compare(PHP_VERSION, '5.3.0', '<')) { 2149 set_magic_quotes_runtime($magic_quotes); 2150 } else { 2151 ini_set('magic_quotes_runtime', $magic_quotes); 2152 } 2153 } 2154 return $file_buffer; 2155 } catch (Exception $e) { 2156 $this->setError($e->getMessage()); 2157 return ''; 2158 } 2159 } 2160 2161 /** 2162 * Encode a string in requested format. 2163 * Returns an empty string on failure. 2164 * @param string $str The text to encode 2165 * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' 2166 * @access public 2167 * @return string 2168 */ 2169 public function encodeString($str, $encoding = 'base64') 2170 { 2171 $encoded = ''; 2172 switch (strtolower($encoding)) { 2173 case 'base64': 2174 $encoded = chunk_split(base64_encode($str), 76, $this->LE); 2175 break; 2176 case '7bit': 2177 case '8bit': 2178 $encoded = $this->fixEOL($str); 2179 //Make sure it ends with a line break 2180 if (substr($encoded, -(strlen($this->LE))) != $this->LE) { 2181 $encoded .= $this->LE; 2182 } 2183 break; 2184 case 'binary': 2185 $encoded = $str; 2186 break; 2187 case 'quoted-printable': 2188 $encoded = $this->encodeQP($str); 2189 break; 2190 default: 2191 $this->setError($this->lang('encoding') . $encoding); 2192 break; 2193 } 2194 return $encoded; 2195 } 2196 2197 /** 2198 * Encode a header string optimally. 2199 * Picks shortest of Q, B, quoted-printable or none. 2200 * @access public 2201 * @param string $str 2202 * @param string $position 2203 * @return string 2204 */ 2205 public function encodeHeader($str, $position = 'text') 2206 { 2207 $x = 0; 2208 switch (strtolower($position)) { 2209 case 'phrase': 2210 if (!preg_match('/[\200-\377]/', $str)) { 2211 // Can't use addslashes as we don't know what value has magic_quotes_sybase 2212 $encoded = addcslashes($str, "\0..\37\177\\\""); 2213 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { 2214 return ($encoded); 2215 } else { 2216 return ("\"$encoded\""); 2217 } 2218 } 2219 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); 2220 break; 2221 /** @noinspection PhpMissingBreakStatementInspection */ 2222 case 'comment': 2223 $x = preg_match_all('/[()"]/', $str, $matches); 2224 // Intentional fall-through 2225 case 'text': 2226 default: 2227 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); 2228 break; 2229 } 2230 2231 if ($x == 0) { //There are no chars that need encoding 2232 return ($str); 2233 } 2234 2235 $maxlen = 75 - 7 - strlen($this->CharSet); 2236 // Try to select the encoding which should produce the shortest output 2237 if ($x > strlen($str) / 3) { 2238 //More than a third of the content will need encoding, so B encoding will be most efficient 2239 $encoding = 'B'; 2240 if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) { 2241 // Use a custom function which correctly encodes and wraps long 2242 // multibyte strings without breaking lines within a character 2243 $encoded = $this->base64EncodeWrapMB($str, "\n"); 2244 } else { 2245 $encoded = base64_encode($str); 2246 $maxlen -= $maxlen % 4; 2247 $encoded = trim(chunk_split($encoded, $maxlen, "\n")); 2248 } 2249 } else { 2250 $encoding = 'Q'; 2251 $encoded = $this->encodeQ($str, $position); 2252 $encoded = $this->wrapText($encoded, $maxlen, true); 2253 $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded)); 2254 } 2255 2256 $encoded = preg_replace('/^(.*)$/m', " =?" . $this->CharSet . "?$encoding?\\1?=", $encoded); 2257 $encoded = trim(str_replace("\n", $this->LE, $encoded)); 2258 2259 return $encoded; 2260 } 2261 2262 /** 2263 * Check if a string contains multi-byte characters. 2264 * @access public 2265 * @param string $str multi-byte text to wrap encode 2266 * @return bool 2267 */ 2268 public function hasMultiBytes($str) 2269 { 2270 if (function_exists('mb_strlen')) { 2271 return (strlen($str) > mb_strlen($str, $this->CharSet)); 2272 } else { // Assume no multibytes (we can't handle without mbstring functions anyway) 2273 return false; 2274 } 2275 } 2276 2277 /** 2278 * Encode and wrap long multibyte strings for mail headers 2279 * without breaking lines within a character. 2280 * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php 2281 * @access public 2282 * @param string $str multi-byte text to wrap encode 2283 * @param string $lf string to use as linefeed/end-of-line 2284 * @return string 2285 */ 2286 public function base64EncodeWrapMB($str, $lf = null) 2287 { 2288 $start = "=?" . $this->CharSet . "?B?"; 2289 $end = "?="; 2290 $encoded = ""; 2291 if ($lf === null) { 2292 $lf = $this->LE; 2293 } 2294 2295 $mb_length = mb_strlen($str, $this->CharSet); 2296 // Each line must have length <= 75, including $start and $end 2297 $length = 75 - strlen($start) - strlen($end); 2298 // Average multi-byte ratio 2299 $ratio = $mb_length / strlen($str); 2300 // Base64 has a 4:3 ratio 2301 $avgLength = floor($length * $ratio * .75); 2302 2303 for ($i = 0; $i < $mb_length; $i += $offset) { 2304 $lookBack = 0; 2305 do { 2306 $offset = $avgLength - $lookBack; 2307 $chunk = mb_substr($str, $i, $offset, $this->CharSet); 2308 $chunk = base64_encode($chunk); 2309 $lookBack++; 2310 } while (strlen($chunk) > $length); 2311 $encoded .= $chunk . $lf; 2312 } 2313 2314 // Chomp the last linefeed 2315 $encoded = substr($encoded, 0, -strlen($lf)); 2316 return $encoded; 2317 } 2318 2319 /** 2320 * Encode a string in quoted-printable format. 2321 * According to RFC2045 section 6.7. 2322 * @access public 2323 * @param string $string The text to encode 2324 * @param integer $line_max Number of chars allowed on a line before wrapping 2325 * @return string 2326 * @link PHP version adapted from http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 2327 */ 2328 public function encodeQP($string, $line_max = 76) 2329 { 2330 if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3) 2331 return quoted_printable_encode($string); 2332 } 2333 //Fall back to a pure PHP implementation 2334 $string = str_replace( 2335 array('%20', '%0D%0A.', '%0D%0A', '%'), 2336 array(' ', "\r\n=2E", "\r\n", '='), 2337 rawurlencode($string) 2338 ); 2339 $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string); 2340 return $string; 2341 } 2342 2343 /** 2344 * Backward compatibility wrapper for an old QP encoding function that was removed. 2345 * @see PHPMailer::encodeQP() 2346 * @access public 2347 * @param string $string 2348 * @param integer $line_max 2349 * @param bool $space_conv 2350 * @return string 2351 * @deprecated Use encodeQP instead. 2352 */ 2353 public function encodeQPphp( 2354 $string, 2355 $line_max = 76, 2356 /** @noinspection PhpUnusedParameterInspection */ $space_conv = false 2357 ) { 2358 return $this->encodeQP($string, $line_max); 2359 } 2360 2361 /** 2362 * Encode a string using Q encoding. 2363 * @link http://tools.ietf.org/html/rfc2047 2364 * @param string $str the text to encode 2365 * @param string $position Where the text is going to be used, see the RFC for what that means 2366 * @access public 2367 * @return string 2368 */ 2369 public function encodeQ($str, $position = 'text') 2370 { 2371 //There should not be any EOL in the string 2372 $pattern = ''; 2373 $encoded = str_replace(array("\r", "\n"), '', $str); 2374 switch (strtolower($position)) { 2375 case 'phrase': 2376 //RFC 2047 section 5.3 2377 $pattern = '^A-Za-z0-9!*+\/ -'; 2378 break; 2379 /** @noinspection PhpMissingBreakStatementInspection */ 2380 case 'comment': 2381 //RFC 2047 section 5.2 2382 $pattern = '\(\)"'; 2383 //intentional fall-through 2384 //for this reason we build the $pattern without including delimiters and [] 2385 case 'text': 2386 default: 2387 //RFC 2047 section 5.1 2388 //Replace every high ascii, control, =, ? and _ characters 2389 $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern; 2390 break; 2391 } 2392 $matches = array(); 2393 if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) { 2394 //If the string contains an '=', make sure it's the first thing we replace 2395 //so as to avoid double-encoding 2396 $s = array_search('=', $matches[0]); 2397 if ($s !== false) { 2398 unset($matches[0][$s]); 2399 array_unshift($matches[0], '='); 2400 } 2401 foreach (array_unique($matches[0]) as $char) { 2402 $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded); 2403 } 2404 } 2405 //Replace every spaces to _ (more readable than =20) 2406 return str_replace(' ', '_', $encoded); 2407 } 2408 2409 2410 /** 2411 * Add a string or binary attachment (non-filesystem). 2412 * This method can be used to attach ascii or binary data, 2413 * such as a BLOB record from a database. 2414 * @param string $string String attachment data. 2415 * @param string $filename Name of the attachment. 2416 * @param string $encoding File encoding (see $Encoding). 2417 * @param string $type File extension (MIME) type. 2418 * @param string $disposition Disposition to use 2419 * @return void 2420 */ 2421 public function addStringAttachment( 2422 $string, 2423 $filename, 2424 $encoding = 'base64', 2425 $type = '', 2426 $disposition = 'attachment' 2427 ) { 2428 //If a MIME type is not specified, try to work it out from the file name 2429 if ($type == '') { 2430 $type = self::filenameToType($filename); 2431 } 2432 // Append to $attachment array 2433 $this->attachment[] = array( 2434 0 => $string, 2435 1 => $filename, 2436 2 => basename($filename), 2437 3 => $encoding, 2438 4 => $type, 2439 5 => true, // isStringAttachment 2440 6 => $disposition, 2441 7 => 0 2442 ); 2443 } 2444 2445 /** 2446 * Add an embedded (inline) attachment from a file. 2447 * This can include images, sounds, and just about any other document type. 2448 * These differ from 'regular' attachmants in that they are intended to be 2449 * displayed inline with the message, not just attached for download. 2450 * This is used in HTML messages that embed the images 2451 * the HTML refers to using the $cid value. 2452 * @param string $path Path to the attachment. 2453 * @param string $cid Content ID of the attachment; Use this to reference 2454 * the content when using an embedded image in HTML. 2455 * @param string $name Overrides the attachment name. 2456 * @param string $encoding File encoding (see $Encoding). 2457 * @param string $type File MIME type. 2458 * @param string $disposition Disposition to use 2459 * @return bool True on successfully adding an attachment 2460 */ 2461 public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline') 2462 { 2463 if (!@is_file($path)) { 2464 $this->setError($this->lang('file_access') . $path); 2465 return false; 2466 } 2467 2468 //If a MIME type is not specified, try to work it out from the file name 2469 if ($type == '') { 2470 $type = self::filenameToType($path); 2471 } 2472 2473 $filename = basename($path); 2474 if ($name == '') { 2475 $name = $filename; 2476 } 2477 2478 // Append to $attachment array 2479 $this->attachment[] = array( 2480 0 => $path, 2481 1 => $filename, 2482 2 => $name, 2483 3 => $encoding, 2484 4 => $type, 2485 5 => false, // isStringAttachment 2486 6 => $disposition, 2487 7 => $cid 2488 ); 2489 return true; 2490 } 2491 2492 /** 2493 * Add an embedded stringified attachment. 2494 * This can include images, sounds, and just about any other document type. 2495 * Be sure to set the $type to an image type for images: 2496 * JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'. 2497 * @param string $string The attachment binary data. 2498 * @param string $cid Content ID of the attachment; Use this to reference 2499 * the content when using an embedded image in HTML. 2500 * @param string $name 2501 * @param string $encoding File encoding (see $Encoding). 2502 * @param string $type MIME type. 2503 * @param string $disposition Disposition to use 2504 * @return bool True on successfully adding an attachment 2505 */ 2506 public function addStringEmbeddedImage( 2507 $string, 2508 $cid, 2509 $name = '', 2510 $encoding = 'base64', 2511 $type = '', 2512 $disposition = 'inline' 2513 ) { 2514 //If a MIME type is not specified, try to work it out from the name 2515 if ($type == '') { 2516 $type = self::filenameToType($name); 2517 } 2518 2519 // Append to $attachment array 2520 $this->attachment[] = array( 2521 0 => $string, 2522 1 => $name, 2523 2 => $name, 2524 3 => $encoding, 2525 4 => $type, 2526 5 => true, // isStringAttachment 2527 6 => $disposition, 2528 7 => $cid 2529 ); 2530 return true; 2531 } 2532 2533 /** 2534 * Check if an inline attachment is present. 2535 * @access public 2536 * @return bool 2537 */ 2538 public function inlineImageExists() 2539 { 2540 foreach ($this->attachment as $attachment) { 2541 if ($attachment[6] == 'inline') { 2542 return true; 2543 } 2544 } 2545 return false; 2546 } 2547 2548 /** 2549 * Check if an attachment (non-inline) is present. 2550 * @return bool 2551 */ 2552 public function attachmentExists() 2553 { 2554 foreach ($this->attachment as $attachment) { 2555 if ($attachment[6] == 'attachment') { 2556 return true; 2557 } 2558 } 2559 return false; 2560 } 2561 2562 /** 2563 * Check if this message has an alternative body set. 2564 * @return bool 2565 */ 2566 public function alternativeExists() 2567 { 2568 return !empty($this->AltBody); 2569 } 2570 2571 /** 2572 * Clear all To recipients. 2573 * @return void 2574 */ 2575 public function clearAddresses() 2576 { 2577 foreach ($this->to as $to) { 2578 unset($this->all_recipients[strtolower($to[0])]); 2579 } 2580 $this->to = array(); 2581 } 2582 2583 /** 2584 * Clear all CC recipients. 2585 * @return void 2586 */ 2587 public function clearCCs() 2588 { 2589 foreach ($this->cc as $cc) { 2590 unset($this->all_recipients[strtolower($cc[0])]); 2591 } 2592 $this->cc = array(); 2593 } 2594 2595 /** 2596 * Clear all BCC recipients. 2597 * @return void 2598 */ 2599 public function clearBCCs() 2600 { 2601 foreach ($this->bcc as $bcc) { 2602 unset($this->all_recipients[strtolower($bcc[0])]); 2603 } 2604 $this->bcc = array(); 2605 } 2606 2607 /** 2608 * Clear all ReplyTo recipients. 2609 * @return void 2610 */ 2611 public function clearReplyTos() 2612 { 2613 $this->ReplyTo = array(); 2614 } 2615 2616 /** 2617 * Clear all recipient types. 2618 * @return void 2619 */ 2620 public function clearAllRecipients() 2621 { 2622 $this->to = array(); 2623 $this->cc = array(); 2624 $this->bcc = array(); 2625 $this->all_recipients = array(); 2626 } 2627 2628 /** 2629 * Clear all filesystem, string, and binary attachments. 2630 * @return void 2631 */ 2632 public function clearAttachments() 2633 { 2634 $this->attachment = array(); 2635 } 2636 2637 /** 2638 * Clear all custom headers. 2639 * @return void 2640 */ 2641 public function clearCustomHeaders() 2642 { 2643 $this->CustomHeader = array(); 2644 } 2645 2646 /** 2647 * Add an error message to the error container. 2648 * @access protected 2649 * @param string $msg 2650 * @return void 2651 */ 2652 protected function setError($msg) 2653 { 2654 $this->error_count++; 2655 if ($this->Mailer == 'smtp' and !is_null($this->smtp)) { 2656 $lasterror = $this->smtp->getError(); 2657 if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) { 2658 $msg .= '<p>' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n"; 2659 } 2660 } 2661 $this->ErrorInfo = $msg; 2662 } 2663 2664 /** 2665 * Return an RFC 822 formatted date. 2666 * @access public 2667 * @return string 2668 * @static 2669 */ 2670 public static function rfcDate() 2671 { 2672 //Set the time zone to whatever the default is to avoid 500 errors 2673 //Will default to UTC if it's not set properly in php.ini 2674 date_default_timezone_set(@date_default_timezone_get()); 2675 return date('D, j M Y H:i:s O'); 2676 } 2677 2678 /** 2679 * Get the server hostname. 2680 * Returns 'localhost.localdomain' if unknown. 2681 * @access protected 2682 * @return string 2683 */ 2684 protected function serverHostname() 2685 { 2686 if (!empty($this->Hostname)) { 2687 $result = $this->Hostname; 2688 } elseif (isset($_SERVER['SERVER_NAME'])) { 2689 $result = $_SERVER['SERVER_NAME']; 2690 } else { 2691 $result = 'localhost.localdomain'; 2692 } 2693 2694 return $result; 2695 } 2696 2697 /** 2698 * Get an error message in the current language. 2699 * @access protected 2700 * @param string $key 2701 * @return string 2702 */ 2703 protected function lang($key) 2704 { 2705 if (count($this->language) < 1) { 2706 $this->setLanguage('en'); // set the default language 2707 } 2708 2709 if (isset($this->language[$key])) { 2710 return $this->language[$key]; 2711 } else { 2712 return 'Language string failed to load: ' . $key; 2713 } 2714 } 2715 2716 /** 2717 * Check if an error occurred. 2718 * @access public 2719 * @return bool True if an error did occur. 2720 */ 2721 public function isError() 2722 { 2723 return ($this->error_count > 0); 2724 } 2725 2726 /** 2727 * Ensure consistent line endings in a string. 2728 * Changes every end of line from CRLF, CR or LF to $this->LE. 2729 * @access public 2730 * @param string $str String to fixEOL 2731 * @return string 2732 */ 2733 public function fixEOL($str) 2734 { 2735 // Normalise to \n 2736 $nstr = str_replace(array("\r\n", "\r"), "\n", $str); 2737 // Now convert LE as needed 2738 if ($this->LE !== "\n") { 2739 $nstr = str_replace("\n", $this->LE, $nstr); 2740 } 2741 return $nstr; 2742 } 2743 2744 /** 2745 * Add a custom header. 2746 * $name value can be overloaded to contain 2747 * both header name and value (name:value) 2748 * @access public 2749 * @param string $name Custom header name 2750 * @param string $value Header value 2751 * @return void 2752 */ 2753 public function addCustomHeader($name, $value = null) 2754 { 2755 if ($value === null) { 2756 // Value passed in as name:value 2757 $this->CustomHeader[] = explode(':', $name, 2); 2758 } else { 2759 $this->CustomHeader[] = array($name, $value); 2760 } 2761 } 2762 2763 /** 2764 * Create a message from an HTML string. 2765 * Automatically makes modifications for inline images and backgrounds 2766 * and creates a plain-text version by converting the HTML. 2767 * Overwrites any existing values in $this->Body and $this->AltBody 2768 * @access public 2769 * @param string $message HTML message string 2770 * @param string $basedir baseline directory for path 2771 * @param bool $advanced Whether to use the advanced HTML to text converter 2772 * @return string $message 2773 */ 2774 public function msgHTML($message, $basedir = '', $advanced = false) 2775 { 2776 preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images); 2777 if (isset($images[2])) { 2778 foreach ($images[2] as $i => $url) { 2779 // do not change urls for absolute images (thanks to corvuscorax) 2780 if (!preg_match('#^[A-z]+://#', $url)) { 2781 $filename = basename($url); 2782 $directory = dirname($url); 2783 if ($directory == '.') { 2784 $directory = ''; 2785 } 2786 $cid = md5($url) . '@phpmailer.0'; //RFC2392 S 2 2787 if (strlen($basedir) > 1 && substr($basedir, -1) != '/') { 2788 $basedir .= '/'; 2789 } 2790 if (strlen($directory) > 1 && substr($directory, -1) != '/') { 2791 $directory .= '/'; 2792 } 2793 if ($this->addEmbeddedImage( 2794 $basedir . $directory . $filename, 2795 $cid, 2796 $filename, 2797 'base64', 2798 self::_mime_types(self::mb_pathinfo($filename, PATHINFO_EXTENSION)) 2799 ) 2800 ) { 2801 $message = preg_replace( 2802 "/" . $images[1][$i] . "=[\"']" . preg_quote($url, '/') . "[\"']/Ui", 2803 $images[1][$i] . "=\"cid:" . $cid . "\"", 2804 $message 2805 ); 2806 } 2807 } 2808 } 2809 } 2810 $this->isHTML(true); 2811 if (empty($this->AltBody)) { 2812 $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n"; 2813 } 2814 //Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better 2815 $this->Body = $this->normalizeBreaks($message); 2816 $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced)); 2817 return $this->Body; 2818 } 2819 2820 /** 2821 * Convert an HTML string into plain text. 2822 * @param string $html The HTML text to convert 2823 * @param bool $advanced Should this use the more complex html2text converter or just a simple one? 2824 * @return string 2825 */ 2826 public function html2text($html, $advanced = false) 2827 { 2828 if ($advanced) { 2829 require_once 'extras/class.html2text.php'; 2830 $h = new html2text($html); 2831 return $h->get_text(); 2832 } 2833 return html_entity_decode( 2834 trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))), 2835 ENT_QUOTES, 2836 $this->CharSet 2837 ); 2838 } 2839 2840 /** 2841 * Get the MIME type for a file extension. 2842 * @param string $ext File extension 2843 * @access public 2844 * @return string MIME type of file. 2845 * @static 2846 */ 2847 public static function _mime_types($ext = '') 2848 { 2849 $mimes = array( 2850 'xl' => 'application/excel', 2851 'hqx' => 'application/mac-binhex40', 2852 'cpt' => 'application/mac-compactpro', 2853 'bin' => 'application/macbinary', 2854 'doc' => 'application/msword', 2855 'word' => 'application/msword', 2856 'class' => 'application/octet-stream', 2857 'dll' => 'application/octet-stream', 2858 'dms' => 'application/octet-stream', 2859 'exe' => 'application/octet-stream', 2860 'lha' => 'application/octet-stream', 2861 'lzh' => 'application/octet-stream', 2862 'psd' => 'application/octet-stream', 2863 'sea' => 'application/octet-stream', 2864 'so' => 'application/octet-stream', 2865 'oda' => 'application/oda', 2866 'pdf' => 'application/pdf', 2867 'ai' => 'application/postscript', 2868 'eps' => 'application/postscript', 2869 'ps' => 'application/postscript', 2870 'smi' => 'application/smil', 2871 'smil' => 'application/smil', 2872 'mif' => 'application/vnd.mif', 2873 'xls' => 'application/vnd.ms-excel', 2874 'ppt' => 'application/vnd.ms-powerpoint', 2875 'wbxml' => 'application/vnd.wap.wbxml', 2876 'wmlc' => 'application/vnd.wap.wmlc', 2877 'dcr' => 'application/x-director', 2878 'dir' => 'application/x-director', 2879 'dxr' => 'application/x-director', 2880 'dvi' => 'application/x-dvi', 2881 'gtar' => 'application/x-gtar', 2882 'php3' => 'application/x-httpd-php', 2883 'php4' => 'application/x-httpd-php', 2884 'php' => 'application/x-httpd-php', 2885 'phtml' => 'application/x-httpd-php', 2886 'phps' => 'application/x-httpd-php-source', 2887 'js' => 'application/x-javascript', 2888 'swf' => 'application/x-shockwave-flash', 2889 'sit' => 'application/x-stuffit', 2890 'tar' => 'application/x-tar', 2891 'tgz' => 'application/x-tar', 2892 'xht' => 'application/xhtml+xml', 2893 'xhtml' => 'application/xhtml+xml', 2894 'zip' => 'application/zip', 2895 'mid' => 'audio/midi', 2896 'midi' => 'audio/midi', 2897 'mp2' => 'audio/mpeg', 2898 'mp3' => 'audio/mpeg', 2899 'mpga' => 'audio/mpeg', 2900 'aif' => 'audio/x-aiff', 2901 'aifc' => 'audio/x-aiff', 2902 'aiff' => 'audio/x-aiff', 2903 'ram' => 'audio/x-pn-realaudio', 2904 'rm' => 'audio/x-pn-realaudio', 2905 'rpm' => 'audio/x-pn-realaudio-plugin', 2906 'ra' => 'audio/x-realaudio', 2907 'wav' => 'audio/x-wav', 2908 'bmp' => 'image/bmp', 2909 'gif' => 'image/gif', 2910 'jpeg' => 'image/jpeg', 2911 'jpe' => 'image/jpeg', 2912 'jpg' => 'image/jpeg', 2913 'png' => 'image/png', 2914 'tiff' => 'image/tiff', 2915 'tif' => 'image/tiff', 2916 'eml' => 'message/rfc822', 2917 'css' => 'text/css', 2918 'html' => 'text/html', 2919 'htm' => 'text/html', 2920 'shtml' => 'text/html', 2921 'log' => 'text/plain', 2922 'text' => 'text/plain', 2923 'txt' => 'text/plain', 2924 'rtx' => 'text/richtext', 2925 'rtf' => 'text/rtf', 2926 'xml' => 'text/xml', 2927 'xsl' => 'text/xml', 2928 'mpeg' => 'video/mpeg', 2929 'mpe' => 'video/mpeg', 2930 'mpg' => 'video/mpeg', 2931 'mov' => 'video/quicktime', 2932 'qt' => 'video/quicktime', 2933 'rv' => 'video/vnd.rn-realvideo', 2934 'avi' => 'video/x-msvideo', 2935 'movie' => 'video/x-sgi-movie' 2936 ); 2937 return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]: 'application/octet-stream'); 2938 } 2939 2940 /** 2941 * Map a file name to a MIME type. 2942 * Defaults to 'application/octet-stream', i.e.. arbitrary binary data. 2943 * @param string $filename A file name or full path, does not need to exist as a file 2944 * @return string 2945 * @static 2946 */ 2947 public static function filenameToType($filename) 2948 { 2949 //In case the path is a URL, strip any query string before getting extension 2950 $qpos = strpos($filename, '?'); 2951 if ($qpos !== false) { 2952 $filename = substr($filename, 0, $qpos); 2953 } 2954 $pathinfo = self::mb_pathinfo($filename); 2955 return self::_mime_types($pathinfo['extension']); 2956 } 2957 2958 /** 2959 * Multi-byte-safe pathinfo replacement. 2960 * Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe. 2961 * Works similarly to the one in PHP >= 5.2.0 2962 * @link http://www.php.net/manual/en/function.pathinfo.php#107461 2963 * @param string $path A filename or path, does not need to exist as a file 2964 * @param integer|string $options Either a PATHINFO_* constant, 2965 * or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2 2966 * @return string|array 2967 * @static 2968 */ 2969 public static function mb_pathinfo($path, $options = null) 2970 { 2971 $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => ''); 2972 $m = array(); 2973 preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $m); 2974 if (array_key_exists(1, $m)) { 2975 $ret['dirname'] = $m[1]; 2976 } 2977 if (array_key_exists(2, $m)) { 2978 $ret['basename'] = $m[2]; 2979 } 2980 if (array_key_exists(5, $m)) { 2981 $ret['extension'] = $m[5]; 2982 } 2983 if (array_key_exists(3, $m)) { 2984 $ret['filename'] = $m[3]; 2985 } 2986 switch ($options) { 2987 case PATHINFO_DIRNAME: 2988 case 'dirname': 2989 return $ret['dirname']; 2990 break; 2991 case PATHINFO_BASENAME: 2992 case 'basename': 2993 return $ret['basename']; 2994 break; 2995 case PATHINFO_EXTENSION: 2996 case 'extension': 2997 return $ret['extension']; 2998 break; 2999 case PATHINFO_FILENAME: 3000 case 'filename': 3001 return $ret['filename']; 3002 break; 3003 default: 3004 return $ret; 3005 } 3006 } 3007 3008 /** 3009 * Set or reset instance properties. 3010 * 3011 * Usage Example: 3012 * $page->set('X-Priority', '3'); 3013 * 3014 * @access public 3015 * @param string $name 3016 * @param mixed $value 3017 * NOTE: will not work with arrays, there are no arrays to set/reset 3018 * @throws phpmailerException 3019 * @return bool 3020 * @todo Should this not be using __set() magic function? 3021 */ 3022 public function set($name, $value = '') 3023 { 3024 try { 3025 if (isset($this->$name)) { 3026 $this->$name = $value; 3027 } else { 3028 throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL); 3029 } 3030 } catch (Exception $e) { 3031 $this->setError($e->getMessage()); 3032 if ($e->getCode() == self::STOP_CRITICAL) { 3033 return false; 3034 } 3035 } 3036 return true; 3037 } 3038 3039 /** 3040 * Strip newlines to prevent header injection. 3041 * @access public 3042 * @param string $str 3043 * @return string 3044 */ 3045 public function secureHeader($str) 3046 { 3047 return trim(str_replace(array("\r", "\n"), '', $str)); 3048 } 3049 3050 /** 3051 * Normalize line breaks in a string. 3052 * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format. 3053 * Defaults to CRLF (for message bodies) and preserves consecutive breaks. 3054 * @param string $text 3055 * @param string $breaktype What kind of line break to use, defaults to CRLF 3056 * @return string 3057 * @access public 3058 * @static 3059 */ 3060 public static function normalizeBreaks($text, $breaktype = "\r\n") 3061 { 3062 return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text); 3063 } 3064 3065 3066 /** 3067 * Set the private key file and password for S/MIME signing. 3068 * @access public 3069 * @param string $cert_filename 3070 * @param string $key_filename 3071 * @param string $key_pass Password for private key 3072 */ 3073 public function sign($cert_filename, $key_filename, $key_pass) 3074 { 3075 $this->sign_cert_file = $cert_filename; 3076 $this->sign_key_file = $key_filename; 3077 $this->sign_key_pass = $key_pass; 3078 } 3079 3080 /** 3081 * Quoted-Printable-encode a DKIM header. 3082 * @access public 3083 * @param string $txt 3084 * @return string 3085 */ 3086 public function DKIM_QP($txt) 3087 { 3088 $line = ''; 3089 for ($i = 0; $i < strlen($txt); $i++) { 3090 $ord = ord($txt[$i]); 3091 if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) { 3092 $line .= $txt[$i]; 3093 } else { 3094 $line .= "=" . sprintf("%02X", $ord); 3095 } 3096 } 3097 return $line; 3098 } 3099 3100 /** 3101 * Generate a DKIM signature. 3102 * @access public 3103 * @param string $s Header 3104 * @throws phpmailerException 3105 * @return string 3106 */ 3107 public function DKIM_Sign($s) 3108 { 3109 if (!defined('PKCS7_TEXT')) { 3110 if ($this->exceptions) { 3111 throw new phpmailerException($this->lang("signing") . ' OpenSSL extension missing.'); 3112 } 3113 return ''; 3114 } 3115 $privKeyStr = file_get_contents($this->DKIM_private); 3116 if ($this->DKIM_passphrase != '') { 3117 $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase); 3118 } else { 3119 $privKey = $privKeyStr; 3120 } 3121 if (openssl_sign($s, $signature, $privKey)) { 3122 return base64_encode($signature); 3123 } 3124 return ''; 3125 } 3126 3127 /** 3128 * Generate a DKIM canonicalization header. 3129 * @access public 3130 * @param string $s Header 3131 * @return string 3132 */ 3133 public function DKIM_HeaderC($s) 3134 { 3135 $s = preg_replace("/\r\n\s+/", " ", $s); 3136 $lines = explode("\r\n", $s); 3137 foreach ($lines as $key => $line) { 3138 list($heading, $value) = explode(":", $line, 2); 3139 $heading = strtolower($heading); 3140 $value = preg_replace("/\s+/", " ", $value); // Compress useless spaces 3141 $lines[$key] = $heading . ":" . trim($value); // Don't forget to remove WSP around the value 3142 } 3143 $s = implode("\r\n", $lines); 3144 return $s; 3145 } 3146 3147 /** 3148 * Generate a DKIM canonicalization body. 3149 * @access public 3150 * @param string $body Message Body 3151 * @return string 3152 */ 3153 public function DKIM_BodyC($body) 3154 { 3155 if ($body == '') { 3156 return "\r\n"; 3157 } 3158 // stabilize line endings 3159 $body = str_replace("\r\n", "\n", $body); 3160 $body = str_replace("\n", "\r\n", $body); 3161 // END stabilize line endings 3162 while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") { 3163 $body = substr($body, 0, strlen($body) - 2); 3164 } 3165 return $body; 3166 } 3167 3168 /** 3169 * Create the DKIM header and body in a new message header. 3170 * @access public 3171 * @param string $headers_line Header lines 3172 * @param string $subject Subject 3173 * @param string $body Body 3174 * @return string 3175 */ 3176 public function DKIM_Add($headers_line, $subject, $body) 3177 { 3178 $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms 3179 $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body 3180 $DKIMquery = 'dns/txt'; // Query method 3181 $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) 3182 $subject_header = "Subject: $subject"; 3183 $headers = explode($this->LE, $headers_line); 3184 $from_header = ''; 3185 $to_header = ''; 3186 $current = ''; 3187 foreach ($headers as $header) { 3188 if (strpos($header, 'From:') === 0) { 3189 $from_header = $header; 3190 $current = 'from_header'; 3191 } elseif (strpos($header, 'To:') === 0) { 3192 $to_header = $header; 3193 $current = 'to_header'; 3194 } else { 3195 if ($current && strpos($header, ' =?') === 0) { 3196 $current .= $header; 3197 } else { 3198 $current = ''; 3199 } 3200 } 3201 } 3202 $from = str_replace('|', '=7C', $this->DKIM_QP($from_header)); 3203 $to = str_replace('|', '=7C', $this->DKIM_QP($to_header)); 3204 $subject = str_replace( 3205 '|', 3206 '=7C', 3207 $this->DKIM_QP($subject_header) 3208 ); // Copied header fields (dkim-quoted-printable) 3209 $body = $this->DKIM_BodyC($body); 3210 $DKIMlen = strlen($body); // Length of body 3211 $DKIMb64 = base64_encode(pack("H*", sha1($body))); // Base64 of packed binary SHA-1 hash of body 3212 $ident = ($this->DKIM_identity == '') ? '' : " i=" . $this->DKIM_identity . ";"; 3213 $dkimhdrs = "DKIM-Signature: v=1; a=" . 3214 $DKIMsignatureType . "; q=" . 3215 $DKIMquery . "; l=" . 3216 $DKIMlen . "; s=" . 3217 $this->DKIM_selector . 3218 ";\r\n" . 3219 "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n" . 3220 "\th=From:To:Subject;\r\n" . 3221 "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n" . 3222 "\tz=$from\r\n" . 3223 "\t|$to\r\n" . 3224 "\t|$subject;\r\n" . 3225 "\tbh=" . $DKIMb64 . ";\r\n" . 3226 "\tb="; 3227 $toSign = $this->DKIM_HeaderC( 3228 $from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs 3229 ); 3230 $signed = $this->DKIM_Sign($toSign); 3231 return $dkimhdrs . $signed . "\r\n"; 3232 } 3233 3234 /** 3235 * Perform a callback. 3236 * @param bool $isSent 3237 * @param string $to 3238 * @param string $cc 3239 * @param string $bcc 3240 * @param string $subject 3241 * @param string $body 3242 * @param string $from 3243 */ 3244 protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from = null) 3245 { 3246 if (!empty($this->action_function) && is_callable($this->action_function)) { 3247 $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from); 3248 call_user_func_array($this->action_function, $params); 3249 } 3250 } 3251 } 3252 3253 /** 3254 * PHPMailer exception handler 3255 * @package PHPMailer 3256 */ 3257 class phpmailerException extends Exception 3258 { 3259 /** 3260 * Prettify error message output 3261 * @return string 3262 */ 3263 public function errorMessage() 3264 { 3265 $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n"; 3266 return $errorMsg; 3267 } 3268 } -
new file src/wp-includes/PHPMailer/class.pop3.php
diff --git src/wp-includes/PHPMailer/class.pop3.php src/wp-includes/PHPMailer/class.pop3.php new file mode 100644 index 0000000..042b93a
- + 1 <?php 2 /** 3 * PHPMailer POP-Before-SMTP Authentication Class. 4 * PHP Version 5.0.0 5 * Version 5.2.7 6 * @package PHPMailer 7 * @link https://github.com/PHPMailer/PHPMailer/ 8 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk> 9 * @author Jim Jagielski (jimjag) <jimjag@gmail.com> 10 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> 11 * @author Brent R. Matzelle (original founder) 12 * @copyright 2013 Marcus Bointon 13 * @copyright 2010 - 2012 Jim Jagielski 14 * @copyright 2004 - 2009 Andy Prevost 15 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License 16 * @note This program is distributed in the hope that it will be useful - WITHOUT 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * FITNESS FOR A PARTICULAR PURPOSE. 19 */ 20 21 /** 22 * PHPMailer POP-Before-SMTP Authentication Class. 23 * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication. 24 * Does not support APOP. 25 * @package PHPMailer 26 * @author Richard Davey (original author) <rich@corephp.co.uk> 27 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk> 28 * @author Jim Jagielski (jimjag) <jimjag@gmail.com> 29 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> 30 */ 31 32 class POP3 33 { 34 /** 35 * The POP3 PHPMailer Version number. 36 * @type string 37 * @access public 38 */ 39 public $Version = '5.2.7'; 40 41 /** 42 * Default POP3 port number. 43 * @type int 44 * @access public 45 */ 46 public $POP3_PORT = 110; 47 48 /** 49 * Default timeout in seconds. 50 * @type int 51 * @access public 52 */ 53 public $POP3_TIMEOUT = 30; 54 55 /** 56 * POP3 Carriage Return + Line Feed. 57 * @type string 58 * @access public 59 * @deprecated Use the constant instead 60 */ 61 public $CRLF = "\r\n"; 62 63 /** 64 * Debug display level. 65 * Options: 0 = no, 1+ = yes 66 * @type int 67 * @access public 68 */ 69 public $do_debug = 0; 70 71 /** 72 * POP3 mail server hostname. 73 * @type string 74 * @access public 75 */ 76 public $host; 77 78 /** 79 * POP3 port number. 80 * @type int 81 * @access public 82 */ 83 public $port; 84 85 /** 86 * POP3 Timeout Value in seconds. 87 * @type int 88 * @access public 89 */ 90 public $tval; 91 92 /** 93 * POP3 username 94 * @type string 95 * @access public 96 */ 97 public $username; 98 99 /** 100 * POP3 password. 101 * @type string 102 * @access public 103 */ 104 public $password; 105 106 /** 107 * Resource handle for the POP3 connection socket. 108 * @type resource 109 * @access private 110 */ 111 private $pop_conn; 112 113 /** 114 * Are we connected? 115 * @type bool 116 * @access private 117 */ 118 private $connected; 119 120 /** 121 * Error container. 122 * @type array 123 * @access private 124 */ 125 private $error; 126 127 /** 128 * Line break constant 129 */ 130 const CRLF = "\r\n"; 131 132 /** 133 * Constructor. 134 * @access public 135 */ 136 public function __construct() 137 { 138 $this->pop_conn = 0; 139 $this->connected = false; 140 $this->error = null; 141 } 142 143 /** 144 * Simple static wrapper for all-in-one POP before SMTP 145 * @param $host 146 * @param bool $port 147 * @param bool $tval 148 * @param string $username 149 * @param string $password 150 * @param int $debug_level 151 * @return bool 152 */ 153 public static function popBeforeSmtp( 154 $host, 155 $port = false, 156 $tval = false, 157 $username = '', 158 $password = '', 159 $debug_level = 0 160 ) { 161 $pop = new POP3; 162 return $pop->authorise($host, $port, $tval, $username, $password, $debug_level); 163 } 164 165 /** 166 * Authenticate with a POP3 server. 167 * A connect, login, disconnect sequence 168 * appropriate for POP-before SMTP authorisation. 169 * @access public 170 * @param string $host 171 * @param bool|int $port 172 * @param bool|int $tval 173 * @param string $username 174 * @param string $password 175 * @param int $debug_level 176 * @return bool 177 */ 178 public function authorise($host, $port = false, $tval = false, $username = '', $password = '', $debug_level = 0) 179 { 180 $this->host = $host; 181 // If no port value provided, use default 182 if ($port === false) { 183 $this->port = $this->POP3_PORT; 184 } else { 185 $this->port = $port; 186 } 187 // If no timeout value provided, use default 188 if ($tval === false) { 189 $this->tval = $this->POP3_TIMEOUT; 190 } else { 191 $this->tval = $tval; 192 } 193 $this->do_debug = $debug_level; 194 $this->username = $username; 195 $this->password = $password; 196 // Refresh the error log 197 $this->error = null; 198 // connect 199 $result = $this->connect($this->host, $this->port, $this->tval); 200 if ($result) { 201 $login_result = $this->login($this->username, $this->password); 202 if ($login_result) { 203 $this->disconnect(); 204 return true; 205 } 206 } 207 // We need to disconnect regardless of whether the login succeeded 208 $this->disconnect(); 209 return false; 210 } 211 212 /** 213 * Connect to a POP3 server. 214 * @access public 215 * @param string $host 216 * @param bool|int $port 217 * @param integer $tval 218 * @return boolean 219 */ 220 public function connect($host, $port = false, $tval = 30) 221 { 222 // Are we already connected? 223 if ($this->connected) { 224 return true; 225 } 226 227 //On Windows this will raise a PHP Warning error if the hostname doesn't exist. 228 //Rather than suppress it with @fsockopen, capture it cleanly instead 229 set_error_handler(array($this, 'catchWarning')); 230 231 // connect to the POP3 server 232 $this->pop_conn = fsockopen( 233 $host, // POP3 Host 234 $port, // Port # 235 $errno, // Error Number 236 $errstr, // Error Message 237 $tval 238 ); // Timeout (seconds) 239 // Restore the error handler 240 restore_error_handler(); 241 // Does the Error Log now contain anything? 242 if ($this->error && $this->do_debug >= 1) { 243 $this->displayErrors(); 244 } 245 // Did we connect? 246 if ($this->pop_conn == false) { 247 // It would appear not... 248 $this->error = array( 249 'error' => "Failed to connect to server $host on port $port", 250 'errno' => $errno, 251 'errstr' => $errstr 252 ); 253 if ($this->do_debug >= 1) { 254 $this->displayErrors(); 255 } 256 return false; 257 } 258 259 // Increase the stream time-out 260 // Check for PHP 4.3.0 or later 261 if (version_compare(phpversion(), '5.0.0', 'ge')) { 262 stream_set_timeout($this->pop_conn, $tval, 0); 263 } else { 264 // Does not work on Windows 265 if (substr(PHP_OS, 0, 3) !== 'WIN') { 266 socket_set_timeout($this->pop_conn, $tval, 0); 267 } 268 } 269 270 // Get the POP3 server response 271 $pop3_response = $this->getResponse(); 272 // Check for the +OK 273 if ($this->checkResponse($pop3_response)) { 274 // The connection is established and the POP3 server is talking 275 $this->connected = true; 276 return true; 277 } 278 return false; 279 } 280 281 /** 282 * Log in to the POP3 server. 283 * Does not support APOP (RFC 2828, 4949). 284 * @access public 285 * @param string $username 286 * @param string $password 287 * @return boolean 288 */ 289 public function login($username = '', $password = '') 290 { 291 if ($this->connected == false) { 292 $this->error = 'Not connected to POP3 server'; 293 294 if ($this->do_debug >= 1) { 295 $this->displayErrors(); 296 } 297 } 298 if (empty($username)) { 299 $username = $this->username; 300 } 301 if (empty($password)) { 302 $password = $this->password; 303 } 304 305 // Send the Username 306 $this->sendString("USER $username" . self::CRLF); 307 $pop3_response = $this->getResponse(); 308 if ($this->checkResponse($pop3_response)) { 309 // Send the Password 310 $this->sendString("PASS $password" . self::CRLF); 311 $pop3_response = $this->getResponse(); 312 if ($this->checkResponse($pop3_response)) { 313 return true; 314 } 315 } 316 return false; 317 } 318 319 /** 320 * Disconnect from the POP3 server. 321 * @access public 322 */ 323 public function disconnect() 324 { 325 $this->sendString('QUIT'); 326 //The QUIT command may cause the daemon to exit, which will kill our connection 327 //So ignore errors here 328 @fclose($this->pop_conn); 329 } 330 331 /** 332 * Get a response from the POP3 server. 333 * $size is the maximum number of bytes to retrieve 334 * @param integer $size 335 * @return string 336 * @access private 337 */ 338 private function getResponse($size = 128) 339 { 340 $r = fgets($this->pop_conn, $size); 341 if ($this->do_debug >= 1) { 342 echo "Server -> Client: $r"; 343 } 344 return $r; 345 } 346 347 /** 348 * Send raw data to the POP3 server. 349 * @param string $string 350 * @return integer 351 * @access private 352 */ 353 private function sendString($string) 354 { 355 if ($this->pop_conn) { 356 if ($this->do_debug >= 2) { //Show client messages when debug >= 2 357 echo "Client -> Server: $string"; 358 } 359 return fwrite($this->pop_conn, $string, strlen($string)); 360 } 361 return 0; 362 } 363 364 /** 365 * Checks the POP3 server response. 366 * Looks for for +OK or -ERR. 367 * @param string $string 368 * @return boolean 369 * @access private 370 */ 371 private function checkResponse($string) 372 { 373 if (substr($string, 0, 3) !== '+OK') { 374 $this->error = array( 375 'error' => "Server reported an error: $string", 376 'errno' => 0, 377 'errstr' => '' 378 ); 379 if ($this->do_debug >= 1) { 380 $this->displayErrors(); 381 } 382 return false; 383 } else { 384 return true; 385 } 386 } 387 388 /** 389 * Display errors if debug is enabled. 390 * @access private 391 */ 392 private function displayErrors() 393 { 394 echo '<pre>'; 395 foreach ($this->error as $single_error) { 396 print_r($single_error); 397 } 398 echo '</pre>'; 399 } 400 401 /** 402 * POP3 connection error handler. 403 * @param integer $errno 404 * @param string $errstr 405 * @param string $errfile 406 * @param integer $errline 407 * @access private 408 */ 409 private function catchWarning($errno, $errstr, $errfile, $errline) 410 { 411 $this->error[] = array( 412 'error' => "Connecting to the POP3 server raised a PHP warning: ", 413 'errno' => $errno, 414 'errstr' => $errstr, 415 'errfile' => $errfile, 416 'errline' => $errline 417 ); 418 } 419 } -
new file src/wp-includes/PHPMailer/class.smtp.php
diff --git src/wp-includes/PHPMailer/class.smtp.php src/wp-includes/PHPMailer/class.smtp.php new file mode 100644 index 0000000..e6b4522
- + 1 <?php 2 /** 3 * PHPMailer RFC821 SMTP email transport class. 4 * Version 5.2.7 5 * PHP version 5.0.0 6 * @category PHP 7 * @package PHPMailer 8 * @link https://github.com/PHPMailer/PHPMailer/ 9 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk> 10 * @author Jim Jagielski (jimjag) <jimjag@gmail.com> 11 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> 12 * @copyright 2013 Marcus Bointon 13 * @copyright 2004 - 2008 Andy Prevost 14 * @copyright 2010 - 2012 Jim Jagielski 15 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL) 16 */ 17 18 /** 19 * PHPMailer RFC821 SMTP email transport class. 20 * 21 * Implements RFC 821 SMTP commands 22 * and provides some utility methods for sending mail to an SMTP server. 23 * 24 * PHP Version 5.0.0 25 * 26 * @category PHP 27 * @package PHPMailer 28 * @link https://github.com/PHPMailer/PHPMailer/blob/master/class.smtp.php 29 * @author Chris Ryan <unknown@example.com> 30 * @author Marcus Bointon <phpmailer@synchromedia.co.uk> 31 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL) 32 */ 33 34 class SMTP 35 { 36 /** 37 * The PHPMailer SMTP Version number. 38 */ 39 const VERSION = '5.2.7'; 40 41 /** 42 * SMTP line break constant. 43 */ 44 const CRLF = "\r\n"; 45 46 /** 47 * The SMTP port to use if one is not specified. 48 */ 49 const DEFAULT_SMTP_PORT = 25; 50 51 /** 52 * The PHPMailer SMTP Version number. 53 * @type string 54 * @deprecated This should be a constant 55 * @see SMTP::VERSION 56 */ 57 public $Version = '5.2.7'; 58 59 /** 60 * SMTP server port number. 61 * @type int 62 * @deprecated This is only ever ued as default value, so should be a constant 63 * @see SMTP::DEFAULT_SMTP_PORT 64 */ 65 public $SMTP_PORT = 25; 66 67 /** 68 * SMTP reply line ending 69 * @type string 70 * @deprecated Use the class constant instead 71 * @see SMTP::CRLF 72 */ 73 public $CRLF = "\r\n"; 74 75 /** 76 * Debug output level. 77 * Options: 0 for no output, 1 for commands, 2 for data and commands 78 * @type int 79 */ 80 public $do_debug = 0; 81 82 /** 83 * The function/method to use for debugging output. 84 * Options: 'echo', 'html' or 'error_log' 85 * @type string 86 */ 87 public $Debugoutput = 'echo'; 88 89 /** 90 * Whether to use VERP. 91 * @type bool 92 */ 93 public $do_verp = false; 94 95 /** 96 * The SMTP timeout value for reads, in seconds. 97 * @type int 98 */ 99 public $Timeout = 15; 100 101 /** 102 * The SMTP timelimit value for reads, in seconds. 103 * @type int 104 */ 105 public $Timelimit = 30; 106 107 /** 108 * The socket for the server connection. 109 * @type resource 110 */ 111 protected $smtp_conn; 112 113 /** 114 * Error message, if any, for the last call. 115 * @type string 116 */ 117 protected $error = ''; 118 119 /** 120 * The reply the server sent to us for HELO. 121 * @type string 122 */ 123 protected $helo_rply = ''; 124 125 /** 126 * The most recent reply received from the server. 127 * @type string 128 */ 129 protected $last_reply = ''; 130 131 /** 132 * Constructor. 133 * @access public 134 */ 135 public function __construct() 136 { 137 $this->smtp_conn = 0; 138 $this->error = null; 139 $this->helo_rply = null; 140 141 $this->do_debug = 0; 142 } 143 144 /** 145 * Output debugging info via a user-selected method. 146 * @param string $str Debug string to output 147 * @return void 148 */ 149 protected function edebug($str) 150 { 151 switch ($this->Debugoutput) { 152 case 'error_log': 153 //Don't output, just log 154 error_log($str); 155 break; 156 case 'html': 157 //Cleans up output a bit for a better looking, HTML-safe output 158 echo htmlentities( 159 preg_replace('/[\r\n]+/', '', $str), 160 ENT_QUOTES, 161 'UTF-8' 162 ) 163 . "<br>\n"; 164 break; 165 case 'echo': 166 default: 167 //Just echoes whatever was received 168 echo $str; 169 } 170 } 171 172 /** 173 * Connect to an SMTP server. 174 * @param string $host SMTP server IP or host name 175 * @param int $port The port number to connect to 176 * @param int $timeout How long to wait for the connection to open 177 * @param array $options An array of options for stream_context_create() 178 * @access public 179 * @return bool 180 */ 181 public function connect($host, $port = null, $timeout = 30, $options = array()) 182 { 183 // Clear errors to avoid confusion 184 $this->error = null; 185 186 // Make sure we are __not__ connected 187 if ($this->connected()) { 188 // Already connected, generate error 189 $this->error = array('error' => 'Already connected to a server'); 190 return false; 191 } 192 193 if (empty($port)) { 194 $port = self::DEFAULT_SMTP_PORT; 195 } 196 197 // Connect to the SMTP server 198 $errno = 0; 199 $errstr = ''; 200 $socket_context = stream_context_create($options); 201 //Suppress errors; connection failures are handled at a higher level 202 $this->smtp_conn = @stream_socket_client( 203 $host . ":" . $port, 204 $errno, 205 $errstr, 206 $timeout, 207 STREAM_CLIENT_CONNECT, 208 $socket_context 209 ); 210 211 // Verify we connected properly 212 if (empty($this->smtp_conn)) { 213 $this->error = array( 214 'error' => 'Failed to connect to server', 215 'errno' => $errno, 216 'errstr' => $errstr 217 ); 218 if ($this->do_debug >= 1) { 219 $this->edebug( 220 'SMTP -> ERROR: ' . $this->error['error'] 221 . ": $errstr ($errno)" 222 ); 223 } 224 return false; 225 } 226 227 // SMTP server can take longer to respond, give longer timeout for first read 228 // Windows does not have support for this timeout function 229 if (substr(PHP_OS, 0, 3) != 'WIN') { 230 $max = ini_get('max_execution_time'); 231 if ($max != 0 && $timeout > $max) { // Don't bother if unlimited 232 @set_time_limit($timeout); 233 } 234 stream_set_timeout($this->smtp_conn, $timeout, 0); 235 } 236 237 // Get any announcement 238 $announce = $this->get_lines(); 239 240 if ($this->do_debug >= 2) { 241 $this->edebug('SMTP -> FROM SERVER:' . $announce); 242 } 243 244 return true; 245 } 246 247 /** 248 * Initiate a TLS (encrypted) session. 249 * @access public 250 * @return bool 251 */ 252 public function startTLS() 253 { 254 if (!$this->sendCommand("STARTTLS", "STARTTLS", 220)) { 255 return false; 256 } 257 // Begin encrypted connection 258 if (!stream_socket_enable_crypto( 259 $this->smtp_conn, 260 true, 261 STREAM_CRYPTO_METHOD_TLS_CLIENT 262 ) 263 ) { 264 return false; 265 } 266 return true; 267 } 268 269 /** 270 * Perform SMTP authentication. 271 * Must be run after hello(). 272 * @see hello() 273 * @param string $username The user name 274 * @param string $password The password 275 * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5) 276 * @param string $realm The auth realm for NTLM 277 * @param string $workstation The auth workstation for NTLM 278 * @access public 279 * @return bool True if successfully authenticated. 280 */ 281 public function authenticate( 282 $username, 283 $password, 284 $authtype = 'LOGIN', 285 $realm = '', 286 $workstation = '' 287 ) { 288 if (empty($authtype)) { 289 $authtype = 'LOGIN'; 290 } 291 292 switch ($authtype) { 293 case 'PLAIN': 294 // Start authentication 295 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) { 296 return false; 297 } 298 // Send encoded username and password 299 if (!$this->sendCommand( 300 'User & Password', 301 base64_encode("\0" . $username . "\0" . $password), 302 235 303 ) 304 ) { 305 return false; 306 } 307 break; 308 case 'LOGIN': 309 // Start authentication 310 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { 311 return false; 312 } 313 if (!$this->sendCommand("Username", base64_encode($username), 334)) { 314 return false; 315 } 316 if (!$this->sendCommand("Password", base64_encode($password), 235)) { 317 return false; 318 } 319 break; 320 case 'NTLM': 321 /* 322 * ntlm_sasl_client.php 323 * Bundled with Permission 324 * 325 * How to telnet in windows: 326 * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx 327 * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication 328 */ 329 require_once 'extras/ntlm_sasl_client.php'; 330 $temp = new stdClass(); 331 $ntlm_client = new ntlm_sasl_client_class; 332 //Check that functions are available 333 if (!$ntlm_client->Initialize($temp)) { 334 $this->error = array('error' => $temp->error); 335 if ($this->do_debug >= 1) { 336 $this->edebug( 337 'You need to enable some modules in your php.ini file: ' 338 . $this->error['error'] 339 ); 340 } 341 return false; 342 } 343 //msg1 344 $msg1 = $ntlm_client->TypeMsg1($realm, $workstation); //msg1 345 346 if (!$this->sendCommand( 347 'AUTH NTLM', 348 'AUTH NTLM ' . base64_encode($msg1), 349 334 350 ) 351 ) { 352 return false; 353 } 354 355 //Though 0 based, there is a white space after the 3 digit number 356 //msg2 357 $challenge = substr($this->last_reply, 3); 358 $challenge = base64_decode($challenge); 359 $ntlm_res = $ntlm_client->NTLMResponse( 360 substr($challenge, 24, 8), 361 $password 362 ); 363 //msg3 364 $msg3 = $ntlm_client->TypeMsg3( 365 $ntlm_res, 366 $username, 367 $realm, 368 $workstation 369 ); 370 // send encoded username 371 return $this->sendCommand('Username', base64_encode($msg3), 235); 372 break; 373 case 'CRAM-MD5': 374 // Start authentication 375 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { 376 return false; 377 } 378 // Get the challenge 379 $challenge = base64_decode(substr($this->last_reply, 4)); 380 381 // Build the response 382 $response = $username . ' ' . $this->hmac($challenge, $password); 383 384 // send encoded credentials 385 return $this->sendCommand('Username', base64_encode($response), 235); 386 break; 387 } 388 return true; 389 } 390 391 /** 392 * Calculate an MD5 HMAC hash. 393 * Works like hash_hmac('md5', $data, $key) 394 * in case that function is not available 395 * @param string $data The data to hash 396 * @param string $key The key to hash with 397 * @access protected 398 * @return string 399 */ 400 protected function hmac($data, $key) 401 { 402 if (function_exists('hash_hmac')) { 403 return hash_hmac('md5', $data, $key); 404 } 405 406 // The following borrowed from 407 // http://php.net/manual/en/function.mhash.php#27225 408 409 // RFC 2104 HMAC implementation for php. 410 // Creates an md5 HMAC. 411 // Eliminates the need to install mhash to compute a HMAC 412 // Hacked by Lance Rushing 413 414 $b = 64; // byte length for md5 415 if (strlen($key) > $b) { 416 $key = pack('H*', md5($key)); 417 } 418 $key = str_pad($key, $b, chr(0x00)); 419 $ipad = str_pad('', $b, chr(0x36)); 420 $opad = str_pad('', $b, chr(0x5c)); 421 $k_ipad = $key ^ $ipad; 422 $k_opad = $key ^ $opad; 423 424 return md5($k_opad . pack('H*', md5($k_ipad . $data))); 425 } 426 427 /** 428 * Check connection state. 429 * @access public 430 * @return bool True if connected. 431 */ 432 public function connected() 433 { 434 if (!empty($this->smtp_conn)) { 435 $sock_status = stream_get_meta_data($this->smtp_conn); 436 if ($sock_status['eof']) { 437 // the socket is valid but we are not connected 438 if ($this->do_debug >= 1) { 439 $this->edebug( 440 'SMTP -> NOTICE: EOF caught while checking if connected' 441 ); 442 } 443 $this->close(); 444 return false; 445 } 446 return true; // everything looks good 447 } 448 return false; 449 } 450 451 /** 452 * Close the socket and clean up the state of the class. 453 * Don't use this function without first trying to use QUIT. 454 * @see quit() 455 * @access public 456 * @return void 457 */ 458 public function close() 459 { 460 $this->error = null; // so there is no confusion 461 $this->helo_rply = null; 462 if (!empty($this->smtp_conn)) { 463 // close the connection and cleanup 464 fclose($this->smtp_conn); 465 $this->smtp_conn = 0; 466 } 467 } 468 469 /** 470 * Send an SMTP DATA command. 471 * Issues a data command and sends the msg_data to the server, 472 * finializing the mail transaction. $msg_data is the message 473 * that is to be send with the headers. Each header needs to be 474 * on a single line followed by a <CRLF> with the message headers 475 * and the message body being separated by and additional <CRLF>. 476 * Implements rfc 821: DATA <CRLF> 477 * @param string $msg_data Message data to send 478 * @access public 479 * @return bool 480 */ 481 public function data($msg_data) 482 { 483 if (!$this->sendCommand('DATA', 'DATA', 354)) { 484 return false; 485 } 486 487 /* The server is ready to accept data! 488 * according to rfc821 we should not send more than 1000 489 * including the CRLF 490 * characters on a single line so we will break the data up 491 * into lines by \r and/or \n then if needed we will break 492 * each of those into smaller lines to fit within the limit. 493 * in addition we will be looking for lines that start with 494 * a period '.' and append and additional period '.' to that 495 * line. NOTE: this does not count towards limit. 496 */ 497 498 // Normalize the line breaks before exploding 499 $msg_data = str_replace("\r\n", "\n", $msg_data); 500 $msg_data = str_replace("\r", "\n", $msg_data); 501 $lines = explode("\n", $msg_data); 502 503 /* We need to find a good way to determine if headers are 504 * in the msg_data or if it is a straight msg body 505 * currently I am assuming rfc822 definitions of msg headers 506 * and if the first field of the first line (':' separated) 507 * does not contain a space then it _should_ be a header 508 * and we can process all lines before a blank "" line as 509 * headers. 510 */ 511 512 $field = substr($lines[0], 0, strpos($lines[0], ':')); 513 $in_headers = false; 514 if (!empty($field) && !strstr($field, ' ')) { 515 $in_headers = true; 516 } 517 518 //RFC 2822 section 2.1.1 limit 519 $max_line_length = 998; 520 521 foreach ($lines as $line) { 522 $lines_out = null; 523 if ($line == '' && $in_headers) { 524 $in_headers = false; 525 } 526 // ok we need to break this line up into several smaller lines 527 while (strlen($line) > $max_line_length) { 528 $pos = strrpos(substr($line, 0, $max_line_length), ' '); 529 530 // Patch to fix DOS attack 531 if (!$pos) { 532 $pos = $max_line_length - 1; 533 $lines_out[] = substr($line, 0, $pos); 534 $line = substr($line, $pos); 535 } else { 536 $lines_out[] = substr($line, 0, $pos); 537 $line = substr($line, $pos + 1); 538 } 539 540 /* If processing headers add a LWSP-char to the front of new line 541 * rfc822 on long msg headers 542 */ 543 if ($in_headers) { 544 $line = "\t" . $line; 545 } 546 } 547 $lines_out[] = $line; 548 549 // send the lines to the server 550 while (list(, $line_out) = @each($lines_out)) { 551 if (strlen($line_out) > 0) { 552 if (substr($line_out, 0, 1) == '.') { 553 $line_out = '.' . $line_out; 554 } 555 } 556 $this->client_send($line_out . self::CRLF); 557 } 558 } 559 560 // Message data has been sent, complete the command 561 return $this->sendCommand('DATA END', '.', 250); 562 } 563 564 /** 565 * Send an SMTP HELO or EHLO command. 566 * Used to identify the sending server to the receiving server. 567 * This makes sure that client and server are in a known state. 568 * Implements from RFC 821: HELO <SP> <domain> <CRLF> 569 * and RFC 2821 EHLO. 570 * @param string $host The host name or IP to connect to 571 * @access public 572 * @return bool 573 */ 574 public function hello($host = '') 575 { 576 // Try extended hello first (RFC 2821) 577 if (!$this->sendHello('EHLO', $host)) { 578 if (!$this->sendHello('HELO', $host)) { 579 return false; 580 } 581 } 582 583 return true; 584 } 585 586 /** 587 * Send an SMTP HELO or EHLO command. 588 * Low-level implementation used by hello() 589 * @see hello() 590 * @param string $hello The HELO string 591 * @param string $host The hostname to say we are 592 * @access protected 593 * @return bool 594 */ 595 protected function sendHello($hello, $host) 596 { 597 $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250); 598 $this->helo_rply = $this->last_reply; 599 return $noerror; 600 } 601 602 /** 603 * Send an SMTP MAIL command. 604 * Starts a mail transaction from the email address specified in 605 * $from. Returns true if successful or false otherwise. If True 606 * the mail transaction is started and then one or more recipient 607 * commands may be called followed by a data command. 608 * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF> 609 * @param string $from Source address of this message 610 * @access public 611 * @return bool 612 */ 613 public function mail($from) 614 { 615 $useVerp = ($this->do_verp ? ' XVERP' : ''); 616 return $this->sendCommand( 617 'MAIL FROM', 618 'MAIL FROM:<' . $from . '>' . $useVerp, 619 250 620 ); 621 } 622 623 /** 624 * Send an SMTP QUIT command. 625 * Closes the socket if there is no error or the $close_on_error argument is true. 626 * Implements from rfc 821: QUIT <CRLF> 627 * @param bool $close_on_error Should the connection close if an error occurs? 628 * @access public 629 * @return bool 630 */ 631 public function quit($close_on_error = true) 632 { 633 $noerror = $this->sendCommand('QUIT', 'QUIT', 221); 634 $e = $this->error; //Save any error 635 if ($noerror or $close_on_error) { 636 $this->close(); 637 $this->error = $e; //Restore any error from the quit command 638 } 639 return $noerror; 640 } 641 642 /** 643 * Send an SMTP RCPT command. 644 * Sets the TO argument to $to. 645 * Returns true if the recipient was accepted false if it was rejected. 646 * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF> 647 * @param string $to The address the message is being sent to 648 * @access public 649 * @return bool 650 */ 651 public function recipient($to) 652 { 653 return $this->sendCommand( 654 'RCPT TO ', 655 'RCPT TO:<' . $to . '>', 656 array(250, 251) 657 ); 658 } 659 660 /** 661 * Send an SMTP RSET command. 662 * Abort any transaction that is currently in progress. 663 * Implements rfc 821: RSET <CRLF> 664 * @access public 665 * @return bool True on success. 666 */ 667 public function reset() 668 { 669 return $this->sendCommand('RSET', 'RSET', 250); 670 } 671 672 /** 673 * Send a command to an SMTP server and check its return code. 674 * @param string $command The command name - not sent to the server 675 * @param string $commandstring The actual command to send 676 * @param int|array $expect One or more expected integer success codes 677 * @access protected 678 * @return bool True on success. 679 */ 680 protected function sendCommand($command, $commandstring, $expect) 681 { 682 if (!$this->connected()) { 683 $this->error = array( 684 "error" => "Called $command without being connected" 685 ); 686 return false; 687 } 688 $this->client_send($commandstring . self::CRLF); 689 690 $reply = $this->get_lines(); 691 $code = substr($reply, 0, 3); 692 693 if ($this->do_debug >= 2) { 694 $this->edebug('SMTP -> FROM SERVER:' . $reply); 695 } 696 697 if (!in_array($code, (array)$expect)) { 698 $this->last_reply = null; 699 $this->error = array( 700 "error" => "$command command failed", 701 "smtp_code" => $code, 702 "detail" => substr($reply, 4) 703 ); 704 if ($this->do_debug >= 1) { 705 $this->edebug( 706 'SMTP -> ERROR: ' . $this->error['error'] . ': ' . $reply 707 ); 708 } 709 return false; 710 } 711 712 $this->last_reply = $reply; 713 $this->error = null; 714 return true; 715 } 716 717 /** 718 * Send an SMTP SAML command. 719 * Starts a mail transaction from the email address specified in $from. 720 * Returns true if successful or false otherwise. If True 721 * the mail transaction is started and then one or more recipient 722 * commands may be called followed by a data command. This command 723 * will send the message to the users terminal if they are logged 724 * in and send them an email. 725 * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> 726 * @param string $from The address the message is from 727 * @access public 728 * @return bool 729 */ 730 public function sendAndMail($from) 731 { 732 return $this->sendCommand("SAML", "SAML FROM:$from", 250); 733 } 734 735 /** 736 * Send an SMTP VRFY command. 737 * @param string $name The name to verify 738 * @access public 739 * @return bool 740 */ 741 public function verify($name) 742 { 743 return $this->sendCommand("VRFY", "VRFY $name", array(250, 251)); 744 } 745 746 /** 747 * Send an SMTP NOOP command. 748 * Used to keep keep-alives alive, doesn't actually do anything 749 * @access public 750 * @return bool 751 */ 752 public function noop() 753 { 754 return $this->sendCommand("NOOP", "NOOP", 250); 755 } 756 757 /** 758 * Send an SMTP TURN command. 759 * This is an optional command for SMTP that this class does not support. 760 * This method is here to make the RFC821 Definition 761 * complete for this class and __may__ be implemented in future 762 * Implements from rfc 821: TURN <CRLF> 763 * @access public 764 * @return bool 765 */ 766 public function turn() 767 { 768 $this->error = array( 769 'error' => 'The SMTP TURN command is not implemented' 770 ); 771 if ($this->do_debug >= 1) { 772 $this->edebug('SMTP -> NOTICE: ' . $this->error['error']); 773 } 774 return false; 775 } 776 777 /** 778 * Send raw data to the server. 779 * @param string $data The data to send 780 * @access public 781 * @return int|bool The number of bytes sent to the server or FALSE on error 782 */ 783 public function client_send($data) 784 { 785 if ($this->do_debug >= 1) { 786 $this->edebug("CLIENT -> SMTP: $data"); 787 } 788 return fwrite($this->smtp_conn, $data); 789 } 790 791 /** 792 * Get the latest error. 793 * @access public 794 * @return array 795 */ 796 public function getError() 797 { 798 return $this->error; 799 } 800 801 /** 802 * Get the last reply from the server. 803 * @access public 804 * @return string 805 */ 806 public function getLastReply() 807 { 808 return $this->last_reply; 809 } 810 811 /** 812 * Read the SMTP server's response. 813 * Either before eof or socket timeout occurs on the operation. 814 * With SMTP we can tell if we have more lines to read if the 815 * 4th character is '-' symbol. If it is a space then we don't 816 * need to read anything else. 817 * @access protected 818 * @return string 819 */ 820 protected function get_lines() 821 { 822 $data = ''; 823 $endtime = 0; 824 // If the connection is bad, give up now 825 if (!is_resource($this->smtp_conn)) { 826 return $data; 827 } 828 stream_set_timeout($this->smtp_conn, $this->Timeout); 829 if ($this->Timelimit > 0) { 830 $endtime = time() + $this->Timelimit; 831 } 832 while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { 833 $str = @fgets($this->smtp_conn, 515); 834 if ($this->do_debug >= 4) { 835 $this->edebug("SMTP -> get_lines(): \$data was \"$data\""); 836 $this->edebug("SMTP -> get_lines(): \$str is \"$str\""); 837 } 838 $data .= $str; 839 if ($this->do_debug >= 4) { 840 $this->edebug("SMTP -> get_lines(): \$data is \"$data\""); 841 } 842 // if 4th character is a space, we are done reading, break the loop 843 if (substr($str, 3, 1) == ' ') { 844 break; 845 } 846 // Timed-out? Log and break 847 $info = stream_get_meta_data($this->smtp_conn); 848 if ($info['timed_out']) { 849 if ($this->do_debug >= 4) { 850 $this->edebug( 851 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)' 852 ); 853 } 854 break; 855 } 856 // Now check if reads took too long 857 if ($endtime) { 858 if (time() > $endtime) { 859 if ($this->do_debug >= 4) { 860 $this->edebug( 861 'SMTP -> get_lines(): timelimit reached (' 862 . $this->Timelimit . ' sec)' 863 ); 864 } 865 break; 866 } 867 } 868 } 869 return $data; 870 } 871 872 /** 873 * Enable or disable VERP address generation. 874 * @param bool $enabled 875 */ 876 public function setVerp($enabled = false) 877 { 878 $this->do_verp = $enabled; 879 } 880 881 /** 882 * Get VERP address generation mode. 883 * @return bool 884 */ 885 public function getVerp() 886 { 887 return $this->do_verp; 888 } 889 890 /** 891 * Set debug output method. 892 * @param string $method The function/method to use for debugging output. 893 */ 894 public function setDebugOutput($method = 'echo') 895 { 896 $this->Debugoutput = $method; 897 } 898 899 /** 900 * Get debug output method. 901 * @return string 902 */ 903 public function getDebugOutput() 904 { 905 return $this->Debugoutput; 906 } 907 908 /** 909 * Set debug output level. 910 * @param int $level 911 */ 912 public function setDebugLevel($level = 0) 913 { 914 $this->do_debug = $level; 915 } 916 917 /** 918 * Get debug output level. 919 * @return int 920 */ 921 public function getDebugLevel() 922 { 923 return $this->do_debug; 924 } 925 926 /** 927 * Set SMTP timeout. 928 * @param int $timeout 929 */ 930 public function setTimeout($timeout = 0) 931 { 932 $this->Timeout = $timeout; 933 } 934 935 /** 936 * Get SMTP timeout. 937 * @return int 938 */ 939 public function getTimeout() 940 { 941 return $this->Timeout; 942 } 943 } -
new file src/wp-includes/PHPMailer/composer.json
diff --git src/wp-includes/PHPMailer/composer.json src/wp-includes/PHPMailer/composer.json new file mode 100644 index 0000000..086f381
- + 1 { 2 "name": "phpmailer/phpmailer", 3 "type": "library", 4 "description": "PHPMailer is a full-featured email creation and transfer class for PHP", 5 "authors": [ 6 { 7 "name": "Jim Jagielski",