├── bundle.php ├── config └── phpmailer.php ├── lib ├── LICENSE ├── README ├── VERSION ├── changelog.txt ├── class.phpmailer.php ├── class.pop3.php ├── class.smtp.php ├── extras │ └── htmlfilter.php └── language │ ├── phpmailer.lang-ar.php │ ├── phpmailer.lang-br.php │ ├── phpmailer.lang-ca.php │ ├── phpmailer.lang-ch.php │ ├── phpmailer.lang-cz.php │ ├── phpmailer.lang-de.php │ ├── phpmailer.lang-dk.php │ ├── phpmailer.lang-es.php │ ├── phpmailer.lang-et.php │ ├── phpmailer.lang-fi.php │ ├── phpmailer.lang-fo.php │ ├── phpmailer.lang-fr.php │ ├── phpmailer.lang-hu.php │ ├── phpmailer.lang-it.php │ ├── phpmailer.lang-ja.php │ ├── phpmailer.lang-nl.php │ ├── phpmailer.lang-no.php │ ├── phpmailer.lang-pl.php │ ├── phpmailer.lang-ro.php │ ├── phpmailer.lang-ru.php │ ├── phpmailer.lang-se.php │ ├── phpmailer.lang-tr.php │ ├── phpmailer.lang-zh.php │ └── phpmailer.lang-zh_cn.php ├── readme.md └── start.php /bundle.php: -------------------------------------------------------------------------------- 1 | 'phpmailer' 5 | ); 6 | -------------------------------------------------------------------------------- /config/phpmailer.php: -------------------------------------------------------------------------------- 1 | array('colin@example.com', 'Colin Viebrock'), 14 | * 'IsSMTP' => null, 15 | * 'Host' => 'smtp@example.com', 16 | * ) 17 | * 18 | * that would be equivalent to running this when starting 19 | * a new mailer instance: 20 | * 21 | * $mailer->SetFrom('Colin@example.com', 'Colin Viebrock'); 22 | * $mailer->IsSMTP(); 23 | * $mailer->Host = 'smtp@example.com'; 24 | * 25 | * Sadly, this is a bit limited, mostly because of how PHPMailer handles 26 | * setting values. Sometimes it's: 27 | * 28 | * $foo->bar = $value 29 | * 30 | * and sometimes it's: 31 | * 32 | * $foo->bar($value); 33 | * 34 | * Suggestions on how to better handle this are welcome, although the 35 | * most common elements that you might want to prepopulate (from address, 36 | * SMTP host and info) can be configured. 37 | */ 38 | 39 | return array( 40 | 'SetFrom' => array('colin@example.com','Colin Viebrock'), 41 | 'IsSMTP' => null, 42 | 'Host' => 'smtp.example.com', 43 | ); -------------------------------------------------------------------------------- /lib/LICENSE: -------------------------------------------------------------------------------- 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 | 474 | Copyright (C) 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 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | 504 | 505 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * http://code.google.com/a/apache-extras.org/p/phpmailer/ * 3 | ********************************************************************/ 4 | 5 | PHPMailer 6 | Full Featured Email Transfer Class for PHP 7 | ========================================== 8 | 9 | Version 5.2.1 (January 16, 2012) 10 | 11 | Patch release (see changelog.txt). 12 | 13 | Version 5.2.0 (July 19, 2011) 14 | 15 | With the release of this version, PHPMailer has moved to Apache 16 | Extras: 17 | http://code.google.com/a/apache-extras.org/p/phpmailer/ 18 | 19 | Version 5.0.0 (April 02, 2009) 20 | 21 | With the release of this version, we are initiating a new version numbering 22 | system to differentiate from the PHP4 version of PHPMailer. 23 | 24 | Most notable in this release is fully object oriented code. 25 | 26 | We now have available the PHPDocumentor (phpdocs) documentation. This is 27 | separate from the regular download to keep file sizes down. Please see the 28 | download area of http://phpmailer.codeworxtech.com. 29 | 30 | We also have created a new test script (see /test_script) that you can use 31 | right out of the box. Copy the /test_script folder directly to your server (in 32 | the same structure ... with class.phpmailer.php and class.smtp.php in the 33 | folder above it. Then launch the test script with: 34 | http://www.yourdomain.com/phpmailer/test_script/index.php 35 | from this one script, you can test your server settings for mail(), sendmail (or 36 | qmail), and SMTP. This will email you a sample email (using contents.html for 37 | the email body) and two attachments. One of the attachments is used as an inline 38 | image to demonstrate how PHPMailer will automatically detect if attachments are 39 | the same source as inline graphics and only include one version. Once you click 40 | the Submit button, the results will be displayed including any SMTP debug 41 | information and send status. We will also display a version of the script that 42 | you can cut and paste to include in your projects. Enjoy! 43 | 44 | Version 2.3 (November 08, 2008) 45 | 46 | We have removed the /phpdoc from the downloads. All documentation is now on 47 | the http://phpmailer.codeworxtech.com website. 48 | 49 | The phpunit.php has been updated to support PHP5. 50 | 51 | For all other changes and notes, please see the changelog. 52 | 53 | Donations are accepted at PayPal with our id "paypal@worxteam.com". 54 | 55 | Version 2.2 (July 15 2008) 56 | 57 | - see the changelog. 58 | 59 | Version 2.1 (June 04 2008) 60 | 61 | With this release, we are announcing that the development of PHPMailer for PHP5 62 | will be our focus from this date on. We have implemented all the enhancements 63 | and fixes from the latest release of PHPMailer for PHP4. 64 | 65 | Far more important, though, is that this release of PHPMailer (v2.1) is 66 | fully tested with E_STRICT error checking enabled. 67 | 68 | ** NOTE: WE HAVE A NEW LANGUAGE VARIABLE FOR DIGITALLY SIGNED S/MIME EMAILS. 69 | IF YOU CAN HELP WITH LANGUAGES OTHER THAN ENGLISH AND SPANISH, IT WOULD BE 70 | APPRECIATED. 71 | 72 | We have now added S/MIME functionality (ability to digitally sign emails). 73 | BIG THANKS TO "sergiocambra" for posting this patch back in November 2007. 74 | The "Signed Emails" functionality adds the Sign method to pass the private key 75 | filename and the password to read it, and then email will be sent with 76 | content-type multipart/signed and with the digital signature attached. 77 | 78 | A quick note on E_STRICT: 79 | 80 | - In about half the test environments the development version was subjected 81 | to, an error was thrown for the date() functions (used at line 1565 and 1569). 82 | This is NOT a PHPMailer error, it is the result of an incorrectly configured 83 | PHP5 installation. The fix is to modify your 'php.ini' file and include the 84 | date.timezone = America/New York 85 | directive, (for your own server timezone) 86 | - If you do get this error, and are unable to access your php.ini file, there is 87 | a workaround. In your PHP script, add 88 | date_default_timezone_set('America/Toronto'); 89 | 90 | * do NOT try to use 91 | $myVar = date_default_timezone_get(); 92 | as a test, it will throw an error. 93 | 94 | We have also included more example files to show the use of "sendmail", "mail()", 95 | "smtp", and "gmail". 96 | 97 | We are also looking for more programmers to join the volunteer development team. 98 | If you have an interest in this, please let us know. 99 | 100 | Enjoy! 101 | 102 | 103 | Version 2.1.0beta1 & beta2 104 | 105 | please note, this is BETA software 106 | ** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS 107 | INTENDED STRICTLY FOR TESTING 108 | 109 | ** NOTE: 110 | 111 | As of November 2007, PHPMailer has a new project team headed by industry 112 | veteran Andy Prevost (codeworxtech). The first release in more than two 113 | years will focus on fixes, adding ease-of-use enhancements, provide 114 | basic compatibility with PHP4 and PHP5 using PHP5 backwards compatibility 115 | features. A new release is planned before year-end 2007 that will provide 116 | full compatiblity with PHP4 and PHP5, as well as more bug fixes. 117 | 118 | We are looking for project developers to assist in restoring PHPMailer to 119 | its leadership position. Our goals are to simplify use of PHPMailer, provide 120 | good documentation and examples, and retain backward compatibility to level 121 | 1.7.3 standards. 122 | 123 | If you are interested in helping out, visit http://sourceforge.net/projects/phpmailer 124 | and indicate your interest. 125 | 126 | ** 127 | 128 | http://phpmailer.sourceforge.net/ 129 | 130 | This software is licenced under the LGPL. Please read LICENSE for information on the 131 | software availability and distribution. 132 | 133 | Class Features: 134 | - Send emails with multiple TOs, CCs, BCCs and REPLY-TOs 135 | - Redundant SMTP servers 136 | - Multipart/alternative emails for mail clients that do not read HTML email 137 | - Support for 8bit, base64, binary, and quoted-printable encoding 138 | - Uses the same methods as the very popular AspEmail active server (COM) component 139 | - SMTP authentication 140 | - Native language support 141 | - Word wrap, and more! 142 | 143 | Why you might need it: 144 | 145 | Many PHP developers utilize email in their code. The only PHP function 146 | that supports this is the mail() function. However, it does not expose 147 | any of the popular features that many email clients use nowadays like 148 | HTML-based emails and attachments. There are two proprietary 149 | development tools out there that have all the functionality built into 150 | easy to use classes: AspEmail(tm) and AspMail. Both of these 151 | programs are COM components only available on Windows. They are also a 152 | little pricey for smaller projects. 153 | 154 | Since I do Linux development I�ve missed these tools for my PHP coding. 155 | So I built a version myself that implements the same methods (object 156 | calls) that the Windows-based components do. It is open source and the 157 | LGPL license allows you to place the class in your proprietary PHP 158 | projects. 159 | 160 | 161 | Installation: 162 | 163 | Copy class.phpmailer.php into your php.ini include_path. If you are 164 | using the SMTP mailer then place class.smtp.php in your path as well. 165 | In the language directory you will find several files like 166 | phpmailer.lang-en.php. If you look right before the .php extension 167 | that there are two letters. These represent the language type of the 168 | translation file. For instance "en" is the English file and "br" is 169 | the Portuguese file. Chose the file that best fits with your language 170 | and place it in the PHP include path. If your language is English 171 | then you have nothing more to do. If it is a different language then 172 | you must point PHPMailer to the correct translation. To do this, call 173 | the PHPMailer SetLanguage method like so: 174 | 175 | // To load the Portuguese version 176 | $mail->SetLanguage("br", "/optional/path/to/language/directory/"); 177 | 178 | That's it. You should now be ready to use PHPMailer! 179 | 180 | 181 | A Simple Example: 182 | 183 | IsSMTP(); // set mailer to use SMTP 189 | $mail->Host = "smtp1.example.com;smtp2.example.com"; // specify main and backup server 190 | $mail->SMTPAuth = true; // turn on SMTP authentication 191 | $mail->Username = "jswan"; // SMTP username 192 | $mail->Password = "secret"; // SMTP password 193 | 194 | $mail->From = "from@example.com"; 195 | $mail->FromName = "Mailer"; 196 | $mail->AddAddress("josh@example.net", "Josh Adams"); 197 | $mail->AddAddress("ellen@example.com"); // name is optional 198 | $mail->AddReplyTo("info@example.com", "Information"); 199 | 200 | $mail->WordWrap = 50; // set word wrap to 50 characters 201 | $mail->AddAttachment("/var/tmp/file.tar.gz"); // add attachments 202 | $mail->AddAttachment("/tmp/image.jpg", "new.jpg"); // optional name 203 | $mail->IsHTML(true); // set email format to HTML 204 | 205 | $mail->Subject = "Here is the subject"; 206 | $mail->Body = "This is the HTML message body in bold!"; 207 | $mail->AltBody = "This is the body in plain text for non-HTML mail clients"; 208 | 209 | if(!$mail->Send()) 210 | { 211 | echo "Message could not be sent.

