Ticket #25560: ticket-25560-phpmailer-minimal.patch
| File ticket-25560-phpmailer-minimal.patch, 450.1 KB (added by , 12 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: [](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: [](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", 8 "email": "jimjag@gmail.com" 9 }, 10 { 11 "name": "Marcus Bointon", 12 "email": "phpmailer@synchromedia.co.uk" 13 }, 14 { 15 "name": "Andy Prevost", 16 "email": "codeworxtech@users.sourceforge.net" 17 }, 18 { 19 "name": "Brent R. Matzelle" 20 } 21 ], 22 "require": { 23 "php": ">=5.0.0" 24 }, 25 "require-dev": { 26 "phpdocumentor/phpdocumentor": "*", 27 "phpunit/phpunit": "*" 28 }, 29 "autoload": { 30 "classmap": ["class.phpmailer.php", "class.pop3.php", "class.smtp.php"] 31 }, 32 "license": "LGPL-2.1" 33 } 34 No newline at end of file -
new file src/wp-includes/PHPMailer/extras/EasyPeasyICS.php
diff --git src/wp-includes/PHPMailer/extras/EasyPeasyICS.php src/wp-includes/PHPMailer/extras/EasyPeasyICS.php new file mode 100644 index 0000000..f076895
- + 1 <?php 2 3 /* ------------------------------------------------------------------------ */ 4 /* EasyPeasyICS 5 /* ------------------------------------------------------------------------ */ 6 /* Manuel Reinhard, manu@sprain.ch 7 /* Twitter: @sprain 8 /* Web: www.sprain.ch 9 /* 10 /* Built with inspiration by 11 /" http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355 12 /* ------------------------------------------------------------------------ */ 13 /* History: 14 /* 2010/12/17 - Manuel Reinhard - when it all started 15 /* ------------------------------------------------------------------------ */ 16 17 class EasyPeasyICS { 18 19 protected $calendarName; 20 protected $events = array(); 21 22 23 /** 24 * Constructor 25 * @param string $calendarName 26 */ 27 public function __construct($calendarName=""){ 28 $this->calendarName = $calendarName; 29 }//function 30 31 32 /** 33 * Add event to calendar 34 * @param string $calendarName 35 */ 36 public function addEvent($start, $end, $summary="", $description="", $url=""){ 37 $this->events[] = array( 38 "start" => $start, 39 "end" => $end, 40 "summary" => $summary, 41 "description" => $description, 42 "url" => $url 43 ); 44 }//function 45 46 47 public function render($output = true){ 48 49 //start Variable 50 $ics = ""; 51 52 //Add header 53 $ics .= "BEGIN:VCALENDAR 54 METHOD:PUBLISH 55 VERSION:2.0 56 X-WR-CALNAME:".$this->calendarName." 57 PRODID:-//hacksw/handcal//NONSGML v1.0//EN"; 58 59 //Add events 60 foreach($this->events as $event){ 61 $ics .= " 62 BEGIN:VEVENT 63 UID:". md5(uniqid(mt_rand(), true)) ."@EasyPeasyICS.php 64 DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z 65 DTSTART:".gmdate('Ymd', $event["start"])."T".gmdate('His', $event["start"])."Z 66 DTEND:".gmdate('Ymd', $event["end"])."T".gmdate('His', $event["end"])."Z 67 SUMMARY:".str_replace("\n", "\\n", $event['summary'])." 68 DESCRIPTION:".str_replace("\n", "\\n", $event['description'])." 69 URL;VALUE=URI:".$event['url']." 70 END:VEVENT"; 71 }//foreach 72 73 74 //Footer 75 $ics .= " 76 END:VCALENDAR"; 77 78 79 if ($output) { 80 //Output 81 header('Content-type: text/calendar; charset=utf-8'); 82 header('Content-Disposition: inline; filename='.$this->calendarName.'.ics'); 83 echo $ics; 84 } else { 85 return $ics; 86 } 87 88 }//function 89 90 }//class 91 No newline at end of file -
new file src/wp-includes/PHPMailer/extras/class.html2text.php
diff --git src/wp-includes/PHPMailer/extras/class.html2text.php src/wp-includes/PHPMailer/extras/class.html2text.php new file mode 100644 index 0000000..4dcd5ac
- + 1 <?php 2 /************************************************************************* 3 * * 4 * Converts HTML to formatted plain text * 5 * * 6 * Portions Copyright (c) 2005-2007 Jon Abernathy <jon@chuggnutt.com> * 7 * This version from https://github.com/mtibben/html2text * 8 * * 9 * This script is free software; you can redistribute it and/or modify * 10 * it under the terms of the GNU General Public License as published by * 11 * the Free Software Foundation; either version 2 of the License, or * 12 * (at your option) any later version. * 13 * * 14 * The GNU General Public License can be found at * 15 * http://www.gnu.org/copyleft/gpl.html. * 16 * * 17 * This script is distributed in the hope that it will be useful, * 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 20 * GNU General Public License for more details. * 21 * * 22 *************************************************************************/ 23 24 25 class html2text 26 { 27 28 /** 29 * Contains the HTML content to convert. 30 * 31 * @var string $html 32 * @access public 33 */ 34 public $html; 35 36 /** 37 * Contains the converted, formatted text. 38 * 39 * @var string $text 40 * @access public 41 */ 42 public $text; 43 44 /** 45 * Maximum width of the formatted text, in columns. 46 * 47 * Set this value to 0 (or less) to ignore word wrapping 48 * and not constrain text to a fixed-width column. 49 * 50 * @var integer $width 51 * @access public 52 */ 53 public $width = 70; 54 55 /** 56 * List of preg* regular expression patterns to search for, 57 * used in conjunction with $replace. 58 * 59 * @var array $search 60 * @access public 61 * @see $replace 62 */ 63 public $search = array( 64 "/\r/", // Non-legal carriage return 65 "/[\n\t]+/", // Newlines and tabs 66 '/<head[^>]*>.*?<\/head>/i', // <head> 67 '/<script[^>]*>.*?<\/script>/i', // <script>s -- which strip_tags supposedly has problems with 68 '/<style[^>]*>.*?<\/style>/i', // <style>s -- which strip_tags supposedly has problems with 69 '/<p[^>]*>/i', // <P> 70 '/<br[^>]*>/i', // <br> 71 '/<i[^>]*>(.*?)<\/i>/i', // <i> 72 '/<em[^>]*>(.*?)<\/em>/i', // <em> 73 '/(<ul[^>]*>|<\/ul>)/i', // <ul> and </ul> 74 '/(<ol[^>]*>|<\/ol>)/i', // <ol> and </ol> 75 '/<li[^>]*>(.*?)<\/li>/i', // <li> and </li> 76 '/<li[^>]*>/i', // <li> 77 '/<hr[^>]*>/i', // <hr> 78 '/<div[^>]*>/i', // <div> 79 '/(<table[^>]*>|<\/table>)/i', // <table> and </table> 80 '/(<tr[^>]*>|<\/tr>)/i', // <tr> and </tr> 81 '/<td[^>]*>(.*?)<\/td>/i', // <td> and </td> 82 '/<span class="_html2text_ignore">.+?<\/span>/i' // <span class="_html2text_ignore">...</span> 83 ); 84 85 /** 86 * List of pattern replacements corresponding to patterns searched. 87 * 88 * @var array $replace 89 * @access public 90 * @see $search 91 */ 92 public $replace = array( 93 '', // Non-legal carriage return 94 ' ', // Newlines and tabs 95 '', // <head> 96 '', // <script>s -- which strip_tags supposedly has problems with 97 '', // <style>s -- which strip_tags supposedly has problems with 98 "\n\n", // <P> 99 "\n", // <br> 100 '_\\1_', // <i> 101 '_\\1_', // <em> 102 "\n\n", // <ul> and </ul> 103 "\n\n", // <ol> and </ol> 104 "\t* \\1\n", // <li> and </li> 105 "\n\t* ", // <li> 106 "\n-------------------------\n", // <hr> 107 "<div>\n", // <div> 108 "\n\n", // <table> and </table> 109 "\n", // <tr> and </tr> 110 "\t\t\\1\n", // <td> and </td> 111 "" // <span class="_html2text_ignore">...</span> 112 ); 113 114 /** 115 * List of preg* regular expression patterns to search for, 116 * used in conjunction with $ent_replace. 117 * 118 * @var array $ent_search 119 * @access public 120 * @see $ent_replace 121 */ 122 public $ent_search = array( 123 '/&(nbsp|#160);/i', // Non-breaking space 124 '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i', 125 // Double quotes 126 '/&(apos|rsquo|lsquo|#8216|#8217);/i', // Single quotes 127 '/>/i', // Greater-than 128 '/</i', // Less-than 129 '/&(copy|#169);/i', // Copyright 130 '/&(trade|#8482|#153);/i', // Trademark 131 '/&(reg|#174);/i', // Registered 132 '/&(mdash|#151|#8212);/i', // mdash 133 '/&(ndash|minus|#8211|#8722);/i', // ndash 134 '/&(bull|#149|#8226);/i', // Bullet 135 '/&(pound|#163);/i', // Pound sign 136 '/&(euro|#8364);/i', // Euro sign 137 '/&(amp|#38);/i', // Ampersand: see _converter() 138 '/[ ]{2,}/', // Runs of spaces, post-handling 139 ); 140 141 /** 142 * List of pattern replacements corresponding to patterns searched. 143 * 144 * @var array $ent_replace 145 * @access public 146 * @see $ent_search 147 */ 148 public $ent_replace = array( 149 ' ', // Non-breaking space 150 '"', // Double quotes 151 "'", // Single quotes 152 '>', 153 '<', 154 '(c)', 155 '(tm)', 156 '(R)', 157 '--', 158 '-', 159 '*', 160 '£', 161 'EUR', // Euro sign. € ? 162 '|+|amp|+|', // Ampersand: see _converter() 163 ' ', // Runs of spaces, post-handling 164 ); 165 166 /** 167 * List of preg* regular expression patterns to search for 168 * and replace using callback function. 169 * 170 * @var array $callback_search 171 * @access public 172 */ 173 public $callback_search = array( 174 '/<(a) [^>]*href=("|\')([^"\']+)\2([^>]*)>(.*?)<\/a>/i', // <a href=""> 175 '/<(h)[123456]( [^>]*)?>(.*?)<\/h[123456]>/i', // h1 - h6 176 '/<(b)( [^>]*)?>(.*?)<\/b>/i', // <b> 177 '/<(strong)( [^>]*)?>(.*?)<\/strong>/i', // <strong> 178 '/<(th)( [^>]*)?>(.*?)<\/th>/i', // <th> and </th> 179 ); 180 181 /** 182 * List of preg* regular expression patterns to search for in PRE body, 183 * used in conjunction with $pre_replace. 184 * 185 * @var array $pre_search 186 * @access public 187 * @see $pre_replace 188 */ 189 public $pre_search = array( 190 "/\n/", 191 "/\t/", 192 '/ /', 193 '/<pre[^>]*>/', 194 '/<\/pre>/' 195 ); 196 197 /** 198 * List of pattern replacements corresponding to patterns searched for PRE body. 199 * 200 * @var array $pre_replace 201 * @access public 202 * @see $pre_search 203 */ 204 public $pre_replace = array( 205 '<br>', 206 ' ', 207 ' ', 208 '', 209 '' 210 ); 211 212 /** 213 * Contains a list of HTML tags to allow in the resulting text. 214 * 215 * @var string $allowed_tags 216 * @access public 217 * @see set_allowed_tags() 218 */ 219 public $allowed_tags = ''; 220 221 /** 222 * Contains the base URL that relative links should resolve to. 223 * 224 * @var string $url 225 * @access public 226 */ 227 public $url; 228 229 /** 230 * Indicates whether content in the $html variable has been converted yet. 231 * 232 * @var boolean $_converted 233 * @access private 234 * @see $html, $text 235 */ 236 private $_converted = false; 237 238 /** 239 * Contains URL addresses from links to be rendered in plain text. 240 * 241 * @var array $_link_list 242 * @access private 243 * @see _build_link_list() 244 */ 245 private $_link_list = array(); 246 247 248 /** 249 * Various configuration options (able to be set in the constructor) 250 * 251 * @var array $_options 252 * @access private 253 */ 254 private $_options = array( 255 256 // 'none' 257 // 'inline' (show links inline) 258 // 'nextline' (show links on the next line) 259 // 'table' (if a table of link URLs should be listed after the text. 260 'do_links' => 'inline', 261 262 // Maximum width of the formatted text, in columns. 263 // Set this value to 0 (or less) to ignore word wrapping 264 // and not constrain text to a fixed-width column. 265 'width' => 70, 266 ); 267 268 269 /** 270 * Constructor. 271 * 272 * If the HTML source string (or file) is supplied, the class 273 * will instantiate with that source propagated, all that has 274 * to be done it to call get_text(). 275 * 276 * @param string $source HTML content 277 * @param boolean $from_file Indicates $source is a file to pull content from 278 * @param array $options Set configuration options 279 * @access public 280 * @return void 281 */ 282 public function __construct( $source = '', $from_file = false, $options = array() ) 283 { 284 $this->_options = array_merge($this->_options, $options); 285 286 if ( !empty($source) ) { 287 $this->set_html($source, $from_file); 288 } 289 290 $this->set_base_url(); 291 } 292 293 /** 294 * Loads source HTML into memory, either from $source string or a file. 295 * 296 * @param string $source HTML content 297 * @param boolean $from_file Indicates $source is a file to pull content from 298 * @access public 299 * @return void 300 */ 301 public function set_html( $source, $from_file = false ) 302 { 303 if ( $from_file && file_exists($source) ) { 304 $this->html = file_get_contents($source); 305 } 306 else 307 $this->html = $source; 308 309 $this->_converted = false; 310 } 311 312 /** 313 * Returns the text, converted from HTML. 314 * 315 * @access public 316 * @return string 317 */ 318 public function get_text() 319 { 320 if ( !$this->_converted ) { 321 $this->_convert(); 322 } 323 324 return $this->text; 325 } 326 327 /** 328 * Prints the text, converted from HTML. 329 * 330 * @access public 331 * @return void 332 */ 333 public function print_text() 334 { 335 print $this->get_text(); 336 } 337 338 /** 339 * Alias to print_text(), operates identically. 340 * 341 * @access public 342 * @return void 343 * @see print_text() 344 */ 345 public function p() 346 { 347 print $this->get_text(); 348 } 349 350 /** 351 * Sets the allowed HTML tags to pass through to the resulting text. 352 * 353 * Tags should be in the form "<p>", with no corresponding closing tag. 354 * 355 * @access public 356 * @return void 357 */ 358 public function set_allowed_tags( $allowed_tags = '' ) 359 { 360 if ( !empty($allowed_tags) ) { 361 $this->allowed_tags = $allowed_tags; 362 } 363 } 364 365 /** 366 * Sets a base URL to handle relative links. 367 * 368 * @access public 369 * @return void 370 */ 371 public function set_base_url( $url = '' ) 372 { 373 if ( empty($url) ) { 374 if ( !empty($_SERVER['HTTP_HOST']) ) { 375 $this->url = 'http://' . $_SERVER['HTTP_HOST']; 376 } else { 377 $this->url = ''; 378 } 379 } else { 380 // Strip any trailing slashes for consistency (relative 381 // URLs may already start with a slash like "/file.html") 382 if ( substr($url, -1) == '/' ) { 383 $url = substr($url, 0, -1); 384 } 385 $this->url = $url; 386 } 387 } 388 389 /** 390 * Workhorse function that does actual conversion (calls _converter() method). 391 * 392 * @access private 393 * @return void 394 */ 395 private function _convert() 396 { 397 // Variables used for building the link list 398 $this->_link_list = array(); 399 400 $text = trim(stripslashes($this->html)); 401 402 // Convert HTML to TXT 403 $this->_converter($text); 404 405 // Add link list 406 if (!empty($this->_link_list)) { 407 $text .= "\n\nLinks:\n------\n"; 408 foreach ($this->_link_list as $idx => $url) { 409 $text .= '[' . ($idx+1) . '] ' . $url . "\n"; 410 } 411 } 412 413 $this->text = $text; 414 415 $this->_converted = true; 416 } 417 418 /** 419 * Workhorse function that does actual conversion. 420 * 421 * First performs custom tag replacement specified by $search and 422 * $replace arrays. Then strips any remaining HTML tags, reduces whitespace 423 * and newlines to a readable format, and word wraps the text to 424 * $this->_options['width'] characters. 425 * 426 * @param string Reference to HTML content string 427 * 428 * @access private 429 * @return void 430 */ 431 private function _converter(&$text) 432 { 433 // Convert <BLOCKQUOTE> (before PRE!) 434 $this->_convert_blockquotes($text); 435 436 // Convert <PRE> 437 $this->_convert_pre($text); 438 439 // Run our defined tags search-and-replace 440 $text = preg_replace($this->search, $this->replace, $text); 441 442 // Run our defined tags search-and-replace with callback 443 $text = preg_replace_callback($this->callback_search, array($this, '_preg_callback'), $text); 444 445 // Strip any other HTML tags 446 $text = strip_tags($text, $this->allowed_tags); 447 448 // Run our defined entities/characters search-and-replace 449 $text = preg_replace($this->ent_search, $this->ent_replace, $text); 450 451 // Replace known html entities 452 $text = html_entity_decode($text, ENT_QUOTES); 453 454 // Remove unknown/unhandled entities (this cannot be done in search-and-replace block) 455 $text = preg_replace('/&([a-zA-Z0-9]{2,6}|#[0-9]{2,4});/', '', $text); 456 457 // Convert "|+|amp|+|" into "&", need to be done after handling of unknown entities 458 // This properly handles situation of "&quot;" in input string 459 $text = str_replace('|+|amp|+|', '&', $text); 460 461 // Bring down number of empty lines to 2 max 462 $text = preg_replace("/\n\s+\n/", "\n\n", $text); 463 $text = preg_replace("/[\n]{3,}/", "\n\n", $text); 464 465 // remove leading empty lines (can be produced by eg. P tag on the beginning) 466 $text = ltrim($text, "\n"); 467 468 // Wrap the text to a readable format 469 // for PHP versions >= 4.0.2. Default width is 75 470 // If width is 0 or less, don't wrap the text. 471 if ( $this->_options['width'] > 0 ) { 472 $text = wordwrap($text, $this->_options['width']); 473 } 474 } 475 476 /** 477 * Helper function called by preg_replace() on link replacement. 478 * 479 * Maintains an internal list of links to be displayed at the end of the 480 * text, with numeric indices to the original point in the text they 481 * appeared. Also makes an effort at identifying and handling absolute 482 * and relative links. 483 * 484 * @param string $link URL of the link 485 * @param string $display Part of the text to associate number with 486 * @access private 487 * @return string 488 */ 489 private function _build_link_list( $link, $display, $link_override = null) 490 { 491 $link_method = ($link_override) ? $link_override : $this->_options['do_links']; 492 if ($link_method == 'none') 493 return $display; 494 495 496 // Ignored link types 497 if (preg_match('!^(javascript:|mailto:|#)!i', $link)) { 498 return $display; 499 } 500 if (preg_match('!^([a-z][a-z0-9.+-]+:)!i', $link)) { 501 $url = $link; 502 } 503 else { 504 $url = $this->url; 505 if (substr($link, 0, 1) != '/') { 506 $url .= '/'; 507 } 508 $url .= "$link"; 509 } 510 511 if ($link_method == 'table') 512 { 513 if (($index = array_search($url, $this->_link_list)) === false) { 514 $index = count($this->_link_list); 515 $this->_link_list[] = $url; 516 } 517 518 return $display . ' [' . ($index+1) . ']'; 519 } 520 elseif ($link_method == 'nextline') 521 { 522 return $display . "\n[" . $url . ']'; 523 } 524 else // link_method defaults to inline 525 { 526 return $display . ' [' . $url . ']'; 527 } 528 } 529 530 /** 531 * Helper function for PRE body conversion. 532 * 533 * @param string HTML content 534 * @access private 535 */ 536 private function _convert_pre(&$text) 537 { 538 // get the content of PRE element 539 while (preg_match('/<pre[^>]*>(.*)<\/pre>/ismU', $text, $matches)) { 540 $this->pre_content = $matches[1]; 541 542 // Run our defined tags search-and-replace with callback 543 $this->pre_content = preg_replace_callback($this->callback_search, 544 array($this, '_preg_callback'), $this->pre_content); 545 546 // convert the content 547 $this->pre_content = sprintf('<div><br>%s<br></div>', 548 preg_replace($this->pre_search, $this->pre_replace, $this->pre_content)); 549 // replace the content (use callback because content can contain $0 variable) 550 $text = preg_replace_callback('/<pre[^>]*>.*<\/pre>/ismU', 551 array($this, '_preg_pre_callback'), $text, 1); 552 553 // free memory 554 $this->pre_content = ''; 555 } 556 } 557 558 /** 559 * Helper function for BLOCKQUOTE body conversion. 560 * 561 * @param string HTML content 562 * @access private 563 */ 564 private function _convert_blockquotes(&$text) 565 { 566 if (preg_match_all('/<\/*blockquote[^>]*>/i', $text, $matches, PREG_OFFSET_CAPTURE)) { 567 $level = 0; 568 $diff = 0; 569 $start = 0; 570 $taglen = 0; 571 foreach ($matches[0] as $m) { 572 if ($m[0][0] == '<' && $m[0][1] == '/') { 573 $level--; 574 if ($level < 0) { 575 $level = 0; // malformed HTML: go to next blockquote 576 } 577 else if ($level > 0) { 578 // skip inner blockquote 579 } 580 else { 581 $end = $m[1]; 582 $len = $end - $taglen - $start; 583 // Get blockquote content 584 $body = substr($text, $start + $taglen - $diff, $len); 585 586 // Set text width 587 $p_width = $this->_options['width']; 588 if ($this->_options['width'] > 0) $this->_options['width'] -= 2; 589 // Convert blockquote content 590 $body = trim($body); 591 $this->_converter($body); 592 // Add citation markers and create PRE block 593 $body = preg_replace('/((^|\n)>*)/', '\\1> ', trim($body)); 594 $body = '<pre>' . htmlspecialchars($body) . '</pre>'; 595 // Re-set text width 596 $this->_options['width'] = $p_width; 597 // Replace content 598 $text = substr($text, 0, $start - $diff) 599 . $body . substr($text, $end + strlen($m[0]) - $diff); 600 601 $diff = $len + $taglen + strlen($m[0]) - strlen($body); 602 unset($body); 603 } 604 } 605 else { 606 if ($level == 0) { 607 $start = $m[1]; 608 $taglen = strlen($m[0]); 609 } 610 $level ++; 611 } 612 } 613 } 614 } 615 616 /** 617 * Callback function for preg_replace_callback use. 618 * 619 * @param array PREG matches 620 * @return string 621 */ 622 private function _preg_callback($matches) 623 { 624 switch (strtolower($matches[1])) { 625 case 'b': 626 case 'strong': 627 return $this->_toupper($matches[3]); 628 case 'th': 629 return $this->_toupper("\t\t". $matches[3] ."\n"); 630 case 'h': 631 return $this->_toupper("\n\n". $matches[3] ."\n\n"); 632 case 'a': 633 // override the link method 634 $link_override = null; 635 if (preg_match("/_html2text_link_(\w+)/", $matches[4], $link_override_match)) 636 { 637 $link_override = $link_override_match[1]; 638 } 639 // Remove spaces in URL (#1487805) 640 $url = str_replace(' ', '', $matches[3]); 641 return $this->_build_link_list($url, $matches[5], $link_override); 642 } 643 } 644 645 /** 646 * Callback function for preg_replace_callback use in PRE content handler. 647 * 648 * @param array PREG matches 649 * @return string 650 */ 651 private function _preg_pre_callback($matches) 652 { 653 return $this->pre_content; 654 } 655 656 /** 657 * Strtoupper function with HTML tags and entities handling. 658 * 659 * @param string $str Text to convert 660 * @return string Converted text 661 */ 662 private function _toupper($str) 663 { 664 // string can containg HTML tags 665 $chunks = preg_split('/(<[^>]*>)/', $str, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 666 667 // convert toupper only the text between HTML tags 668 foreach ($chunks as $idx => $chunk) { 669 if ($chunk[0] != '<') { 670 $chunks[$idx] = $this->_strtoupper($chunk); 671 } 672 } 673 674 return implode($chunks); 675 } 676 677 /** 678 * Strtoupper multibyte wrapper function with HTML entities handling. 679 * 680 * @param string $str Text to convert 681 * @return string Converted text 682 */ 683 private function _strtoupper($str) 684 { 685 $str = html_entity_decode($str, ENT_COMPAT); 686 687 if (function_exists('mb_strtoupper')) 688 $str = mb_strtoupper($str); 689 else 690 $str = strtoupper($str); 691 692 $str = htmlspecialchars($str, ENT_COMPAT); 693 694 return $str; 695 } 696 } 697 No newline at end of file -
new file src/wp-includes/PHPMailer/extras/htmlfilter.php
diff --git src/wp-includes/PHPMailer/extras/htmlfilter.php src/wp-includes/PHPMailer/extras/htmlfilter.php new file mode 100644 index 0000000..a5ce589
- + 1 <?php 2 /** 3 * htmlfilter.inc 4 * --------------- 5 * This set of functions allows you to filter html in order to remove 6 * any malicious tags from it. Useful in cases when you need to filter 7 * user input for any cross-site-scripting attempts. 8 * 9 * Copyright (C) 2002-2004 by Duke University 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 24 * 02110-1301 USA 25 * 26 * @Author Konstantin Riabitsev <icon@linux.duke.edu> 27 * @Version 1.1 ($Date: 2011-07-04 14:02:23 -0400 (Mon, 04 Jul 2011) $) 28 */ 29 30 /** 31 * @Author Jim Jagielski <jim@jaguNET.com / jimjag@gmail.com> 32 */ 33 34 /** 35 * This function returns the final tag out of the tag name, an array 36 * of attributes, and the type of the tag. This function is called by 37 * tln_sanitize internally. 38 * 39 * @param $tagname the name of the tag. 40 * @param $attary the array of attributes and their values 41 * @param $tagtype The type of the tag (see in comments). 42 * @return a string with the final tag representation. 43 */ 44 function tln_tagprint($tagname, $attary, $tagtype){ 45 $me = 'tln_tagprint'; 46 if ($tagtype == 2){ 47 $fulltag = '</' . $tagname . '>'; 48 } else { 49 $fulltag = '<' . $tagname; 50 if (is_array($attary) && sizeof($attary)){ 51 $atts = Array(); 52 while (list($attname, $attvalue) = each($attary)){ 53 array_push($atts, "$attname=$attvalue"); 54 } 55 $fulltag .= ' ' . join(' ', $atts); 56 } 57 if ($tagtype == 3){ 58 $fulltag .= ' /'; 59 } 60 $fulltag .= '>'; 61 } 62 return $fulltag; 63 } 64 65 /** 66 * A small helper function to use with array_walk. Modifies a by-ref 67 * value and makes it lowercase. 68 * 69 * @param $val a value passed by-ref. 70 * @return void since it modifies a by-ref value. 71 */ 72 function tln_casenormalize(&$val){ 73 $val = strtolower($val); 74 } 75 76 /** 77 * This function skips any whitespace from the current position within 78 * a string and to the next non-whitespace value. 79 * 80 * @param $body the string 81 * @param $offset the offset within the string where we should start 82 * looking for the next non-whitespace character. 83 * @return the location within the $body where the next 84 * non-whitespace char is located. 85 */ 86 function tln_skipspace($body, $offset){ 87 $me = 'tln_skipspace'; 88 preg_match('/^(\s*)/s', substr($body, $offset), $matches); 89 if (sizeof($matches[1])){ 90 $count = strlen($matches[1]); 91 $offset += $count; 92 } 93 return $offset; 94 } 95 96 /** 97 * This function looks for the next character within a string. It's 98 * really just a glorified "strpos", except it catches the failures 99 * nicely. 100 * 101 * @param $body The string to look for needle in. 102 * @param $offset Start looking from this position. 103 * @param $needle The character/string to look for. 104 * @return location of the next occurrence of the needle, or 105 * strlen($body) if needle wasn't found. 106 */ 107 function tln_findnxstr($body, $offset, $needle){ 108 $me = 'tln_findnxstr'; 109 $pos = strpos($body, $needle, $offset); 110 if ($pos === FALSE){ 111 $pos = strlen($body); 112 } 113 return $pos; 114 } 115 116 /** 117 * This function takes a PCRE-style regexp and tries to match it 118 * within the string. 119 * 120 * @param $body The string to look for needle in. 121 * @param $offset Start looking from here. 122 * @param $reg A PCRE-style regex to match. 123 * @return Returns a false if no matches found, or an array 124 * with the following members: 125 * - integer with the location of the match within $body 126 * - string with whatever content between offset and the match 127 * - string with whatever it is we matched 128 */ 129 function tln_findnxreg($body, $offset, $reg){ 130 $me = 'tln_findnxreg'; 131 $matches = Array(); 132 $retarr = Array(); 133 $preg_rule = '%^(.*?)(' . $reg . ')%s'; 134 preg_match($preg_rule, substr($body, $offset), $matches); 135 if (!isset($matches[0])){ 136 $retarr = false; 137 } else { 138 $retarr[0] = $offset + strlen($matches[1]); 139 $retarr[1] = $matches[1]; 140 $retarr[2] = $matches[2]; 141 } 142 return $retarr; 143 } 144 145 /** 146 * This function looks for the next tag. 147 * 148 * @param $body String where to look for the next tag. 149 * @param $offset Start looking from here. 150 * @return false if no more tags exist in the body, or 151 * an array with the following members: 152 * - string with the name of the tag 153 * - array with attributes and their values 154 * - integer with tag type (1, 2, or 3) 155 * - integer where the tag starts (starting "<") 156 * - integer where the tag ends (ending ">") 157 * first three members will be false, if the tag is invalid. 158 */ 159 function tln_getnxtag($body, $offset){ 160 $me = 'tln_getnxtag'; 161 if ($offset > strlen($body)){ 162 return false; 163 } 164 $lt = tln_findnxstr($body, $offset, '<'); 165 if ($lt == strlen($body)){ 166 return false; 167 } 168 /** 169 * We are here: 170 * blah blah <tag attribute="value"> 171 * \---------^ 172 */ 173 $pos = tln_skipspace($body, $lt + 1); 174 if ($pos >= strlen($body)){ 175 return Array(false, false, false, $lt, strlen($body)); 176 } 177 /** 178 * There are 3 kinds of tags: 179 * 1. Opening tag, e.g.: 180 * <a href="blah"> 181 * 2. Closing tag, e.g.: 182 * </a> 183 * 3. XHTML-style content-less tag, e.g.: 184 * <img src="blah"/> 185 */ 186 $tagtype = false; 187 switch (substr($body, $pos, 1)){ 188 case '/': 189 $tagtype = 2; 190 $pos++; 191 break; 192 case '!': 193 /** 194 * A comment or an SGML declaration. 195 */ 196 if (substr($body, $pos+1, 2) == '--'){ 197 $gt = strpos($body, '-->', $pos); 198 if ($gt === false){ 199 $gt = strlen($body); 200 } else { 201 $gt += 2; 202 } 203 return Array(false, false, false, $lt, $gt); 204 } else { 205 $gt = tln_findnxstr($body, $pos, '>'); 206 return Array(false, false, false, $lt, $gt); 207 } 208 break; 209 default: 210 /** 211 * Assume tagtype 1 for now. If it's type 3, we'll switch values 212 * later. 213 */ 214 $tagtype = 1; 215 break; 216 } 217 218 $tag_start = $pos; 219 $tagname = ''; 220 /** 221 * Look for next [\W-_], which will indicate the end of the tag name. 222 */ 223 $regary = tln_findnxreg($body, $pos, '[^\w\-_]'); 224 if ($regary == false){ 225 return Array(false, false, false, $lt, strlen($body)); 226 } 227 list($pos, $tagname, $match) = $regary; 228 $tagname = strtolower($tagname); 229 230 /** 231 * $match can be either of these: 232 * '>' indicating the end of the tag entirely. 233 * '\s' indicating the end of the tag name. 234 * '/' indicating that this is type-3 xhtml tag. 235 * 236 * Whatever else we find there indicates an invalid tag. 237 */ 238 switch ($match){ 239 case '/': 240 /** 241 * This is an xhtml-style tag with a closing / at the 242 * end, like so: <img src="blah"/>. Check if it's followed 243 * by the closing bracket. If not, then this tag is invalid 244 */ 245 if (substr($body, $pos, 2) == '/>'){ 246 $pos++; 247 $tagtype = 3; 248 } else { 249 $gt = tln_findnxstr($body, $pos, '>'); 250 $retary = Array(false, false, false, $lt, $gt); 251 return $retary; 252 } 253 case '>': 254 return Array($tagname, false, $tagtype, $lt, $pos); 255 break; 256 default: 257 /** 258 * Check if it's whitespace 259 */ 260 if (preg_match('/\s/', $match)){ 261 } else { 262 /** 263 * This is an invalid tag! Look for the next closing ">". 264 */ 265 $gt = tln_findnxstr($body, $lt, '>'); 266 return Array(false, false, false, $lt, $gt); 267 } 268 } 269 270 /** 271 * At this point we're here: 272 * <tagname attribute='blah'> 273 * \-------^ 274 * 275 * At this point we loop in order to find all attributes. 276 */ 277 $attname = ''; 278 $atttype = false; 279 $attary = Array(); 280 281 while ($pos <= strlen($body)){ 282 $pos = tln_skipspace($body, $pos); 283 if ($pos == strlen($body)){ 284 /** 285 * Non-closed tag. 286 */ 287 return Array(false, false, false, $lt, $pos); 288 } 289 /** 290 * See if we arrived at a ">" or "/>", which means that we reached 291 * the end of the tag. 292 */ 293 $matches = Array(); 294 preg_match('%^(\s*)(>|/>)%s', substr($body, $pos), $matches); 295 if (isset($matches[0]) && $matches[0]){ 296 /** 297 * Yep. So we did. 298 */ 299 $pos += strlen($matches[1]); 300 if ($matches[2] == '/>'){ 301 $tagtype = 3; 302 $pos++; 303 } 304 return Array($tagname, $attary, $tagtype, $lt, $pos); 305 } 306 307 /** 308 * There are several types of attributes, with optional 309 * [:space:] between members. 310 * Type 1: 311 * attrname[:space:]=[:space:]'CDATA' 312 * Type 2: 313 * attrname[:space:]=[:space:]"CDATA" 314 * Type 3: 315 * attr[:space:]=[:space:]CDATA 316 * Type 4: 317 * attrname 318 * 319 * We leave types 1 and 2 the same, type 3 we check for 320 * '"' and convert to """ if needed, then wrap in 321 * double quotes. Type 4 we convert into: 322 * attrname="yes". 323 */ 324 $regary = tln_findnxreg($body, $pos, '[^\w\-_]'); 325 if ($regary == false){ 326 /** 327 * Looks like body ended before the end of tag. 328 */ 329 return Array(false, false, false, $lt, strlen($body)); 330 } 331 list($pos, $attname, $match) = $regary; 332 $attname = strtolower($attname); 333 /** 334 * We arrived at the end of attribute name. Several things possible 335 * here: 336 * '>' means the end of the tag and this is attribute type 4 337 * '/' if followed by '>' means the same thing as above 338 * '\s' means a lot of things -- look what it's followed by. 339 * anything else means the attribute is invalid. 340 */ 341 switch($match){ 342 case '/': 343 /** 344 * This is an xhtml-style tag with a closing / at the 345 * end, like so: <img src="blah"/>. Check if it's followed 346 * by the closing bracket. If not, then this tag is invalid 347 */ 348 if (substr($body, $pos, 2) == '/>'){ 349 $pos++; 350 $tagtype = 3; 351 } else { 352 $gt = tln_findnxstr($body, $pos, '>'); 353 $retary = Array(false, false, false, $lt, $gt); 354 return $retary; 355 } 356 case '>': 357 $attary{$attname} = '"yes"'; 358 return Array($tagname, $attary, $tagtype, $lt, $pos); 359 break; 360 default: 361 /** 362 * Skip whitespace and see what we arrive at. 363 */ 364 $pos = tln_skipspace($body, $pos); 365 $char = substr($body, $pos, 1); 366 /** 367 * Two things are valid here: 368 * '=' means this is attribute type 1 2 or 3. 369 * \w means this was attribute type 4. 370 * anything else we ignore and re-loop. End of tag and 371 * invalid stuff will be caught by our checks at the beginning 372 * of the loop. 373 */ 374 if ($char == '='){ 375 $pos++; 376 $pos = tln_skipspace($body, $pos); 377 /** 378 * Here are 3 possibilities: 379 * "'" attribute type 1 380 * '"' attribute type 2 381 * everything else is the content of tag type 3 382 */ 383 $quot = substr($body, $pos, 1); 384 if ($quot == '\''){ 385 $regary = tln_findnxreg($body, $pos+1, '\''); 386 if ($regary == false){ 387 return Array(false, false, false, $lt, strlen($body)); 388 } 389 list($pos, $attval, $match) = $regary; 390 $pos++; 391 $attary{$attname} = '\'' . $attval . '\''; 392 } else if ($quot == '"'){ 393 $regary = tln_findnxreg($body, $pos+1, '\"'); 394 if ($regary == false){ 395 return Array(false, false, false, $lt, strlen($body)); 396 } 397 list($pos, $attval, $match) = $regary; 398 $pos++; 399 $attary{$attname} = '"' . $attval . '"'; 400 } else { 401 /** 402 * These are hateful. Look for \s, or >. 403 */ 404 $regary = tln_findnxreg($body, $pos, '[\s>]'); 405 if ($regary == false){ 406 return Array(false, false, false, $lt, strlen($body)); 407 } 408 list($pos, $attval, $match) = $regary; 409 /** 410 * If it's ">" it will be caught at the top. 411 */ 412 $attval = preg_replace('/\"/s', '"', $attval); 413 $attary{$attname} = '"' . $attval . '"'; 414 } 415 } else if (preg_match('|[\w/>]|', $char)) { 416 /** 417 * That was attribute type 4. 418 */ 419 $attary{$attname} = '"yes"'; 420 } else { 421 /** 422 * An illegal character. Find next '>' and return. 423 */ 424 $gt = tln_findnxstr($body, $pos, '>'); 425 return Array(false, false, false, $lt, $gt); 426 } 427 } 428 } 429 /** 430 * The fact that we got here indicates that the tag end was never 431 * found. Return invalid tag indication so it gets stripped. 432 */ 433 return Array(false, false, false, $lt, strlen($body)); 434 } 435 436 /** 437 * Translates entities into literal values so they can be checked. 438 * 439 * @param $attvalue the by-ref value to check. 440 * @param $regex the regular expression to check against. 441 * @param $hex whether the entites are hexadecimal. 442 * @return True or False depending on whether there were matches. 443 */ 444 function tln_deent(&$attvalue, $regex, $hex=false){ 445 $me = 'tln_deent'; 446 $ret_match = false; 447 preg_match_all($regex, $attvalue, $matches); 448 if (is_array($matches) && sizeof($matches[0]) > 0){ 449 $repl = Array(); 450 for ($i = 0; $i < sizeof($matches[0]); $i++){ 451 $numval = $matches[1][$i]; 452 if ($hex){ 453 $numval = hexdec($numval); 454 } 455 $repl{$matches[0][$i]} = chr($numval); 456 } 457 $attvalue = strtr($attvalue, $repl); 458 return true; 459 } else { 460 return false; 461 } 462 } 463 464 /** 465 * This function checks attribute values for entity-encoded values 466 * and returns them translated into 8-bit strings so we can run 467 * checks on them. 468 * 469 * @param $attvalue A string to run entity check against. 470 * @return Nothing, modifies a reference value. 471 */ 472 function tln_defang(&$attvalue){ 473 $me = 'tln_defang'; 474 /** 475 * Skip this if there aren't ampersands or backslashes. 476 */ 477 if (strpos($attvalue, '&') === false 478 && strpos($attvalue, '\\') === false){ 479 return; 480 } 481 $m = false; 482 do { 483 $m = false; 484 $m = $m || tln_deent($attvalue, '/\�*(\d+);*/s'); 485 $m = $m || tln_deent($attvalue, '/\�*((\d|[a-f])+);*/si', true); 486 $m = $m || tln_deent($attvalue, '/\\\\(\d+)/s', true); 487 } while ($m == true); 488 $attvalue = stripslashes($attvalue); 489 } 490 491 /** 492 * Kill any tabs, newlines, or carriage returns. Our friends the 493 * makers of the browser with 95% market value decided that it'd 494 * be funny to make "java[tab]script" be just as good as "javascript". 495 * 496 * @param attvalue The attribute value before extraneous spaces removed. 497 * @return attvalue Nothing, modifies a reference value. 498 */ 499 function tln_unspace(&$attvalue){ 500 $me = 'tln_unspace'; 501 if (strcspn($attvalue, "\t\r\n\0 ") != strlen($attvalue)){ 502 $attvalue = str_replace(Array("\t", "\r", "\n", "\0", " "), 503 Array('', '', '', '', ''), $attvalue); 504 } 505 } 506 507 /** 508 * This function runs various checks against the attributes. 509 * 510 * @param $tagname String with the name of the tag. 511 * @param $attary Array with all tag attributes. 512 * @param $rm_attnames See description for tln_sanitize 513 * @param $bad_attvals See description for tln_sanitize 514 * @param $add_attr_to_tag See description for tln_sanitize 515 * @return Array with modified attributes. 516 */ 517 function tln_fixatts($tagname, 518 $attary, 519 $rm_attnames, 520 $bad_attvals, 521 $add_attr_to_tag 522 ){ 523 $me = 'tln_fixatts'; 524 while (list($attname, $attvalue) = each($attary)){ 525 /** 526 * See if this attribute should be removed. 527 */ 528 foreach ($rm_attnames as $matchtag=>$matchattrs){ 529 if (preg_match($matchtag, $tagname)){ 530 foreach ($matchattrs as $matchattr){ 531 if (preg_match($matchattr, $attname)){ 532 unset($attary{$attname}); 533 continue; 534 } 535 } 536 } 537 } 538 /** 539 * Remove any backslashes, entities, or extraneous whitespace. 540 */ 541 tln_defang($attvalue); 542 tln_unspace($attvalue); 543 544 /** 545 * Now let's run checks on the attvalues. 546 * I don't expect anyone to comprehend this. If you do, 547 * get in touch with me so I can drive to where you live and 548 * shake your hand personally. :) 549 */ 550 foreach ($bad_attvals as $matchtag=>$matchattrs){ 551 if (preg_match($matchtag, $tagname)){ 552 foreach ($matchattrs as $matchattr=>$valary){ 553 if (preg_match($matchattr, $attname)){ 554 /** 555 * There are two arrays in valary. 556 * First is matches. 557 * Second one is replacements 558 */ 559 list($valmatch, $valrepl) = $valary; 560 $newvalue = preg_replace($valmatch,$valrepl,$attvalue); 561 if ($newvalue != $attvalue){ 562 $attary{$attname} = $newvalue; 563 } 564 } 565 } 566 } 567 } 568 } 569 /** 570 * See if we need to append any attributes to this tag. 571 */ 572 foreach ($add_attr_to_tag as $matchtag=>$addattary){ 573 if (preg_match($matchtag, $tagname)){ 574 $attary = array_merge($attary, $addattary); 575 } 576 } 577 return $attary; 578 } 579 580 /** 581 * 582 * @param $body the string with HTML you wish to filter 583 * @param $tag_list see description above 584 * @param $rm_tags_with_content see description above 585 * @param $self_closing_tags see description above 586 * @param $force_tag_closing see description above 587 * @param $rm_attnames see description above 588 * @param $bad_attvals see description above 589 * @param $add_attr_to_tag see description above 590 * @return tln_sanitized html safe to show on your pages. 591 */ 592 function tln_sanitize($body, 593 $tag_list, 594 $rm_tags_with_content, 595 $self_closing_tags, 596 $force_tag_closing, 597 $rm_attnames, 598 $bad_attvals, 599 $add_attr_to_tag 600 ) 601 { 602 $me = 'tln_sanitize'; 603 /** 604 * Normalize rm_tags and rm_tags_with_content. 605 */ 606 $rm_tags = array_shift($tag_list); 607 @array_walk($tag_list, 'tln_casenormalize'); 608 @array_walk($rm_tags_with_content, 'tln_casenormalize'); 609 @array_walk($self_closing_tags, 'tln_casenormalize'); 610 /** 611 * See if tag_list is of tags to remove or tags to allow. 612 * false means remove these tags 613 * true means allow these tags 614 */ 615 $curpos = 0; 616 $open_tags = Array(); 617 $trusted = "<!-- begin tln_sanitized html -->\n"; 618 $skip_content = false; 619 /** 620 * Take care of netscape's stupid javascript entities like 621 * &{alert('boo')}; 622 */ 623 $body = preg_replace('/&(\{.*?\};)/si', '&\\1', $body); 624 while (($curtag = tln_getnxtag($body, $curpos)) != FALSE){ 625 list($tagname, $attary, $tagtype, $lt, $gt) = $curtag; 626 $free_content = substr($body, $curpos, $lt - $curpos); 627 if ($skip_content == false){ 628 $trusted .= $free_content; 629 } else { 630 } 631 if ($tagname != FALSE){ 632 if ($tagtype == 2){ 633 if ($skip_content == $tagname){ 634 /** 635 * Got to the end of tag we needed to remove. 636 */ 637 $tagname = false; 638 $skip_content = false; 639 } else { 640 if ($skip_content == false){ 641 if (isset($open_tags{$tagname}) && 642 $open_tags{$tagname} > 0){ 643 $open_tags{$tagname}--; 644 } else { 645 $tagname = false; 646 } 647 } else { 648 } 649 } 650 } else { 651 /** 652 * $rm_tags_with_content 653 */ 654 if ($skip_content == false){ 655 /** 656 * See if this is a self-closing type and change 657 * tagtype appropriately. 658 */ 659 if ($tagtype == 1 660 && in_array($tagname, $self_closing_tags)){ 661 $tagtype = 3; 662 } 663 /** 664 * See if we should skip this tag and any content 665 * inside it. 666 */ 667 if ($tagtype == 1 668 && in_array($tagname, $rm_tags_with_content)){ 669 $skip_content = $tagname; 670 } else { 671 if (($rm_tags == false 672 && in_array($tagname, $tag_list)) || 673 ($rm_tags == true 674 && !in_array($tagname, $tag_list))){ 675 $tagname = false; 676 } else { 677 if ($tagtype == 1){ 678 if (isset($open_tags{$tagname})){ 679 $open_tags{$tagname}++; 680 } else { 681 $open_tags{$tagname} = 1; 682 } 683 } 684 /** 685 * This is where we run other checks. 686 */ 687 if (is_array($attary) && sizeof($attary) > 0){ 688 $attary = tln_fixatts($tagname, 689 $attary, 690 $rm_attnames, 691 $bad_attvals, 692 $add_attr_to_tag); 693 } 694 } 695 } 696 } else { 697 } 698 } 699 if ($tagname != false && $skip_content == false){ 700 $trusted .= tln_tagprint($tagname, $attary, $tagtype); 701 } 702 } else { 703 } 704 $curpos = $gt + 1; 705 } 706 $trusted .= substr($body, $curpos, strlen($body) - $curpos); 707 if ($force_tag_closing == true){ 708 foreach ($open_tags as $tagname=>$opentimes){ 709 while ($opentimes > 0){ 710 $trusted .= '</' . $tagname . '>'; 711 $opentimes--; 712 } 713 } 714 $trusted .= "\n"; 715 } 716 $trusted .= "<!-- end tln_sanitized html -->\n"; 717 return $trusted; 718 } 719 720 // 721 // Use the nifty htmlfilter library 722 // 723 724 725 function HTMLFilter($body, $trans_image_path, $block_external_images = false) { 726 727 $tag_list = Array( 728 false, 729 "object", 730 "meta", 731 "html", 732 "head", 733 "base", 734 "link", 735 "frame", 736 "iframe", 737 "plaintext", 738 "marquee" 739 ); 740 741 $rm_tags_with_content = Array( 742 "script", 743 "applet", 744 "embed", 745 "title", 746 "frameset", 747 "xmp", 748 "xml" 749 ); 750 751 $self_closing_tags = Array( 752 "img", 753 "br", 754 "hr", 755 "input", 756 "outbind" 757 ); 758 759 $force_tag_closing = true; 760 761 $rm_attnames = Array( 762 "/.*/" => 763 Array( 764 // "/target/i", 765 "/^on.*/i", 766 "/^dynsrc/i", 767 "/^data.*/i", 768 "/^lowsrc.*/i" 769 ) 770 ); 771 772 $bad_attvals = Array( 773 "/.*/" => 774 Array( 775 "/^src|background/i" => 776 Array( 777 Array( 778 "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si", 779 "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si", 780 "/^([\'\"])\s*about\s*:.*([\'\"])/si" 781 ), 782 Array( 783 "\\1$trans_image_path\\2", 784 "\\1$trans_image_path\\2", 785 "\\1$trans_image_path\\2", 786 "\\1$trans_image_path\\2" 787 ) 788 ), 789 "/^href|action/i" => 790 Array( 791 Array( 792 "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si", 793 "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si", 794 "/^([\'\"])\s*about\s*:.*([\'\"])/si" 795 ), 796 Array( 797 "\\1#\\1", 798 "\\1#\\1", 799 "\\1#\\1", 800 "\\1#\\1" 801 ) 802 ), 803 "/^style/i" => 804 Array( 805 Array( 806 "/expression/i", 807 "/binding/i", 808 "/behaviou*r/i", 809 "/include-source/i", 810 "/position\s*:\s*absolute/i", 811 "/url\s*\(\s*([\'\"])\s*\S+script\s*:.*([\'\"])\s*\)/si", 812 "/url\s*\(\s*([\'\"])\s*mocha\s*:.*([\'\"])\s*\)/si", 813 "/url\s*\(\s*([\'\"])\s*about\s*:.*([\'\"])\s*\)/si", 814 "/(.*)\s*:\s*url\s*\(\s*([\'\"]*)\s*\S+script\s*:.*([\'\"]*)\s*\)/si" 815 ), 816 Array( 817 "idiocy", 818 "idiocy", 819 "idiocy", 820 "idiocy", 821 "", 822 "url(\\1#\\1)", 823 "url(\\1#\\1)", 824 "url(\\1#\\1)", 825 "url(\\1#\\1)", 826 "url(\\1#\\1)", 827 "\\1:url(\\2#\\3)" 828 ) 829 ) 830 ) 831 ); 832 833 if ($block_external_images){ 834 array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[0], 835 '/^([\'\"])\s*https*:.*([\'\"])/si'); 836 array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[1], 837 "\\1$trans_image_path\\1"); 838 array_push($bad_attvals{'/.*/'}{'/^style/i'}[0], 839 '/url\(([\'\"])\s*https*:.*([\'\"])\)/si'); 840 array_push($bad_attvals{'/.*/'}{'/^style/i'}[1], 841 "url(\\1$trans_image_path\\1)"); 842 } 843 844 $add_attr_to_tag = Array( 845 "/^a$/i" => 846 Array('target'=>'"_blank"') 847 ); 848 849 $trusted = tln_sanitize($body, 850 $tag_list, 851 $rm_tags_with_content, 852 $self_closing_tags, 853 $force_tag_closing, 854 $rm_attnames, 855 $bad_attvals, 856 $add_attr_to_tag 857 ); 858 return $trusted; 859 } 860 861 ?> -
new file src/wp-includes/PHPMailer/extras/ntlm_sasl_client.php
diff --git src/wp-includes/PHPMailer/extras/ntlm_sasl_client.php src/wp-includes/PHPMailer/extras/ntlm_sasl_client.php new file mode 100644 index 0000000..b21ccce
- + 1 <?php 2 /* 3 * ntlm_sasl_client.php 4 * 5 * @(#) $Id: ntlm_sasl_client.php,v 1.3 2004/11/17 08:00:37 mlemos Exp $ 6 * 7 ** 8 ** Source: http://www.phpclasses.org/browse/file/7495.html 9 ** License: BSD (http://www.phpclasses.org/package/1888-PHP-Single-API-for-standard-authentication-mechanisms.html) 10 ** Bundled with Permission 11 ** 12 */ 13 14 define("SASL_NTLM_STATE_START", 0); 15 define("SASL_NTLM_STATE_IDENTIFY_DOMAIN", 1); 16 define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2); 17 define("SASL_NTLM_STATE_DONE", 3); 18 19 class ntlm_sasl_client_class 20 { 21 var $credentials=array(); 22 var $state=SASL_NTLM_STATE_START; 23 24 Function Initialize(&$client) 25 { 26 if(!function_exists($function="mcrypt_encrypt") 27 || !function_exists($function="mhash")) 28 { 29 $extensions=array( 30 "mcrypt_encrypt"=>"mcrypt", 31 "mhash"=>"mhash" 32 ); 33 $client->error="the extension ".$extensions[$function]." required by the NTLM SASL client class is not available in this PHP configuration"; 34 return(0); 35 } 36 return(1); 37 } 38 39 Function ASCIIToUnicode($ascii) 40 { 41 for($unicode="",$a=0;$a<strlen($ascii);$a++) 42 $unicode.=substr($ascii,$a,1).chr(0); 43 return($unicode); 44 } 45 46 Function TypeMsg1($domain,$workstation) 47 { 48 $domain_length=strlen($domain); 49 $workstation_length=strlen($workstation); 50 $workstation_offset=32; 51 $domain_offset=$workstation_offset+$workstation_length; 52 return( 53 "NTLMSSP\0". 54 "\x01\x00\x00\x00". 55 "\x07\x32\x00\x00". 56 pack("v",$domain_length). 57 pack("v",$domain_length). 58 pack("V",$domain_offset). 59 pack("v",$workstation_length). 60 pack("v",$workstation_length). 61 pack("V",$workstation_offset). 62 $workstation. 63 $domain 64 ); 65 } 66 67 Function NTLMResponse($challenge,$password) 68 { 69 $unicode=$this->ASCIIToUnicode($password); 70 $md4=mhash(MHASH_MD4,$unicode); 71 $padded=$md4.str_repeat(chr(0),21-strlen($md4)); 72 $iv_size=mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB); 73 $iv=mcrypt_create_iv($iv_size,MCRYPT_RAND); 74 for($response="",$third=0;$third<21;$third+=7) 75 { 76 for($packed="",$p=$third;$p<$third+7;$p++) 77 $packed.=str_pad(decbin(ord(substr($padded,$p,1))),8,"0",STR_PAD_LEFT); 78 for($key="",$p=0;$p<strlen($packed);$p+=7) 79 { 80 $s=substr($packed,$p,7); 81 $b=$s.((substr_count($s,"1") % 2) ? "0" : "1"); 82 $key.=chr(bindec($b)); 83 } 84 $ciphertext=mcrypt_encrypt(MCRYPT_DES,$key,$challenge,MCRYPT_MODE_ECB,$iv); 85 $response.=$ciphertext; 86 } 87 return $response; 88 } 89 90 Function TypeMsg3($ntlm_response,$user,$domain,$workstation) 91 { 92 $domain_unicode=$this->ASCIIToUnicode($domain); 93 $domain_length=strlen($domain_unicode); 94 $domain_offset=64; 95 $user_unicode=$this->ASCIIToUnicode($user); 96 $user_length=strlen($user_unicode); 97 $user_offset=$domain_offset+$domain_length; 98 $workstation_unicode=$this->ASCIIToUnicode($workstation); 99 $workstation_length=strlen($workstation_unicode); 100 $workstation_offset=$user_offset+$user_length; 101 $lm=""; 102 $lm_length=strlen($lm); 103 $lm_offset=$workstation_offset+$workstation_length; 104 $ntlm=$ntlm_response; 105 $ntlm_length=strlen($ntlm); 106 $ntlm_offset=$lm_offset+$lm_length; 107 $session=""; 108 $session_length=strlen($session); 109 $session_offset=$ntlm_offset+$ntlm_length; 110 return( 111 "NTLMSSP\0". 112 "\x03\x00\x00\x00". 113 pack("v",$lm_length). 114 pack("v",$lm_length). 115 pack("V",$lm_offset). 116 pack("v",$ntlm_length). 117 pack("v",$ntlm_length). 118 pack("V",$ntlm_offset). 119 pack("v",$domain_length). 120 pack("v",$domain_length). 121 pack("V",$domain_offset). 122 pack("v",$user_length). 123 pack("v",$user_length). 124 pack("V",$user_offset). 125 pack("v",$workstation_length). 126 pack("v",$workstation_length). 127 pack("V",$workstation_offset). 128 pack("v",$session_length). 129 pack("v",$session_length). 130 pack("V",$session_offset). 131 "\x01\x02\x00\x00". 132 $domain_unicode. 133 $user_unicode. 134 $workstation_unicode. 135 $lm. 136 $ntlm 137 ); 138 } 139 140 Function Start(&$client, &$message, &$interactions) 141 { 142 if($this->state!=SASL_NTLM_STATE_START) 143 { 144 $client->error="NTLM authentication state is not at the start"; 145 return(SASL_FAIL); 146 } 147 $this->credentials=array( 148 "user"=>"", 149 "password"=>"", 150 "realm"=>"", 151 "workstation"=>"" 152 ); 153 $defaults=array(); 154 $status=$client->GetCredentials($this->credentials,$defaults,$interactions); 155 if($status==SASL_CONTINUE) 156 $this->state=SASL_NTLM_STATE_IDENTIFY_DOMAIN; 157 Unset($message); 158 return($status); 159 } 160 161 Function Step(&$client, $response, &$message, &$interactions) 162 { 163 switch($this->state) 164 { 165 case SASL_NTLM_STATE_IDENTIFY_DOMAIN: 166 $message=$this->TypeMsg1($this->credentials["realm"],$this->credentials["workstation"]); 167 $this->state=SASL_NTLM_STATE_RESPOND_CHALLENGE; 168 break; 169 case SASL_NTLM_STATE_RESPOND_CHALLENGE: 170 $ntlm_response=$this->NTLMResponse(substr($response,24,8),$this->credentials["password"]); 171 $message=$this->TypeMsg3($ntlm_response,$this->credentials["user"],$this->credentials["realm"],$this->credentials["workstation"]); 172 $this->state=SASL_NTLM_STATE_DONE; 173 break; 174 case SASL_NTLM_STATE_DONE: 175 $client->error="NTLM authentication was finished without success"; 176 return(SASL_FAIL); 177 default: 178 $client->error="invalid NTLM authentication step state"; 179 return(SASL_FAIL); 180 } 181 return(SASL_CONTINUE); 182 } 183 }; 184 185 ?> 186 No newline at end of file -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-ar.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ar.php src/wp-includes/PHPMailer/language/phpmailer.lang-ar.php new file mode 100644 index 0000000..67364e9
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Arabic Version, UTF-8 5 * by : bahjat al mostafa <bahjat983@hotmail.com> 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP Error: لم نستطع تأكيد الهوية.'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP Error: لم نستطع الاتصال بمخدم SMTP.'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: لم يتم قبول المعلومات .'; 11 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 12 $PHPMAILER_LANG['encoding'] = 'ترميز غير معروف: '; 13 $PHPMAILER_LANG['execute'] = 'لم أستطع تنفيذ : '; 14 $PHPMAILER_LANG['file_access'] = 'لم نستطع الوصول للملف: '; 15 $PHPMAILER_LANG['file_open'] = 'File Error: لم نستطع فتح الملف: '; 16 $PHPMAILER_LANG['from_failed'] = 'البريد التالي لم نستطع ارسال البريد له : '; 17 $PHPMAILER_LANG['instantiate'] = 'لم نستطع توفير خدمة البريد.'; 18 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 19 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer غير مدعوم.'; 20 //$PHPMAILER_LANG['provide_address'] = 'You must provide at least one recipient email address.'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: الأخطاء التالية ' . 22 'فشل في الارسال لكل من : '; 23 $PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: '; 24 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 25 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 26 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-br.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-br.php src/wp-includes/PHPMailer/language/phpmailer.lang-br.php new file mode 100644 index 0000000..87ecbdf
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Portuguese Version 5 * By Paulo Henrique Garcia - paulo@controllerweb.com.br 6 * Edited by Lucas Guimarães - lucas@lucasguimaraes.com 7 */ 8 9 $PHPMAILER_LANG['authenticate'] = 'Erro de SMTP: Não foi possível autenticar.'; 10 $PHPMAILER_LANG['connect_host'] = 'Erro de SMTP: Não foi possível conectar com o servidor SMTP.'; 11 $PHPMAILER_LANG['data_not_accepted'] = 'Erro de SMTP: Dados rejeitados.'; 12 $PHPMAILER_LANG['empty_message'] = 'Corpo da mensagem vazio'; 13 $PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: '; 14 $PHPMAILER_LANG['execute'] = 'Não foi possível executar: '; 15 $PHPMAILER_LANG['file_access'] = 'Não foi possível acessar o arquivo: '; 16 $PHPMAILER_LANG['file_open'] = 'Erro de Arquivo: Não foi possível abrir o arquivo: '; 17 $PHPMAILER_LANG['from_failed'] = 'Os endereços dos remententes a seguir falharam: '; 18 $PHPMAILER_LANG['instantiate'] = 'Não foi possível iniciar uma instância da função mail.'; 19 $PHPMAILER_LANG['invalid_address'] = 'Não enviando, endereço de e-mail inválido: '; 20 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.'; 21 $PHPMAILER_LANG['provide_address'] = 'Você deve fornecer pelo menos um endereço de destinatário de e-mail.'; 22 $PHPMAILER_LANG['recipients_failed'] = 'Erro de SMTP: Os endereços de destinatário a seguir falharam: '; 23 $PHPMAILER_LANG['signing'] = 'Erro ao assinar: '; 24 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.'; 25 $PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: '; 26 $PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou resetar a variável: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-ca.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ca.php src/wp-includes/PHPMailer/language/phpmailer.lang-ca.php new file mode 100644 index 0000000..dc563e7
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Catalan Version 5 * By Ivan: web AT microstudi DOT com 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'Error SMTP: No s\'hapogut autenticar.'; 9 $PHPMAILER_LANG['connect_host'] = 'Error SMTP: No es pot connectar al servidor SMTP.'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Dades no acceptades.'; 11 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 12 $PHPMAILER_LANG['encoding'] = 'Codificació desconeguda: '; 13 $PHPMAILER_LANG['execute'] = 'No es pot executar: '; 14 $PHPMAILER_LANG['file_access'] = 'No es pot accedir a l\'arxiu: '; 15 $PHPMAILER_LANG['file_open'] = 'Error d\'Arxiu: No es pot obrir l\'arxiu: '; 16 $PHPMAILER_LANG['from_failed'] = 'La(s) següent(s) adreces de remitent han fallat: '; 17 $PHPMAILER_LANG['instantiate'] = 'No s\'ha pogut crear una instància de la funció Mail.'; 18 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 19 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer no està suportat'; 20 $PHPMAILER_LANG['provide_address'] = 'S\'ha de proveir almenys una adreça d\'email com a destinatari.'; 21 $PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Els següents destinataris han fallat: '; 22 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 23 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 24 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 25 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-ch.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ch.php src/wp-includes/PHPMailer/language/phpmailer.lang-ch.php new file mode 100644 index 0000000..d28eba6
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Chinese Version 5 * By LiuXin: www.80x86.cn/blog/ 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP 错误:身份验证失败。'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP 错误: 不能连接SMTP主机。'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误: 数据不可接受。'; 11 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 12 $PHPMAILER_LANG['encoding'] = '未知编码:'; 13 $PHPMAILER_LANG['execute'] = '不能执行: '; 14 $PHPMAILER_LANG['file_access'] = '不能访问文件:'; 15 $PHPMAILER_LANG['file_open'] = '文件错误:不能打开文件:'; 16 $PHPMAILER_LANG['from_failed'] = '下面的发送地址邮件发送失败了: '; 17 $PHPMAILER_LANG['instantiate'] = '不能实现mail方法。'; 18 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 19 $PHPMAILER_LANG['mailer_not_supported'] = ' 您所选择的发送邮件的方法并不支持。'; 20 $PHPMAILER_LANG['provide_address'] = '您必须提供至少一个 收信人的email地址。'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误: 下面的 收件人失败了: '; 22 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 23 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 24 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 25 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-cz.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-cz.php src/wp-includes/PHPMailer/language/phpmailer.lang-cz.php new file mode 100644 index 0000000..6da3bd8
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Czech Version 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'Chyba SMTP: Autentizace selhala.'; 8 $PHPMAILER_LANG['connect_host'] = 'Chyba SMTP: Nelze navázat spojení se SMTP serverem.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'Chyba SMTP: Data nebyla přijata.'; 10 $PHPMAILER_LANG['empty_message'] = 'Prázdné tělo zprávy'; 11 $PHPMAILER_LANG['encoding'] = 'Neznámé kódování: '; 12 $PHPMAILER_LANG['execute'] = 'Nelze provést: '; 13 $PHPMAILER_LANG['file_access'] = 'Nelze získat přístup k souboru: '; 14 $PHPMAILER_LANG['file_open'] = 'Chyba souboru: Nelze otevřít soubor pro čtení: '; 15 $PHPMAILER_LANG['from_failed'] = 'Následující adresa odesílatele je nesprávná: '; 16 $PHPMAILER_LANG['instantiate'] = 'Nelze vytvořit instanci emailové funkce.'; 17 $PHPMAILER_LANG['invalid_address'] = 'Neplatná adresa: '; 18 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer není podporován.'; 19 $PHPMAILER_LANG['provide_address'] = 'Musíte zadat alespoň jednu emailovou adresu příjemce.'; 20 $PHPMAILER_LANG['recipients_failed'] = 'Chyba SMTP: Následující adresy příjemců nejsou správně: '; 21 $PHPMAILER_LANG['signing'] = 'Chyba přihlašování: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() selhal.'; 23 $PHPMAILER_LANG['smtp_error'] = 'Chyba SMTP serveru: '; 24 $PHPMAILER_LANG['variable_set'] = 'Nelze nastavit nebo změnit proměnnou: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-de.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-de.php src/wp-includes/PHPMailer/language/phpmailer.lang-de.php new file mode 100644 index 0000000..ba17a92
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * German Version 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'SMTP Fehler: Authentifizierung fehlgeschlagen.'; 8 $PHPMAILER_LANG['connect_host'] = 'SMTP Fehler: Konnte keine Verbindung zum SMTP-Host herstellen.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Fehler: Daten werden nicht akzeptiert.'; 10 $PHPMAILER_LANG['empty_message'] = 'E-Mail Inhalt ist leer.'; 11 $PHPMAILER_LANG['encoding'] = 'Unbekanntes Encoding-Format: '; 12 $PHPMAILER_LANG['execute'] = 'Konnte folgenden Befehl nicht ausführen: '; 13 $PHPMAILER_LANG['file_access'] = 'Zugriff auf folgende Datei fehlgeschlagen: '; 14 $PHPMAILER_LANG['file_open'] = 'Datei Fehler: konnte folgende Datei nicht öffnen: '; 15 $PHPMAILER_LANG['from_failed'] = 'Die folgende Absenderadresse ist nicht korrekt: '; 16 $PHPMAILER_LANG['instantiate'] = 'Mail Funktion konnte nicht initialisiert werden.'; 17 $PHPMAILER_LANG['invalid_address'] = 'E-Mail wird nicht gesendet, die Adresse ist ungültig.'; 18 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer wird nicht unterstützt.'; 19 $PHPMAILER_LANG['provide_address'] = 'Bitte geben Sie mindestens eine Empfänger E-Mailadresse an.'; 20 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Fehler: Die folgenden Empfänger sind nicht korrekt: '; 21 $PHPMAILER_LANG['signing'] = 'Fehler beim Signieren: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'Verbindung zu SMTP Server fehlgeschlagen.'; 23 $PHPMAILER_LANG['smtp_error'] = 'Fehler vom SMTP Server: '; 24 $PHPMAILER_LANG['variable_set'] = 'Kann Variable nicht setzen oder zurücksetzen: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-dk.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-dk.php src/wp-includes/PHPMailer/language/phpmailer.lang-dk.php new file mode 100644 index 0000000..fdb0b17
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Danish Version 5 * Author: Mikael Stokkebro <info@stokkebro.dk> 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Kunne ikke logge på.'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data kunne ikke accepteres.'; 11 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 12 $PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: '; 13 $PHPMAILER_LANG['execute'] = 'Kunne ikke køre: '; 14 $PHPMAILER_LANG['file_access'] = 'Ingen adgang til fil: '; 15 $PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: '; 16 $PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: '; 17 $PHPMAILER_LANG['instantiate'] = 'Kunne ikke initialisere email funktionen.'; 18 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 19 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.'; 20 $PHPMAILER_LANG['provide_address'] = 'Du skal indtaste mindst en modtagers emailadresse.'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: '; 22 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 23 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 24 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 25 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-eo.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-eo.php src/wp-includes/PHPMailer/language/phpmailer.lang-eo.php new file mode 100644 index 0000000..799b331
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Esperanto version 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'Eraro de servilo SMTP : aŭtentigo malsukcesis.'; 8 $PHPMAILER_LANG['connect_host'] = 'Eraro de servilo SMTP : konektado al servilo malsukcesis.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'Eraro de servilo SMTP : neĝustaj datumoj.'; 10 $PHPMAILER_LANG['empty_message'] = 'Teksto de mesaĝo mankas.'; 11 $PHPMAILER_LANG['encoding'] = 'Nekonata kodoprezento: '; 12 $PHPMAILER_LANG['execute'] = 'Lanĉi rulumadon ne eblis: '; 13 $PHPMAILER_LANG['file_access'] = 'Aliro al dosiero ne sukcesis: '; 14 $PHPMAILER_LANG['file_open'] = 'Eraro de dosiero: malfermo neeblas: '; 15 $PHPMAILER_LANG['from_failed'] = 'Jena adreso de sendinto malsukcesis: '; 16 $PHPMAILER_LANG['instantiate'] = 'Genero de retmesaĝa funkcio neeblis.'; 17 $PHPMAILER_LANG['invalid_address'] = 'Retadreso ne validas: '; 18 $PHPMAILER_LANG['mailer_not_supported'] = ' mesaĝilo ne subtenata.'; 19 $PHPMAILER_LANG['provide_address'] = 'Vi devas tajpi almenaŭ unu recevontan retadreson.'; 20 $PHPMAILER_LANG['recipients_failed'] = 'Eraro de servilo SMTP : la jenaj poŝtrecivuloj kaŭzis eraron: '; 21 $PHPMAILER_LANG['signing'] = 'Eraro de subskribo: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP konektado malsukcesis.'; 23 $PHPMAILER_LANG['smtp_error'] = 'Eraro de servilo SMTP : '; 24 $PHPMAILER_LANG['variable_set'] = 'Variablo ne pravalorizeblas aŭ ne repravalorizeblas: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-es.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-es.php src/wp-includes/PHPMailer/language/phpmailer.lang-es.php new file mode 100644 index 0000000..b81520f
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Spanish version 5 * Versión en español 6 * Edited by Matt Sturdy - matt.sturdy@gmail.com 7 */ 8 9 $PHPMAILER_LANG['authenticate'] = 'Error SMTP: No se pudo autentificar.'; 10 $PHPMAILER_LANG['connect_host'] = 'Error SMTP: No se pudo conectar al servidor SMTP.'; 11 $PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.'; 12 $PHPMAILER_LANG['empty_message'] = 'Cuerpo del mensaje vacío'; 13 $PHPMAILER_LANG['encoding'] = 'Codificación desconocida: '; 14 $PHPMAILER_LANG['execute'] = 'No se pudo ejecutar: '; 15 $PHPMAILER_LANG['file_access'] = 'No se pudo acceder al archivo: '; 16 $PHPMAILER_LANG['file_open'] = 'Error de Archivo: No se pudo abrir el archivo: '; 17 $PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: '; 18 $PHPMAILER_LANG['instantiate'] = 'No se pudo crear una instancia de la función Mail.'; 19 $PHPMAILER_LANG['invalid_address'] = 'No se pudo enviar: dirección de email inválido: '; 20 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.'; 21 $PHPMAILER_LANG['provide_address'] = 'Debe proveer al menos una dirección de email como destino.'; 22 $PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Los siguientes destinos fallaron: '; 23 $PHPMAILER_LANG['signing'] = 'Error al firmar: '; 24 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() se falló.'; 25 $PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: '; 26 $PHPMAILER_LANG['variable_set'] = 'No se pudo ajustar o reajustar la variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-et.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-et.php src/wp-includes/PHPMailer/language/phpmailer.lang-et.php new file mode 100644 index 0000000..eee4e58
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Estonian Version 5 * By Indrek Päri 6 * Revised By Elan Ruusamäe <glen@delfi.ee> 7 */ 8 9 $PHPMAILER_LANG['authenticate'] = 'SMTP Viga: Autoriseerimise viga.'; 10 $PHPMAILER_LANG['connect_host'] = 'SMTP Viga: Ei õnnestunud luua ühendust SMTP serveriga.'; 11 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Viga: Vigased andmed.'; 12 $PHPMAILER_LANG['empty_message'] = 'Tühi kirja sisu'; 13 $PHPMAILER_LANG["encoding"] = 'Tundmatu kodeering: '; 14 $PHPMAILER_LANG['execute'] = 'Tegevus ebaõnnestus: '; 15 $PHPMAILER_LANG['file_access'] = 'Pole piisavalt õiguseid järgneva faili avamiseks: '; 16 $PHPMAILER_LANG['file_open'] = 'Faili Viga: Faili avamine ebaõnnestus: '; 17 $PHPMAILER_LANG['from_failed'] = 'Järgnev saatja e-posti aadress on vigane: '; 18 $PHPMAILER_LANG['instantiate'] = 'mail funktiooni käivitamine ebaõnnestus.'; 19 $PHPMAILER_LANG['invalid_address'] = 'Saatmine peatatud, e-posti address vigane: '; 20 $PHPMAILER_LANG['provide_address'] = 'Te peate määrama vähemalt ühe saaja e-posti aadressi.'; 21 $PHPMAILER_LANG['mailer_not_supported'] = ' maileri tugi puudub.'; 22 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Viga: Järgnevate saajate e-posti aadressid on vigased: '; 23 $PHPMAILER_LANG["signing"] = 'Viga allkirjastamisel: '; 24 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() ebaõnnestus.'; 25 $PHPMAILER_LANG['smtp_error'] = 'SMTP serveri viga: '; 26 $PHPMAILER_LANG['variable_set'] = 'Ei õnnestunud määrata või lähtestada muutujat: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-fa.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-fa.php src/wp-includes/PHPMailer/language/phpmailer.lang-fa.php new file mode 100644 index 0000000..49aad1b
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Persian/Farsi Version, UTF-8 5 * By: Ali Jazayeri <jaza.ali@gmail.com> 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP Error: احراز هویت با شکست مواجه شد.'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP Error: اتصال به سرور SMTP برقرار نشد.'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: داده ها نادرست هستند.'; 11 $PHPMAILER_LANG['empty_message'] = 'بخش متن پیام خالی است.'; 12 $PHPMAILER_LANG['encoding'] = 'رمزگذاری ناشناخته: '; 13 $PHPMAILER_LANG['execute'] = 'امکان اجرا وجود ندارد: '; 14 $PHPMAILER_LANG['file_access'] = 'امکان دسترسی به فایل وجود ندارد: '; 15 $PHPMAILER_LANG['file_open'] = 'File Error: امکان بازکردن فایل وجود ندارد: '; 16 $PHPMAILER_LANG['from_failed'] = 'آدرس فرستنده اشتباه است: '; 17 $PHPMAILER_LANG['instantiate'] = 'امکان معرفی تابع ایمیل وجود ندارد.'; 18 $PHPMAILER_LANG['invalid_address'] = 'آدرس ایمیل معتبر نیست: '; 19 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer پشتیبانی نمی شود.'; 20 $PHPMAILER_LANG['provide_address'] = 'باید حداقل یک آدرس گیرنده وارد کنید.'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: ارسال به آدرس گیرنده با خطا مواجه شد: '; 22 $PHPMAILER_LANG['signing'] = 'خطا در امضا: '; 23 $PHPMAILER_LANG['smtp_connect_failed'] = 'خطا در اتصال به SMTP.'; 24 $PHPMAILER_LANG['smtp_error'] = 'خطا در SMTP Server: '; 25 $PHPMAILER_LANG['variable_set'] = 'امکان ارسال یا ارسال مجدد متغیرها وجود ندارد: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-fi.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-fi.php src/wp-includes/PHPMailer/language/phpmailer.lang-fi.php new file mode 100644 index 0000000..16a02e1
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Finnish Version 5 * By Jyry Kuukanen 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP-virhe: käyttäjätunnistus epäonnistui.'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP-virhe: yhteys palvelimeen ei onnistu.'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP-virhe: data on virheellinen.'; 11 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 12 $PHPMAILER_LANG['encoding'] = 'Tuntematon koodaustyyppi: '; 13 $PHPMAILER_LANG['execute'] = 'Suoritus epäonnistui: '; 14 $PHPMAILER_LANG['file_access'] = 'Seuraavaan tiedostoon ei ole oikeuksia: '; 15 $PHPMAILER_LANG['file_open'] = 'Tiedostovirhe: Ei voida avata tiedostoa: '; 16 $PHPMAILER_LANG['from_failed'] = 'Seuraava lähettäjän osoite on virheellinen: '; 17 $PHPMAILER_LANG['instantiate'] = 'mail-funktion luonti epäonnistui.'; 18 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 19 $PHPMAILER_LANG['mailer_not_supported'] = 'postivälitintyyppiä ei tueta.'; 20 $PHPMAILER_LANG['provide_address'] = 'Aseta vähintään yksi vastaanottajan sähköpostiosoite.'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.'; 22 $PHPMAILER_LANG['encoding'] = 'Tuntematon koodaustyyppi: '; 23 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 24 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 25 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 26 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-fo.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-fo.php src/wp-includes/PHPMailer/language/phpmailer.lang-fo.php new file mode 100644 index 0000000..fc5d6d5
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Faroese Version [language of the Faroe Islands, a Danish dominion] 5 * This file created: 11-06-2004 6 * Supplied by Dávur Sørensen [www.profo-webdesign.dk] 7 */ 8 9 $PHPMAILER_LANG['authenticate'] = 'SMTP feilur: Kundi ikki góðkenna.'; 10 $PHPMAILER_LANG['connect_host'] = 'SMTP feilur: Kundi ikki knýta samband við SMTP vert.'; 11 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP feilur: Data ikki góðkent.'; 12 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 13 $PHPMAILER_LANG['encoding'] = 'Ókend encoding: '; 14 $PHPMAILER_LANG['execute'] = 'Kundi ikki útføra: '; 15 $PHPMAILER_LANG['file_access'] = 'Kundi ikki tilganga fílu: '; 16 $PHPMAILER_LANG['file_open'] = 'Fílu feilur: Kundi ikki opna fílu: '; 17 $PHPMAILER_LANG['from_failed'] = 'fylgjandi Frá/From adressa miseydnaðist: '; 18 $PHPMAILER_LANG['instantiate'] = 'Kuni ikki instantiera mail funktión.'; 19 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 20 $PHPMAILER_LANG['mailer_not_supported'] = ' er ikki supporterað.'; 21 $PHPMAILER_LANG['provide_address'] = 'Tú skal uppgeva minst móttakara-emailadressu(r).'; 22 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Feilur: Fylgjandi móttakarar miseydnaðust: '; 23 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 24 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 25 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 26 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-fr.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-fr.php src/wp-includes/PHPMailer/language/phpmailer.lang-fr.php new file mode 100644 index 0000000..2d23cf5
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * French Version 5 * Some French punctuation requires a thin non-breaking space (U+202F) character before it, 6 * for example before a colon or exclamation mark. 7 * There is one of these characters between these quotes: " " 8 * @link http://unicode.org/udhr/n/notes_fra.html 9 * 10 */ 11 12 $PHPMAILER_LANG['authenticate'] = 'Erreur SMTP : échec de l\'authentification.'; 13 $PHPMAILER_LANG['connect_host'] = 'Erreur SMTP : impossible de se connecter au serveur SMTP.'; 14 $PHPMAILER_LANG['data_not_accepted'] = 'Erreur SMTP : données incorrectes.'; 15 $PHPMAILER_LANG['empty_message'] = 'Corps de message vide.'; 16 $PHPMAILER_LANG['encoding'] = 'Encodage inconnu : '; 17 $PHPMAILER_LANG['execute'] = 'Impossible de lancer l\'exécution : '; 18 $PHPMAILER_LANG['file_access'] = 'Impossible d\'accéder au fichier : '; 19 $PHPMAILER_LANG['file_open'] = 'Erreur de fichier : ouverture impossible : '; 20 $PHPMAILER_LANG['from_failed'] = 'L\'adresse d\'expéditeur suivante a échouée : '; 21 $PHPMAILER_LANG['instantiate'] = 'Impossible d\'instancier la fonction mail.'; 22 $PHPMAILER_LANG['invalid_address'] = 'L\'adresse courriel n\'est pas valide : '; 23 $PHPMAILER_LANG['mailer_not_supported'] = ' client de messagerie non supporté.'; 24 $PHPMAILER_LANG['provide_address'] = 'Vous devez fournir au moins une adresse de destinataire.'; 25 $PHPMAILER_LANG['recipients_failed'] = 'Erreur SMTP : les destinataires suivants sont en erreur : '; 26 $PHPMAILER_LANG['signing'] = 'Erreur de signature : '; 27 $PHPMAILER_LANG['smtp_connect_failed'] = 'Échec de la connexion SMTP.'; 28 $PHPMAILER_LANG['smtp_error'] = 'Erreur du serveur SMTP : '; 29 $PHPMAILER_LANG['variable_set'] = 'Ne peut initialiser ou réinitialiser une variable : '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-he.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-he.php src/wp-includes/PHPMailer/language/phpmailer.lang-he.php new file mode 100644 index 0000000..e30b596
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Hebrew Version, UTF-8 5 * by : Ronny Sherer <ronny@hoojima.com> 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'שגיאת SMTP: פעולת האימות נכשלה.'; 9 $PHPMAILER_LANG['connect_host'] = 'שגיאת SMTP: לא הצלחתי להתחבר לשרת SMTP.'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'שגיאת SMTP: מידע לא התקבל.'; 11 $PHPMAILER_LANG['empty_message'] = 'גוף ההודעה ריק'; 12 $PHPMAILER_LANG['invalid_address'] = 'כתובת שגויה'; 13 $PHPMAILER_LANG['encoding'] = 'קידוד לא מוכר: '; 14 $PHPMAILER_LANG['execute'] = 'לא הצלחתי להפעיל את: '; 15 $PHPMAILER_LANG['file_access'] = 'לא ניתן לגשת לקובץ: '; 16 $PHPMAILER_LANG['file_open'] = 'שגיאת קובץ: לא ניתן לגשת לקובץ: '; 17 $PHPMAILER_LANG['from_failed'] = 'כתובות הנמענים הבאות נכשלו: '; 18 $PHPMAILER_LANG['instantiate'] = 'לא הצלחתי להפעיל את פונקציית המייל.'; 19 $PHPMAILER_LANG['mailer_not_supported'] = ' אינה נתמכת.'; 20 $PHPMAILER_LANG['provide_address'] = 'חובה לספק לפחות כתובת אחת של מקבל המייל.'; 21 $PHPMAILER_LANG['recipients_failed'] = 'שגיאת SMTP: הנמענים הבאים נכשלו: '; 22 $PHPMAILER_LANG['signing'] = 'שגיאת חתימה: '; 23 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 24 $PHPMAILER_LANG['smtp_error'] = 'שגיאת שרת SMTP: '; 25 $PHPMAILER_LANG['variable_set'] = 'לא ניתן לקבוע או לשנות את המשתנה: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-hu.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-hu.php src/wp-includes/PHPMailer/language/phpmailer.lang-hu.php new file mode 100644 index 0000000..d8d1926
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Hungarian Version by @dominicus-75 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'SMTP hiba: az azonosítás sikertelen.'; 8 $PHPMAILER_LANG['connect_host'] = 'SMTP hiba: nem lehet kapcsolódni az SMTP-szerverhez.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP hiba: adatok visszautasítva.'; 10 $PHPMAILER_LANG['empty_message'] = 'Üres az üzenettörzs.'; 11 $PHPMAILER_LANG['encoding'] = 'Ismeretlen kódolás: '; 12 $PHPMAILER_LANG['execute'] = 'Nem lehet végrehajtani: '; 13 $PHPMAILER_LANG['file_access'] = 'A következő fájl nem elérhető: '; 14 $PHPMAILER_LANG['file_open'] = 'Fájl hiba: a következő fájlt nem lehet megnyitni: '; 15 $PHPMAILER_LANG['from_failed'] = 'A feladóként megadott következő cím hibás: '; 16 $PHPMAILER_LANG['instantiate'] = 'A PHP mail() függvényt nem sikerült végrehajtani.'; 17 $PHPMAILER_LANG['invalid_address'] = 'Érvénytelen cím: '; 18 $PHPMAILER_LANG['mailer_not_supported'] = ' a mailer-osztály nem támogatott.'; 19 $PHPMAILER_LANG['provide_address'] = 'Legalább egy címzettet fel kell tüntetni.'; 20 $PHPMAILER_LANG['recipients_failed'] = 'SMTP hiba: a címzettként megadott következő címek hibásak: '; 21 $PHPMAILER_LANG['signing'] = 'Hibás aláírás: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'Hiba az SMTP-kapcsolatban.'; 23 $PHPMAILER_LANG['smtp_error'] = 'SMTP-szerver hiba: '; 24 $PHPMAILER_LANG['variable_set'] = 'A következő változók beállítása nem sikerült: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-it.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-it.php src/wp-includes/PHPMailer/language/phpmailer.lang-it.php new file mode 100644 index 0000000..27ab0ea
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Italian version 5 * @package PHPMailer 6 * @author Ilias Bartolini <brain79@inwind.it>, Stefano Sabatini <sabas88@gmail.com> 7 */ 8 9 $PHPMAILER_LANG['authenticate'] = 'SMTP Error: Impossibile autenticarsi.'; 10 $PHPMAILER_LANG['connect_host'] = 'SMTP Error: Impossibile connettersi all\'host SMTP.'; 11 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Dati non accettati dal server.'; 12 $PHPMAILER_LANG['empty_message'] = 'Il corpo del messaggio è vuoto'; 13 $PHPMAILER_LANG['encoding'] = 'Codifica dei caratteri sconosciuta: '; 14 $PHPMAILER_LANG['execute'] = 'Impossibile eseguire l\'operazione: '; 15 $PHPMAILER_LANG['file_access'] = 'Impossibile accedere al file: '; 16 $PHPMAILER_LANG['file_open'] = 'File Error: Impossibile aprire il file: '; 17 $PHPMAILER_LANG['from_failed'] = 'I seguenti indirizzi mittenti hanno generato errore: '; 18 $PHPMAILER_LANG['instantiate'] = 'Impossibile istanziare la funzione mail'; 19 $PHPMAILER_LANG['invalid_address'] = 'Impossibile inviare, l\'indirizzo email non è valido: '; 20 $PHPMAILER_LANG['provide_address'] = 'Deve essere fornito almeno un indirizzo ricevente'; 21 $PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato'; 22 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: I seguenti indirizzi destinatari hanno generato un errore: '; 23 $PHPMAILER_LANG['signing'] = 'Errore nella firma: '; 24 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fallita.'; 25 $PHPMAILER_LANG['smtp_error'] = 'Errore del server SMTP: '; 26 $PHPMAILER_LANG['variable_set'] = 'Impossibile impostare o resettare la variabile: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-ja.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ja.php src/wp-includes/PHPMailer/language/phpmailer.lang-ja.php new file mode 100644 index 0000000..ca6de90
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Japanese Version 5 * By Mitsuhiro Yoshida - http://mitstek.com/ 6 * Modified by Yoshi Sakai - http://bluemooninc.jp/ 7 */ 8 9 $PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。'; 10 $PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。'; 11 $PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。'; 12 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 13 $PHPMAILER_LANG['encoding'] = '不明なエンコーディング: '; 14 $PHPMAILER_LANG['execute'] = '実行できませんでした: '; 15 $PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: '; 16 $PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: '; 17 $PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: '; 18 $PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。'; 19 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 20 $PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。'; 21 $PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。'; 22 $PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: '; 23 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 24 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 25 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 26 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-lt.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-lt.php src/wp-includes/PHPMailer/language/phpmailer.lang-lt.php new file mode 100644 index 0000000..5dba58a
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Lithuanian version by Dainius Kaupaitis <dk@sum.lt> 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'SMTP klaida: autentifikacija nepavyko.'; 8 $PHPMAILER_LANG['connect_host'] = 'SMTP klaida: nepavyksta prisijungti prie SMTP stoties.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP klaida: duomenys nepriimti.'; 10 $PHPMAILER_LANG['empty_message'] = 'Laiško turinys tuščias'; 11 $PHPMAILER_LANG['encoding'] = 'Neatpažinta koduotė: '; 12 $PHPMAILER_LANG['execute'] = 'Nepavyko įvykdyti komandos: '; 13 $PHPMAILER_LANG['file_access'] = 'Byla nepasiekiama: '; 14 $PHPMAILER_LANG['file_open'] = 'Bylos klaida: Nepavyksta atidaryti: '; 15 $PHPMAILER_LANG['from_failed'] = 'Neteisingas siuntėjo adresas: '; 16 $PHPMAILER_LANG['instantiate'] = 'Nepavyko paleisti mail funkcijos.'; 17 $PHPMAILER_LANG['invalid_address'] = 'Neteisingas adresas'; 18 $PHPMAILER_LANG['mailer_not_supported'] = ' pašto stotis nepalaikoma.'; 19 $PHPMAILER_LANG['provide_address'] = 'Nurodykite bent vieną gavėjo adresą.'; 20 $PHPMAILER_LANG['recipients_failed'] = 'SMTP klaida: nepavyko išsiųsti šiems gavėjams: '; 21 $PHPMAILER_LANG['signing'] = 'Prisijungimo klaida: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP susijungimo klaida'; 23 $PHPMAILER_LANG['smtp_error'] = 'SMTP stoties klaida: '; 24 $PHPMAILER_LANG['variable_set'] = 'Nepavyko priskirti reikšmės kintamajam: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-nl.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-nl.php src/wp-includes/PHPMailer/language/phpmailer.lang-nl.php new file mode 100644 index 0000000..c86d769
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to class.phpmailer.php for definitive list. 4 * Dutch Version by Tuxion <team@tuxion.nl> 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'SMTP-fout: authenticatie mislukt.';//SMTP Error: Could not authenticate. 8 $PHPMAILER_LANG['connect_host'] = 'SMTP-fout: kon niet verbinden met SMTP-host.';//SMTP Error: Could not connect to SMTP host. 9 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP-fout: data niet geaccepteerd.';//SMTP Error: Data not accepted. 10 $PHPMAILER_LANG['empty_message'] = 'Berichttekst is leeg';//Message body empty 11 $PHPMAILER_LANG['encoding'] = 'Onbekende codering: ';//Unknown encoding: 12 $PHPMAILER_LANG['execute'] = 'Kon niet uitvoeren: ';//Could not execute: 13 $PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: ';//Could not access file: 14 $PHPMAILER_LANG['file_open'] = 'Bestandsfout: kon bestand niet openen: ';//File Error: Could not open file: 15 $PHPMAILER_LANG['from_failed'] = 'Het volgende afzendersadres is mislukt: ';//The following From address failed: 16 $PHPMAILER_LANG['instantiate'] = 'Kon mailfunctie niet initialiseren.';//Could not instantiate mail function. 17 $PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres';//Invalid address 18 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';// mailer is not supported. 19 $PHPMAILER_LANG['provide_address'] = 'Er moet minstens één ontvanger worden opgegeven.';//You must provide at least one recipient email address. 20 $PHPMAILER_LANG['recipients_failed'] = 'SMTP-fout: de volgende ontvangers zijn mislukt: ';//SMTP Error: The following recipients failed: 21 $PHPMAILER_LANG['signing'] = 'Signeerfout: ';//Signing Error: 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Verbinding mislukt.'; 23 $PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfout: ';//SMTP server error: 24 $PHPMAILER_LANG['variable_set'] = 'Kan de volgende variablen niet instellen of resetten: ';//Cannot set or reset variable: -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-no.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-no.php src/wp-includes/PHPMailer/language/phpmailer.lang-no.php new file mode 100644 index 0000000..e697520
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Norwegian Version 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'SMTP Feil: Kunne ikke authentisere.'; 8 $PHPMAILER_LANG['connect_host'] = 'SMTP Feil: Kunne ikke koble til SMTP host.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Feil: Data ble ikke akseptert.'; 10 $PHPMAILER_LANG['empty_message'] = 'Meldingsinnholdet er tomt'; 11 $PHPMAILER_LANG['encoding'] = 'Ukjent tegnkoding: '; 12 $PHPMAILER_LANG['execute'] = 'Kunne ikke utføre: '; 13 $PHPMAILER_LANG['file_access'] = 'Får ikke tilgang til filen: '; 14 $PHPMAILER_LANG['file_open'] = 'Fil feil: Kunne ikke åpne filen: '; 15 $PHPMAILER_LANG['from_failed'] = 'Følgende avsenderadresse feilet: '; 16 $PHPMAILER_LANG['instantiate'] = 'Kunne ikke initialisere mailfunksjonen.'; 17 $PHPMAILER_LANG['invalid_address'] = 'Meldingen ble ikke sendt, følgende adresse er ugyldig: '; 18 $PHPMAILER_LANG['provide_address'] = 'Du må angi minst en mottakeradresse.'; 19 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer er ikke supportert.'; 20 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Feil: Følgende mottagere feilet: '; 21 $PHPMAILER_LANG['signing'] = 'Signeringsfeil: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() feilet.'; 23 $PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfeil: '; 24 $PHPMAILER_LANG['variable_set'] = 'Kan ikke sette eller resette variabelen: '; 25 No newline at end of file -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-pl.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-pl.php src/wp-includes/PHPMailer/language/phpmailer.lang-pl.php new file mode 100644 index 0000000..5a4ad38
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Polish Version 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzić autentykacji.'; 8 $PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.'; 10 $PHPMAILER_LANG['empty_message'] = 'Wiadomość jest pusta.'; 11 $PHPMAILER_LANG['encoding'] = 'Nieznany sposób kodowania znaków: '; 12 $PHPMAILER_LANG['execute'] = 'Nie można uruchomić: '; 13 $PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: '; 14 $PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: '; 15 $PHPMAILER_LANG['from_failed'] = 'Następujący adres Nadawcy jest nieprawidłowy: '; 16 $PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.'; 17 $PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, następujący adres Odbiorcy jest nieprawidłowy: '; 18 $PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email Odbiorcy.'; 19 $PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.'; 20 $PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi: '; 21 $PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() zakończone niepowodzeniem.'; 23 $PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: '; 24 $PHPMAILER_LANG['variable_set'] = 'Nie można zmienić zmiennej: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-ro.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ro.php src/wp-includes/PHPMailer/language/phpmailer.lang-ro.php new file mode 100644 index 0000000..1727cef
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Romanian Version 5 * @package PHPMailer 6 * @author Catalin Constantin <catalin@dazoot.ro> 7 */ 8 9 $PHPMAILER_LANG['authenticate'] = 'Eroare SMTP: Nu a functionat autentificarea.'; 10 $PHPMAILER_LANG['connect_host'] = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.'; 11 $PHPMAILER_LANG['data_not_accepted'] = 'Eroare SMTP: Continutul mailului nu a fost acceptat.'; 12 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 13 $PHPMAILER_LANG['encoding'] = 'Encodare necunoscuta: '; 14 $PHPMAILER_LANG['execute'] = 'Nu pot executa: '; 15 $PHPMAILER_LANG['file_access'] = 'Nu pot accesa fisierul: '; 16 $PHPMAILER_LANG['file_open'] = 'Eroare de fisier: Nu pot deschide fisierul: '; 17 $PHPMAILER_LANG['from_failed'] = 'Urmatoarele adrese From au dat eroare: '; 18 $PHPMAILER_LANG['instantiate'] = 'Nu am putut instantia functia mail.'; 19 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 20 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.'; 21 $PHPMAILER_LANG['provide_address'] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).'; 22 $PHPMAILER_LANG['recipients_failed'] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: '; 23 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 24 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 25 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 26 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-ru.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ru.php src/wp-includes/PHPMailer/language/phpmailer.lang-ru.php new file mode 100644 index 0000000..9e583da
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Russian Version by Alexey Chumakov <alex@chumakov.ru> 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.'; 8 $PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к серверу SMTP.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не приняты.'; 10 $PHPMAILER_LANG['encoding'] = 'Неизвестный вид кодировки: '; 11 $PHPMAILER_LANG['execute'] = 'Невозможно выполнить команду: '; 12 $PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: '; 13 $PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удается открыть файл: '; 14 $PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: '; 15 $PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail.'; 16 $PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.'; 17 $PHPMAILER_LANG['mailer_not_supported'] = ' - почтовый сервер не поддерживается.'; 18 $PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: '; 19 $PHPMAILER_LANG['empty_message'] = 'Пустое тело сообщения'; 20 $PHPMAILER_LANG['invalid_address'] = 'Не отослано, неправильный формат email адреса: '; 21 $PHPMAILER_LANG['signing'] = 'Ошибка подписывания: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером'; 23 $PHPMAILER_LANG['smtp_error'] = 'Ошибка SMTP-сервера: '; 24 $PHPMAILER_LANG['variable_set'] = 'Невозможно установить или переустановить переменную: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-se.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-se.php src/wp-includes/PHPMailer/language/phpmailer.lang-se.php new file mode 100644 index 0000000..65d1979
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Swedish Version 5 * Author: Johan Linnér <johan@linner.biz> 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP fel: Kunde inte autentisera.'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP fel: Kunde inte ansluta till SMTP-server.'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP fel: Data accepterades inte.'; 11 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 12 $PHPMAILER_LANG['encoding'] = 'Okänt encode-format: '; 13 $PHPMAILER_LANG['execute'] = 'Kunde inte köra: '; 14 $PHPMAILER_LANG['file_access'] = 'Ingen åtkomst till fil: '; 15 $PHPMAILER_LANG['file_open'] = 'Fil fel: Kunde inte öppna fil: '; 16 $PHPMAILER_LANG['from_failed'] = 'Följande avsändaradress är felaktig: '; 17 $PHPMAILER_LANG['instantiate'] = 'Kunde inte initiera e-postfunktion.'; 18 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 19 $PHPMAILER_LANG['provide_address'] = 'Du måste ange minst en mottagares e-postadress.'; 20 $PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP fel: Följande mottagare är felaktig: '; 22 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 23 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 24 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 25 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-sk.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-sk.php src/wp-includes/PHPMailer/language/phpmailer.lang-sk.php new file mode 100644 index 0000000..1722a5f
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Slovak Version 5 * Author: Michal Tinka <michaltinka@gmail.com> 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP Error: Chyba autentifikácie.'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP Error: Nebolo možné nadviazať spojenie so SMTP serverom.'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Dáta neboli prijaté'; 11 $PHPMAILER_LANG['empty_message'] = 'Prázdne telo správy.'; 12 $PHPMAILER_LANG['encoding'] = 'Neznáme kódovanie: '; 13 $PHPMAILER_LANG['execute'] = 'Nedá sa vykonať: '; 14 $PHPMAILER_LANG['file_access'] = 'Súbor nebol nájdený: '; 15 $PHPMAILER_LANG['file_open'] = 'File Error: Súbor sa otvoriť pre čítanie: '; 16 $PHPMAILER_LANG['from_failed'] = 'Následujúca adresa From je nesprávna: '; 17 $PHPMAILER_LANG['instantiate'] = 'Nedá sa vytvoriť inštancia emailovej funkcie.'; 18 $PHPMAILER_LANG['invalid_address'] = 'Neodoslané, emailová adresa je nesprávna: '; 19 $PHPMAILER_LANG['mailer_not_supported'] = ' emailový klient nieje podporovaný.'; 20 $PHPMAILER_LANG['provide_address'] = 'Musíte zadať aspoň jednu emailovú adresu príjemcu.'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: Adresy príjemcov niesu správne '; 22 $PHPMAILER_LANG['signing'] = 'Chyba prihlasovania: '; 23 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() zlyhalo.'; 24 $PHPMAILER_LANG['smtp_error'] = 'SMTP chyba serveru: '; 25 $PHPMAILER_LANG['variable_set'] = 'Nemožno nastaviť alebo resetovať premennú: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-tr.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-tr.php src/wp-includes/PHPMailer/language/phpmailer.lang-tr.php new file mode 100644 index 0000000..abba081
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Turkish version 5 * Türkçe Versiyonu 6 * ÝZYAZILIM - Elçin Özel - Can Yýlmaz - Mehmet Benlioðlu 7 */ 8 9 $PHPMAILER_LANG['authenticate'] = 'SMTP Hatası: Doğrulanamıyor.'; 10 $PHPMAILER_LANG['connect_host'] = 'SMTP Hatası: SMTP hosta bağlanılamıyor.'; 11 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Hatası: Veri kabul edilmedi.'; 12 $PHPMAILER_LANG['empty_message'] = 'Mesaj içeriği boş'; 13 $PHPMAILER_LANG['encoding'] = 'Bilinmeyen şifreleme: '; 14 $PHPMAILER_LANG['execute'] = 'Çalıtırılamıyor: '; 15 $PHPMAILER_LANG['file_access'] = 'Dosyaya erişilemiyor: '; 16 $PHPMAILER_LANG['file_open'] = 'Dosya Hatası: Dosya açılamıyor: '; 17 $PHPMAILER_LANG['from_failed'] = 'Başarısız olan gönderici adresi: '; 18 $PHPMAILER_LANG['instantiate'] = 'Örnek mail fonksiyonu oluşturulamadı.'; 19 $PHPMAILER_LANG['invalid_address'] = 'Gönderilmedi, email adresi geçersiz: '; 20 $PHPMAILER_LANG['provide_address'] = 'En az bir tane mail adresi belirtmek zorundasınız alıcının email adresi.'; 21 $PHPMAILER_LANG['mailer_not_supported'] = ' mailler desteklenmemektedir.'; 22 $PHPMAILER_LANG['recipients_failed'] = 'SMTP Hatası: alıcılara ulaımadı: '; 23 $PHPMAILER_LANG['signing'] = 'İmzalama hatası: '; 24 $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP bağlantı() başarısız.'; 25 $PHPMAILER_LANG['smtp_error'] = 'SMTP sunucu hatası: '; 26 $PHPMAILER_LANG['variable_set'] = 'Ayarlanamıyor yada sıfırlanamıyor: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-uk.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-uk.php src/wp-includes/PHPMailer/language/phpmailer.lang-uk.php new file mode 100644 index 0000000..112bba8
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Ukrainian Version by Yuriy Rudyy <yrudyy@prs.net.ua> 5 */ 6 7 $PHPMAILER_LANG['authenticate'] = 'Помилка SMTP: помилка авторизації.'; 8 $PHPMAILER_LANG['connect_host'] = 'Помилка SMTP: не вдається підєднатися до серверу SMTP.'; 9 $PHPMAILER_LANG['data_not_accepted'] = 'Помилка SMTP: дані не прийняті.'; 10 $PHPMAILER_LANG['encoding'] = 'Невідомий тип кодування: '; 11 $PHPMAILER_LANG['execute'] = 'Неможливо виконати команду: '; 12 $PHPMAILER_LANG['file_access'] = 'Немає доступу до файлу: '; 13 $PHPMAILER_LANG['file_open'] = 'Помилка файлової системи: не вдається відкрити файл: '; 14 $PHPMAILER_LANG['from_failed'] = 'Невірна адреса відправника: '; 15 $PHPMAILER_LANG['instantiate'] = 'Неможливо запустити функцію mail.'; 16 $PHPMAILER_LANG['provide_address'] = 'Будь-ласка, введіть хоча б одну адресу e-mail отримувача.'; 17 $PHPMAILER_LANG['mailer_not_supported'] = ' - поштовий сервер не підтримується.'; 18 $PHPMAILER_LANG['recipients_failed'] = 'Помилка SMTP: відправти наступним отрмувачам не вдалася: '; 19 $PHPMAILER_LANG['empty_message'] = 'Пусте тіло повідомлення'; 20 $PHPMAILER_LANG['invalid_address'] = 'Не відправлено, невірний формат email адреси: '; 21 $PHPMAILER_LANG['signing'] = 'Помилка підпису: '; 22 $PHPMAILER_LANG['smtp_connect_failed'] = 'Помилка зєднання із SMTP-сервером'; 23 $PHPMAILER_LANG['smtp_error'] = 'Помилка SMTP-сервера: '; 24 $PHPMAILER_LANG['variable_set'] = 'Неможливо встановити або перевстановити змінну: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-zh.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-zh.php src/wp-includes/PHPMailer/language/phpmailer.lang-zh.php new file mode 100644 index 0000000..b0e8f4e
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Traditional Chinese Version 5 * @author liqwei <liqwei@liqwei.com> 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登錄失敗。'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連接到 SMTP 主機。'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 錯誤:數據不被接受。'; 11 //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 12 $PHPMAILER_LANG['encoding'] = '未知編碼: '; 13 $PHPMAILER_LANG['file_access'] = '無法訪問文件:'; 14 $PHPMAILER_LANG['file_open'] = '文件錯誤:無法打開文件:'; 15 $PHPMAILER_LANG['from_failed'] = '發送地址錯誤:'; 16 $PHPMAILER_LANG['execute'] = '無法執行:'; 17 $PHPMAILER_LANG['instantiate'] = '未知函數調用。'; 18 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 19 $PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。'; 20 $PHPMAILER_LANG['mailer_not_supported'] = '發信客戶端不被支持。'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:收件人地址錯誤:'; 22 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 23 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 24 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 25 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
new file src/wp-includes/PHPMailer/language/phpmailer.lang-zh_cn.php
diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-zh_cn.php src/wp-includes/PHPMailer/language/phpmailer.lang-zh_cn.php new file mode 100644 index 0000000..78eb9ac
- + 1 <?php 2 /** 3 * PHPMailer language file: refer to English translation for definitive list 4 * Simplified Chinese Version 5 * @author liqwei <liqwei@liqwei.com> 6 */ 7 8 $PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。'; 9 $PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。'; 10 $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。'; 11 //$P$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 12 $PHPMAILER_LANG['encoding'] = '未知编码: '; 13 $PHPMAILER_LANG['execute'] = '无法执行:'; 14 $PHPMAILER_LANG['file_access'] = '无法访问文件:'; 15 $PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; 16 $PHPMAILER_LANG['from_failed'] = '发送地址错误:'; 17 $PHPMAILER_LANG['instantiate'] = '未知函数调用。'; 18 //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; 19 $PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; 20 $PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; 21 $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:'; 22 //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 23 //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 24 //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 25 //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; -
src/wp-includes/class-phpmailer.php
diff --git src/wp-includes/class-phpmailer.php src/wp-includes/class-phpmailer.php index 238474e..e4d2d1b 100644
1 1 <?php 2 /*~ class.phpmailer.php3 .---------------------------------------------------------------------------.4 | Software: PHPMailer - PHP email class |5 | Version: 5.2.4 |6 | Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ |7 | ------------------------------------------------------------------------- |8 | Admin: Jim Jagielski (project admininistrator) |9 | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |10 | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |11 | : Jim Jagielski (jimjag) jimjag@gmail.com |12 | Founder: Brent R. Matzelle (original founder) |13 | Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved. |14 | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |15 | Copyright (c) 2001-2003, Brent R. Matzelle |16 | ------------------------------------------------------------------------- |17 | License: Distributed under the Lesser General Public License (LGPL) |18 | http://www.gnu.org/copyleft/lesser.html |19 | This program is distributed in the hope that it will be useful - WITHOUT |20 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |21 | FITNESS FOR A PARTICULAR PURPOSE. |22 '---------------------------------------------------------------------------'23 */24 25 /**26 * PHPMailer - PHP email creation and transport class27 * NOTE: Requires PHP version 5 or later28 * @package PHPMailer29 * @author Andy Prevost30 * @author Marcus Bointon31 * @author Jim Jagielski32 * @copyright 2010 - 2012 Jim Jagielski33 * @copyright 2004 - 2009 Andy Prevost34 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License35 */36 37 if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n");38 39 2 /** 40 * PHP email creation and transport class 41 * @package PHPMailer 3 * Backwards compatible shim for PHPMailer library. 4 * 5 * @package WordPress 42 6 */ 43 class PHPMailer {44 45 /////////////////////////////////////////////////46 // PROPERTIES, PUBLIC47 /////////////////////////////////////////////////48 49 /**50 * Email priority (1 = High, 3 = Normal, 5 = low).51 * @var int52 */53 public $Priority = 3;54 55 /**56 * Sets the CharSet of the message.57 * @var string58 */59 public $CharSet = 'iso-8859-1';60 61 /**62 * Sets the Content-type of the message.63 * @var string64 */65 public $ContentType = 'text/plain';66 67 /**68 * Sets the Encoding of the message. Options for this are69 * "8bit", "7bit", "binary", "base64", and "quoted-printable".70 * @var string71 */72 public $Encoding = '8bit';73 74 /**75 * Holds the most recent mailer error message.76 * @var string77 */78 public $ErrorInfo = '';79 80 /**81 * Sets the From email address for the message.82 * @var string83 */84 public $From = 'root@localhost';85 86 /**87 * Sets the From name of the message.88 * @var string89 */90 public $FromName = 'Root User';91 92 /**93 * Sets the Sender email (Return-Path) of the message. If not empty,94 * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.95 * @var string96 */97 public $Sender = '';98 99 /**100 * Sets the Return-Path of the message. If empty, it will101 * be set to either From or Sender.102 * @var string103 */104 public $ReturnPath = '';105 106 /**107 * Sets the Subject of the message.108 * @var string109 */110 public $Subject = '';111 112 /**113 * Sets the Body of the message. This can be either an HTML or text body.114 * If HTML then run IsHTML(true).115 * @var string116 */117 public $Body = '';118 119 /**120 * Sets the text-only body of the message. This automatically sets the121 * email to multipart/alternative. This body can be read by mail122 * clients that do not have HTML email capability such as mutt. Clients123 * that can read HTML will view the normal Body.124 * @var string125 */126 public $AltBody = '';127 128 /**129 * Stores the complete compiled MIME message body.130 * @var string131 * @access protected132 */133 protected $MIMEBody = '';134 135 /**136 * Stores the complete compiled MIME message headers.137 * @var string138 * @access protected139 */140 protected $MIMEHeader = '';141 142 /**143 * Stores the extra header list which CreateHeader() doesn't fold in144 * @var string145 * @access protected146 */147 protected $mailHeader = '';148 149 /**150 * Sets word wrapping on the body of the message to a given number of151 * characters.152 * @var int153 */154 public $WordWrap = 0;155 156 /**157 * Method to send mail: ("mail", "sendmail", or "smtp").158 * @var string159 */160 public $Mailer = 'mail';161 162 /**163 * Sets the path of the sendmail program.164 * @var string165 */166 public $Sendmail = '/usr/sbin/sendmail';167 168 /**169 * Determine if mail() uses a fully sendmail compatible MTA that170 * supports sendmail's "-oi -f" options171 * @var boolean172 */173 public $UseSendmailOptions = true;174 175 /**176 * Path to PHPMailer plugins. Useful if the SMTP class177 * is in a different directory than the PHP include path.178 * @var string179 */180 public $PluginDir = '';181 182 /**183 * Sets the email address that a reading confirmation will be sent.184 * @var string185 */186 public $ConfirmReadingTo = '';187 188 /**189 * Sets the hostname to use in Message-Id and Received headers190 * and as default HELO string. If empty, the value returned191 * by SERVER_NAME is used or 'localhost.localdomain'.192 * @var string193 */194 public $Hostname = '';195 196 /**197 * Sets the message ID to be used in the Message-Id header.198 * If empty, a unique id will be generated.199 * @var string200 */201 public $MessageID = '';202 203 /**204 * Sets the message Date to be used in the Date header.205 * If empty, the current date will be added.206 * @var string207 */208 public $MessageDate = '';209 210 /////////////////////////////////////////////////211 // PROPERTIES FOR SMTP212 /////////////////////////////////////////////////213 214 /**215 * Sets the SMTP hosts.216 *217 * All hosts must be separated by a218 * semicolon. You can also specify a different port219 * for each host by using this format: [hostname:port]220 * (e.g. "smtp1.example.com:25;smtp2.example.com").221 * Hosts will be tried in order.222 * @var string223 */224 public $Host = 'localhost';225 226 /**227 * Sets the default SMTP server port.228 * @var int229 */230 public $Port = 25;231 232 /**233 * Sets the SMTP HELO of the message (Default is $Hostname).234 * @var string235 */236 public $Helo = '';237 238 /**239 * Sets connection prefix. Options are "", "ssl" or "tls"240 * @var string241 */242 public $SMTPSecure = '';243 244 /**245 * Sets SMTP authentication. Utilizes the Username and Password variables.246 * @var bool247 */248 public $SMTPAuth = false;249 250 /**251 * Sets SMTP username.252 * @var string253 */254 public $Username = '';255 256 /**257 * Sets SMTP password.258 * @var string259 */260 public $Password = '';261 262 /**263 * Sets SMTP auth type. Options are LOGIN | PLAIN | NTLM (default LOGIN)264 * @var string265 */266 public $AuthType = '';267 268 /**269 * Sets SMTP realm.270 * @var string271 */272 public $Realm = '';273 274 /**275 * Sets SMTP workstation.276 * @var string277 */278 public $Workstation = '';279 280 /**281 * Sets the SMTP server timeout in seconds.282 * This function will not work with the win32 version.283 * @var int284 */285 public $Timeout = 10;286 287 /**288 * Sets SMTP class debugging on or off.289 * @var bool290 */291 public $SMTPDebug = false;292 293 /**294 * Sets the function/method to use for debugging output.295 * Right now we only honor "echo" or "error_log"296 * @var string297 */298 public $Debugoutput = "echo";299 300 /**301 * Prevents the SMTP connection from being closed after each mail302 * sending. If this is set to true then to close the connection303 * requires an explicit call to SmtpClose().304 * @var bool305 */306 public $SMTPKeepAlive = false;307 308 /**309 * Provides the ability to have the TO field process individual310 * emails, instead of sending to entire TO addresses311 * @var bool312 */313 public $SingleTo = false;314 315 /**316 * If SingleTo is true, this provides the array to hold the email addresses317 * @var bool318 */319 public $SingleToArray = array();320 321 /**322 * Provides the ability to change the generic line ending323 * NOTE: The default remains '\n'. We force CRLF where we KNOW324 * it must be used via self::CRLF325 * @var string326 */327 public $LE = "\n";328 329 /**330 * Used with DKIM Signing331 * required parameter if DKIM is enabled332 *333 * domain selector example domainkey334 * @var string335 */336 public $DKIM_selector = '';337 338 /**339 * Used with DKIM Signing340 * required if DKIM is enabled, in format of email address 'you@yourdomain.com' typically used as the source of the email341 * @var string342 */343 public $DKIM_identity = '';344 345 /**346 * Used with DKIM Signing347 * optional parameter if your private key requires a passphras348 * @var string349 */350 public $DKIM_passphrase = '';351 352 /**353 * Used with DKIM Singing354 * required if DKIM is enabled, in format of email address 'domain.com'355 * @var string356 */357 public $DKIM_domain = '';358 359 /**360 * Used with DKIM Signing361 * required if DKIM is enabled, path to private key file362 * @var string363 */364 public $DKIM_private = '';365 366 /**367 * Callback Action function name.368 * The function that handles the result of the send email action.369 * It is called out by Send() for each email sent.370 *371 * Value can be:372 * - 'function_name' for function names373 * - 'Class::Method' for static method calls374 * - array($object, 'Method') for calling methods on $object375 * See http://php.net/is_callable manual page for more details.376 *377 * Parameters:378 * bool $result result of the send action379 * string $to email address of the recipient380 * string $cc cc email addresses381 * string $bcc bcc email addresses382 * string $subject the subject383 * string $body the email body384 * string $from email address of sender385 * @var string386 */387 public $action_function = ''; //'callbackAction';388 389 /**390 * Sets the PHPMailer Version number391 * @var string392 */393 public $Version = '5.2.4';394 395 /**396 * What to use in the X-Mailer header397 * @var string NULL for default, whitespace for None, or actual string to use398 */399 public $XMailer = '';400 401 /////////////////////////////////////////////////402 // PROPERTIES, PRIVATE AND PROTECTED403 /////////////////////////////////////////////////404 405 /**406 * @var SMTP An instance of the SMTP sender class407 * @access protected408 */409 protected $smtp = null;410 /**411 * @var array An array of 'to' addresses412 * @access protected413 */414 protected $to = array();415 /**416 * @var array An array of 'cc' addresses417 * @access protected418 */419 protected $cc = array();420 /**421 * @var array An array of 'bcc' addresses422 * @access protected423 */424 protected $bcc = array();425 /**426 * @var array An array of reply-to name and address427 * @access protected428 */429 protected $ReplyTo = array();430 /**431 * @var array An array of all kinds of addresses: to, cc, bcc, replyto432 * @access protected433 */434 protected $all_recipients = array();435 /**436 * @var array An array of attachments437 * @access protected438 */439 protected $attachment = array();440 /**441 * @var array An array of custom headers442 * @access protected443 */444 protected $CustomHeader = array();445 /**446 * @var string The message's MIME type447 * @access protected448 */449 protected $message_type = '';450 /**451 * @var array An array of MIME boundary strings452 * @access protected453 */454 protected $boundary = array();455 /**456 * @var array An array of available languages457 * @access protected458 */459 protected $language = array();460 /**461 * @var integer The number of errors encountered462 * @access protected463 */464 protected $error_count = 0;465 /**466 * @var string The filename of a DKIM certificate file467 * @access protected468 */469 protected $sign_cert_file = '';470 /**471 * @var string The filename of a DKIM key file472 * @access protected473 */474 protected $sign_key_file = '';475 /**476 * @var string The password of a DKIM key477 * @access protected478 */479 protected $sign_key_pass = '';480 /**481 * @var boolean Whether to throw exceptions for errors482 * @access protected483 */484 protected $exceptions = false;485 486 /////////////////////////////////////////////////487 // CONSTANTS488 /////////////////////////////////////////////////489 490 const STOP_MESSAGE = 0; // message only, continue processing491 const STOP_CONTINUE = 1; // message?, likely ok to continue processing492 const STOP_CRITICAL = 2; // message, plus full stop, critical error reached493 const CRLF = "\r\n"; // SMTP RFC specified EOL494 495 /////////////////////////////////////////////////496 // METHODS, VARIABLES497 /////////////////////////////////////////////////498 499 /**500 * Calls actual mail() function, but in a safe_mode aware fashion501 * Also, unless sendmail_path points to sendmail (or something that502 * claims to be sendmail), don't pass params (not a perfect fix,503 * but it will do)504 * @param string $to To505 * @param string $subject Subject506 * @param string $body Message Body507 * @param string $header Additional Header(s)508 * @param string $params Params509 * @access private510 * @return bool511 */512 private function mail_passthru($to, $subject, $body, $header, $params) {513 if ( ini_get('safe_mode') || !($this->UseSendmailOptions) ) {514 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($subject)), $body, $header);515 } else {516 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($subject)), $body, $header, $params);517 }518 return $rt;519 }520 521 /**522 * Outputs debugging info via user-defined method523 * @param string $str524 */525 private function edebug($str) {526 if ($this->Debugoutput == "error_log") {527 error_log($str);528 } else {529 echo $str;530 }531 }532 533 /**534 * Constructor535 * @param boolean $exceptions Should we throw external exceptions?536 */537 public function __construct($exceptions = false) {538 $this->exceptions = ($exceptions == true);539 }540 541 /**542 * Sets message type to HTML.543 * @param bool $ishtml544 * @return void545 */546 public function IsHTML($ishtml = true) {547 if ($ishtml) {548 $this->ContentType = 'text/html';549 } else {550 $this->ContentType = 'text/plain';551 }552 }553 554 /**555 * Sets Mailer to send message using SMTP.556 * @return void557 */558 public function IsSMTP() {559 $this->Mailer = 'smtp';560 }561 562 /**563 * Sets Mailer to send message using PHP mail() function.564 * @return void565 */566 public function IsMail() {567 $this->Mailer = 'mail';568 }569 570 /**571 * Sets Mailer to send message using the $Sendmail program.572 * @return void573 */574 public function IsSendmail() {575 if (!stristr(ini_get('sendmail_path'), 'sendmail')) {576 $this->Sendmail = '/var/qmail/bin/sendmail';577 }578 $this->Mailer = 'sendmail';579 }580 581 /**582 * Sets Mailer to send message using the qmail MTA.583 * @return void584 */585 public function IsQmail() {586 if (stristr(ini_get('sendmail_path'), 'qmail')) {587 $this->Sendmail = '/var/qmail/bin/sendmail';588 }589 $this->Mailer = 'sendmail';590 }591 592 /////////////////////////////////////////////////593 // METHODS, RECIPIENTS594 /////////////////////////////////////////////////595 596 /**597 * Adds a "To" address.598 * @param string $address599 * @param string $name600 * @return boolean true on success, false if address already used601 */602 public function AddAddress($address, $name = '') {603 return $this->AddAnAddress('to', $address, $name);604 }605 606 /**607 * Adds a "Cc" address.608 * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.609 * @param string $address610 * @param string $name611 * @return boolean true on success, false if address already used612 */613 public function AddCC($address, $name = '') {614 return $this->AddAnAddress('cc', $address, $name);615 }616 617 /**618 * Adds a "Bcc" address.619 * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.620 * @param string $address621 * @param string $name622 * @return boolean true on success, false if address already used623 */624 public function AddBCC($address, $name = '') {625 return $this->AddAnAddress('bcc', $address, $name);626 }627 628 /**629 * Adds a "Reply-to" address.630 * @param string $address631 * @param string $name632 * @return boolean633 */634 public function AddReplyTo($address, $name = '') {635 return $this->AddAnAddress('Reply-To', $address, $name);636 }637 638 /**639 * Adds an address to one of the recipient arrays640 * Addresses that have been added already return false, but do not throw exceptions641 * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'642 * @param string $address The email address to send to643 * @param string $name644 * @throws phpmailerException645 * @return boolean true on success, false if address already used or invalid in some way646 * @access protected647 */648 protected function AddAnAddress($kind, $address, $name = '') {649 if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {650 $this->SetError($this->Lang('Invalid recipient array').': '.$kind);651 if ($this->exceptions) {652 throw new phpmailerException('Invalid recipient array: ' . $kind);653 }654 if ($this->SMTPDebug) {655 $this->edebug($this->Lang('Invalid recipient array').': '.$kind);656 }657 return false;658 }659 $address = trim($address);660 $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim661 if (!$this->ValidateAddress($address)) {662 $this->SetError($this->Lang('invalid_address').': '. $address);663 if ($this->exceptions) {664 throw new phpmailerException($this->Lang('invalid_address').': '.$address);665 }666 if ($this->SMTPDebug) {667 $this->edebug($this->Lang('invalid_address').': '.$address);668 }669 return false;670 }671 if ($kind != 'Reply-To') {672 if (!isset($this->all_recipients[strtolower($address)])) {673 array_push($this->$kind, array($address, $name));674 $this->all_recipients[strtolower($address)] = true;675 return true;676 }677 } else {678 if (!array_key_exists(strtolower($address), $this->ReplyTo)) {679 $this->ReplyTo[strtolower($address)] = array($address, $name);680 return true;681 }682 }683 return false;684 }685 686 /**687 * Set the From and FromName properties688 * @param string $address689 * @param string $name690 * @param int $auto Also set Reply-To and Sender691 * @throws phpmailerException692 * @return boolean693 */694 public function SetFrom($address, $name = '', $auto = 1) {695 $address = trim($address);696 $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim697 if (!$this->ValidateAddress($address)) {698 $this->SetError($this->Lang('invalid_address').': '. $address);699 if ($this->exceptions) {700 throw new phpmailerException($this->Lang('invalid_address').': '.$address);701 }702 if ($this->SMTPDebug) {703 $this->edebug($this->Lang('invalid_address').': '.$address);704 }705 return false;706 }707 $this->From = $address;708 $this->FromName = $name;709 if ($auto) {710 if (empty($this->ReplyTo)) {711 $this->AddAnAddress('Reply-To', $address, $name);712 }713 if (empty($this->Sender)) {714 $this->Sender = $address;715 }716 }717 return true;718 }719 720 /**721 * Check that a string looks roughly like an email address should722 * Static so it can be used without instantiation, public so people can overload723 * Conforms to RFC5322: Uses *correct* regex on which FILTER_VALIDATE_EMAIL is724 * based; So why not use FILTER_VALIDATE_EMAIL? Because it was broken to725 * not allow a@b type valid addresses :(726 * Some Versions of PHP break on the regex though, likely due to PCRE, so use727 * the older validation method for those users. (http://php.net/manual/en/pcre.installation.php)728 * @link http://squiloople.com/2009/12/20/email-address-validation/729 * @copyright regex Copyright Michael Rushton 2009-10 | http://squiloople.com/ | Feel free to use and redistribute this code. But please keep this copyright notice.730 * @param string $address The email address to check731 * @return boolean732 * @static733 * @access public734 */735 public static function ValidateAddress($address) {736 if ((defined('PCRE_VERSION')) && (version_compare(PCRE_VERSION, '8.0') >= 0)) {737 return preg_match('/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[ ])+|(?>[ ]*\x0D\x0A)?[ ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){7,})((?6)(?>:(?6)){0,5})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){5,})(?8)?::(?>((?6)(?>:(?6)){0,3}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', $address);738 } elseif (function_exists('filter_var')) { //Introduced in PHP 5.2739 if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {740 return false;741 } else {742 return true;743 }744 } else {745 return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);746 }747 }748 749 /////////////////////////////////////////////////750 // METHODS, MAIL SENDING751 /////////////////////////////////////////////////752 753 /**754 * Creates message and assigns Mailer. If the message is755 * not sent successfully then it returns false. Use the ErrorInfo756 * variable to view description of the error.757 * @throws phpmailerException758 * @return bool759 */760 public function Send() {761 try {762 if(!$this->PreSend()) return false;763 return $this->PostSend();764 } catch (phpmailerException $e) {765 $this->mailHeader = '';766 $this->SetError($e->getMessage());767 if ($this->exceptions) {768 throw $e;769 }770 return false;771 }772 }773 774 /**775 * Prep mail by constructing all message entities776 * @throws phpmailerException777 * @return bool778 */779 public function PreSend() {780 try {781 $this->mailHeader = "";782 if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {783 throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL);784 }785 786 // Set whether the message is multipart/alternative787 if(!empty($this->AltBody)) {788 $this->ContentType = 'multipart/alternative';789 }790 791 $this->error_count = 0; // reset errors792 $this->SetMessageType();793 //Refuse to send an empty message794 if (empty($this->Body)) {795 throw new phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL);796 }797 798 $this->MIMEHeader = $this->CreateHeader();799 $this->MIMEBody = $this->CreateBody();800 801 // To capture the complete message when using mail(), create802 // an extra header list which CreateHeader() doesn't fold in803 if ($this->Mailer == 'mail') {804 if (count($this->to) > 0) {805 $this->mailHeader .= $this->AddrAppend("To", $this->to);806 } else {807 $this->mailHeader .= $this->HeaderLine("To", "undisclosed-recipients:;");808 }809 $this->mailHeader .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader(trim($this->Subject))));810 // if(count($this->cc) > 0) {811 // $this->mailHeader .= $this->AddrAppend("Cc", $this->cc);812 // }813 }814 815 // digitally sign with DKIM if enabled816 if (!empty($this->DKIM_domain) && !empty($this->DKIM_private) && !empty($this->DKIM_selector) && !empty($this->DKIM_domain) && file_exists($this->DKIM_private)) {817 $header_dkim = $this->DKIM_Add($this->MIMEHeader, $this->EncodeHeader($this->SecureHeader($this->Subject)), $this->MIMEBody);818 $this->MIMEHeader = str_replace("\r\n", "\n", $header_dkim) . $this->MIMEHeader;819 }820 821 return true;822 823 } catch (phpmailerException $e) {824 $this->SetError($e->getMessage());825 if ($this->exceptions) {826 throw $e;827 }828 return false;829 }830 }831 832 /**833 * Actual Email transport function834 * Send the email via the selected mechanism835 * @throws phpmailerException836 * @return bool837 */838 public function PostSend() {839 try {840 // Choose the mailer and send through it841 switch($this->Mailer) {842 case 'sendmail':843 return $this->SendmailSend($this->MIMEHeader, $this->MIMEBody);844 case 'smtp':845 return $this->SmtpSend($this->MIMEHeader, $this->MIMEBody);846 case 'mail':847 return $this->MailSend($this->MIMEHeader, $this->MIMEBody);848 default:849 return $this->MailSend($this->MIMEHeader, $this->MIMEBody);850 }851 } catch (phpmailerException $e) {852 $this->SetError($e->getMessage());853 if ($this->exceptions) {854 throw $e;855 }856 if ($this->SMTPDebug) {857 $this->edebug($e->getMessage()."\n");858 }859 }860 return false;861 }862 863 /**864 * Sends mail using the $Sendmail program.865 * @param string $header The message headers866 * @param string $body The message body867 * @throws phpmailerException868 * @access protected869 * @return bool870 */871 protected function SendmailSend($header, $body) {872 if ($this->Sender != '') {873 $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));874 } else {875 $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));876 }877 if ($this->SingleTo === true) {878 foreach ($this->SingleToArray as $val) {879 if(!@$mail = popen($sendmail, 'w')) {880 throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);881 }882 fputs($mail, "To: " . $val . "\n");883 fputs($mail, $header);884 fputs($mail, $body);885 $result = pclose($mail);886 // implement call back function if it exists887 $isSent = ($result == 0) ? 1 : 0;888 $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);889 if($result != 0) {890 throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);891 }892 }893 } else {894 if(!@$mail = popen($sendmail, 'w')) {895 throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);896 }897 fputs($mail, $header);898 fputs($mail, $body);899 $result = pclose($mail);900 // implement call back function if it exists901 $isSent = ($result == 0) ? 1 : 0;902 $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body);903 if($result != 0) {904 throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);905 }906 }907 return true;908 }909 910 /**911 * Sends mail using the PHP mail() function.912 * @param string $header The message headers913 * @param string $body The message body914 * @throws phpmailerException915 * @access protected916 * @return bool917 */918 protected function MailSend($header, $body) {919 $toArr = array();920 foreach($this->to as $t) {921 $toArr[] = $this->AddrFormat($t);922 }923 $to = implode(', ', $toArr);924 925 if (empty($this->Sender)) {926 $params = " ";927 } else {928 $params = sprintf("-f%s", $this->Sender);929 }930 if ($this->Sender != '' and !ini_get('safe_mode')) {931 $old_from = ini_get('sendmail_from');932 ini_set('sendmail_from', $this->Sender);933 }934 $rt = false;935 if ($this->SingleTo === true && count($toArr) > 1) {936 foreach ($toArr as $val) {937 $rt = $this->mail_passthru($val, $this->Subject, $body, $header, $params);938 // implement call back function if it exists939 $isSent = ($rt == 1) ? 1 : 0;940 $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);941 }942 } else {943 $rt = $this->mail_passthru($to, $this->Subject, $body, $header, $params);944 // implement call back function if it exists945 $isSent = ($rt == 1) ? 1 : 0;946 $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);947 }948 if (isset($old_from)) {949 ini_set('sendmail_from', $old_from);950 }951 if(!$rt) {952 throw new phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL);953 }954 return true;955 }956 957 /**958 * Sends mail via SMTP using PhpSMTP959 * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.960 * @param string $header The message headers961 * @param string $body The message body962 * @throws phpmailerException963 * @uses SMTP964 * @access protected965 * @return bool966 */967 protected function SmtpSend($header, $body) {968 require_once $this->PluginDir . 'class-smtp.php';969 $bad_rcpt = array();970 971 if(!$this->SmtpConnect()) {972 throw new phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL);973 }974 $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;975 if(!$this->smtp->Mail($smtp_from)) {976 $this->SetError($this->Lang('from_failed') . $smtp_from . " : " . implode(",",$this->smtp->getError())) ;977 throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);978 }979 980 // Attempt to send attach all recipients981 foreach($this->to as $to) {982 if (!$this->smtp->Recipient($to[0])) {983 $bad_rcpt[] = $to[0];984 // implement call back function if it exists985 $isSent = 0;986 $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body);987 } else {988 // implement call back function if it exists989 $isSent = 1;990 $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body);991 }992 }993 foreach($this->cc as $cc) {994 if (!$this->smtp->Recipient($cc[0])) {995 $bad_rcpt[] = $cc[0];996 // implement call back function if it exists997 $isSent = 0;998 $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body);999 } else {1000 // implement call back function if it exists1001 $isSent = 1;1002 $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body);1003 }1004 }1005 foreach($this->bcc as $bcc) {1006 if (!$this->smtp->Recipient($bcc[0])) {1007 $bad_rcpt[] = $bcc[0];1008 // implement call back function if it exists1009 $isSent = 0;1010 $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body);1011 } else {1012 // implement call back function if it exists1013 $isSent = 1;1014 $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body);1015 }1016 }1017 1018 1019 if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses1020 $badaddresses = implode(', ', $bad_rcpt);1021 throw new phpmailerException($this->Lang('recipients_failed') . $badaddresses);1022 }1023 if(!$this->smtp->Data($header . $body)) {1024 throw new phpmailerException($this->Lang('data_not_accepted'), self::STOP_CRITICAL);1025 }1026 if($this->SMTPKeepAlive == true) {1027 $this->smtp->Reset();1028 } else {1029 $this->smtp->Quit();1030 $this->smtp->Close();1031 }1032 return true;1033 }1034 1035 /**1036 * Initiates a connection to an SMTP server.1037 * Returns false if the operation failed.1038 * @uses SMTP1039 * @access public1040 * @throws phpmailerException1041 * @return bool1042 */1043 public function SmtpConnect() {1044 if(is_null($this->smtp)) {1045 $this->smtp = new SMTP;1046 }1047 1048 $this->smtp->Timeout = $this->Timeout;1049 $this->smtp->do_debug = $this->SMTPDebug;1050 $hosts = explode(';', $this->Host);1051 $index = 0;1052 $connection = $this->smtp->Connected();1053 1054 // Retry while there is no connection1055 try {1056 while($index < count($hosts) && !$connection) {1057 $hostinfo = array();1058 if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {1059 $host = $hostinfo[1];1060 $port = $hostinfo[2];1061 } else {1062 $host = $hosts[$index];1063 $port = $this->Port;1064 }1065 1066 $tls = ($this->SMTPSecure == 'tls');1067 $ssl = ($this->SMTPSecure == 'ssl');1068 1069 if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) {1070 1071 $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname());1072 $this->smtp->Hello($hello);1073 1074 if ($tls) {1075 if (!$this->smtp->StartTLS()) {1076 throw new phpmailerException($this->Lang('connect_host'));1077 }1078 1079 //We must resend HELO after tls negotiation1080 $this->smtp->Hello($hello);1081 }1082 1083 $connection = true;1084 if ($this->SMTPAuth) {1085 if (!$this->smtp->Authenticate($this->Username, $this->Password, $this->AuthType,1086 $this->Realm, $this->Workstation)) {1087 throw new phpmailerException($this->Lang('authenticate'));1088 }1089 }1090 }1091 $index++;1092 if (!$connection) {1093 throw new phpmailerException($this->Lang('connect_host'));1094 }1095 }1096 } catch (phpmailerException $e) {1097 $this->smtp->Reset();1098 if ($this->exceptions) {1099 throw $e;1100 }1101 }1102 return true;1103 }1104 1105 /**1106 * Closes the active SMTP session if one exists.1107 * @return void1108 */1109 public function SmtpClose() {1110 if ($this->smtp !== null) {1111 if($this->smtp->Connected()) {1112 $this->smtp->Quit();1113 $this->smtp->Close();1114 }1115 }1116 }1117 1118 /**1119 * Sets the language for all class error messages.1120 * Returns false if it cannot load the language file. The default language is English.1121 * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br")1122 * @param string $lang_path Path to the language file directory1123 * @return bool1124 * @access public1125 */1126 function SetLanguage($langcode = 'en', $lang_path = 'language/') {1127 //Define full set of translatable strings1128 $PHPMAILER_LANG = array(1129 'authenticate' => 'SMTP Error: Could not authenticate.',1130 'connect_host' => 'SMTP Error: Could not connect to SMTP host.',1131 'data_not_accepted' => 'SMTP Error: Data not accepted.',1132 'empty_message' => 'Message body empty',1133 'encoding' => 'Unknown encoding: ',1134 'execute' => 'Could not execute: ',1135 'file_access' => 'Could not access file: ',1136 'file_open' => 'File Error: Could not open file: ',1137 'from_failed' => 'The following From address failed: ',1138 'instantiate' => 'Could not instantiate mail function.',1139 'invalid_address' => 'Invalid address',1140 'mailer_not_supported' => ' mailer is not supported.',1141 'provide_address' => 'You must provide at least one recipient email address.',1142 'recipients_failed' => 'SMTP Error: The following recipients failed: ',1143 'signing' => 'Signing Error: ',1144 'smtp_connect_failed' => 'SMTP Connect() failed.',1145 'smtp_error' => 'SMTP server error: ',1146 'variable_set' => 'Cannot set or reset variable: '1147 );1148 //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"!1149 $l = true;1150 if ($langcode != 'en') { //There is no English translation file1151 $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php';1152 }1153 $this->language = $PHPMAILER_LANG;1154 return ($l == true); //Returns false if language not found1155 }1156 1157 /**1158 * Return the current array of language strings1159 * @return array1160 */1161 public function GetTranslations() {1162 return $this->language;1163 }1164 1165 /////////////////////////////////////////////////1166 // METHODS, MESSAGE CREATION1167 /////////////////////////////////////////////////1168 1169 /**1170 * Creates recipient headers.1171 * @access public1172 * @param string $type1173 * @param array $addr1174 * @return string1175 */1176 public function AddrAppend($type, $addr) {1177 $addr_str = $type . ': ';1178 $addresses = array();1179 foreach ($addr as $a) {1180 $addresses[] = $this->AddrFormat($a);1181 }1182 $addr_str .= implode(', ', $addresses);1183 $addr_str .= $this->LE;1184 1185 return $addr_str;1186 }1187 1188 /**1189 * Formats an address correctly.1190 * @access public1191 * @param string $addr1192 * @return string1193 */1194 public function AddrFormat($addr) {1195 if (empty($addr[1])) {1196 return $this->SecureHeader($addr[0]);1197 } else {1198 return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";1199 }1200 }1201 1202 /**1203 * Wraps message for use with mailers that do not1204 * automatically perform wrapping and for quoted-printable.1205 * Original written by philippe.1206 * @param string $message The message to wrap1207 * @param integer $length The line length to wrap to1208 * @param boolean $qp_mode Whether to run in Quoted-Printable mode1209 * @access public1210 * @return string1211 */1212 public function WrapText($message, $length, $qp_mode = false) {1213 $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;1214 // If utf-8 encoding is used, we will need to make sure we don't1215 // split multibyte characters when we wrap1216 $is_utf8 = (strtolower($this->CharSet) == "utf-8");1217 $lelen = strlen($this->LE);1218 $crlflen = strlen(self::CRLF);1219 1220 $message = $this->FixEOL($message);1221 if (substr($message, -$lelen) == $this->LE) {1222 $message = substr($message, 0, -$lelen);1223 }1224 1225 $line = explode($this->LE, $message); // Magic. We know FixEOL uses $LE1226 $message = '';1227 for ($i = 0 ;$i < count($line); $i++) {1228 $line_part = explode(' ', $line[$i]);1229 $buf = '';1230 for ($e = 0; $e<count($line_part); $e++) {1231 $word = $line_part[$e];1232 if ($qp_mode and (strlen($word) > $length)) {1233 $space_left = $length - strlen($buf) - $crlflen;1234 if ($e != 0) {1235 if ($space_left > 20) {1236 $len = $space_left;1237 if ($is_utf8) {1238 $len = $this->UTF8CharBoundary($word, $len);1239 } elseif (substr($word, $len - 1, 1) == "=") {1240 $len--;1241 } elseif (substr($word, $len - 2, 1) == "=") {1242 $len -= 2;1243 }1244 $part = substr($word, 0, $len);1245 $word = substr($word, $len);1246 $buf .= ' ' . $part;1247 $message .= $buf . sprintf("=%s", self::CRLF);1248 } else {1249 $message .= $buf . $soft_break;1250 }1251 $buf = '';1252 }1253 while (strlen($word) > 0) {1254 $len = $length;1255 if ($is_utf8) {1256 $len = $this->UTF8CharBoundary($word, $len);1257 } elseif (substr($word, $len - 1, 1) == "=") {1258 $len--;1259 } elseif (substr($word, $len - 2, 1) == "=") {1260 $len -= 2;1261 }1262 $part = substr($word, 0, $len);1263 $word = substr($word, $len);1264 1265 if (strlen($word) > 0) {1266 $message .= $part . sprintf("=%s", self::CRLF);1267 } else {1268 $buf = $part;1269 }1270 }1271 } else {1272 $buf_o = $buf;1273 $buf .= ($e == 0) ? $word : (' ' . $word);1274 7 1275 if (strlen($buf) > $length and $buf_o != '') { 1276 $message .= $buf_o . $soft_break; 1277 $buf = $word; 1278 } 1279 } 1280 } 1281 $message .= $buf . self::CRLF; 1282 } 1283 1284 return $message; 1285 } 1286 1287 /** 1288 * Finds last character boundary prior to maxLength in a utf-8 1289 * quoted (printable) encoded string. 1290 * Original written by Colin Brown. 1291 * @access public 1292 * @param string $encodedText utf-8 QP text 1293 * @param int $maxLength find last character boundary prior to this length 1294 * @return int 1295 */ 1296 public function UTF8CharBoundary($encodedText, $maxLength) { 1297 $foundSplitPos = false; 1298 $lookBack = 3; 1299 while (!$foundSplitPos) { 1300 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); 1301 $encodedCharPos = strpos($lastChunk, "="); 1302 if ($encodedCharPos !== false) { 1303 // Found start of encoded character byte within $lookBack block. 1304 // Check the encoded byte value (the 2 chars after the '=') 1305 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); 1306 $dec = hexdec($hex); 1307 if ($dec < 128) { // Single byte character. 1308 // If the encoded char was found at pos 0, it will fit 1309 // otherwise reduce maxLength to start of the encoded char 1310 $maxLength = ($encodedCharPos == 0) ? $maxLength : 1311 $maxLength - ($lookBack - $encodedCharPos); 1312 $foundSplitPos = true; 1313 } elseif ($dec >= 192) { // First byte of a multi byte character 1314 // Reduce maxLength to split at start of character 1315 $maxLength = $maxLength - ($lookBack - $encodedCharPos); 1316 $foundSplitPos = true; 1317 } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back 1318 $lookBack += 3; 1319 } 1320 } else { 1321 // No encoded character found 1322 $foundSplitPos = true; 1323 } 1324 } 1325 return $maxLength; 1326 } 1327 1328 1329 /** 1330 * Set the body wrapping. 1331 * @access public 1332 * @return void 1333 */ 1334 public function SetWordWrap() { 1335 if($this->WordWrap < 1) { 1336 return; 1337 } 1338 1339 switch($this->message_type) { 1340 case 'alt': 1341 case 'alt_inline': 1342 case 'alt_attach': 1343 case 'alt_inline_attach': 1344 $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 1345 break; 1346 default: 1347 $this->Body = $this->WrapText($this->Body, $this->WordWrap); 1348 break; 1349 } 1350 } 1351 1352 /** 1353 * Assembles message header. 1354 * @access public 1355 * @return string The assembled header 1356 */ 1357 public function CreateHeader() { 1358 $result = ''; 1359 1360 // Set the boundaries 1361 $uniq_id = md5(uniqid(time())); 1362 $this->boundary[1] = 'b1_' . $uniq_id; 1363 $this->boundary[2] = 'b2_' . $uniq_id; 1364 $this->boundary[3] = 'b3_' . $uniq_id; 1365 1366 if ($this->MessageDate == '') { 1367 $result .= $this->HeaderLine('Date', self::RFCDate()); 1368 } else { 1369 $result .= $this->HeaderLine('Date', $this->MessageDate); 1370 } 1371 1372 if ($this->ReturnPath) { 1373 $result .= $this->HeaderLine('Return-Path', trim($this->ReturnPath)); 1374 } elseif ($this->Sender == '') { 1375 $result .= $this->HeaderLine('Return-Path', trim($this->From)); 1376 } else { 1377 $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); 1378 } 1379 1380 // To be created automatically by mail() 1381 if($this->Mailer != 'mail') { 1382 if ($this->SingleTo === true) { 1383 foreach($this->to as $t) { 1384 $this->SingleToArray[] = $this->AddrFormat($t); 1385 } 1386 } else { 1387 if(count($this->to) > 0) { 1388 $result .= $this->AddrAppend('To', $this->to); 1389 } elseif (count($this->cc) == 0) { 1390 $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); 1391 } 1392 } 1393 } 1394 1395 $from = array(); 1396 $from[0][0] = trim($this->From); 1397 $from[0][1] = $this->FromName; 1398 $result .= $this->AddrAppend('From', $from); 1399 1400 // sendmail and mail() extract Cc from the header before sending 1401 if(count($this->cc) > 0) { 1402 $result .= $this->AddrAppend('Cc', $this->cc); 1403 } 1404 1405 // sendmail and mail() extract Bcc from the header before sending 1406 if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { 1407 $result .= $this->AddrAppend('Bcc', $this->bcc); 1408 } 1409 1410 if(count($this->ReplyTo) > 0) { 1411 $result .= $this->AddrAppend('Reply-To', $this->ReplyTo); 1412 } 1413 1414 // mail() sets the subject itself 1415 if($this->Mailer != 'mail') { 1416 $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); 1417 } 1418 1419 if($this->MessageID != '') { 1420 $result .= $this->HeaderLine('Message-ID', $this->MessageID); 1421 } else { 1422 $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); 1423 } 1424 $result .= $this->HeaderLine('X-Priority', $this->Priority); 1425 if ($this->XMailer == '') { 1426 $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (http://code.google.com/a/apache-extras.org/p/phpmailer/)'); 1427 } else { 1428 $myXmailer = trim($this->XMailer); 1429 if ($myXmailer) { 1430 $result .= $this->HeaderLine('X-Mailer', $myXmailer); 1431 } 1432 } 1433 1434 if($this->ConfirmReadingTo != '') { 1435 $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); 1436 } 1437 1438 // Add custom headers 1439 for($index = 0; $index < count($this->CustomHeader); $index++) { 1440 $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); 1441 } 1442 if (!$this->sign_key_file) { 1443 $result .= $this->HeaderLine('MIME-Version', '1.0'); 1444 $result .= $this->GetMailMIME(); 1445 } 1446 1447 return $result; 1448 } 1449 1450 /** 1451 * Returns the message MIME. 1452 * @access public 1453 * @return string 1454 */ 1455 public function GetMailMIME() { 1456 $result = ''; 1457 switch($this->message_type) { 1458 case 'inline': 1459 $result .= $this->HeaderLine('Content-Type', 'multipart/related;'); 1460 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 1461 break; 1462 case 'attach': 1463 case 'inline_attach': 1464 case 'alt_attach': 1465 case 'alt_inline_attach': 1466 $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); 1467 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 1468 break; 1469 case 'alt': 1470 case 'alt_inline': 1471 $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); 1472 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 1473 break; 1474 default: 1475 // Catches case 'plain': and case '': 1476 $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding); 1477 $result .= $this->TextLine('Content-Type: '.$this->ContentType.'; charset='.$this->CharSet); 1478 break; 1479 } 1480 1481 if($this->Mailer != 'mail') { 1482 $result .= $this->LE; 1483 } 1484 1485 return $result; 1486 } 1487 1488 /** 1489 * Returns the MIME message (headers and body). Only really valid post PreSend(). 1490 * @access public 1491 * @return string 1492 */ 1493 public function GetSentMIMEMessage() { 1494 return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody; 1495 } 1496 1497 1498 /** 1499 * Assembles the message body. Returns an empty string on failure. 1500 * @access public 1501 * @throws phpmailerException 1502 * @return string The assembled message body 1503 */ 1504 public function CreateBody() { 1505 $body = ''; 1506 1507 if ($this->sign_key_file) { 1508 $body .= $this->GetMailMIME().$this->LE; 1509 } 1510 1511 $this->SetWordWrap(); 1512 1513 switch($this->message_type) { 1514 case 'inline': 1515 $body .= $this->GetBoundary($this->boundary[1], '', '', ''); 1516 $body .= $this->EncodeString($this->Body, $this->Encoding); 1517 $body .= $this->LE.$this->LE; 1518 $body .= $this->AttachAll("inline", $this->boundary[1]); 1519 break; 1520 case 'attach': 1521 $body .= $this->GetBoundary($this->boundary[1], '', '', ''); 1522 $body .= $this->EncodeString($this->Body, $this->Encoding); 1523 $body .= $this->LE.$this->LE; 1524 $body .= $this->AttachAll("attachment", $this->boundary[1]); 1525 break; 1526 case 'inline_attach': 1527 $body .= $this->TextLine("--" . $this->boundary[1]); 1528 $body .= $this->HeaderLine('Content-Type', 'multipart/related;'); 1529 $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"'); 1530 $body .= $this->LE; 1531 $body .= $this->GetBoundary($this->boundary[2], '', '', ''); 1532 $body .= $this->EncodeString($this->Body, $this->Encoding); 1533 $body .= $this->LE.$this->LE; 1534 $body .= $this->AttachAll("inline", $this->boundary[2]); 1535 $body .= $this->LE; 1536 $body .= $this->AttachAll("attachment", $this->boundary[1]); 1537 break; 1538 case 'alt': 1539 $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); 1540 $body .= $this->EncodeString($this->AltBody, $this->Encoding); 1541 $body .= $this->LE.$this->LE; 1542 $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); 1543 $body .= $this->EncodeString($this->Body, $this->Encoding); 1544 $body .= $this->LE.$this->LE; 1545 $body .= $this->EndBoundary($this->boundary[1]); 1546 break; 1547 case 'alt_inline': 1548 $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); 1549 $body .= $this->EncodeString($this->AltBody, $this->Encoding); 1550 $body .= $this->LE.$this->LE; 1551 $body .= $this->TextLine("--" . $this->boundary[1]); 1552 $body .= $this->HeaderLine('Content-Type', 'multipart/related;'); 1553 $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"'); 1554 $body .= $this->LE; 1555 $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', ''); 1556 $body .= $this->EncodeString($this->Body, $this->Encoding); 1557 $body .= $this->LE.$this->LE; 1558 $body .= $this->AttachAll("inline", $this->boundary[2]); 1559 $body .= $this->LE; 1560 $body .= $this->EndBoundary($this->boundary[1]); 1561 break; 1562 case 'alt_attach': 1563 $body .= $this->TextLine("--" . $this->boundary[1]); 1564 $body .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); 1565 $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"'); 1566 $body .= $this->LE; 1567 $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', ''); 1568 $body .= $this->EncodeString($this->AltBody, $this->Encoding); 1569 $body .= $this->LE.$this->LE; 1570 $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', ''); 1571 $body .= $this->EncodeString($this->Body, $this->Encoding); 1572 $body .= $this->LE.$this->LE; 1573 $body .= $this->EndBoundary($this->boundary[2]); 1574 $body .= $this->LE; 1575 $body .= $this->AttachAll("attachment", $this->boundary[1]); 1576 break; 1577 case 'alt_inline_attach': 1578 $body .= $this->TextLine("--" . $this->boundary[1]); 1579 $body .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); 1580 $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"'); 1581 $body .= $this->LE; 1582 $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', ''); 1583 $body .= $this->EncodeString($this->AltBody, $this->Encoding); 1584 $body .= $this->LE.$this->LE; 1585 $body .= $this->TextLine("--" . $this->boundary[2]); 1586 $body .= $this->HeaderLine('Content-Type', 'multipart/related;'); 1587 $body .= $this->TextLine("\tboundary=\"" . $this->boundary[3] . '"'); 1588 $body .= $this->LE; 1589 $body .= $this->GetBoundary($this->boundary[3], '', 'text/html', ''); 1590 $body .= $this->EncodeString($this->Body, $this->Encoding); 1591 $body .= $this->LE.$this->LE; 1592 $body .= $this->AttachAll("inline", $this->boundary[3]); 1593 $body .= $this->LE; 1594 $body .= $this->EndBoundary($this->boundary[2]); 1595 $body .= $this->LE; 1596 $body .= $this->AttachAll("attachment", $this->boundary[1]); 1597 break; 1598 default: 1599 // catch case 'plain' and case '' 1600 $body .= $this->EncodeString($this->Body, $this->Encoding); 1601 break; 1602 } 1603 1604 if ($this->IsError()) { 1605 $body = ''; 1606 } elseif ($this->sign_key_file) { 1607 try { 1608 $file = tempnam('', 'mail'); 1609 file_put_contents($file, $body); //TODO check this worked 1610 $signed = tempnam("", "signed"); 1611 if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) { 1612 @unlink($file); 1613 $body = file_get_contents($signed); 1614 @unlink($signed); 1615 } else { 1616 @unlink($file); 1617 @unlink($signed); 1618 throw new phpmailerException($this->Lang("signing").openssl_error_string()); 1619 } 1620 } catch (phpmailerException $e) { 1621 $body = ''; 1622 if ($this->exceptions) { 1623 throw $e; 1624 } 1625 } 1626 } 1627 1628 return $body; 1629 } 1630 1631 /** 1632 * Returns the start of a message boundary. 1633 * @access protected 1634 * @param string $boundary 1635 * @param string $charSet 1636 * @param string $contentType 1637 * @param string $encoding 1638 * @return string 1639 */ 1640 protected function GetBoundary($boundary, $charSet, $contentType, $encoding) { 1641 $result = ''; 1642 if($charSet == '') { 1643 $charSet = $this->CharSet; 1644 } 1645 if($contentType == '') { 1646 $contentType = $this->ContentType; 1647 } 1648 if($encoding == '') { 1649 $encoding = $this->Encoding; 1650 } 1651 $result .= $this->TextLine('--' . $boundary); 1652 $result .= sprintf("Content-Type: %s; charset=%s", $contentType, $charSet); 1653 $result .= $this->LE; 1654 $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding); 1655 $result .= $this->LE; 1656 1657 return $result; 1658 } 1659 1660 /** 1661 * Returns the end of a message boundary. 1662 * @access protected 1663 * @param string $boundary 1664 * @return string 1665 */ 1666 protected function EndBoundary($boundary) { 1667 return $this->LE . '--' . $boundary . '--' . $this->LE; 1668 } 1669 1670 /** 1671 * Sets the message type. 1672 * @access protected 1673 * @return void 1674 */ 1675 protected function SetMessageType() { 1676 $this->message_type = array(); 1677 if($this->AlternativeExists()) $this->message_type[] = "alt"; 1678 if($this->InlineImageExists()) $this->message_type[] = "inline"; 1679 if($this->AttachmentExists()) $this->message_type[] = "attach"; 1680 $this->message_type = implode("_", $this->message_type); 1681 if($this->message_type == "") $this->message_type = "plain"; 1682 } 1683 1684 /** 1685 * Returns a formatted header line. 1686 * @access public 1687 * @param string $name 1688 * @param string $value 1689 * @return string 1690 */ 1691 public function HeaderLine($name, $value) { 1692 return $name . ': ' . $value . $this->LE; 1693 } 1694 1695 /** 1696 * Returns a formatted mail line. 1697 * @access public 1698 * @param string $value 1699 * @return string 1700 */ 1701 public function TextLine($value) { 1702 return $value . $this->LE; 1703 } 1704 1705 ///////////////////////////////////////////////// 1706 // CLASS METHODS, ATTACHMENTS 1707 ///////////////////////////////////////////////// 1708 1709 /** 1710 * Adds an attachment from a path on the filesystem. 1711 * Returns false if the file could not be found 1712 * or accessed. 1713 * @param string $path Path to the attachment. 1714 * @param string $name Overrides the attachment name. 1715 * @param string $encoding File encoding (see $Encoding). 1716 * @param string $type File extension (MIME) type. 1717 * @throws phpmailerException 1718 * @return bool 1719 */ 1720 public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 1721 try { 1722 if ( !@is_file($path) ) { 1723 throw new phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE); 1724 } 1725 $filename = basename($path); 1726 if ( $name == '' ) { 1727 $name = $filename; 1728 } 1729 1730 $this->attachment[] = array( 1731 0 => $path, 1732 1 => $filename, 1733 2 => $name, 1734 3 => $encoding, 1735 4 => $type, 1736 5 => false, // isStringAttachment 1737 6 => 'attachment', 1738 7 => 0 1739 ); 1740 1741 } catch (phpmailerException $e) { 1742 $this->SetError($e->getMessage()); 1743 if ($this->exceptions) { 1744 throw $e; 1745 } 1746 if ($this->SMTPDebug) { 1747 $this->edebug($e->getMessage()."\n"); 1748 } 1749 if ( $e->getCode() == self::STOP_CRITICAL ) { 1750 return false; 1751 } 1752 } 1753 return true; 1754 } 1755 1756 /** 1757 * Return the current array of attachments 1758 * @return array 1759 */ 1760 public function GetAttachments() { 1761 return $this->attachment; 1762 } 1763 1764 /** 1765 * Attaches all fs, string, and binary attachments to the message. 1766 * Returns an empty string on failure. 1767 * @access protected 1768 * @param string $disposition_type 1769 * @param string $boundary 1770 * @return string 1771 */ 1772 protected function AttachAll($disposition_type, $boundary) { 1773 // Return text of body 1774 $mime = array(); 1775 $cidUniq = array(); 1776 $incl = array(); 1777 1778 // Add all attachments 1779 foreach ($this->attachment as $attachment) { 1780 // CHECK IF IT IS A VALID DISPOSITION_FILTER 1781 if($attachment[6] == $disposition_type) { 1782 // Check for string attachment 1783 $string = ''; 1784 $path = ''; 1785 $bString = $attachment[5]; 1786 if ($bString) { 1787 $string = $attachment[0]; 1788 } else { 1789 $path = $attachment[0]; 1790 } 1791 1792 $inclhash = md5(serialize($attachment)); 1793 if (in_array($inclhash, $incl)) { continue; } 1794 $incl[] = $inclhash; 1795 $filename = $attachment[1]; 1796 $name = $attachment[2]; 1797 $encoding = $attachment[3]; 1798 $type = $attachment[4]; 1799 $disposition = $attachment[6]; 1800 $cid = $attachment[7]; 1801 if ( $disposition == 'inline' && isset($cidUniq[$cid]) ) { continue; } 1802 $cidUniq[$cid] = true; 1803 1804 $mime[] = sprintf("--%s%s", $boundary, $this->LE); 1805 $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE); 1806 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); 1807 1808 if($disposition == 'inline') { 1809 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); 1810 } 1811 1812 $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE); 1813 1814 // Encode as string attachment 1815 if($bString) { 1816 $mime[] = $this->EncodeString($string, $encoding); 1817 if($this->IsError()) { 1818 return ''; 1819 } 1820 $mime[] = $this->LE.$this->LE; 1821 } else { 1822 $mime[] = $this->EncodeFile($path, $encoding); 1823 if($this->IsError()) { 1824 return ''; 1825 } 1826 $mime[] = $this->LE.$this->LE; 1827 } 1828 } 1829 } 1830 1831 $mime[] = sprintf("--%s--%s", $boundary, $this->LE); 1832 1833 return implode("", $mime); 1834 } 1835 1836 /** 1837 * Encodes attachment in requested format. 1838 * Returns an empty string on failure. 1839 * @param string $path The full path to the file 1840 * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' 1841 * @throws phpmailerException 1842 * @see EncodeFile() 1843 * @access protected 1844 * @return string 1845 */ 1846 protected function EncodeFile($path, $encoding = 'base64') { 1847 try { 1848 if (!is_readable($path)) { 1849 throw new phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE); 1850 } 1851 // if (!function_exists('get_magic_quotes')) { 1852 // function get_magic_quotes() { 1853 // return false; 1854 // } 1855 // } 1856 $magic_quotes = get_magic_quotes_runtime(); 1857 if ($magic_quotes) { 1858 if (version_compare(PHP_VERSION, '5.3.0', '<')) { 1859 set_magic_quotes_runtime(0); 1860 } else { 1861 ini_set('magic_quotes_runtime', 0); 1862 } 1863 } 1864 $file_buffer = file_get_contents($path); 1865 $file_buffer = $this->EncodeString($file_buffer, $encoding); 1866 if ($magic_quotes) { 1867 if (version_compare(PHP_VERSION, '5.3.0', '<')) { 1868 set_magic_quotes_runtime($magic_quotes); 1869 } else { 1870 ini_set('magic_quotes_runtime', $magic_quotes); 1871 } 1872 } 1873 return $file_buffer; 1874 } catch (Exception $e) { 1875 $this->SetError($e->getMessage()); 1876 return ''; 1877 } 1878 } 1879 1880 /** 1881 * Encodes string to requested format. 1882 * Returns an empty string on failure. 1883 * @param string $str The text to encode 1884 * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' 1885 * @access public 1886 * @return string 1887 */ 1888 public function EncodeString($str, $encoding = 'base64') { 1889 $encoded = ''; 1890 switch(strtolower($encoding)) { 1891 case 'base64': 1892 $encoded = chunk_split(base64_encode($str), 76, $this->LE); 1893 break; 1894 case '7bit': 1895 case '8bit': 1896 $encoded = $this->FixEOL($str); 1897 //Make sure it ends with a line break 1898 if (substr($encoded, -(strlen($this->LE))) != $this->LE) 1899 $encoded .= $this->LE; 1900 break; 1901 case 'binary': 1902 $encoded = $str; 1903 break; 1904 case 'quoted-printable': 1905 $encoded = $this->EncodeQP($str); 1906 break; 1907 default: 1908 $this->SetError($this->Lang('encoding') . $encoding); 1909 break; 1910 } 1911 return $encoded; 1912 } 1913 1914 /** 1915 * Encode a header string to best (shortest) of Q, B, quoted or none. 1916 * @access public 1917 * @param string $str 1918 * @param string $position 1919 * @return string 1920 */ 1921 public function EncodeHeader($str, $position = 'text') { 1922 $x = 0; 1923 1924 switch (strtolower($position)) { 1925 case 'phrase': 1926 if (!preg_match('/[\200-\377]/', $str)) { 1927 // Can't use addslashes as we don't know what value has magic_quotes_sybase 1928 $encoded = addcslashes($str, "\0..\37\177\\\""); 1929 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { 1930 return ($encoded); 1931 } else { 1932 return ("\"$encoded\""); 1933 } 1934 } 1935 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); 1936 break; 1937 case 'comment': 1938 $x = preg_match_all('/[()"]/', $str, $matches); 1939 // Fall-through 1940 case 'text': 1941 default: 1942 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); 1943 break; 1944 } 1945 1946 if ($x == 0) { 1947 return ($str); 1948 } 1949 1950 $maxlen = 75 - 7 - strlen($this->CharSet); 1951 // Try to select the encoding which should produce the shortest output 1952 if (strlen($str)/3 < $x) { 1953 $encoding = 'B'; 1954 if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) { 1955 // Use a custom function which correctly encodes and wraps long 1956 // multibyte strings without breaking lines within a character 1957 $encoded = $this->Base64EncodeWrapMB($str, "\n"); 1958 } else { 1959 $encoded = base64_encode($str); 1960 $maxlen -= $maxlen % 4; 1961 $encoded = trim(chunk_split($encoded, $maxlen, "\n")); 1962 } 1963 } else { 1964 $encoding = 'Q'; 1965 $encoded = $this->EncodeQ($str, $position); 1966 $encoded = $this->WrapText($encoded, $maxlen, true); 1967 $encoded = str_replace('='.self::CRLF, "\n", trim($encoded)); 1968 } 1969 1970 $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); 1971 $encoded = trim(str_replace("\n", $this->LE, $encoded)); 1972 1973 return $encoded; 1974 } 1975 1976 /** 1977 * Checks if a string contains multibyte characters. 1978 * @access public 1979 * @param string $str multi-byte text to wrap encode 1980 * @return bool 1981 */ 1982 public function HasMultiBytes($str) { 1983 if (function_exists('mb_strlen')) { 1984 return (strlen($str) > mb_strlen($str, $this->CharSet)); 1985 } else { // Assume no multibytes (we can't handle without mbstring functions anyway) 1986 return false; 1987 } 1988 } 1989 1990 /** 1991 * Correctly encodes and wraps long multibyte strings for mail headers 1992 * without breaking lines within a character. 1993 * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php 1994 * @access public 1995 * @param string $str multi-byte text to wrap encode 1996 * @param string $lf string to use as linefeed/end-of-line 1997 * @return string 1998 */ 1999 public function Base64EncodeWrapMB($str, $lf=null) { 2000 $start = "=?".$this->CharSet."?B?"; 2001 $end = "?="; 2002 $encoded = ""; 2003 if ($lf === null) { 2004 $lf = $this->LE; 2005 } 2006 2007 $mb_length = mb_strlen($str, $this->CharSet); 2008 // Each line must have length <= 75, including $start and $end 2009 $length = 75 - strlen($start) - strlen($end); 2010 // Average multi-byte ratio 2011 $ratio = $mb_length / strlen($str); 2012 // Base64 has a 4:3 ratio 2013 $offset = $avgLength = floor($length * $ratio * .75); 2014 2015 for ($i = 0; $i < $mb_length; $i += $offset) { 2016 $lookBack = 0; 2017 2018 do { 2019 $offset = $avgLength - $lookBack; 2020 $chunk = mb_substr($str, $i, $offset, $this->CharSet); 2021 $chunk = base64_encode($chunk); 2022 $lookBack++; 2023 } 2024 while (strlen($chunk) > $length); 2025 2026 $encoded .= $chunk . $lf; 2027 } 2028 2029 // Chomp the last linefeed 2030 $encoded = substr($encoded, 0, -strlen($lf)); 2031 return $encoded; 2032 } 2033 2034 /** 2035 * Encode string to quoted-printable. 2036 * Only uses standard PHP, slow, but will always work 2037 * @access public 2038 * @param string $input 2039 * @param integer $line_max Number of chars allowed on a line before wrapping 2040 * @param bool $space_conv 2041 * @internal param string $string the text to encode 2042 * @return string 2043 */ 2044 public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) { 2045 $hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); 2046 $lines = preg_split('/(?:\r\n|\r|\n)/', $input); 2047 $eol = "\r\n"; 2048 $escape = '='; 2049 $output = ''; 2050 while( list(, $line) = each($lines) ) { 2051 $linlen = strlen($line); 2052 $newline = ''; 2053 for($i = 0; $i < $linlen; $i++) { 2054 $c = substr( $line, $i, 1 ); 2055 $dec = ord( $c ); 2056 if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E 2057 $c = '=2E'; 2058 } 2059 if ( $dec == 32 ) { 2060 if ( $i == ( $linlen - 1 ) ) { // convert space at eol only 2061 $c = '=20'; 2062 } else if ( $space_conv ) { 2063 $c = '=20'; 2064 } 2065 } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required 2066 $h2 = (integer)floor($dec/16); 2067 $h1 = (integer)floor($dec%16); 2068 $c = $escape.$hex[$h2].$hex[$h1]; 2069 } 2070 if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted 2071 $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay 2072 $newline = ''; 2073 // check if newline first character will be point or not 2074 if ( $dec == 46 ) { 2075 $c = '=2E'; 2076 } 2077 } 2078 $newline .= $c; 2079 } // end of for 2080 $output .= $newline.$eol; 2081 } // end of while 2082 return $output; 2083 } 2084 2085 /** 2086 * Encode string to RFC2045 (6.7) quoted-printable format 2087 * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version 2088 * Also results in same content as you started with after decoding 2089 * @see EncodeQPphp() 2090 * @access public 2091 * @param string $string the text to encode 2092 * @param integer $line_max Number of chars allowed on a line before wrapping 2093 * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function 2094 * @return string 2095 * @author Marcus Bointon 2096 */ 2097 public function EncodeQP($string, $line_max = 76, $space_conv = false) { 2098 if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3) 2099 return quoted_printable_encode($string); 2100 } 2101 $filters = stream_get_filters(); 2102 if (!in_array('convert.*', $filters)) { //Got convert stream filter? 2103 return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation 2104 } 2105 $fp = fopen('php://temp/', 'r+'); 2106 $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks 2107 $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE); 2108 $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params); 2109 fputs($fp, $string); 2110 rewind($fp); 2111 $out = stream_get_contents($fp); 2112 stream_filter_remove($s); 2113 $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange 2114 fclose($fp); 2115 return $out; 2116 } 2117 2118 /** 2119 * Encode string to q encoding. 2120 * @link http://tools.ietf.org/html/rfc2047 2121 * @param string $str the text to encode 2122 * @param string $position Where the text is going to be used, see the RFC for what that means 2123 * @access public 2124 * @return string 2125 */ 2126 public function EncodeQ($str, $position = 'text') { 2127 //There should not be any EOL in the string 2128 $pattern=""; 2129 $encoded = str_replace(array("\r", "\n"), '', $str); 2130 switch (strtolower($position)) { 2131 case 'phrase': 2132 $pattern = '^A-Za-z0-9!*+\/ -'; 2133 break; 2134 2135 case 'comment': 2136 $pattern = '\(\)"'; 2137 //note that we dont break here! 2138 //for this reason we build the $pattern withoud including delimiters and [] 2139 2140 case 'text': 2141 default: 2142 //Replace every high ascii, control =, ? and _ characters 2143 //We put \075 (=) as first value to make sure it's the first one in being converted, preventing double encode 2144 $pattern = '\075\000-\011\013\014\016-\037\077\137\177-\377' . $pattern; 2145 break; 2146 } 2147 2148 if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) { 2149 foreach (array_unique($matches[0]) as $char) { 2150 $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded); 2151 } 2152 } 2153 2154 //Replace every spaces to _ (more readable than =20) 2155 return str_replace(' ', '_', $encoded); 2156 } 2157 2158 2159 /** 2160 * Adds a string or binary attachment (non-filesystem) to the list. 2161 * This method can be used to attach ascii or binary data, 2162 * such as a BLOB record from a database. 2163 * @param string $string String attachment data. 2164 * @param string $filename Name of the attachment. 2165 * @param string $encoding File encoding (see $Encoding). 2166 * @param string $type File extension (MIME) type. 2167 * @return void 2168 */ 2169 public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') { 2170 // Append to $attachment array 2171 $this->attachment[] = array( 2172 0 => $string, 2173 1 => $filename, 2174 2 => basename($filename), 2175 3 => $encoding, 2176 4 => $type, 2177 5 => true, // isStringAttachment 2178 6 => 'attachment', 2179 7 => 0 2180 ); 2181 } 2182 2183 /** 2184 * Adds an embedded attachment. This can include images, sounds, and 2185 * just about any other document. Make sure to set the $type to an 2186 * image type. For JPEG images use "image/jpeg" and for GIF images 2187 * use "image/gif". 2188 * @param string $path Path to the attachment. 2189 * @param string $cid Content ID of the attachment. Use this to identify 2190 * the Id for accessing the image in an HTML form. 2191 * @param string $name Overrides the attachment name. 2192 * @param string $encoding File encoding (see $Encoding). 2193 * @param string $type File extension (MIME) type. 2194 * @return bool 2195 */ 2196 public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 2197 2198 if ( !@is_file($path) ) { 2199 $this->SetError($this->Lang('file_access') . $path); 2200 return false; 2201 } 2202 2203 $filename = basename($path); 2204 if ( $name == '' ) { 2205 $name = $filename; 2206 } 2207 2208 // Append to $attachment array 2209 $this->attachment[] = array( 2210 0 => $path, 2211 1 => $filename, 2212 2 => $name, 2213 3 => $encoding, 2214 4 => $type, 2215 5 => false, // isStringAttachment 2216 6 => 'inline', 2217 7 => $cid 2218 ); 2219 2220 return true; 2221 } 2222 2223 /** 2224 * Adds an embedded stringified attachment. This can include images, sounds, and 2225 * just about any other document. Make sure to set the $type to an 2226 * image type. For JPEG images use "image/jpeg" and for GIF images 2227 * use "image/gif". 2228 * @param string $string The attachment. 2229 * @param string $cid Content ID of the attachment. Use this to identify 2230 * the Id for accessing the image in an HTML form. 2231 * @param string $name Overrides the attachment name. 2232 * @param string $encoding File encoding (see $Encoding). 2233 * @param string $type File extension (MIME) type. 2234 * @return bool 2235 */ 2236 public function AddStringEmbeddedImage($string, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 2237 // Append to $attachment array 2238 $this->attachment[] = array( 2239 0 => $string, 2240 1 => $name, 2241 2 => $name, 2242 3 => $encoding, 2243 4 => $type, 2244 5 => true, // isStringAttachment 2245 6 => 'inline', 2246 7 => $cid 2247 ); 2248 } 2249 2250 /** 2251 * Returns true if an inline attachment is present. 2252 * @access public 2253 * @return bool 2254 */ 2255 public function InlineImageExists() { 2256 foreach($this->attachment as $attachment) { 2257 if ($attachment[6] == 'inline') { 2258 return true; 2259 } 2260 } 2261 return false; 2262 } 2263 2264 /** 2265 * Returns true if an attachment (non-inline) is present. 2266 * @return bool 2267 */ 2268 public function AttachmentExists() { 2269 foreach($this->attachment as $attachment) { 2270 if ($attachment[6] == 'attachment') { 2271 return true; 2272 } 2273 } 2274 return false; 2275 } 2276 2277 /** 2278 * Does this message have an alternative body set? 2279 * @return bool 2280 */ 2281 public function AlternativeExists() { 2282 return !empty($this->AltBody); 2283 } 2284 2285 ///////////////////////////////////////////////// 2286 // CLASS METHODS, MESSAGE RESET 2287 ///////////////////////////////////////////////// 2288 2289 /** 2290 * Clears all recipients assigned in the TO array. Returns void. 2291 * @return void 2292 */ 2293 public function ClearAddresses() { 2294 foreach($this->to as $to) { 2295 unset($this->all_recipients[strtolower($to[0])]); 2296 } 2297 $this->to = array(); 2298 } 2299 2300 /** 2301 * Clears all recipients assigned in the CC array. Returns void. 2302 * @return void 2303 */ 2304 public function ClearCCs() { 2305 foreach($this->cc as $cc) { 2306 unset($this->all_recipients[strtolower($cc[0])]); 2307 } 2308 $this->cc = array(); 2309 } 2310 2311 /** 2312 * Clears all recipients assigned in the BCC array. Returns void. 2313 * @return void 2314 */ 2315 public function ClearBCCs() { 2316 foreach($this->bcc as $bcc) { 2317 unset($this->all_recipients[strtolower($bcc[0])]); 2318 } 2319 $this->bcc = array(); 2320 } 2321 2322 /** 2323 * Clears all recipients assigned in the ReplyTo array. Returns void. 2324 * @return void 2325 */ 2326 public function ClearReplyTos() { 2327 $this->ReplyTo = array(); 2328 } 2329 2330 /** 2331 * Clears all recipients assigned in the TO, CC and BCC 2332 * array. Returns void. 2333 * @return void 2334 */ 2335 public function ClearAllRecipients() { 2336 $this->to = array(); 2337 $this->cc = array(); 2338 $this->bcc = array(); 2339 $this->all_recipients = array(); 2340 } 2341 2342 /** 2343 * Clears all previously set filesystem, string, and binary 2344 * attachments. Returns void. 2345 * @return void 2346 */ 2347 public function ClearAttachments() { 2348 $this->attachment = array(); 2349 } 2350 2351 /** 2352 * Clears all custom headers. Returns void. 2353 * @return void 2354 */ 2355 public function ClearCustomHeaders() { 2356 $this->CustomHeader = array(); 2357 } 2358 2359 ///////////////////////////////////////////////// 2360 // CLASS METHODS, MISCELLANEOUS 2361 ///////////////////////////////////////////////// 2362 2363 /** 2364 * Adds the error message to the error container. 2365 * @access protected 2366 * @param string $msg 2367 * @return void 2368 */ 2369 protected function SetError($msg) { 2370 $this->error_count++; 2371 if ($this->Mailer == 'smtp' and !is_null($this->smtp)) { 2372 $lasterror = $this->smtp->getError(); 2373 if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) { 2374 $msg .= '<p>' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n"; 2375 } 2376 } 2377 $this->ErrorInfo = $msg; 2378 } 2379 2380 /** 2381 * Returns the proper RFC 822 formatted date. 2382 * @access public 2383 * @return string 2384 * @static 2385 */ 2386 public static function RFCDate() { 2387 $tz = date('Z'); 2388 $tzs = ($tz < 0) ? '-' : '+'; 2389 $tz = abs($tz); 2390 $tz = (int)($tz/3600)*100 + ($tz%3600)/60; 2391 $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz); 2392 2393 return $result; 2394 } 2395 2396 /** 2397 * Returns the server hostname or 'localhost.localdomain' if unknown. 2398 * @access protected 2399 * @return string 2400 */ 2401 protected function ServerHostname() { 2402 if (!empty($this->Hostname)) { 2403 $result = $this->Hostname; 2404 } elseif (isset($_SERVER['SERVER_NAME'])) { 2405 $result = $_SERVER['SERVER_NAME']; 2406 } else { 2407 $result = 'localhost.localdomain'; 2408 } 2409 2410 return $result; 2411 } 2412 2413 /** 2414 * Returns a message in the appropriate language. 2415 * @access protected 2416 * @param string $key 2417 * @return string 2418 */ 2419 protected function Lang($key) { 2420 if(count($this->language) < 1) { 2421 $this->SetLanguage('en'); // set the default language 2422 } 2423 2424 if(isset($this->language[$key])) { 2425 return $this->language[$key]; 2426 } else { 2427 return 'Language string failed to load: ' . $key; 2428 } 2429 } 2430 2431 /** 2432 * Returns true if an error occurred. 2433 * @access public 2434 * @return bool 2435 */ 2436 public function IsError() { 2437 return ($this->error_count > 0); 2438 } 2439 2440 /** 2441 * Changes every end of line from CRLF, CR or LF to $this->LE. 2442 * @access public 2443 * @param string $str String to FixEOL 2444 * @return string 2445 */ 2446 public function FixEOL($str) { 2447 // condense down to \n 2448 $nstr = str_replace(array("\r\n", "\r"), "\n", $str); 2449 // Now convert LE as needed 2450 if ($this->LE !== "\n") { 2451 $nstr = str_replace("\n", $this->LE, $nstr); 2452 } 2453 return $nstr; 2454 } 2455 2456 /** 2457 * Adds a custom header. $name value can be overloaded to contain 2458 * both header name and value (name:value) 2459 * @access public 2460 * @param string $name custom header name 2461 * @param string $value header value 2462 * @return void 2463 */ 2464 public function AddCustomHeader($name, $value=null) { 2465 if ($value === null) { 2466 // Value passed in as name:value 2467 $this->CustomHeader[] = explode(':', $name, 2); 2468 } else { 2469 $this->CustomHeader[] = array($name, $value); 2470 } 2471 } 2472 2473 /** 2474 * Evaluates the message and returns modifications for inline images and backgrounds 2475 * @access public 2476 * @param string $message Text to be HTML modified 2477 * @param string $basedir baseline directory for path 2478 * @return string $message 2479 */ 2480 public function MsgHTML($message, $basedir = '') { 2481 preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images); 2482 if(isset($images[2])) { 2483 foreach($images[2] as $i => $url) { 2484 // do not change urls for absolute images (thanks to corvuscorax) 2485 if (!preg_match('#^[A-z]+://#', $url)) { 2486 $filename = basename($url); 2487 $directory = dirname($url); 2488 if ($directory == '.') { 2489 $directory = ''; 2490 } 2491 $cid = 'cid:' . md5($url); 2492 $ext = pathinfo($filename, PATHINFO_EXTENSION); 2493 $mimeType = self::_mime_types($ext); 2494 if ( strlen($basedir) > 1 && substr($basedir, -1) != '/') { $basedir .= '/'; } 2495 if ( strlen($directory) > 1 && substr($directory, -1) != '/') { $directory .= '/'; } 2496 if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($url), $filename, 'base64', $mimeType) ) { 2497 $message = preg_replace("/".$images[1][$i]."=[\"']".preg_quote($url, '/')."[\"']/Ui", $images[1][$i]."=\"".$cid."\"", $message); 2498 } 2499 } 2500 } 2501 } 2502 $this->IsHTML(true); 2503 $this->Body = $message; 2504 if (empty($this->AltBody)) { 2505 $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message))); 2506 if (!empty($textMsg)) { 2507 $this->AltBody = html_entity_decode($textMsg, ENT_QUOTES, $this->CharSet); 2508 } 2509 } 2510 if (empty($this->AltBody)) { 2511 $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n"; 2512 } 2513 return $message; 2514 } 2515 2516 /** 2517 * Gets the MIME type of the embedded or inline image 2518 * @param string $ext File extension 2519 * @access public 2520 * @return string MIME type of ext 2521 * @static 2522 */ 2523 public static function _mime_types($ext = '') { 2524 $mimes = array( 2525 'xl' => 'application/excel', 2526 'hqx' => 'application/mac-binhex40', 2527 'cpt' => 'application/mac-compactpro', 2528 'bin' => 'application/macbinary', 2529 'doc' => 'application/msword', 2530 'word' => 'application/msword', 2531 'class' => 'application/octet-stream', 2532 'dll' => 'application/octet-stream', 2533 'dms' => 'application/octet-stream', 2534 'exe' => 'application/octet-stream', 2535 'lha' => 'application/octet-stream', 2536 'lzh' => 'application/octet-stream', 2537 'psd' => 'application/octet-stream', 2538 'sea' => 'application/octet-stream', 2539 'so' => 'application/octet-stream', 2540 'oda' => 'application/oda', 2541 'pdf' => 'application/pdf', 2542 'ai' => 'application/postscript', 2543 'eps' => 'application/postscript', 2544 'ps' => 'application/postscript', 2545 'smi' => 'application/smil', 2546 'smil' => 'application/smil', 2547 'mif' => 'application/vnd.mif', 2548 'xls' => 'application/vnd.ms-excel', 2549 'ppt' => 'application/vnd.ms-powerpoint', 2550 'wbxml' => 'application/vnd.wap.wbxml', 2551 'wmlc' => 'application/vnd.wap.wmlc', 2552 'dcr' => 'application/x-director', 2553 'dir' => 'application/x-director', 2554 'dxr' => 'application/x-director', 2555 'dvi' => 'application/x-dvi', 2556 'gtar' => 'application/x-gtar', 2557 'php3' => 'application/x-httpd-php', 2558 'php4' => 'application/x-httpd-php', 2559 'php' => 'application/x-httpd-php', 2560 'phtml' => 'application/x-httpd-php', 2561 'phps' => 'application/x-httpd-php-source', 2562 'js' => 'application/x-javascript', 2563 'swf' => 'application/x-shockwave-flash', 2564 'sit' => 'application/x-stuffit', 2565 'tar' => 'application/x-tar', 2566 'tgz' => 'application/x-tar', 2567 'xht' => 'application/xhtml+xml', 2568 'xhtml' => 'application/xhtml+xml', 2569 'zip' => 'application/zip', 2570 'mid' => 'audio/midi', 2571 'midi' => 'audio/midi', 2572 'mp2' => 'audio/mpeg', 2573 'mp3' => 'audio/mpeg', 2574 'mpga' => 'audio/mpeg', 2575 'aif' => 'audio/x-aiff', 2576 'aifc' => 'audio/x-aiff', 2577 'aiff' => 'audio/x-aiff', 2578 'ram' => 'audio/x-pn-realaudio', 2579 'rm' => 'audio/x-pn-realaudio', 2580 'rpm' => 'audio/x-pn-realaudio-plugin', 2581 'ra' => 'audio/x-realaudio', 2582 'wav' => 'audio/x-wav', 2583 'bmp' => 'image/bmp', 2584 'gif' => 'image/gif', 2585 'jpeg' => 'image/jpeg', 2586 'jpe' => 'image/jpeg', 2587 'jpg' => 'image/jpeg', 2588 'png' => 'image/png', 2589 'tiff' => 'image/tiff', 2590 'tif' => 'image/tiff', 2591 'eml' => 'message/rfc822', 2592 'css' => 'text/css', 2593 'html' => 'text/html', 2594 'htm' => 'text/html', 2595 'shtml' => 'text/html', 2596 'log' => 'text/plain', 2597 'text' => 'text/plain', 2598 'txt' => 'text/plain', 2599 'rtx' => 'text/richtext', 2600 'rtf' => 'text/rtf', 2601 'xml' => 'text/xml', 2602 'xsl' => 'text/xml', 2603 'mpeg' => 'video/mpeg', 2604 'mpe' => 'video/mpeg', 2605 'mpg' => 'video/mpeg', 2606 'mov' => 'video/quicktime', 2607 'qt' => 'video/quicktime', 2608 'rv' => 'video/vnd.rn-realvideo', 2609 'avi' => 'video/x-msvideo', 2610 'movie' => 'video/x-sgi-movie' 2611 ); 2612 return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; 2613 } 2614 2615 /** 2616 * Set (or reset) Class Objects (variables) 2617 * 2618 * Usage Example: 2619 * $page->set('X-Priority', '3'); 2620 * 2621 * @access public 2622 * @param string $name Parameter Name 2623 * @param mixed $value Parameter Value 2624 * NOTE: will not work with arrays, there are no arrays to set/reset 2625 * @throws phpmailerException 2626 * @return bool 2627 * @todo Should this not be using __set() magic function? 2628 */ 2629 public function set($name, $value = '') { 2630 try { 2631 if (isset($this->$name) ) { 2632 $this->$name = $value; 2633 } else { 2634 throw new phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL); 2635 } 2636 } catch (Exception $e) { 2637 $this->SetError($e->getMessage()); 2638 if ($e->getCode() == self::STOP_CRITICAL) { 2639 return false; 2640 } 2641 } 2642 return true; 2643 } 2644 2645 /** 2646 * Strips newlines to prevent header injection. 2647 * @access public 2648 * @param string $str String 2649 * @return string 2650 */ 2651 public function SecureHeader($str) { 2652 return trim(str_replace(array("\r", "\n"), '', $str)); 2653 } 2654 2655 /** 2656 * Set the private key file and password to sign the message. 2657 * 2658 * @access public 2659 * @param $cert_filename 2660 * @param string $key_filename Parameter File Name 2661 * @param string $key_pass Password for private key 2662 */ 2663 public function Sign($cert_filename, $key_filename, $key_pass) { 2664 $this->sign_cert_file = $cert_filename; 2665 $this->sign_key_file = $key_filename; 2666 $this->sign_key_pass = $key_pass; 2667 } 2668 2669 /** 2670 * Set the private key file and password to sign the message. 2671 * 2672 * @access public 2673 * @param string $txt 2674 * @return string 2675 */ 2676 public function DKIM_QP($txt) { 2677 $line = ''; 2678 for ($i = 0; $i < strlen($txt); $i++) { 2679 $ord = ord($txt[$i]); 2680 if ( ((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E)) ) { 2681 $line .= $txt[$i]; 2682 } else { 2683 $line .= "=".sprintf("%02X", $ord); 2684 } 2685 } 2686 return $line; 2687 } 2688 2689 /** 2690 * Generate DKIM signature 2691 * 2692 * @access public 2693 * @param string $s Header 2694 * @return string 2695 */ 2696 public function DKIM_Sign($s) { 2697 $privKeyStr = file_get_contents($this->DKIM_private); 2698 if ($this->DKIM_passphrase != '') { 2699 $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase); 2700 } else { 2701 $privKey = $privKeyStr; 2702 } 2703 if (openssl_sign($s, $signature, $privKey)) { 2704 return base64_encode($signature); 2705 } 2706 return ''; 2707 } 2708 2709 /** 2710 * Generate DKIM Canonicalization Header 2711 * 2712 * @access public 2713 * @param string $s Header 2714 * @return string 2715 */ 2716 public function DKIM_HeaderC($s) { 2717 $s = preg_replace("/\r\n\s+/", " ", $s); 2718 $lines = explode("\r\n", $s); 2719 foreach ($lines as $key => $line) { 2720 list($heading, $value) = explode(":", $line, 2); 2721 $heading = strtolower($heading); 2722 $value = preg_replace("/\s+/", " ", $value) ; // Compress useless spaces 2723 $lines[$key] = $heading.":".trim($value) ; // Don't forget to remove WSP around the value 2724 } 2725 $s = implode("\r\n", $lines); 2726 return $s; 2727 } 2728 2729 /** 2730 * Generate DKIM Canonicalization Body 2731 * 2732 * @access public 2733 * @param string $body Message Body 2734 * @return string 2735 */ 2736 public function DKIM_BodyC($body) { 2737 if ($body == '') return "\r\n"; 2738 // stabilize line endings 2739 $body = str_replace("\r\n", "\n", $body); 2740 $body = str_replace("\n", "\r\n", $body); 2741 // END stabilize line endings 2742 while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") { 2743 $body = substr($body, 0, strlen($body) - 2); 2744 } 2745 return $body; 2746 } 2747 2748 /** 2749 * Create the DKIM header, body, as new header 2750 * 2751 * @access public 2752 * @param string $headers_line Header lines 2753 * @param string $subject Subject 2754 * @param string $body Body 2755 * @return string 2756 */ 2757 public function DKIM_Add($headers_line, $subject, $body) { 2758 $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms 2759 $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body 2760 $DKIMquery = 'dns/txt'; // Query method 2761 $DKIMtime = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) 2762 $subject_header = "Subject: $subject"; 2763 $headers = explode($this->LE, $headers_line); 2764 $from_header = ""; 2765 $to_header = ""; 2766 foreach($headers as $header) { 2767 if (strpos($header, 'From:') === 0) { 2768 $from_header = $header; 2769 } elseif (strpos($header, 'To:') === 0) { 2770 $to_header = $header; 2771 } 2772 } 2773 $from = str_replace('|', '=7C', $this->DKIM_QP($from_header)); 2774 $to = str_replace('|', '=7C', $this->DKIM_QP($to_header)); 2775 $subject = str_replace('|', '=7C', $this->DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable 2776 $body = $this->DKIM_BodyC($body); 2777 $DKIMlen = strlen($body) ; // Length of body 2778 $DKIMb64 = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body 2779 $ident = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";"; 2780 $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n". 2781 "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n". 2782 "\th=From:To:Subject;\r\n". 2783 "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n". 2784 "\tz=$from\r\n". 2785 "\t|$to\r\n". 2786 "\t|$subject;\r\n". 2787 "\tbh=" . $DKIMb64 . ";\r\n". 2788 "\tb="; 2789 $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs); 2790 $signed = $this->DKIM_Sign($toSign); 2791 return "X-PHPMAILER-DKIM: code.google.com/a/apache-extras.org/p/phpmailer/\r\n".$dkimhdrs.$signed."\r\n"; 2792 } 2793 2794 /** 2795 * Perform callback 2796 * @param boolean $isSent 2797 * @param string $to 2798 * @param string $cc 2799 * @param string $bcc 2800 * @param string $subject 2801 * @param string $body 2802 * @param string $from 2803 */ 2804 protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from=null) { 2805 if (!empty($this->action_function) && is_callable($this->action_function)) { 2806 $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from); 2807 call_user_func_array($this->action_function, $params); 2808 } 2809 } 2810 } 2811 2812 /** 2813 * Exception handler for PHPMailer 2814 * @package PHPMailer 2815 */ 2816 class phpmailerException extends Exception { 2817 /** 2818 * Prettify error message output 2819 * @return string 2820 */ 2821 public function errorMessage() { 2822 $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n"; 2823 return $errorMsg; 2824 } 2825 } 2826 ?> 8 require_once( 'PHPMailer/PHPMailerAutoload.php' ); -
src/wp-includes/class-smtp.php
diff --git src/wp-includes/class-smtp.php src/wp-includes/class-smtp.php index 72361bb..e4d2d1b 100644
1 1 <?php 2 /*~ class.smtp.php3 .---------------------------------------------------------------------------.4 | Software: PHPMailer - PHP email class |5 | Version: 5.2.4 |6 | Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ |7 | ------------------------------------------------------------------------- |8 | Admin: Jim Jagielski (project admininistrator) |9 | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |10 | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |11 | : Jim Jagielski (jimjag) jimjag@gmail.com |12 | Founder: Brent R. Matzelle (original founder) |13 | Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved. |14 | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |15 | Copyright (c) 2001-2003, Brent R. Matzelle |16 | ------------------------------------------------------------------------- |17 | License: Distributed under the Lesser General Public License (LGPL) |18 | http://www.gnu.org/copyleft/lesser.html |19 | This program is distributed in the hope that it will be useful - WITHOUT |20 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |21 | FITNESS FOR A PARTICULAR PURPOSE. |22 '---------------------------------------------------------------------------'23 */24 25 /**26 * PHPMailer - PHP SMTP email transport class27 * NOTE: Designed for use with PHP version 5 and up28 * @package PHPMailer29 * @author Andy Prevost30 * @author Marcus Bointon31 * @copyright 2004 - 2008 Andy Prevost32 * @author Jim Jagielski33 * @copyright 2010 - 2012 Jim Jagielski34 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)35 */36 37 2 /** 38 * PHP RFC821 SMTP client3 * Backwards compatible shim for PHPMailer library. 39 4 * 40 * Implements all the RFC 821 SMTP commands except TURN which will always return a not implemented error. 41 * SMTP also provides some utility methods for sending mail to an SMTP server. 42 * @author Chris Ryan 43 * @package PHPMailer 5 * @package WordPress 44 6 */ 45 7 46 class SMTP { 47 /** 48 * SMTP server port 49 * @var int 50 */ 51 public $SMTP_PORT = 25; 52 53 /** 54 * SMTP reply line ending (don't change) 55 * @var string 56 */ 57 public $CRLF = "\r\n"; 58 59 /** 60 * Sets whether debugging is turned on 61 * @var bool 62 */ 63 public $do_debug; // the level of debug to perform 64 65 /** 66 * Sets the function/method to use for debugging output. 67 * Right now we only honor "echo" or "error_log" 68 * @var string 69 */ 70 public $Debugoutput = "echo"; 71 72 /** 73 * Sets VERP use on/off (default is off) 74 * @var bool 75 */ 76 public $do_verp = false; 77 78 /** 79 * Sets the SMTP timeout value for reads, in seconds 80 * @var int 81 */ 82 public $Timeout = 15; 83 84 /** 85 * Sets the SMTP timelimit value for reads, in seconds 86 * @var int 87 */ 88 public $Timelimit = 30; 89 90 /** 91 * Sets the SMTP PHPMailer Version number 92 * @var string 93 */ 94 public $Version = '5.2.4'; 95 96 ///////////////////////////////////////////////// 97 // PROPERTIES, PRIVATE AND PROTECTED 98 ///////////////////////////////////////////////// 99 100 /** 101 * @var resource The socket to the server 102 */ 103 private $smtp_conn; 104 /** 105 * @var string Error message, if any, for the last call 106 */ 107 private $error; 108 /** 109 * @var string The reply the server sent to us for HELO 110 */ 111 private $helo_rply; 112 113 /** 114 * Outputs debugging info via user-defined method 115 * @param string $str 116 */ 117 private function edebug($str) { 118 if ($this->Debugoutput == "error_log") { 119 error_log($str); 120 } else { 121 echo $str; 122 } 123 } 124 125 /** 126 * Initialize the class so that the data is in a known state. 127 * @access public 128 * @return SMTP 129 */ 130 public function __construct() { 131 $this->smtp_conn = 0; 132 $this->error = null; 133 $this->helo_rply = null; 134 135 $this->do_debug = 0; 136 } 137 138 ///////////////////////////////////////////////// 139 // CONNECTION FUNCTIONS 140 ///////////////////////////////////////////////// 141 142 /** 143 * Connect to the server specified on the port specified. 144 * If the port is not specified use the default SMTP_PORT. 145 * If tval is specified then a connection will try and be 146 * established with the server for that number of seconds. 147 * If tval is not specified the default is 30 seconds to 148 * try on the connection. 149 * 150 * SMTP CODE SUCCESS: 220 151 * SMTP CODE FAILURE: 421 152 * @access public 153 * @param string $host 154 * @param int $port 155 * @param int $tval 156 * @return bool 157 */ 158 public function Connect($host, $port = 0, $tval = 30) { 159 // set the error val to null so there is no confusion 160 $this->error = null; 161 162 // make sure we are __not__ connected 163 if($this->connected()) { 164 // already connected, generate error 165 $this->error = array("error" => "Already connected to a server"); 166 return false; 167 } 168 169 if(empty($port)) { 170 $port = $this->SMTP_PORT; 171 } 172 173 // connect to the smtp server 174 $this->smtp_conn = @fsockopen($host, // the host of the server 175 $port, // the port to use 176 $errno, // error number if any 177 $errstr, // error message if any 178 $tval); // give up after ? secs 179 // verify we connected properly 180 if(empty($this->smtp_conn)) { 181 $this->error = array("error" => "Failed to connect to server", 182 "errno" => $errno, 183 "errstr" => $errstr); 184 if($this->do_debug >= 1) { 185 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />'); 186 } 187 return false; 188 } 189 190 // SMTP server can take longer to respond, give longer timeout for first read 191 // Windows does not have support for this timeout function 192 if(substr(PHP_OS, 0, 3) != "WIN") { 193 $max = ini_get('max_execution_time'); 194 if ($max != 0 && $tval > $max) { // don't bother if unlimited 195 @set_time_limit($tval); 196 } 197 stream_set_timeout($this->smtp_conn, $tval, 0); 198 } 199 200 // get any announcement 201 $announce = $this->get_lines(); 202 203 if($this->do_debug >= 2) { 204 $this->edebug("SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />'); 205 } 206 207 return true; 208 } 209 210 /** 211 * Initiate a TLS communication with the server. 212 * 213 * SMTP CODE 220 Ready to start TLS 214 * SMTP CODE 501 Syntax error (no parameters allowed) 215 * SMTP CODE 454 TLS not available due to temporary reason 216 * @access public 217 * @return bool success 218 */ 219 public function StartTLS() { 220 $this->error = null; # to avoid confusion 221 222 if(!$this->connected()) { 223 $this->error = array("error" => "Called StartTLS() without being connected"); 224 return false; 225 } 226 227 fputs($this->smtp_conn,"STARTTLS" . $this->CRLF); 228 229 $rply = $this->get_lines(); 230 $code = substr($rply,0,3); 231 232 if($this->do_debug >= 2) { 233 $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'); 234 } 235 236 if($code != 220) { 237 $this->error = 238 array("error" => "STARTTLS not accepted from server", 239 "smtp_code" => $code, 240 "smtp_msg" => substr($rply,4)); 241 if($this->do_debug >= 1) { 242 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 243 } 244 return false; 245 } 246 247 // Begin encrypted connection 248 if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { 249 return false; 250 } 251 252 return true; 253 } 254 255 /** 256 * Performs SMTP authentication. Must be run after running the 257 * Hello() method. Returns true if successfully authenticated. 258 * @access public 259 * @param string $username 260 * @param string $password 261 * @param string $authtype 262 * @param string $realm 263 * @param string $workstation 264 * @return bool 265 */ 266 public function Authenticate($username, $password, $authtype='LOGIN', $realm='', $workstation='') { 267 if (empty($authtype)) { 268 $authtype = 'LOGIN'; 269 } 270 271 switch ($authtype) { 272 case 'PLAIN': 273 // Start authentication 274 fputs($this->smtp_conn,"AUTH PLAIN" . $this->CRLF); 275 276 $rply = $this->get_lines(); 277 $code = substr($rply,0,3); 278 279 if($code != 334) { 280 $this->error = 281 array("error" => "AUTH not accepted from server", 282 "smtp_code" => $code, 283 "smtp_msg" => substr($rply,4)); 284 if($this->do_debug >= 1) { 285 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 286 } 287 return false; 288 } 289 // Send encoded username and password 290 fputs($this->smtp_conn, base64_encode("\0".$username."\0".$password) . $this->CRLF); 291 292 $rply = $this->get_lines(); 293 $code = substr($rply,0,3); 294 295 if($code != 235) { 296 $this->error = 297 array("error" => "Authentication not accepted from server", 298 "smtp_code" => $code, 299 "smtp_msg" => substr($rply,4)); 300 if($this->do_debug >= 1) { 301 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 302 } 303 return false; 304 } 305 break; 306 case 'LOGIN': 307 // Start authentication 308 fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); 309 310 $rply = $this->get_lines(); 311 $code = substr($rply,0,3); 312 313 if($code != 334) { 314 $this->error = 315 array("error" => "AUTH not accepted from server", 316 "smtp_code" => $code, 317 "smtp_msg" => substr($rply,4)); 318 if($this->do_debug >= 1) { 319 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 320 } 321 return false; 322 } 323 324 // Send encoded username 325 fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); 326 327 $rply = $this->get_lines(); 328 $code = substr($rply,0,3); 329 330 if($code != 334) { 331 $this->error = 332 array("error" => "Username not accepted from server", 333 "smtp_code" => $code, 334 "smtp_msg" => substr($rply,4)); 335 if($this->do_debug >= 1) { 336 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 337 } 338 return false; 339 } 340 341 // Send encoded password 342 fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); 343 344 $rply = $this->get_lines(); 345 $code = substr($rply,0,3); 346 347 if($code != 235) { 348 $this->error = 349 array("error" => "Password not accepted from server", 350 "smtp_code" => $code, 351 "smtp_msg" => substr($rply,4)); 352 if($this->do_debug >= 1) { 353 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 354 } 355 return false; 356 } 357 break; 358 case 'NTLM': 359 /* 360 * ntlm_sasl_client.php 361 ** Bundled with Permission 362 ** 363 ** How to telnet in windows: http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx 364 ** PROTOCOL Documentation http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication 365 */ 366 require_once('ntlm_sasl_client.php'); 367 $temp = new stdClass(); 368 $ntlm_client = new ntlm_sasl_client_class; 369 if(! $ntlm_client->Initialize($temp)){//let's test if every function its available 370 $this->error = array("error" => $temp->error); 371 if($this->do_debug >= 1) { 372 $this->edebug("You need to enable some modules in your php.ini file: " . $this->error["error"] . $this->CRLF); 373 } 374 return false; 375 } 376 $msg1 = $ntlm_client->TypeMsg1($realm, $workstation);//msg1 377 378 fputs($this->smtp_conn,"AUTH NTLM " . base64_encode($msg1) . $this->CRLF); 379 380 $rply = $this->get_lines(); 381 $code = substr($rply,0,3); 382 383 384 if($code != 334) { 385 $this->error = 386 array("error" => "AUTH not accepted from server", 387 "smtp_code" => $code, 388 "smtp_msg" => substr($rply,4)); 389 if($this->do_debug >= 1) { 390 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF); 391 } 392 return false; 393 } 394 395 $challange = substr($rply,3);//though 0 based, there is a white space after the 3 digit number....//msg2 396 $challange = base64_decode($challange); 397 $ntlm_res = $ntlm_client->NTLMResponse(substr($challange,24,8),$password); 398 $msg3 = $ntlm_client->TypeMsg3($ntlm_res,$username,$realm,$workstation);//msg3 399 // Send encoded username 400 fputs($this->smtp_conn, base64_encode($msg3) . $this->CRLF); 401 402 $rply = $this->get_lines(); 403 $code = substr($rply,0,3); 404 405 if($code != 235) { 406 $this->error = 407 array("error" => "Could not authenticate", 408 "smtp_code" => $code, 409 "smtp_msg" => substr($rply,4)); 410 if($this->do_debug >= 1) { 411 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF); 412 } 413 return false; 414 } 415 break; 416 } 417 return true; 418 } 419 420 /** 421 * Returns true if connected to a server otherwise false 422 * @access public 423 * @return bool 424 */ 425 public function Connected() { 426 if(!empty($this->smtp_conn)) { 427 $sock_status = socket_get_status($this->smtp_conn); 428 if($sock_status["eof"]) { 429 // the socket is valid but we are not connected 430 if($this->do_debug >= 1) { 431 $this->edebug("SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected"); 432 } 433 $this->Close(); 434 return false; 435 } 436 return true; // everything looks good 437 } 438 return false; 439 } 440 441 /** 442 * Closes the socket and cleans up the state of the class. 443 * It is not considered good to use this function without 444 * first trying to use QUIT. 445 * @access public 446 * @return void 447 */ 448 public function Close() { 449 $this->error = null; // so there is no confusion 450 $this->helo_rply = null; 451 if(!empty($this->smtp_conn)) { 452 // close the connection and cleanup 453 fclose($this->smtp_conn); 454 $this->smtp_conn = 0; 455 } 456 } 457 458 ///////////////////////////////////////////////// 459 // SMTP COMMANDS 460 ///////////////////////////////////////////////// 461 462 /** 463 * Issues a data command and sends the msg_data to the server 464 * finializing the mail transaction. $msg_data is the message 465 * that is to be send with the headers. Each header needs to be 466 * on a single line followed by a <CRLF> with the message headers 467 * and the message body being seperated by and additional <CRLF>. 468 * 469 * Implements rfc 821: DATA <CRLF> 470 * 471 * SMTP CODE INTERMEDIATE: 354 472 * [data] 473 * <CRLF>.<CRLF> 474 * SMTP CODE SUCCESS: 250 475 * SMTP CODE FAILURE: 552,554,451,452 476 * SMTP CODE FAILURE: 451,554 477 * SMTP CODE ERROR : 500,501,503,421 478 * @access public 479 * @param string $msg_data 480 * @return bool 481 */ 482 public function Data($msg_data) { 483 $this->error = null; // so no confusion is caused 484 485 if(!$this->connected()) { 486 $this->error = array( 487 "error" => "Called Data() without being connected"); 488 return false; 489 } 490 491 fputs($this->smtp_conn,"DATA" . $this->CRLF); 492 493 $rply = $this->get_lines(); 494 $code = substr($rply,0,3); 495 496 if($this->do_debug >= 2) { 497 $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'); 498 } 499 500 if($code != 354) { 501 $this->error = 502 array("error" => "DATA command not accepted from server", 503 "smtp_code" => $code, 504 "smtp_msg" => substr($rply,4)); 505 if($this->do_debug >= 1) { 506 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 507 } 508 return false; 509 } 510 511 /* the server is ready to accept data! 512 * according to rfc 821 we should not send more than 1000 513 * including the CRLF 514 * characters on a single line so we will break the data up 515 * into lines by \r and/or \n then if needed we will break 516 * each of those into smaller lines to fit within the limit. 517 * in addition we will be looking for lines that start with 518 * a period '.' and append and additional period '.' to that 519 * line. NOTE: this does not count towards limit. 520 */ 521 522 // normalize the line breaks so we know the explode works 523 $msg_data = str_replace("\r\n","\n",$msg_data); 524 $msg_data = str_replace("\r","\n",$msg_data); 525 $lines = explode("\n",$msg_data); 526 527 /* we need to find a good way to determine is headers are 528 * in the msg_data or if it is a straight msg body 529 * currently I am assuming rfc 822 definitions of msg headers 530 * and if the first field of the first line (':' sperated) 531 * does not contain a space then it _should_ be a header 532 * and we can process all lines before a blank "" line as 533 * headers. 534 */ 535 536 $field = substr($lines[0],0,strpos($lines[0],":")); 537 $in_headers = false; 538 if(!empty($field) && !strstr($field," ")) { 539 $in_headers = true; 540 } 541 542 $max_line_length = 998; // used below; set here for ease in change 543 544 while(list(,$line) = @each($lines)) { 545 $lines_out = null; 546 if($line == "" && $in_headers) { 547 $in_headers = false; 548 } 549 // ok we need to break this line up into several smaller lines 550 while(strlen($line) > $max_line_length) { 551 $pos = strrpos(substr($line,0,$max_line_length)," "); 552 553 // Patch to fix DOS attack 554 if(!$pos) { 555 $pos = $max_line_length - 1; 556 $lines_out[] = substr($line,0,$pos); 557 $line = substr($line,$pos); 558 } else { 559 $lines_out[] = substr($line,0,$pos); 560 $line = substr($line,$pos + 1); 561 } 562 563 /* if processing headers add a LWSP-char to the front of new line 564 * rfc 822 on long msg headers 565 */ 566 if($in_headers) { 567 $line = "\t" . $line; 568 } 569 } 570 $lines_out[] = $line; 571 572 // send the lines to the server 573 while(list(,$line_out) = @each($lines_out)) { 574 if(strlen($line_out) > 0) 575 { 576 if(substr($line_out, 0, 1) == ".") { 577 $line_out = "." . $line_out; 578 } 579 } 580 fputs($this->smtp_conn,$line_out . $this->CRLF); 581 } 582 } 583 584 // message data has been sent 585 fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); 586 587 $rply = $this->get_lines(); 588 $code = substr($rply,0,3); 589 590 if($this->do_debug >= 2) { 591 $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'); 592 } 593 594 if($code != 250) { 595 $this->error = 596 array("error" => "DATA not accepted from server", 597 "smtp_code" => $code, 598 "smtp_msg" => substr($rply,4)); 599 if($this->do_debug >= 1) { 600 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 601 } 602 return false; 603 } 604 return true; 605 } 606 607 /** 608 * Sends the HELO command to the smtp server. 609 * This makes sure that we and the server are in 610 * the same known state. 611 * 612 * Implements from rfc 821: HELO <SP> <domain> <CRLF> 613 * 614 * SMTP CODE SUCCESS: 250 615 * SMTP CODE ERROR : 500, 501, 504, 421 616 * @access public 617 * @param string $host 618 * @return bool 619 */ 620 public function Hello($host = '') { 621 $this->error = null; // so no confusion is caused 622 623 if(!$this->connected()) { 624 $this->error = array( 625 "error" => "Called Hello() without being connected"); 626 return false; 627 } 628 629 // if hostname for HELO was not specified send default 630 if(empty($host)) { 631 // determine appropriate default to send to server 632 $host = "localhost"; 633 } 634 635 // Send extended hello first (RFC 2821) 636 if(!$this->SendHello("EHLO", $host)) { 637 if(!$this->SendHello("HELO", $host)) { 638 return false; 639 } 640 } 641 642 return true; 643 } 644 645 /** 646 * Sends a HELO/EHLO command. 647 * @access private 648 * @param string $hello 649 * @param string $host 650 * @return bool 651 */ 652 private function SendHello($hello, $host) { 653 fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); 654 655 $rply = $this->get_lines(); 656 $code = substr($rply,0,3); 657 658 if($this->do_debug >= 2) { 659 $this->edebug("SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />'); 660 } 661 662 if($code != 250) { 663 $this->error = 664 array("error" => $hello . " not accepted from server", 665 "smtp_code" => $code, 666 "smtp_msg" => substr($rply,4)); 667 if($this->do_debug >= 1) { 668 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 669 } 670 return false; 671 } 672 673 $this->helo_rply = $rply; 674 675 return true; 676 } 677 678 /** 679 * Starts a mail transaction from the email address specified in 680 * $from. Returns true if successful or false otherwise. If True 681 * the mail transaction is started and then one or more Recipient 682 * commands may be called followed by a Data command. 683 * 684 * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF> 685 * 686 * SMTP CODE SUCCESS: 250 687 * SMTP CODE SUCCESS: 552,451,452 688 * SMTP CODE SUCCESS: 500,501,421 689 * @access public 690 * @param string $from 691 * @return bool 692 */ 693 public function Mail($from) { 694 $this->error = null; // so no confusion is caused 695 696 if(!$this->connected()) { 697 $this->error = array( 698 "error" => "Called Mail() without being connected"); 699 return false; 700 } 701 702 $useVerp = ($this->do_verp ? " XVERP" : ""); 703 fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF); 704 705 $rply = $this->get_lines(); 706 $code = substr($rply,0,3); 707 708 if($this->do_debug >= 2) { 709 $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'); 710 } 711 712 if($code != 250) { 713 $this->error = 714 array("error" => "MAIL not accepted from server", 715 "smtp_code" => $code, 716 "smtp_msg" => substr($rply,4)); 717 if($this->do_debug >= 1) { 718 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 719 } 720 return false; 721 } 722 return true; 723 } 724 725 /** 726 * Sends the quit command to the server and then closes the socket 727 * if there is no error or the $close_on_error argument is true. 728 * 729 * Implements from rfc 821: QUIT <CRLF> 730 * 731 * SMTP CODE SUCCESS: 221 732 * SMTP CODE ERROR : 500 733 * @access public 734 * @param bool $close_on_error 735 * @return bool 736 */ 737 public function Quit($close_on_error = true) { 738 $this->error = null; // so there is no confusion 739 740 if(!$this->connected()) { 741 $this->error = array( 742 "error" => "Called Quit() without being connected"); 743 return false; 744 } 745 746 // send the quit command to the server 747 fputs($this->smtp_conn,"quit" . $this->CRLF); 748 749 // get any good-bye messages 750 $byemsg = $this->get_lines(); 751 752 if($this->do_debug >= 2) { 753 $this->edebug("SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />'); 754 } 755 756 $rval = true; 757 $e = null; 758 759 $code = substr($byemsg,0,3); 760 if($code != 221) { 761 // use e as a tmp var cause Close will overwrite $this->error 762 $e = array("error" => "SMTP server rejected quit command", 763 "smtp_code" => $code, 764 "smtp_rply" => substr($byemsg,4)); 765 $rval = false; 766 if($this->do_debug >= 1) { 767 $this->edebug("SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />'); 768 } 769 } 770 771 if(empty($e) || $close_on_error) { 772 $this->Close(); 773 } 774 775 return $rval; 776 } 777 778 /** 779 * Sends the command RCPT to the SMTP server with the TO: argument of $to. 780 * Returns true if the recipient was accepted false if it was rejected. 781 * 782 * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF> 783 * 784 * SMTP CODE SUCCESS: 250,251 785 * SMTP CODE FAILURE: 550,551,552,553,450,451,452 786 * SMTP CODE ERROR : 500,501,503,421 787 * @access public 788 * @param string $to 789 * @return bool 790 */ 791 public function Recipient($to) { 792 $this->error = null; // so no confusion is caused 793 794 if(!$this->connected()) { 795 $this->error = array( 796 "error" => "Called Recipient() without being connected"); 797 return false; 798 } 799 800 fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); 801 802 $rply = $this->get_lines(); 803 $code = substr($rply,0,3); 804 805 if($this->do_debug >= 2) { 806 $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'); 807 } 808 809 if($code != 250 && $code != 251) { 810 $this->error = 811 array("error" => "RCPT not accepted from server", 812 "smtp_code" => $code, 813 "smtp_msg" => substr($rply,4)); 814 if($this->do_debug >= 1) { 815 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 816 } 817 return false; 818 } 819 return true; 820 } 821 822 /** 823 * Sends the RSET command to abort and transaction that is 824 * currently in progress. Returns true if successful false 825 * otherwise. 826 * 827 * Implements rfc 821: RSET <CRLF> 828 * 829 * SMTP CODE SUCCESS: 250 830 * SMTP CODE ERROR : 500,501,504,421 831 * @access public 832 * @return bool 833 */ 834 public function Reset() { 835 $this->error = null; // so no confusion is caused 836 837 if(!$this->connected()) { 838 $this->error = array( 839 "error" => "Called Reset() without being connected"); 840 return false; 841 } 842 843 fputs($this->smtp_conn,"RSET" . $this->CRLF); 844 845 $rply = $this->get_lines(); 846 $code = substr($rply,0,3); 847 848 if($this->do_debug >= 2) { 849 $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'); 850 } 851 852 if($code != 250) { 853 $this->error = 854 array("error" => "RSET failed", 855 "smtp_code" => $code, 856 "smtp_msg" => substr($rply,4)); 857 if($this->do_debug >= 1) { 858 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 859 } 860 return false; 861 } 862 863 return true; 864 } 865 866 /** 867 * Starts a mail transaction from the email address specified in 868 * $from. Returns true if successful or false otherwise. If True 869 * the mail transaction is started and then one or more Recipient 870 * commands may be called followed by a Data command. This command 871 * will send the message to the users terminal if they are logged 872 * in and send them an email. 873 * 874 * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> 875 * 876 * SMTP CODE SUCCESS: 250 877 * SMTP CODE SUCCESS: 552,451,452 878 * SMTP CODE SUCCESS: 500,501,502,421 879 * @access public 880 * @param string $from 881 * @return bool 882 */ 883 public function SendAndMail($from) { 884 $this->error = null; // so no confusion is caused 885 886 if(!$this->connected()) { 887 $this->error = array( 888 "error" => "Called SendAndMail() without being connected"); 889 return false; 890 } 891 892 fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); 893 894 $rply = $this->get_lines(); 895 $code = substr($rply,0,3); 896 897 if($this->do_debug >= 2) { 898 $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />'); 899 } 900 901 if($code != 250) { 902 $this->error = 903 array("error" => "SAML not accepted from server", 904 "smtp_code" => $code, 905 "smtp_msg" => substr($rply,4)); 906 if($this->do_debug >= 1) { 907 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />'); 908 } 909 return false; 910 } 911 return true; 912 } 913 914 /** 915 * This is an optional command for SMTP that this class does not 916 * support. This method is here to make the RFC821 Definition 917 * complete for this class and __may__ be implimented in the future 918 * 919 * Implements from rfc 821: TURN <CRLF> 920 * 921 * SMTP CODE SUCCESS: 250 922 * SMTP CODE FAILURE: 502 923 * SMTP CODE ERROR : 500, 503 924 * @access public 925 * @return bool 926 */ 927 public function Turn() { 928 $this->error = array("error" => "This method, TURN, of the SMTP ". 929 "is not implemented"); 930 if($this->do_debug >= 1) { 931 $this->edebug("SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />'); 932 } 933 return false; 934 } 935 936 /** 937 * Get the current error 938 * @access public 939 * @return array 940 */ 941 public function getError() { 942 return $this->error; 943 } 944 945 ///////////////////////////////////////////////// 946 // INTERNAL FUNCTIONS 947 ///////////////////////////////////////////////// 948 949 /** 950 * Read in as many lines as possible 951 * either before eof or socket timeout occurs on the operation. 952 * With SMTP we can tell if we have more lines to read if the 953 * 4th character is '-' symbol. If it is a space then we don't 954 * need to read anything else. 955 * @access private 956 * @return string 957 */ 958 private function get_lines() { 959 $data = ""; 960 $endtime = 0; 961 /* If for some reason the fp is bad, don't inf loop */ 962 if (!is_resource($this->smtp_conn)) { 963 return $data; 964 } 965 stream_set_timeout($this->smtp_conn, $this->Timeout); 966 if ($this->Timelimit > 0) { 967 $endtime = time() + $this->Timelimit; 968 } 969 while(is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { 970 $str = @fgets($this->smtp_conn,515); 971 if($this->do_debug >= 4) { 972 $this->edebug("SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />'); 973 $this->edebug("SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />'); 974 } 975 $data .= $str; 976 if($this->do_debug >= 4) { 977 $this->edebug("SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />'); 978 } 979 // if 4th character is a space, we are done reading, break the loop 980 if(substr($str,3,1) == " ") { break; } 981 // Timed-out? Log and break 982 $info = stream_get_meta_data($this->smtp_conn); 983 if ($info['timed_out']) { 984 if($this->do_debug >= 4) { 985 $this->edebug("SMTP -> get_lines(): timed-out (" . $this->Timeout . " seconds) <br />"); 986 } 987 break; 988 } 989 // Now check if reads took too long 990 if ($endtime) { 991 if (time() > $endtime) { 992 if($this->do_debug >= 4) { 993 $this->edebug("SMTP -> get_lines(): timelimit reached (" . $this->Timelimit . " seconds) <br />"); 994 } 995 break; 996 } 997 } 998 } 999 return $data; 1000 } 1001 1002 } 1003 ?> 8 require_once( 'PHPMailer/PHPMailerAutoload.php' ); -
src/wp-includes/pluggable.php
diff --git src/wp-includes/pluggable.php src/wp-includes/pluggable.php index 794565f..a575c6f 100644
function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() 222 222 223 223 // (Re)create it, if it's gone missing 224 224 if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) { 225 require_once ABSPATH . WPINC . '/ class-phpmailer.php';226 require_once ABSPATH . WPINC . '/ class-smtp.php';225 require_once ABSPATH . WPINC . '/PHPMailer/class.phpmailer.php'; 226 require_once ABSPATH . WPINC . '/PHPMailer/class.smtp.php'; 227 227 $phpmailer = new PHPMailer( true ); 228 228 } 229 229 -
tests/phpunit/includes/mock-mailer.php
diff --git tests/phpunit/includes/mock-mailer.php tests/phpunit/includes/mock-mailer.php index f52a95a..06d7976 100644
1 1 <?php 2 require_once( ABSPATH . '/wp-includes/ class-phpmailer.php' );2 require_once( ABSPATH . '/wp-includes/PHPMailer/PHPMailerAutoload.php' ); 3 3 4 4 class MockPHPMailer extends PHPMailer { 5 5 var $mock_sent = array(); 6 6 7 // override the Send function so it doesn't actually send anything 8 function Send() { 7 /** 8 * Override send() so mail isn't actually sent. 9 */ 10 function send() { 9 11 try { 10 if ( ! $this-> PreSend() )12 if ( ! $this->preSend() ) 11 13 return false; 12 14 13 15 $this->mock_sent[] = array(