"; 212 | echo "Mailer Error: " . $mail->ErrorInfo; 213 | exit; 214 | } 215 | 216 | echo "Message has been sent"; 217 | ?> 218 | 219 | CHANGELOG 220 | 221 | See ChangeLog.txt 222 | 223 | Download: http://sourceforge.net/project/showfiles.php?group_id=26031 224 | 225 | Andy Prevost 226 | -------------------------------------------------------------------------------- /lib/VERSION: -------------------------------------------------------------------------------- 1 | PHPMailer-5.2.1 -------------------------------------------------------------------------------- /lib/changelog.txt: -------------------------------------------------------------------------------- 1 | ChangeLog 2 | 3 | NOTE: THIS VERSION OF PHPMAILER IS DESIGNED FOR PHP5/PHP6. 4 | IT WILL NOT WORK WITH PHP4. 5 | 6 | Version 5.2.1 (January 16, 2012) 7 | * Closed several bugs 8 | * Performance improvements 9 | * MsgHTML() now returns the message as required. 10 | * New method: GetSentMIMEMessage() (returns full copy of sent message) 11 | 12 | Version 5.2 (July 19, 2011) 13 | * protected MIME body and header 14 | * better DKIM DNS Resource Record support 15 | * better aly handling 16 | * htmlfilter class added to extras 17 | * moved to Apache Extras 18 | 19 | Version 5.1 (October 20, 2009) 20 | * fixed filename issue with AddStringAttachment (thanks to Tony) 21 | * fixed "SingleTo" property, now works with Senmail, Qmail, and SMTP in 22 | addition to PHP mail() 23 | * added DKIM digital signing functionality 24 | New properties: 25 | - DKIM_domain (sets the domain name) 26 | - DKIM_private (holds DKIM private key) 27 | - DKIM_passphrase (holds your DKIM passphrase) 28 | - DKIM_selector (holds the DKIM "selector") 29 | - DKIM_identity (holds the identifying email address) 30 | * added callback function support 31 | - callback function parameters include: 32 | result, to, cc, bcc, subject and body 33 | * see the test/test_callback.php file for usage. 34 | * added "auto" identity functionality 35 | - can automatically add: 36 | - Return-path (if Sender not set) 37 | - Reply-To (if ReplyTo not set) 38 | - can be disabled: 39 | - $mail->SetFrom('yourname@yourdomain.com','First Last',false); 40 | - or by adding the $mail->Sender and/or $mail->ReplyTo properties 41 | Note: "auto" identity added to help with emails ending up in spam 42 | or junk boxes because of missing headers 43 | 44 | Version 5.0.2 (May 24, 2009) 45 | * Fix for missing attachments when inline graphics are present 46 | * Fix for missing Cc in header when using SMTP (mail was sent, 47 | but not displayed in header -- Cc receiver only saw email To: 48 | line and no Cc line, but did get the email (To receiver 49 | saw same) 50 | 51 | Version 5.0.1 (April 05, 2009) 52 | * Temporary fix for missing attachments 53 | 54 | Version 5.0.0 (April 02, 2009) 55 | 56 | * With the release of this version, we are initiating a new version numbering 57 | system to differentiate from the PHP4 version of PHPMailer. 58 | * Most notable in this release is fully object oriented code. 59 | class.smtp.php: 60 | * Refactored class.smtp.php to support new exception handling 61 | code size reduced from 29.2 Kb to 25.6 Kb 62 | * Removed unnecessary functions from class.smtp.php: 63 | public function Expand($name) { 64 | public function Help($keyword="") { 65 | public function Noop() { 66 | public function Send($from) { 67 | public function SendOrMail($from) { 68 | public function Verify($name) { 69 | class.phpmailer.php: 70 | * Refactored class.phpmailer.php with new exception handling 71 | * Changed processing functionality of Sendmail and Qmail so they cannot be 72 | inadvertently used 73 | * removed getFile() function, just became a simple wrapper for 74 | file_get_contents() 75 | * added check for PHP version (will gracefully exit if not at least PHP 5.0) 76 | class.phpmailer.php enhancements 77 | * enhanced code to check if an attachment source is the same as an embedded or 78 | inline graphic source to eliminate duplicate attachments 79 | New /test_script 80 | * We have written a test script you can use to test the script as part of your 81 | installation. Once you press submit, the test script will send a multi-mime 82 | email with either the message you type in or an HTML email with an inline 83 | graphic. Two attachments are included in the email (one of the attachments 84 | is also the inline graphic so you can see that only one copy of the graphic 85 | is sent in the email). The test script will also display the functional 86 | script that you can copy/paste to your editor to duplicate the functionality. 87 | New examples 88 | * All new examples in both basic and advanced modes. Advanced examples show 89 | Exception handling. 90 | PHPDocumentator (phpdocs) documentation for PHPMailer version 5.0.0 91 | * all new documentation 92 | 93 | Please note: the website has been updated to reflect the changes in PHPMailer 94 | version 5.0.0. http://phpmailer.codeworxtech.com/ 95 | 96 | Version 2.3 (November 06, 2008) 97 | 98 | * added Arabic language (many thanks to Bahjat Al Mostafa) 99 | * removed English language from language files and made it a default within 100 | class.phpmailer.php - if no language is found, it will default to use 101 | the english language translation 102 | * fixed public/private declarations 103 | * corrected line 1728, $basedir to $directory 104 | * added $sign_cert_file to avoid improper duplicate use of $sign_key_file 105 | * corrected $this->Hello on line 612 to $this->Helo 106 | * changed default of $LE to "\r\n" to comply with RFC 2822. Can be set by the user 107 | if default is not acceptable 108 | * removed trim() from return results in EncodeQP 109 | * /test and three files it contained are removed from version 2.3 110 | * fixed phpunit.php for compliance with PHP5 111 | * changed $this->AltBody = $textMsg; to $this->AltBody = html_entity_decode($textMsg); 112 | * We have removed the /phpdoc from the downloads. All documentation is now on 113 | the http://phpmailer.codeworxtech.com website. 114 | 115 | Version 2.2.1 () July 19 2008 116 | 117 | * fixed line 1092 in class.smtp.php (my apologies, error on my part) 118 | 119 | Version 2.2 () July 15 2008 120 | 121 | * Fixed redirect issue (display of UTF-8 in thank you redirect) 122 | * fixed error in getResponse function declaration (class.pop3.php) 123 | * PHPMailer now PHP6 compliant 124 | * fixed line 1092 in class.smtp.php (endless loop from missing = sign) 125 | 126 | Version 2.1 (Wed, June 04 2008) 127 | 128 | ** NOTE: WE HAVE A NEW LANGUAGE VARIABLE FOR DIGITALLY SIGNED S/MIME EMAILS. 129 | IF YOU CAN HELP WITH LANGUAGES OTHER THAN ENGLISH AND SPANISH, IT WOULD BE 130 | APPRECIATED. 131 | 132 | * added S/MIME functionality (ability to digitally sign emails) 133 | BIG THANKS TO "sergiocambra" for posting this patch back in November 2007. 134 | The "Signed Emails" functionality adds the Sign method to pass the private key 135 | filename and the password to read it, and then email will be sent with 136 | content-type multipart/signed and with the digital signature attached. 137 | * fully compatible with E_STRICT error level 138 | - Please note: 139 | In about half the test environments this development version was subjected 140 | to, an error was thrown for the date() functions used (line 1565 and 1569). 141 | This is NOT a PHPMailer error, it is the result of an incorrectly configured 142 | PHP5 installation. The fix is to modify your 'php.ini' file and include the 143 | date.timezone = America/New York 144 | directive, to your own server timezone 145 | - If you do get this error, and are unable to access your php.ini file: 146 | In your PHP script, add 147 | date_default_timezone_set('America/Toronto'); 148 | - do not try to use 149 | $myVar = date_default_timezone_get(); 150 | as a test, it will throw an error. 151 | * added ability to define path (mainly for embedded images) 152 | function MsgHTML($message,$basedir='') ... where: 153 | $basedir is the fully qualified path 154 | * fixed MsgHTML() function: 155 | - Embedded Images where images are specified by :// will not be altered or embedded 156 | * fixed the return value of SMTP exit code ( pclose ) 157 | * addressed issue of multibyte characters in subject line and truncating 158 | * added ability to have user specified Message ID 159 | (default is still that PHPMailer create a unique Message ID) 160 | * corrected unidentified message type to 'application/octet-stream' 161 | * fixed chunk_split() multibyte issue (thanks to Colin Brown, et al). 162 | * added check for added attachments 163 | * enhanced conversion of HTML to text in MsgHTML (thanks to "brunny") 164 | 165 | Version 2.1.0beta2 (Sun, Dec 02 2007) 166 | * implemented updated EncodeQP (thanks to coolbru, aka Marcus Bointon) 167 | * finished all testing, all known bugs corrected, enhancements tested 168 | - note: will NOT work with PHP4. 169 | 170 | please note, this is BETA software 171 | ** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS 172 | INTENDED STRICTLY FOR TESTING 173 | 174 | Version 2.1.0beta1 175 | please note, this is BETA software 176 | ** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS 177 | INTENDED STRICTLY FOR TESTING 178 | 179 | Version 2.0.0 rc2 (Fri, Nov 16 2007), interim release 180 | * implements new property to control VERP in class.smtp.php 181 | example (requires instantiating class.smtp.php): 182 | $mail->do_verp = true; 183 | * POP-before-SMTP functionality included, thanks to Richard Davey 184 | (see class.pop3.php & pop3_before_smtp_test.php for examples) 185 | * included example showing how to use PHPMailer with GMAIL 186 | * fixed the missing Cc in SendMail() and Mail() 187 | 188 | ****************** 189 | A note on sending bulk emails: 190 | 191 | If the email you are sending is not personalized, consider using the 192 | "undisclosed-recipient:;" strategy. That is, put all of your recipients 193 | in the Bcc field and set the To field to "undisclosed-recipients:;". 194 | It's a lot faster (only one send) and saves quite a bit on resources. 195 | Contrary to some opinions, this will not get you listed in spam engines - 196 | it's a legitimate way for you to send emails. 197 | 198 | A partial example for use with PHPMailer: 199 | 200 | $mail->AddAddress("undisclosed-recipients:;"); 201 | $mail->AddBCC("email1@anydomain.com,email2@anyotherdomain.com,email3@anyalternatedomain.com"); 202 | 203 | Many email service providers restrict the number of emails that can be sent 204 | in any given time period. Often that is between 50 - 60 emails maximum 205 | per hour or per send session. 206 | 207 | If that's the case, then break up your Bcc lists into chunks that are one 208 | less than your limit, and put a pause in your script. 209 | ******************* 210 | 211 | Version 2.0.0 rc1 (Thu, Nov 08 2007), interim release 212 | * dramatically simplified using inline graphics ... it's fully automated and requires no user input 213 | * added automatic document type detection for attachments and pictures 214 | * added MsgHTML() function to replace Body tag for HTML emails 215 | * fixed the SendMail security issues (input validation vulnerability) 216 | * enhanced the AddAddresses functionality so that the "Name" portion is used in the email address 217 | * removed the need to use the AltBody method (set from the HTML, or default text used) 218 | * set the PHP Mail() function as the default (still support SendMail, SMTP Mail) 219 | * removed the need to set the IsHTML property (set automatically) 220 | * added Estonian language file by Indrek Päri 221 | * added header injection patch 222 | * added "set" method to permit users to create their own pseudo-properties like 'X-Headers', etc. 223 | example of use: 224 | $mail->set('X-Priority', '3'); 225 | $mail->set('X-MSMail-Priority', 'Normal'); 226 | * fixed warning message in SMTP get_lines method 227 | * added TLS/SSL SMTP support 228 | example of use: 229 | $mail = new PHPMailer(); 230 | $mail->Mailer = "smtp"; 231 | $mail->Host = "smtp.example.com"; 232 | $mail->SMTPSecure = "tls"; // option 233 | //$mail->SMTPSecure = "ssl"; // option 234 | ... 235 | $mail->Send(); 236 | * PHPMailer has been tested with PHP4 (4.4.7) and PHP5 (5.2.7) 237 | * Works with PHP installed as a module or as CGI-PHP 238 | - NOTE: will NOT work with PHP5 in E_STRICT error mode 239 | 240 | Version 1.73 (Sun, Jun 10 2005) 241 | * Fixed denial of service bug: http://www.cybsec.com/vuln/PHPMailer-DOS.pdf 242 | * Now has a total of 20 translations 243 | * Fixed alt attachments bug: http://tinyurl.com/98u9k 244 | 245 | Version 1.72 (Wed, May 25 2004) 246 | * Added Dutch, Swedish, Czech, Norwegian, and Turkish translations. 247 | * Received: Removed this method because spam filter programs like 248 | SpamAssassin reject this header. 249 | * Fixed error count bug. 250 | * SetLanguage default is now "language/". 251 | * Fixed magic_quotes_runtime bug. 252 | 253 | Version 1.71 (Tue, Jul 28 2003) 254 | * Made several speed enhancements 255 | * Added German and Italian translation files 256 | * Fixed HELO/AUTH bugs on keep-alive connects 257 | * Now provides an error message if language file does not load 258 | * Fixed attachment EOL bug 259 | * Updated some unclear documentation 260 | * Added additional tests and improved others 261 | 262 | Version 1.70 (Mon, Jun 20 2003) 263 | * Added SMTP keep-alive support 264 | * Added IsError method for error detection 265 | * Added error message translation support (SetLanguage) 266 | * Refactored many methods to increase library performance 267 | * Hello now sends the newer EHLO message before HELO as per RFC 2821 268 | * Removed the boundary class and replaced it with GetBoundary 269 | * Removed queue support methods 270 | * New $Hostname variable 271 | * New Message-ID header 272 | * Received header reformat 273 | * Helo variable default changed to $Hostname 274 | * Removed extra spaces in Content-Type definition (#667182) 275 | * Return-Path should be set to Sender when set 276 | * Adds Q or B encoding to headers when necessary 277 | * quoted-encoding should now encode NULs \000 278 | * Fixed encoding of body/AltBody (#553370) 279 | * Adds "To: undisclosed-recipients:;" when all recipients are hidden (BCC) 280 | * Multiple bug fixes 281 | 282 | Version 1.65 (Fri, Aug 09 2002) 283 | * Fixed non-visible attachment bug (#585097) for Outlook 284 | * SMTP connections are now closed after each transaction 285 | * Fixed SMTP::Expand return value 286 | * Converted SMTP class documentation to phpDocumentor format 287 | 288 | Version 1.62 (Wed, Jun 26 2002) 289 | * Fixed multi-attach bug 290 | * Set proper word wrapping 291 | * Reduced memory use with attachments 292 | * Added more debugging 293 | * Changed documentation to phpDocumentor format 294 | 295 | Version 1.60 (Sat, Mar 30 2002) 296 | * Sendmail pipe and address patch (Christian Holtje) 297 | * Added embedded image and read confirmation support (A. Ognio) 298 | * Added unit tests 299 | * Added SMTP timeout support (*nix only) 300 | * Added possibly temporary PluginDir variable for SMTP class 301 | * Added LE message line ending variable 302 | * Refactored boundary and attachment code 303 | * Eliminated SMTP class warnings 304 | * Added SendToQueue method for future queuing support 305 | 306 | Version 1.54 (Wed, Dec 19 2001) 307 | * Add some queuing support code 308 | * Fixed a pesky multi/alt bug 309 | * Messages are no longer forced to have "To" addresses 310 | 311 | Version 1.50 (Thu, Nov 08 2001) 312 | * Fix extra lines when not using SMTP mailer 313 | * Set WordWrap variable to int with a zero default 314 | 315 | Version 1.47 (Tue, Oct 16 2001) 316 | * Fixed Received header code format 317 | * Fixed AltBody order error 318 | * Fixed alternate port warning 319 | 320 | Version 1.45 (Tue, Sep 25 2001) 321 | * Added enhanced SMTP debug support 322 | * Added support for multiple ports on SMTP 323 | * Added Received header for tracing 324 | * Fixed AddStringAttachment encoding 325 | * Fixed possible header name quote bug 326 | * Fixed wordwrap() trim bug 327 | * Couple other small bug fixes 328 | 329 | Version 1.41 (Wed, Aug 22 2001) 330 | * Fixed AltBody bug w/o attachments 331 | * Fixed rfc_date() for certain mail servers 332 | 333 | Version 1.40 (Sun, Aug 12 2001) 334 | * Added multipart/alternative support (AltBody) 335 | * Documentation update 336 | * Fixed bug in Mercury MTA 337 | 338 | Version 1.29 (Fri, Aug 03 2001) 339 | * Added AddStringAttachment() method 340 | * Added SMTP authentication support 341 | 342 | Version 1.28 (Mon, Jul 30 2001) 343 | * Fixed a typo in SMTP class 344 | * Fixed header issue with Imail (win32) SMTP server 345 | * Made fopen() calls for attachments use "rb" to fix win32 error 346 | 347 | Version 1.25 (Mon, Jul 02 2001) 348 | * Added RFC 822 date fix (Patrice) 349 | * Added improved error handling by adding a $ErrorInfo variable 350 | * Removed MailerDebug variable (obsolete with new error handler) 351 | 352 | Version 1.20 (Mon, Jun 25 2001) 353 | * Added quoted-printable encoding (Patrice) 354 | * Set Version as public and removed PrintVersion() 355 | * Changed phpdoc to only display public variables and methods 356 | 357 | Version 1.19 (Thu, Jun 21 2001) 358 | * Fixed MS Mail header bug 359 | * Added fix for Bcc problem with mail(). *Does not work on Win32* 360 | (See PHP bug report: http://www.php.net/bugs.php?id=11616) 361 | * mail() no longer passes a fifth parameter when not needed 362 | 363 | Version 1.15 (Fri, Jun 15 2001) 364 | [Note: these changes contributed by Patrice Fournier] 365 | * Changed all remaining \n to \r\n 366 | * Bcc: header no longer writen to message except 367 | when sent directly to sendmail 368 | * Added a small message to non-MIME compliant mail reader 369 | * Added Sender variable to change the Sender email 370 | used in -f for sendmail/mail and in 'MAIL FROM' for smtp mode 371 | * Changed boundary setting to a place it will be set only once 372 | * Removed transfer encoding for whole message when using multipart 373 | * Message body now uses Encoding in multipart messages 374 | * Can set encoding and type to attachments 7bit, 8bit 375 | and binary attachment are sent as is, base64 are encoded 376 | * Can set Encoding to base64 to send 8 bits body 377 | through 7 bits servers 378 | 379 | Version 1.10 (Tue, Jun 12 2001) 380 | * Fixed win32 mail header bug (printed out headers in message body) 381 | 382 | Version 1.09 (Fri, Jun 08 2001) 383 | * Changed date header to work with Netscape mail programs 384 | * Altered phpdoc documentation 385 | 386 | Version 1.08 (Tue, Jun 05 2001) 387 | * Added enhanced error-checking 388 | * Added phpdoc documentation to source 389 | 390 | Version 1.06 (Fri, Jun 01 2001) 391 | * Added optional name for file attachments 392 | 393 | Version 1.05 (Tue, May 29 2001) 394 | * Code cleanup 395 | * Eliminated sendmail header warning message 396 | * Fixed possible SMTP error 397 | 398 | Version 1.03 (Thu, May 24 2001) 399 | * Fixed problem where qmail sends out duplicate messages 400 | 401 | Version 1.02 (Wed, May 23 2001) 402 | * Added multiple recipient and attachment Clear* methods 403 | * Added Sendmail public variable 404 | * Fixed problem with loading SMTP library multiple times 405 | 406 | Version 0.98 (Tue, May 22 2001) 407 | * Fixed problem with redundant mail hosts sending out multiple messages 408 | * Added additional error handler code 409 | * Added AddCustomHeader() function 410 | * Added support for Microsoft mail client headers (affects priority) 411 | * Fixed small bug with Mailer variable 412 | * Added PrintVersion() function 413 | 414 | Version 0.92 (Tue, May 15 2001) 415 | * Changed file names to class.phpmailer.php and class.smtp.php to match 416 | current PHP class trend. 417 | * Fixed problem where body not being printed when a message is attached 418 | * Several small bug fixes 419 | 420 | Version 0.90 (Tue, April 17 2001) 421 | * Intial public release 422 | -------------------------------------------------------------------------------- /lib/class.pop3.php: -------------------------------------------------------------------------------- 1 | pop_conn = 0; 135 | $this->connected = false; 136 | $this->error = null; 137 | } 138 | 139 | /** 140 | * Combination of public events - connect, login, disconnect 141 | * @access public 142 | * @param string $host 143 | * @param integer $port 144 | * @param integer $tval 145 | * @param string $username 146 | * @param string $password 147 | */ 148 | public function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0) { 149 | $this->host = $host; 150 | 151 | // If no port value is passed, retrieve it 152 | if ($port == false) { 153 | $this->port = $this->POP3_PORT; 154 | } else { 155 | $this->port = $port; 156 | } 157 | 158 | // If no port value is passed, retrieve it 159 | if ($tval == false) { 160 | $this->tval = $this->POP3_TIMEOUT; 161 | } else { 162 | $this->tval = $tval; 163 | } 164 | 165 | $this->do_debug = $debug_level; 166 | $this->username = $username; 167 | $this->password = $password; 168 | 169 | // Refresh the error log 170 | $this->error = null; 171 | 172 | // Connect 173 | $result = $this->Connect($this->host, $this->port, $this->tval); 174 | 175 | if ($result) { 176 | $login_result = $this->Login($this->username, $this->password); 177 | 178 | if ($login_result) { 179 | $this->Disconnect(); 180 | 181 | return true; 182 | } 183 | 184 | } 185 | 186 | // We need to disconnect regardless if the login succeeded 187 | $this->Disconnect(); 188 | 189 | return false; 190 | } 191 | 192 | /** 193 | * Connect to the POP3 server 194 | * @access public 195 | * @param string $host 196 | * @param integer $port 197 | * @param integer $tval 198 | * @return boolean 199 | */ 200 | public function Connect ($host, $port = false, $tval = 30) { 201 | // Are we already connected? 202 | if ($this->connected) { 203 | return true; 204 | } 205 | 206 | /* 207 | On Windows this will raise a PHP Warning error if the hostname doesn't exist. 208 | Rather than supress it with @fsockopen, let's capture it cleanly instead 209 | */ 210 | 211 | set_error_handler(array(&$this, 'catchWarning')); 212 | 213 | // Connect to the POP3 server 214 | $this->pop_conn = fsockopen($host, // POP3 Host 215 | $port, // Port # 216 | $errno, // Error Number 217 | $errstr, // Error Message 218 | $tval); // Timeout (seconds) 219 | 220 | // Restore the error handler 221 | restore_error_handler(); 222 | 223 | // Does the Error Log now contain anything? 224 | if ($this->error && $this->do_debug >= 1) { 225 | $this->displayErrors(); 226 | } 227 | 228 | // Did we connect? 229 | if ($this->pop_conn == false) { 230 | // It would appear not... 231 | $this->error = array( 232 | 'error' => "Failed to connect to server $host on port $port", 233 | 'errno' => $errno, 234 | 'errstr' => $errstr 235 | ); 236 | 237 | if ($this->do_debug >= 1) { 238 | $this->displayErrors(); 239 | } 240 | 241 | return false; 242 | } 243 | 244 | // Increase the stream time-out 245 | 246 | // Check for PHP 4.3.0 or later 247 | if (version_compare(phpversion(), '5.0.0', 'ge')) { 248 | stream_set_timeout($this->pop_conn, $tval, 0); 249 | } else { 250 | // Does not work on Windows 251 | if (substr(PHP_OS, 0, 3) !== 'WIN') { 252 | socket_set_timeout($this->pop_conn, $tval, 0); 253 | } 254 | } 255 | 256 | // Get the POP3 server response 257 | $pop3_response = $this->getResponse(); 258 | 259 | // Check for the +OK 260 | if ($this->checkResponse($pop3_response)) { 261 | // The connection is established and the POP3 server is talking 262 | $this->connected = true; 263 | return true; 264 | } 265 | 266 | } 267 | 268 | /** 269 | * Login to the POP3 server (does not support APOP yet) 270 | * @access public 271 | * @param string $username 272 | * @param string $password 273 | * @return boolean 274 | */ 275 | public function Login ($username = '', $password = '') { 276 | if ($this->connected == false) { 277 | $this->error = 'Not connected to POP3 server'; 278 | 279 | if ($this->do_debug >= 1) { 280 | $this->displayErrors(); 281 | } 282 | } 283 | 284 | if (empty($username)) { 285 | $username = $this->username; 286 | } 287 | 288 | if (empty($password)) { 289 | $password = $this->password; 290 | } 291 | 292 | $pop_username = "USER $username" . $this->CRLF; 293 | $pop_password = "PASS $password" . $this->CRLF; 294 | 295 | // Send the Username 296 | $this->sendString($pop_username); 297 | $pop3_response = $this->getResponse(); 298 | 299 | if ($this->checkResponse($pop3_response)) { 300 | // Send the Password 301 | $this->sendString($pop_password); 302 | $pop3_response = $this->getResponse(); 303 | 304 | if ($this->checkResponse($pop3_response)) { 305 | return true; 306 | } else { 307 | return false; 308 | } 309 | } else { 310 | return false; 311 | } 312 | } 313 | 314 | /** 315 | * Disconnect from the POP3 server 316 | * @access public 317 | */ 318 | public function Disconnect () { 319 | $this->sendString('QUIT'); 320 | 321 | fclose($this->pop_conn); 322 | } 323 | 324 | ///////////////////////////////////////////////// 325 | // Private Methods 326 | ///////////////////////////////////////////////// 327 | 328 | /** 329 | * Get the socket response back. 330 | * $size is the maximum number of bytes to retrieve 331 | * @access private 332 | * @param integer $size 333 | * @return string 334 | */ 335 | private function getResponse ($size = 128) { 336 | $pop3_response = fgets($this->pop_conn, $size); 337 | 338 | return $pop3_response; 339 | } 340 | 341 | /** 342 | * Send a string down the open socket connection to the POP3 server 343 | * @access private 344 | * @param string $string 345 | * @return integer 346 | */ 347 | private function sendString ($string) { 348 | $bytes_sent = fwrite($this->pop_conn, $string, strlen($string)); 349 | 350 | return $bytes_sent; 351 | } 352 | 353 | /** 354 | * Checks the POP3 server response for +OK or -ERR 355 | * @access private 356 | * @param string $string 357 | * @return boolean 358 | */ 359 | private function checkResponse ($string) { 360 | if (substr($string, 0, 3) !== '+OK') { 361 | $this->error = array( 362 | 'error' => "Server reported an error: $string", 363 | 'errno' => 0, 364 | 'errstr' => '' 365 | ); 366 | 367 | if ($this->do_debug >= 1) { 368 | $this->displayErrors(); 369 | } 370 | 371 | return false; 372 | } else { 373 | return true; 374 | } 375 | 376 | } 377 | 378 | /** 379 | * If debug is enabled, display the error message array 380 | * @access private 381 | */ 382 | private function displayErrors () { 383 | echo '

';
384 | 
385 |     foreach ($this->error as $single_error) {
386 |       print_r($single_error);
387 |     }
388 | 
389 |     echo '
'; 390 | } 391 | 392 | /** 393 | * Takes over from PHP for the socket warning handler 394 | * @access private 395 | * @param integer $errno 396 | * @param string $errstr 397 | * @param string $errfile 398 | * @param integer $errline 399 | */ 400 | private function catchWarning ($errno, $errstr, $errfile, $errline) { 401 | $this->error[] = array( 402 | 'error' => "Connecting to the POP3 server raised a PHP warning: ", 403 | 'errno' => $errno, 404 | 'errstr' => $errstr 405 | ); 406 | } 407 | 408 | // End of class 409 | } 410 | ?> 411 | -------------------------------------------------------------------------------- /lib/class.smtp.php: -------------------------------------------------------------------------------- 1 | smtp_conn = 0; 92 | $this->error = null; 93 | $this->helo_rply = null; 94 | 95 | $this->do_debug = 0; 96 | } 97 | 98 | ///////////////////////////////////////////////// 99 | // CONNECTION FUNCTIONS 100 | ///////////////////////////////////////////////// 101 | 102 | /** 103 | * Connect to the server specified on the port specified. 104 | * If the port is not specified use the default SMTP_PORT. 105 | * If tval is specified then a connection will try and be 106 | * established with the server for that number of seconds. 107 | * If tval is not specified the default is 30 seconds to 108 | * try on the connection. 109 | * 110 | * SMTP CODE SUCCESS: 220 111 | * SMTP CODE FAILURE: 421 112 | * @access public 113 | * @return bool 114 | */ 115 | public function Connect($host, $port = 0, $tval = 30) { 116 | // set the error val to null so there is no confusion 117 | $this->error = null; 118 | 119 | // make sure we are __not__ connected 120 | if($this->connected()) { 121 | // already connected, generate error 122 | $this->error = array("error" => "Already connected to a server"); 123 | return false; 124 | } 125 | 126 | if(empty($port)) { 127 | $port = $this->SMTP_PORT; 128 | } 129 | 130 | // connect to the smtp server 131 | $this->smtp_conn = @fsockopen($host, // the host of the server 132 | $port, // the port to use 133 | $errno, // error number if any 134 | $errstr, // error message if any 135 | $tval); // give up after ? secs 136 | // verify we connected properly 137 | if(empty($this->smtp_conn)) { 138 | $this->error = array("error" => "Failed to connect to server", 139 | "errno" => $errno, 140 | "errstr" => $errstr); 141 | if($this->do_debug >= 1) { 142 | echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '
'; 143 | } 144 | return false; 145 | } 146 | 147 | // SMTP server can take longer to respond, give longer timeout for first read 148 | // Windows does not have support for this timeout function 149 | if(substr(PHP_OS, 0, 3) != "WIN") 150 | socket_set_timeout($this->smtp_conn, $tval, 0); 151 | 152 | // get any announcement 153 | $announce = $this->get_lines(); 154 | 155 | if($this->do_debug >= 2) { 156 | echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '
'; 157 | } 158 | 159 | return true; 160 | } 161 | 162 | /** 163 | * Initiate a TLS communication with the server. 164 | * 165 | * SMTP CODE 220 Ready to start TLS 166 | * SMTP CODE 501 Syntax error (no parameters allowed) 167 | * SMTP CODE 454 TLS not available due to temporary reason 168 | * @access public 169 | * @return bool success 170 | */ 171 | public function StartTLS() { 172 | $this->error = null; # to avoid confusion 173 | 174 | if(!$this->connected()) { 175 | $this->error = array("error" => "Called StartTLS() without being connected"); 176 | return false; 177 | } 178 | 179 | fputs($this->smtp_conn,"STARTTLS" . $this->CRLF); 180 | 181 | $rply = $this->get_lines(); 182 | $code = substr($rply,0,3); 183 | 184 | if($this->do_debug >= 2) { 185 | echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; 186 | } 187 | 188 | if($code != 220) { 189 | $this->error = 190 | array("error" => "STARTTLS not accepted from server", 191 | "smtp_code" => $code, 192 | "smtp_msg" => substr($rply,4)); 193 | if($this->do_debug >= 1) { 194 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 195 | } 196 | return false; 197 | } 198 | 199 | // Begin encrypted connection 200 | if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { 201 | return false; 202 | } 203 | 204 | return true; 205 | } 206 | 207 | /** 208 | * Performs SMTP authentication. Must be run after running the 209 | * Hello() method. Returns true if successfully authenticated. 210 | * @access public 211 | * @return bool 212 | */ 213 | public function Authenticate($username, $password) { 214 | // Start authentication 215 | fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); 216 | 217 | $rply = $this->get_lines(); 218 | $code = substr($rply,0,3); 219 | 220 | if($code != 334) { 221 | $this->error = 222 | array("error" => "AUTH not accepted from server", 223 | "smtp_code" => $code, 224 | "smtp_msg" => substr($rply,4)); 225 | if($this->do_debug >= 1) { 226 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 227 | } 228 | return false; 229 | } 230 | 231 | // Send encoded username 232 | fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); 233 | 234 | $rply = $this->get_lines(); 235 | $code = substr($rply,0,3); 236 | 237 | if($code != 334) { 238 | $this->error = 239 | array("error" => "Username not accepted from server", 240 | "smtp_code" => $code, 241 | "smtp_msg" => substr($rply,4)); 242 | if($this->do_debug >= 1) { 243 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 244 | } 245 | return false; 246 | } 247 | 248 | // Send encoded password 249 | fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); 250 | 251 | $rply = $this->get_lines(); 252 | $code = substr($rply,0,3); 253 | 254 | if($code != 235) { 255 | $this->error = 256 | array("error" => "Password not accepted from server", 257 | "smtp_code" => $code, 258 | "smtp_msg" => substr($rply,4)); 259 | if($this->do_debug >= 1) { 260 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 261 | } 262 | return false; 263 | } 264 | 265 | return true; 266 | } 267 | 268 | /** 269 | * Returns true if connected to a server otherwise false 270 | * @access public 271 | * @return bool 272 | */ 273 | public function Connected() { 274 | if(!empty($this->smtp_conn)) { 275 | $sock_status = socket_get_status($this->smtp_conn); 276 | if($sock_status["eof"]) { 277 | // the socket is valid but we are not connected 278 | if($this->do_debug >= 1) { 279 | echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected"; 280 | } 281 | $this->Close(); 282 | return false; 283 | } 284 | return true; // everything looks good 285 | } 286 | return false; 287 | } 288 | 289 | /** 290 | * Closes the socket and cleans up the state of the class. 291 | * It is not considered good to use this function without 292 | * first trying to use QUIT. 293 | * @access public 294 | * @return void 295 | */ 296 | public function Close() { 297 | $this->error = null; // so there is no confusion 298 | $this->helo_rply = null; 299 | if(!empty($this->smtp_conn)) { 300 | // close the connection and cleanup 301 | fclose($this->smtp_conn); 302 | $this->smtp_conn = 0; 303 | } 304 | } 305 | 306 | ///////////////////////////////////////////////// 307 | // SMTP COMMANDS 308 | ///////////////////////////////////////////////// 309 | 310 | /** 311 | * Issues a data command and sends the msg_data to the server 312 | * finializing the mail transaction. $msg_data is the message 313 | * that is to be send with the headers. Each header needs to be 314 | * on a single line followed by a with the message headers 315 | * and the message body being seperated by and additional . 316 | * 317 | * Implements rfc 821: DATA 318 | * 319 | * SMTP CODE INTERMEDIATE: 354 320 | * [data] 321 | * . 322 | * SMTP CODE SUCCESS: 250 323 | * SMTP CODE FAILURE: 552,554,451,452 324 | * SMTP CODE FAILURE: 451,554 325 | * SMTP CODE ERROR : 500,501,503,421 326 | * @access public 327 | * @return bool 328 | */ 329 | public function Data($msg_data) { 330 | $this->error = null; // so no confusion is caused 331 | 332 | if(!$this->connected()) { 333 | $this->error = array( 334 | "error" => "Called Data() without being connected"); 335 | return false; 336 | } 337 | 338 | fputs($this->smtp_conn,"DATA" . $this->CRLF); 339 | 340 | $rply = $this->get_lines(); 341 | $code = substr($rply,0,3); 342 | 343 | if($this->do_debug >= 2) { 344 | echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; 345 | } 346 | 347 | if($code != 354) { 348 | $this->error = 349 | array("error" => "DATA command not accepted from server", 350 | "smtp_code" => $code, 351 | "smtp_msg" => substr($rply,4)); 352 | if($this->do_debug >= 1) { 353 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 354 | } 355 | return false; 356 | } 357 | 358 | /* the server is ready to accept data! 359 | * according to rfc 821 we should not send more than 1000 360 | * including the CRLF 361 | * characters on a single line so we will break the data up 362 | * into lines by \r and/or \n then if needed we will break 363 | * each of those into smaller lines to fit within the limit. 364 | * in addition we will be looking for lines that start with 365 | * a period '.' and append and additional period '.' to that 366 | * line. NOTE: this does not count towards limit. 367 | */ 368 | 369 | // normalize the line breaks so we know the explode works 370 | $msg_data = str_replace("\r\n","\n",$msg_data); 371 | $msg_data = str_replace("\r","\n",$msg_data); 372 | $lines = explode("\n",$msg_data); 373 | 374 | /* we need to find a good way to determine is headers are 375 | * in the msg_data or if it is a straight msg body 376 | * currently I am assuming rfc 822 definitions of msg headers 377 | * and if the first field of the first line (':' sperated) 378 | * does not contain a space then it _should_ be a header 379 | * and we can process all lines before a blank "" line as 380 | * headers. 381 | */ 382 | 383 | $field = substr($lines[0],0,strpos($lines[0],":")); 384 | $in_headers = false; 385 | if(!empty($field) && !strstr($field," ")) { 386 | $in_headers = true; 387 | } 388 | 389 | $max_line_length = 998; // used below; set here for ease in change 390 | 391 | while(list(,$line) = @each($lines)) { 392 | $lines_out = null; 393 | if($line == "" && $in_headers) { 394 | $in_headers = false; 395 | } 396 | // ok we need to break this line up into several smaller lines 397 | while(strlen($line) > $max_line_length) { 398 | $pos = strrpos(substr($line,0,$max_line_length)," "); 399 | 400 | // Patch to fix DOS attack 401 | if(!$pos) { 402 | $pos = $max_line_length - 1; 403 | $lines_out[] = substr($line,0,$pos); 404 | $line = substr($line,$pos); 405 | } else { 406 | $lines_out[] = substr($line,0,$pos); 407 | $line = substr($line,$pos + 1); 408 | } 409 | 410 | /* if processing headers add a LWSP-char to the front of new line 411 | * rfc 822 on long msg headers 412 | */ 413 | if($in_headers) { 414 | $line = "\t" . $line; 415 | } 416 | } 417 | $lines_out[] = $line; 418 | 419 | // send the lines to the server 420 | while(list(,$line_out) = @each($lines_out)) { 421 | if(strlen($line_out) > 0) 422 | { 423 | if(substr($line_out, 0, 1) == ".") { 424 | $line_out = "." . $line_out; 425 | } 426 | } 427 | fputs($this->smtp_conn,$line_out . $this->CRLF); 428 | } 429 | } 430 | 431 | // message data has been sent 432 | fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); 433 | 434 | $rply = $this->get_lines(); 435 | $code = substr($rply,0,3); 436 | 437 | if($this->do_debug >= 2) { 438 | echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; 439 | } 440 | 441 | if($code != 250) { 442 | $this->error = 443 | array("error" => "DATA not accepted from server", 444 | "smtp_code" => $code, 445 | "smtp_msg" => substr($rply,4)); 446 | if($this->do_debug >= 1) { 447 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 448 | } 449 | return false; 450 | } 451 | return true; 452 | } 453 | 454 | /** 455 | * Sends the HELO command to the smtp server. 456 | * This makes sure that we and the server are in 457 | * the same known state. 458 | * 459 | * Implements from rfc 821: HELO 460 | * 461 | * SMTP CODE SUCCESS: 250 462 | * SMTP CODE ERROR : 500, 501, 504, 421 463 | * @access public 464 | * @return bool 465 | */ 466 | public function Hello($host = '') { 467 | $this->error = null; // so no confusion is caused 468 | 469 | if(!$this->connected()) { 470 | $this->error = array( 471 | "error" => "Called Hello() without being connected"); 472 | return false; 473 | } 474 | 475 | // if hostname for HELO was not specified send default 476 | if(empty($host)) { 477 | // determine appropriate default to send to server 478 | $host = "localhost"; 479 | } 480 | 481 | // Send extended hello first (RFC 2821) 482 | if(!$this->SendHello("EHLO", $host)) { 483 | if(!$this->SendHello("HELO", $host)) { 484 | return false; 485 | } 486 | } 487 | 488 | return true; 489 | } 490 | 491 | /** 492 | * Sends a HELO/EHLO command. 493 | * @access private 494 | * @return bool 495 | */ 496 | private function SendHello($hello, $host) { 497 | fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); 498 | 499 | $rply = $this->get_lines(); 500 | $code = substr($rply,0,3); 501 | 502 | if($this->do_debug >= 2) { 503 | echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '
'; 504 | } 505 | 506 | if($code != 250) { 507 | $this->error = 508 | array("error" => $hello . " not accepted from server", 509 | "smtp_code" => $code, 510 | "smtp_msg" => substr($rply,4)); 511 | if($this->do_debug >= 1) { 512 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 513 | } 514 | return false; 515 | } 516 | 517 | $this->helo_rply = $rply; 518 | 519 | return true; 520 | } 521 | 522 | /** 523 | * Starts a mail transaction from the email address specified in 524 | * $from. Returns true if successful or false otherwise. If True 525 | * the mail transaction is started and then one or more Recipient 526 | * commands may be called followed by a Data command. 527 | * 528 | * Implements rfc 821: MAIL FROM: 529 | * 530 | * SMTP CODE SUCCESS: 250 531 | * SMTP CODE SUCCESS: 552,451,452 532 | * SMTP CODE SUCCESS: 500,501,421 533 | * @access public 534 | * @return bool 535 | */ 536 | public function Mail($from) { 537 | $this->error = null; // so no confusion is caused 538 | 539 | if(!$this->connected()) { 540 | $this->error = array( 541 | "error" => "Called Mail() without being connected"); 542 | return false; 543 | } 544 | 545 | $useVerp = ($this->do_verp ? "XVERP" : ""); 546 | fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF); 547 | 548 | $rply = $this->get_lines(); 549 | $code = substr($rply,0,3); 550 | 551 | if($this->do_debug >= 2) { 552 | echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; 553 | } 554 | 555 | if($code != 250) { 556 | $this->error = 557 | array("error" => "MAIL not accepted from server", 558 | "smtp_code" => $code, 559 | "smtp_msg" => substr($rply,4)); 560 | if($this->do_debug >= 1) { 561 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 562 | } 563 | return false; 564 | } 565 | return true; 566 | } 567 | 568 | /** 569 | * Sends the quit command to the server and then closes the socket 570 | * if there is no error or the $close_on_error argument is true. 571 | * 572 | * Implements from rfc 821: QUIT 573 | * 574 | * SMTP CODE SUCCESS: 221 575 | * SMTP CODE ERROR : 500 576 | * @access public 577 | * @return bool 578 | */ 579 | public function Quit($close_on_error = true) { 580 | $this->error = null; // so there is no confusion 581 | 582 | if(!$this->connected()) { 583 | $this->error = array( 584 | "error" => "Called Quit() without being connected"); 585 | return false; 586 | } 587 | 588 | // send the quit command to the server 589 | fputs($this->smtp_conn,"quit" . $this->CRLF); 590 | 591 | // get any good-bye messages 592 | $byemsg = $this->get_lines(); 593 | 594 | if($this->do_debug >= 2) { 595 | echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '
'; 596 | } 597 | 598 | $rval = true; 599 | $e = null; 600 | 601 | $code = substr($byemsg,0,3); 602 | if($code != 221) { 603 | // use e as a tmp var cause Close will overwrite $this->error 604 | $e = array("error" => "SMTP server rejected quit command", 605 | "smtp_code" => $code, 606 | "smtp_rply" => substr($byemsg,4)); 607 | $rval = false; 608 | if($this->do_debug >= 1) { 609 | echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '
'; 610 | } 611 | } 612 | 613 | if(empty($e) || $close_on_error) { 614 | $this->Close(); 615 | } 616 | 617 | return $rval; 618 | } 619 | 620 | /** 621 | * Sends the command RCPT to the SMTP server with the TO: argument of $to. 622 | * Returns true if the recipient was accepted false if it was rejected. 623 | * 624 | * Implements from rfc 821: RCPT TO: 625 | * 626 | * SMTP CODE SUCCESS: 250,251 627 | * SMTP CODE FAILURE: 550,551,552,553,450,451,452 628 | * SMTP CODE ERROR : 500,501,503,421 629 | * @access public 630 | * @return bool 631 | */ 632 | public function Recipient($to) { 633 | $this->error = null; // so no confusion is caused 634 | 635 | if(!$this->connected()) { 636 | $this->error = array( 637 | "error" => "Called Recipient() without being connected"); 638 | return false; 639 | } 640 | 641 | fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); 642 | 643 | $rply = $this->get_lines(); 644 | $code = substr($rply,0,3); 645 | 646 | if($this->do_debug >= 2) { 647 | echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; 648 | } 649 | 650 | if($code != 250 && $code != 251) { 651 | $this->error = 652 | array("error" => "RCPT not accepted from server", 653 | "smtp_code" => $code, 654 | "smtp_msg" => substr($rply,4)); 655 | if($this->do_debug >= 1) { 656 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 657 | } 658 | return false; 659 | } 660 | return true; 661 | } 662 | 663 | /** 664 | * Sends the RSET command to abort and transaction that is 665 | * currently in progress. Returns true if successful false 666 | * otherwise. 667 | * 668 | * Implements rfc 821: RSET 669 | * 670 | * SMTP CODE SUCCESS: 250 671 | * SMTP CODE ERROR : 500,501,504,421 672 | * @access public 673 | * @return bool 674 | */ 675 | public function Reset() { 676 | $this->error = null; // so no confusion is caused 677 | 678 | if(!$this->connected()) { 679 | $this->error = array( 680 | "error" => "Called Reset() without being connected"); 681 | return false; 682 | } 683 | 684 | fputs($this->smtp_conn,"RSET" . $this->CRLF); 685 | 686 | $rply = $this->get_lines(); 687 | $code = substr($rply,0,3); 688 | 689 | if($this->do_debug >= 2) { 690 | echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; 691 | } 692 | 693 | if($code != 250) { 694 | $this->error = 695 | array("error" => "RSET failed", 696 | "smtp_code" => $code, 697 | "smtp_msg" => substr($rply,4)); 698 | if($this->do_debug >= 1) { 699 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 700 | } 701 | return false; 702 | } 703 | 704 | return true; 705 | } 706 | 707 | /** 708 | * Starts a mail transaction from the email address specified in 709 | * $from. Returns true if successful or false otherwise. If True 710 | * the mail transaction is started and then one or more Recipient 711 | * commands may be called followed by a Data command. This command 712 | * will send the message to the users terminal if they are logged 713 | * in and send them an email. 714 | * 715 | * Implements rfc 821: SAML FROM: 716 | * 717 | * SMTP CODE SUCCESS: 250 718 | * SMTP CODE SUCCESS: 552,451,452 719 | * SMTP CODE SUCCESS: 500,501,502,421 720 | * @access public 721 | * @return bool 722 | */ 723 | public function SendAndMail($from) { 724 | $this->error = null; // so no confusion is caused 725 | 726 | if(!$this->connected()) { 727 | $this->error = array( 728 | "error" => "Called SendAndMail() without being connected"); 729 | return false; 730 | } 731 | 732 | fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); 733 | 734 | $rply = $this->get_lines(); 735 | $code = substr($rply,0,3); 736 | 737 | if($this->do_debug >= 2) { 738 | echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; 739 | } 740 | 741 | if($code != 250) { 742 | $this->error = 743 | array("error" => "SAML not accepted from server", 744 | "smtp_code" => $code, 745 | "smtp_msg" => substr($rply,4)); 746 | if($this->do_debug >= 1) { 747 | echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; 748 | } 749 | return false; 750 | } 751 | return true; 752 | } 753 | 754 | /** 755 | * This is an optional command for SMTP that this class does not 756 | * support. This method is here to make the RFC821 Definition 757 | * complete for this class and __may__ be implimented in the future 758 | * 759 | * Implements from rfc 821: TURN 760 | * 761 | * SMTP CODE SUCCESS: 250 762 | * SMTP CODE FAILURE: 502 763 | * SMTP CODE ERROR : 500, 503 764 | * @access public 765 | * @return bool 766 | */ 767 | public function Turn() { 768 | $this->error = array("error" => "This method, TURN, of the SMTP ". 769 | "is not implemented"); 770 | if($this->do_debug >= 1) { 771 | echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '
'; 772 | } 773 | return false; 774 | } 775 | 776 | /** 777 | * Get the current error 778 | * @access public 779 | * @return array 780 | */ 781 | public function getError() { 782 | return $this->error; 783 | } 784 | 785 | ///////////////////////////////////////////////// 786 | // INTERNAL FUNCTIONS 787 | ///////////////////////////////////////////////// 788 | 789 | /** 790 | * Read in as many lines as possible 791 | * either before eof or socket timeout occurs on the operation. 792 | * With SMTP we can tell if we have more lines to read if the 793 | * 4th character is '-' symbol. If it is a space then we don't 794 | * need to read anything else. 795 | * @access private 796 | * @return string 797 | */ 798 | private function get_lines() { 799 | $data = ""; 800 | while(!feof($this->smtp_conn)) { 801 | $str = @fgets($this->smtp_conn,515); 802 | if($this->do_debug >= 4) { 803 | echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '
'; 804 | echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '
'; 805 | } 806 | $data .= $str; 807 | if($this->do_debug >= 4) { 808 | echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '
'; 809 | } 810 | // if 4th character is a space, we are done reading, break the loop 811 | if(substr($str,3,1) == " ") { break; } 812 | } 813 | return $data; 814 | } 815 | 816 | } 817 | 818 | ?> 819 | -------------------------------------------------------------------------------- /lib/extras/htmlfilter.php: -------------------------------------------------------------------------------- 1 | 27 | * @Version 1.1 ($Date: 2011-07-04 14:02:23 -0400 (Mon, 04 Jul 2011) $) 28 | */ 29 | 30 | /** 31 | * @Author Jim Jagielski 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 = ''; 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 occurance 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 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 | * 181 | * 2. Closing tag, e.g.: 182 | * 183 | * 3. XHTML-style content-less tag, e.g.: 184 | * 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: . 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 | * 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: . 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 = "\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 .= ''; 711 | $opentimes--; 712 | } 713 | } 714 | $trusted .= "\n"; 715 | } 716 | $trusted .= "\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 | ?> 862 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-ar.php: -------------------------------------------------------------------------------- 1 | 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_email'] = '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: '; 27 | ?> -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-br.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-ca.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-ch.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-cz.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-de.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-dk.php: -------------------------------------------------------------------------------- 1 | 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_email'] = '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: '; 26 | ?> -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-es.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-et.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-fi.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-fo.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-fr.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-hu.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-it.php: -------------------------------------------------------------------------------- 1 | 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: Data non accettati dal server.'; 12 | //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 13 | $PHPMAILER_LANG['encoding'] = 'Encoding set dei caratteri sconosciuto: '; 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_email'] = 'Not sending, email address is invalid: '; 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 errore: '; 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: '; 27 | ?> -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-ja.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-nl.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-no.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-pl.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-ro.php: -------------------------------------------------------------------------------- 1 | 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_email'] = '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: '; 27 | ?> -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-ru.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | 7 | $PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.'; 8 | $PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к серверу SMTP.'; 9 | $PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не приняты.'; 10 | //$PHPMAILER_LANG['empty_message'] = 'Message body empty'; 11 | $PHPMAILER_LANG['encoding'] = 'Неизвестный вид кодировки: '; 12 | $PHPMAILER_LANG['execute'] = 'Невозможно выполнить команду: '; 13 | $PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: '; 14 | $PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удается открыть файл: '; 15 | $PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: '; 16 | $PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail.'; 17 | //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; 18 | $PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.'; 19 | $PHPMAILER_LANG['mailer_not_supported'] = ' - почтовый сервер не поддерживается.'; 20 | $PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: '; 21 | //$PHPMAILER_LANG['signing'] = 'Signing Error: '; 22 | //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; 23 | //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; 24 | //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; 25 | ?> -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-se.php: -------------------------------------------------------------------------------- 1 | 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_email'] = '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: '; 26 | ?> -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-tr.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-zh.php: -------------------------------------------------------------------------------- 1 | 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_email'] = '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: '; 26 | ?> -------------------------------------------------------------------------------- /lib/language/phpmailer.lang-zh_cn.php: -------------------------------------------------------------------------------- 1 | 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_email'] = '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: '; 26 | ?> -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # PHPMailer Bundle, by Colin Viebrock 2 | 3 | > [!WARNING] 4 | > This project is no longer maintained. If you want to make changes, please [fork your own copy](https://github.com/cviebrock/phpmailer-laravel/fork) 5 | > and use that in your Laravel 3 projects. 6 | 7 | * * * 8 | 9 | A Laravel PHPMailer bundle, installable via the Artisan CLI: 10 | 11 | php artisan bundle:install phpmailer 12 | 13 | Add it to `application/bundles.php`: 14 | 15 | return array( 16 | ... 17 | 'phpmailer' => array( 18 | 'auto' => true 19 | ), 20 | ... 21 | ); 22 | 23 | To get a PHPMailer instance: 24 | 25 | $mailer = IoC::resolve('phpmailer'); 26 | 27 | Then, use it just like you normally might: 28 | 29 | try { 30 | $mailer->AddAddress( $user->email, $user->name ); 31 | $mailer->Subject = "Laravel Rocks"; 32 | $mailer->Body = "Hi! Laravel is awesomesauce!"; 33 | $mailer->Send(); 34 | } catch (Exception $e) { 35 | echo 'Message was not sent.'; 36 | echo 'Mailer error: ' . $e->getMessage(); 37 | } 38 | 39 | The default "From:" address -- among other settings -- can be defined in the configuration file. 40 | 41 | * * * 42 | 43 | Includes *PHPMailer - Full Featured Email Transfer Class for PHP* 44 | 45 | - Version: 5.2.1 (January 16, 2012) 46 | - Homepage: https://code.google.com/a/apache-extras.org/p/phpmailer/ 47 | -------------------------------------------------------------------------------- /start.php: -------------------------------------------------------------------------------- 1 | Bundle::path('phpmailer').'lib'.DS.'class.phpmailer.php', 7 | )); 8 | 9 | 10 | // Register a mailer in the IoC container 11 | IoC::register('phpmailer', function() 12 | { 13 | 14 | // Instantiate a new PHPMailer. Passing 'true' to the constructor 15 | // means that exceptions are thrown on errors, which you can 16 | // catch in your application. 17 | 18 | $mailer = new PHPMailer(true); 19 | 20 | 21 | // set the default plugin dir for the instance 22 | 23 | $mailer->PluginDir = Bundle::path('phpmailer').'lib'.DS; 24 | 25 | 26 | // Load the default settings, if they exist. 27 | 28 | $config = Config::get('phpmailer::phpmailer', array()); 29 | 30 | foreach( $config as $key => $value ) { 31 | if (is_null($value)) { 32 | $mailer->{$key}(); 33 | } else if (is_array($value)) { 34 | call_user_func_array(array($mailer, $key), $value); 35 | } else { 36 | $mailer->{$key} = $value; 37 | } 38 | } 39 | 40 | // Return the instance. 41 | 42 | return $mailer; 43 | 44 | }); 45 | --------------------------------------------------------------------------------