Make WordPress Core

Ticket #25560: ticket-25560-phpmailer-minimal.patch

File ticket-25560-phpmailer-minimal.patch, 450.1 KB (added by bpetty, 12 years ago)
  • new file src/wp-includes/PHPMailer/.gitignore

    diff --git src/wp-includes/PHPMailer/.gitignore src/wp-includes/PHPMailer/.gitignore
    new file mode 100644
    index 0000000..88d2922
    - +  
     1docs/phpdoc/
     2test/message.txt
     3test/testbootstrap.php
     4.idea
  • new file src/wp-includes/PHPMailer/.travis.yml

    diff --git src/wp-includes/PHPMailer/.travis.yml src/wp-includes/PHPMailer/.travis.yml
    new file mode 100644
    index 0000000..28f0099
    - +  
     1language: php
     2php:
     3  - 5.5
     4  - 5.4
     5  - 5.3
     6before_install:
     7  - sudo apt-get update -qq
     8  - sudo apt-get install -y -qq postfix
     9before_script:
     10  - sudo service postfix stop
     11  - smtp-sink -d "%d.%H.%M.%S" localhost:2500 1000 &
     12  - cd test
     13  - cp testbootstrap-dist.php testbootstrap.php
     14  - chmod +x fakesendmail.sh
     15  - sudo mkdir -p /var/qmail/bin
     16  - sudo cp fakesendmail.sh /var/qmail/bin/sendmail
     17  - sudo cp fakesendmail.sh /usr/sbin/sendmail
     18  - echo 'sendmail_path = "/usr/sbin/sendmail -t -i "' | sudo tee "/home/travis/.phpenv/versions/`php -i|grep "PHP Version"|head -n 1|grep -o -P '\d+\.\d+\.\d+.*'`/etc/conf.d/sendmail.ini"
     19script:
     20  - phpunit phpmailerTest
  • new file src/wp-includes/PHPMailer/LICENSE

    diff --git src/wp-includes/PHPMailer/LICENSE src/wp-includes/PHPMailer/LICENSE
    new file mode 100644
    index 0000000..8e0763d
    - +  
     1                  GNU LESSER GENERAL PUBLIC LICENSE
     2                       Version 2.1, February 1999
     3
     4 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
     5     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     6 Everyone is permitted to copy and distribute verbatim copies
     7 of this license document, but changing it is not allowed.
     8
     9[This is the first released version of the Lesser GPL.  It also counts
     10 as the successor of the GNU Library Public License, version 2, hence
     11 the version number 2.1.]
     12
     13                            Preamble
     14
     15  The licenses for most software are designed to take away your
     16freedom to share and change it.  By contrast, the GNU General Public
     17Licenses are intended to guarantee your freedom to share and change
     18free software--to make sure the software is free for all its users.
     19
     20  This license, the Lesser General Public License, applies to some
     21specially designated software packages--typically libraries--of the
     22Free Software Foundation and other authors who decide to use it.  You
     23can use it too, but we suggest you first think carefully about whether
     24this license or the ordinary General Public License is the better
     25strategy 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,
     28not price.  Our General Public Licenses are designed to make sure that
     29you have the freedom to distribute copies of free software (and charge
     30for this service if you wish); that you receive source code or can get
     31it if you want it; that you can change the software and use pieces of
     32it in new free programs; and that you are informed that you can do
     33these things.
     34
     35  To protect your rights, we need to make restrictions that forbid
     36distributors to deny you these rights or to ask you to surrender these
     37rights.  These restrictions translate to certain responsibilities for
     38you 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
     41or for a fee, you must give the recipients all the rights that we gave
     42you.  You must make sure that they, too, receive or can get the source
     43code.  If you link other code with the library, you must provide
     44complete object files to the recipients, so that they can relink them
     45with the library after making changes to the library and recompiling
     46it.  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
     49library, and (2) we offer you this license, which gives you legal
     50permission to copy, distribute and/or modify the library.
     51
     52  To protect each distributor, we want to make it very clear that
     53there is no warranty for the free library.  Also, if the library is
     54modified by someone else and passed on, the recipients should know
     55that what they have is not the original version, so that the original
     56author's reputation will not be affected by problems that might be
     57introduced by others.
     58
     59  Finally, software patents pose a constant threat to the existence of
     60any free program.  We wish to make sure that a company cannot
     61effectively restrict the users of a free program by obtaining a
     62restrictive license from a patent holder.  Therefore, we insist that
     63any patent license obtained for a version of the library must be
     64consistent with the full freedom of use specified in this license.
     65
     66  Most GNU software, including some libraries, is covered by the
     67ordinary GNU General Public License.  This license, the GNU Lesser
     68General Public License, applies to certain designated libraries, and
     69is quite different from the ordinary General Public License.  We use
     70this license for certain libraries in order to permit linking those
     71libraries into non-free programs.
     72
     73  When a program is linked with a library, whether statically or using
     74a shared library, the combination of the two is legally speaking a
     75combined work, a derivative of the original library.  The ordinary
     76General Public License therefore permits such linking only if the
     77entire combination fits its criteria of freedom.  The Lesser General
     78Public License permits more lax criteria for linking other code with
     79the library.
     80
     81  We call this license the "Lesser" General Public License because it
     82does Less to protect the user's freedom than the ordinary General
     83Public License.  It also provides other free software developers Less
     84of an advantage over competing non-free programs.  These disadvantages
     85are the reason we use the ordinary General Public License for many
     86libraries.  However, the Lesser license provides advantages in certain
     87special circumstances.
     88
     89  For example, on rare occasions, there may be a special need to
     90encourage the widest possible use of a certain library, so that it becomes
     91a de-facto standard.  To achieve this, non-free programs must be
     92allowed to use the library.  A more frequent case is that a free
     93library does the same job as widely used non-free libraries.  In this
     94case, there is little to gain by limiting the free library to free
     95software only, so we use the Lesser General Public License.
     96
     97  In other cases, permission to use a particular library in non-free
     98programs enables a greater number of people to use a large body of
     99free software.  For example, permission to use the GNU C Library in
     100non-free programs enables many more people to use the whole GNU
     101operating system, as well as its variant, the GNU/Linux operating
     102system.
     103
     104  Although the Lesser General Public License is Less protective of the
     105users' freedom, it does ensure that the user of a program that is
     106linked with the Library has the freedom and the wherewithal to run
     107that program using a modified version of the Library.
     108
     109  The precise terms and conditions for copying, distribution and
     110modification follow.  Pay close attention to the difference between a
     111"work based on the library" and a "work that uses the library".  The
     112former contains code derived from the library, whereas the latter must
     113be 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
     119program which contains a notice placed by the copyright holder or
     120other authorized party saying it may be distributed under the terms of
     121this Lesser General Public License (also called "this License").
     122Each licensee is addressed as "you".
     123
     124  A "library" means a collection of software functions and/or data
     125prepared 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
     129which has been distributed under these terms.  A "work based on the
     130Library" means either the Library or any derivative work under
     131copyright law: that is to say, a work containing the Library or a
     132portion of it, either verbatim or with modifications and/or translated
     133straightforwardly into another language.  (Hereinafter, translation is
     134included without limitation in the term "modification".)
     135
     136  "Source code" for a work means the preferred form of the work for
     137making modifications to it.  For a library, complete source code means
     138all the source code for all modules it contains, plus any associated
     139interface definition files, plus the scripts used to control compilation
     140and installation of the library.
     141
     142  Activities other than copying, distribution and modification are not
     143covered by this License; they are outside its scope.  The act of
     144running a program using the Library is not restricted, and output from
     145such a program is covered only if its contents constitute a work based
     146on the Library (independent of the use of the Library in a tool for
     147writing it).  Whether that is true depends on what the Library does
     148and what the program that uses the Library does.
     149 
     150  1. You may copy and distribute verbatim copies of the Library's
     151complete source code as you receive it, in any medium, provided that
     152you conspicuously and appropriately publish on each copy an
     153appropriate copyright notice and disclaimer of warranty; keep intact
     154all the notices that refer to this License and to the absence of any
     155warranty; and distribute a copy of this License along with the
     156Library.
     157
     158  You may charge a fee for the physical act of transferring a copy,
     159and you may at your option offer warranty protection in exchange for a
     160fee.
     161
     162  2. You may modify your copy or copies of the Library or any portion
     163of it, thus forming a work based on the Library, and copy and
     164distribute such modifications or work under the terms of Section 1
     165above, 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
     190These requirements apply to the modified work as a whole.  If
     191identifiable sections of that work are not derived from the Library,
     192and can be reasonably considered independent and separate works in
     193themselves, then this License, and its terms, do not apply to those
     194sections when you distribute them as separate works.  But when you
     195distribute the same sections as part of a whole which is a work based
     196on the Library, the distribution of the whole must be on the terms of
     197this License, whose permissions for other licensees extend to the
     198entire whole, and thus to each and every part regardless of who wrote
     199it.
     200
     201Thus, it is not the intent of this section to claim rights or contest
     202your rights to work written entirely by you; rather, the intent is to
     203exercise the right to control the distribution of derivative or
     204collective works based on the Library.
     205
     206In addition, mere aggregation of another work not based on the Library
     207with the Library (or with a work based on the Library) on a volume of
     208a storage or distribution medium does not bring the other work under
     209the scope of this License.
     210
     211  3. You may opt to apply the terms of the ordinary GNU General Public
     212License instead of this License to a given copy of the Library.  To do
     213this, you must alter all the notices that refer to this License, so
     214that they refer to the ordinary GNU General Public License, version 2,
     215instead of to this License.  (If a newer version than version 2 of the
     216ordinary GNU General Public License has appeared, then you can specify
     217that version instead if you wish.)  Do not make any other change in
     218these notices.
     219
     220  Once this change is made in a given copy, it is irreversible for
     221that copy, so the ordinary GNU General Public License applies to all
     222subsequent copies and derivative works made from that copy.
     223
     224  This option is useful when you wish to copy part of the code of
     225the Library into a program that is not a library.
     226
     227  4. You may copy and distribute the Library (or a portion or
     228derivative of it, under Section 2) in object code or executable form
     229under the terms of Sections 1 and 2 above provided that you accompany
     230it with the complete corresponding machine-readable source code, which
     231must be distributed under the terms of Sections 1 and 2 above on a
     232medium customarily used for software interchange.
     233
     234  If distribution of object code is made by offering access to copy
     235from a designated place, then offering equivalent access to copy the
     236source code from the same place satisfies the requirement to
     237distribute the source code, even though third parties are not
     238compelled to copy the source along with the object code.
     239
     240  5. A program that contains no derivative of any portion of the
     241Library, but is designed to work with the Library by being compiled or
     242linked with it, is called a "work that uses the Library".  Such a
     243work, in isolation, is not a derivative work of the Library, and
     244therefore falls outside the scope of this License.
     245
     246  However, linking a "work that uses the Library" with the Library
     247creates an executable that is a derivative of the Library (because it
     248contains portions of the Library), rather than a "work that uses the
     249library".  The executable is therefore covered by this License.
     250Section 6 states terms for distribution of such executables.
     251
     252  When a "work that uses the Library" uses material from a header file
     253that is part of the Library, the object code for the work may be a
     254derivative work of the Library even though the source code is not.
     255Whether this is true is especially significant if the work can be
     256linked without the Library, or if the work is itself a library.  The
     257threshold for this to be true is not precisely defined by law.
     258
     259  If such an object file uses only numerical parameters, data
     260structure layouts and accessors, and small macros and small inline
     261functions (ten lines or less in length), then the use of the object
     262file is unrestricted, regardless of whether it is legally a derivative
     263work.  (Executables containing this object code plus portions of the
     264Library will still fall under Section 6.)
     265
     266  Otherwise, if the work is a derivative of the Library, you may
     267distribute the object code for the work under the terms of Section 6.
     268Any executables containing that work also fall under Section 6,
     269whether 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
     272link a "work that uses the Library" with the Library to produce a
     273work containing portions of the Library, and distribute that work
     274under terms of your choice, provided that the terms permit
     275modification of the work for the customer's own use and reverse
     276engineering for debugging such modifications.
     277
     278  You must give prominent notice with each copy of the work that the
     279Library is used in it and that the Library and its use are covered by
     280this License.  You must supply a copy of this License.  If the work
     281during execution displays copyright notices, you must include the
     282copyright notice for the Library among them, as well as a reference
     283directing the user to the copy of this License.  Also, you must do one
     284of 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
     319Library" must include any data and utility programs needed for
     320reproducing the executable from it.  However, as a special exception,
     321the materials to be distributed need not include anything that is
     322normally distributed (in either source or binary form) with the major
     323components (compiler, kernel, and so on) of the operating system on
     324which the executable runs, unless that component itself accompanies
     325the executable.
     326
     327  It may happen that this requirement contradicts the license
     328restrictions of other proprietary libraries that do not normally
     329accompany the operating system.  Such a contradiction means you cannot
     330use both them and the Library together in an executable that you
     331distribute.
     332
     333  7. You may place library facilities that are a work based on the
     334Library side-by-side in a single library together with other library
     335facilities not covered by this License, and distribute such a combined
     336library, provided that the separate distribution of the work based on
     337the Library and of the other library facilities is otherwise
     338permitted, 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
     350the Library except as expressly provided under this License.  Any
     351attempt otherwise to copy, modify, sublicense, link with, or
     352distribute the Library is void, and will automatically terminate your
     353rights under this License.  However, parties who have received copies,
     354or rights, from you under this License will not have their licenses
     355terminated so long as such parties remain in full compliance.
     356
     357  9. You are not required to accept this License, since you have not
     358signed it.  However, nothing else grants you permission to modify or
     359distribute the Library or its derivative works.  These actions are
     360prohibited by law if you do not accept this License.  Therefore, by
     361modifying or distributing the Library (or any work based on the
     362Library), you indicate your acceptance of this License to do so, and
     363all its terms and conditions for copying, distributing or modifying
     364the Library or works based on it.
     365
     366  10. Each time you redistribute the Library (or any work based on the
     367Library), the recipient automatically receives a license from the
     368original licensor to copy, distribute, link with or modify the Library
     369subject to these terms and conditions.  You may not impose any further
     370restrictions on the recipients' exercise of the rights granted herein.
     371You are not responsible for enforcing compliance by third parties with
     372this License.
     373
     374  11. If, as a consequence of a court judgment or allegation of patent
     375infringement or for any other reason (not limited to patent issues),
     376conditions are imposed on you (whether by court order, agreement or
     377otherwise) that contradict the conditions of this License, they do not
     378excuse you from the conditions of this License.  If you cannot
     379distribute so as to satisfy simultaneously your obligations under this
     380License and any other pertinent obligations, then as a consequence you
     381may not distribute the Library at all.  For example, if a patent
     382license would not permit royalty-free redistribution of the Library by
     383all those who receive copies directly or indirectly through you, then
     384the only way you could satisfy both it and this License would be to
     385refrain entirely from distribution of the Library.
     386
     387If any portion of this section is held invalid or unenforceable under any
     388particular circumstance, the balance of the section is intended to apply,
     389and the section as a whole is intended to apply in other circumstances.
     390
     391It is not the purpose of this section to induce you to infringe any
     392patents or other property right claims or to contest validity of any
     393such claims; this section has the sole purpose of protecting the
     394integrity of the free software distribution system which is
     395implemented by public license practices.  Many people have made
     396generous contributions to the wide range of software distributed
     397through that system in reliance on consistent application of that
     398system; it is up to the author/donor to decide if he or she is willing
     399to distribute software through any other system and a licensee cannot
     400impose that choice.
     401
     402This section is intended to make thoroughly clear what is believed to
     403be a consequence of the rest of this License.
     404
     405  12. If the distribution and/or use of the Library is restricted in
     406certain countries either by patents or by copyrighted interfaces, the
     407original copyright holder who places the Library under this License may add
     408an explicit geographical distribution limitation excluding those countries,
     409so that distribution is permitted only in or among countries not thus
     410excluded.  In such case, this License incorporates the limitation as if
     411written in the body of this License.
     412
     413  13. The Free Software Foundation may publish revised and/or new
     414versions of the Lesser General Public License from time to time.
     415Such new versions will be similar in spirit to the present version,
     416but may differ in detail to address new problems or concerns.
     417
     418Each version is given a distinguishing version number.  If the Library
     419specifies a version number of this License which applies to it and
     420"any later version", you have the option of following the terms and
     421conditions either of that version or of any later version published by
     422the Free Software Foundation.  If the Library does not specify a
     423license version number, you may choose any version ever published by
     424the Free Software Foundation.
     425
     426  14. If you wish to incorporate parts of the Library into other free
     427programs whose distribution conditions are incompatible with these,
     428write to the author to ask for permission.  For software which is
     429copyrighted by the Free Software Foundation, write to the Free
     430Software Foundation; we sometimes make exceptions for this.  Our
     431decision will be guided by the two goals of preserving the free status
     432of all derivatives of our free software and of promoting the sharing
     433and reuse of software generally.
     434
     435                            NO WARRANTY
     436
     437  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
     438WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
     439EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
     440OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
     441KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
     442IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     443PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
     444LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
     445THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
     446
     447  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
     448WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
     449AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
     450FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
     451CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
     452LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
     453RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
     454FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
     455SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     456DAMAGES.
     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
     463possible use to the public, we recommend making it free software that
     464everyone can redistribute and change.  You can do so by permitting
     465redistribution under these terms (or, alternatively, under the terms of the
     466ordinary General Public License).
     467
     468  To apply these terms, attach the following notices to the library.  It is
     469safest to attach them to the start of each source file to most effectively
     470convey the exclusion of warranty; and each file should have at least the
     471"copyright" line and a pointer to where the full notice is found.
     472
     473    <one line to give the library's name and a brief idea of what it does.>
     474    Copyright (C) <year>  <name of author>
     475
     476    This library is free software; you can redistribute it and/or
     477    modify it under the terms of the GNU Lesser General Public
     478    License as published by the Free Software Foundation; either
     479    version 2.1 of the License, or (at your option) any later version.
     480
     481    This library is distributed in the hope that it will be useful,
     482    but WITHOUT ANY WARRANTY; without even the implied warranty of
     483    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     484    Lesser General Public License for more details.
     485
     486    You should have received a copy of the GNU Lesser General Public
     487    License along with this library; if not, write to the Free Software
     488    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     489
     490Also add information on how to contact you by electronic and paper mail.
     491
     492You should also get your employer (if you work as a programmer) or your
     493school, if any, to sign a "copyright disclaimer" for the library, if
     494necessary.  Here is a sample; alter the names:
     495
     496  Yoyodyne, Inc., hereby disclaims all copyright interest in the
     497  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
     498
     499  <signature of Ty Coon>, 1 April 1990
     500  Ty Coon, President of Vice
     501
     502That's all there is to it!
     503
     504
  • new file src/wp-includes/PHPMailer/PHPMailerAutoload.php

    diff --git src/wp-includes/PHPMailer/PHPMailerAutoload.php src/wp-includes/PHPMailer/PHPMailerAutoload.php
    new file mode 100644
    index 0000000..46db5bd
    - +  
     1<?php
     2/**
     3 * PHPMailer SPL autoloader.
     4 * PHP Version 5.0.0
     5 * @package PHPMailer
     6 * @link https://github.com/PHPMailer/PHPMailer/
     7 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     8 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
     9 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
     10 * @author Brent R. Matzelle (original founder)
     11 * @copyright 2013 Marcus Bointon
     12 * @copyright 2010 - 2012 Jim Jagielski
     13 * @copyright 2004 - 2009 Andy Prevost
     14 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
     15 * @note This program is distributed in the hope that it will be useful - WITHOUT
     16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     17 * FITNESS FOR A PARTICULAR PURPOSE.
     18 */
     19
     20/**
     21 * PHPMailer SPL autoloader.
     22 * @param string $classname The name of the class to load
     23 */
     24function PHPMailerAutoload($classname)
     25{
     26    //Can't use __DIR__ as it's only in PHP 5.3+
     27    $filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php';
     28    if (is_readable($filename)) {
     29        require $filename;
     30    }
     31}
     32
     33spl_autoload_register('PHPMailerAutoload');
  • new file src/wp-includes/PHPMailer/README.md

    diff --git src/wp-includes/PHPMailer/README.md src/wp-includes/PHPMailer/README.md
    new file mode 100644
    index 0000000..de76a76
    - +  
     1# PHPMailer - A full-featured email creation and transfer class for PHP
     2
     3Build status: [![Build Status](https://travis-ci.org/Synchro/PHPMailer.png)](https://travis-ci.org/Synchro/PHPMailer)
     4
     5## Class Features
     6
     7- Probably the world's most popular code for sending email from PHP!
     8- Used by many open-source projects: Drupal, SugarCRM, Yii, Joomla! and many more
     9- Integrated SMTP support - send without a local mail server
     10- send emails with multiple TOs, CCs, BCCs and REPLY-TOs
     11- Multipart/alternative emails for mail clients that do not read HTML email
     12- Support for 8bit, base64, binary, and quoted-printable encoding
     13- SMTP authentication with LOGIN, PLAIN, NTLM and CRAM-MD5 mechanisms
     14- Native language support
     15- Compatible with PHP 5.0 and later
     16- Much more!
     17
     18## Why you might need it
     19
     20Many PHP developers utilize email in their code. The only PHP function that supports this is the mail() function. However, it does not provide any assistance for making use of popular features such as HTML-based emails and attachments.
     21
     22Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules - the vast majority of code that you'll find online that uses the mail() function directly is just plain wrong!
     23*Please* don't be tempted to do it yourself - if you don't use PHPMailer, there are many other excellent libraries that you should look at before rolling your own - try SwiftMailer, Zend_Mail, eZcomponents etc.
     24
     25The PHP mail() function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD and OS X platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server.
     26
     27## License
     28
     29This software is licenced under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html). Please read LICENSE for information on the
     30software availability and distribution.
     31
     32## Installation
     33
     34PHPMailer is available via [Composer/Packagist](https://packagist.org/packages/phpmailer/phpmailer). Alternatively, just copy the contents of the PHPMailer folder into somewhere that's in your PHP `include_path` setting. If you don't speak git or just want a tarball, click the 'zip' button at the top of the page in GitHub.
     35
     36
     37## A Simple Example
     38
     39```php
     40<?php
     41require 'class.phpmailer.php';
     42
     43$mail = new PHPMailer;
     44
     45$mail->isSMTP();                                      // Set mailer to use SMTP
     46$mail->Host = 'smtp1.example.com;smtp2.example.com';  // Specify main and backup server
     47$mail->SMTPAuth = true;                               // Enable SMTP authentication
     48$mail->Username = 'jswan';                            // SMTP username
     49$mail->Password = 'secret';                           // SMTP password
     50$mail->SMTPSecure = 'tls';                            // Enable encryption, 'ssl' also accepted
     51
     52$mail->From = 'from@example.com';
     53$mail->FromName = 'Mailer';
     54$mail->addAddress('josh@example.net', 'Josh Adams');  // Add a recipient
     55$mail->addAddress('ellen@example.com');               // Name is optional
     56$mail->addReplyTo('info@example.com', 'Information');
     57$mail->addCC('cc@example.com');
     58$mail->addBCC('bcc@example.com');
     59
     60$mail->WordWrap = 50;                                 // Set word wrap to 50 characters
     61$mail->addAttachment('/var/tmp/file.tar.gz');         // Add attachments
     62$mail->addAttachment('/tmp/image.jpg', 'new.jpg');    // Optional name
     63$mail->isHTML(true);                                  // Set email format to HTML
     64
     65$mail->Subject = 'Here is the subject';
     66$mail->Body    = 'This is the HTML message body <b>in bold!</b>';
     67$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
     68
     69if(!$mail->send()) {
     70   echo 'Message could not be sent.';
     71   echo 'Mailer Error: ' . $mail->ErrorInfo;
     72   exit;
     73}
     74
     75echo 'Message has been sent';
     76```
     77
     78You'll find plenty more to play with in the `examples` folder.
     79
     80That's it. You should now be ready to use PHPMailer!
     81
     82## Localization
     83PHPMailer defaults to English, but in the `languages` folder you'll find numerous translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
     84
     85```php
     86// To load the French version
     87$mail->setLanguage('fr', '/optional/path/to/language/directory/');
     88```
     89
     90## Documentation
     91
     92You'll find some basic user-level docs in the docs folder, and you can generate complete API-level documentation using the `generatedocs.sh` shell script in the docs folder, though you'll need to install [PHPDocumentor](http://www.phpdoc.org) first.
     93
     94## Tests
     95
     96You'll find a PHPUnit test script in the `test` folder.
     97
     98Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.png)](https://travis-ci.org/PHPMailer/PHPMailer)
     99
     100If this isn't passing, is there something you can do to help?
     101
     102## Contributing
     103
     104Please submit bug reports, suggestions and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues).
     105
     106We're particularly interested in fixing edge-cases, expanding test coverage and updating translations.
     107
     108With the move to the PHPMailer GitHub organisation, you'll need to update any remote URLs referencing the old GitHub location with a command like this from within your clone:
     109
     110`git remote set-url upstream https://github.com/PHPMailer/PHPMailer.git`
     111
     112Please *don't* use the SourceForge or Google Code projects any more.
     113
     114## Changelog
     115
     116See [changelog](changelog.md).
     117
     118## History
     119- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](http://sourceforge.net/projects/phpmailer/).
     120- Marcus Bointon (coolbru on SF) and Andy Prevost (codeworxtech) took over the project in 2004.
     121- Became an Apache incubator project on Google Code in 2010, managed by Jim Jagielski.
     122- Marcus created his fork on [GitHub](https://github.com/Synchro/PHPMailer).
     123- Jim and Marcus decide to join forces and use GitHub as the canonical and official repo for PHPMailer.
     124- PHPMailer moves to the [PHPMailer organisation](https://github.com/PHPMailer) on GitHub.
     125
     126### What's changed since moving from SourceForge?
     127- Official successor to the SourceForge and Google Code projects.
     128- Test suite.
     129- Continuous integration with Travis-CI.
     130- Composer support.
     131- Rolling releases.
     132- Additional languages and language strings.
     133- CRAM-MD5 authentication support.
     134- Preserves full repo history of authors, commits and branches from the original SourceForge project.
  • new file src/wp-includes/PHPMailer/changelog.md

    diff --git src/wp-includes/PHPMailer/changelog.md src/wp-includes/PHPMailer/changelog.md
    new file mode 100644
    index 0000000..4caa777
    - +  
     1# ChangeLog
     2
     3## Version 5.2.7 (September 12th 2013)
     4* Add Ukranian translation from @Krezalis
     5* Support for do_verp
     6* Fix bug in CRAM-MD5 AUTH
     7* Propagate Debugoutput option to SMTP class (@Reblutus)
     8* Determine MIME type of attachments automatically
     9* Add cross-platform, multibyte-safe pathinfo replacement (with tests) and use it
     10* Add a new 'html' Debugoutput type
     11* Clean up SMTP debug output, remove embedded HTML
     12* Some small changes in header formatting to improve IETF msglint test results
     13* Update test_script to use some recently changed features, rename to code_generator
     14* Generated code actually works!
     15* Update SyntaxHighlighter
     16* Major overhaul and cleanup of example code
     17* New PHPMailer graphic
     18* msgHTML now uses RFC2392-compliant content ids
     19* Add line break normalization function and use it in msgHTML
     20* Don't set unnecessary reply-to addresses
     21* Make fakesendmail.sh a bit cleaner and safer
     22* Set a content-transfer-encoding on multiparts (fixes msglint error)
     23* Fix cid generation in msgHTML (Thanks to @digitalthought)
     24* Fix handling of multiple SMTP servers (Thanks to @NanoCaiordo)
     25* SMTP->connect() now supports stream context options (Thanks to @stanislavdavid)
     26* Add support for iCal event alternatives (Thanks to @reblutus)
     27* Update to Polish language file (Thanks to Krzysztof Kowalewski)
     28* Update to Norwegian language file (Thanks to @datagutten)
     29* Update to Hungarian language file (Thanks to @dominicus-75)
     30* Add Persian/Farsi translation from @jaii
     31* Make SMTPDebug property type match type in SMTP class
     32* Add unit tests for DKIM
     33* Major refactor of SMTP class
     34* Reformat to PSR-2 coding standard
     35* Introduce autoloader
     36* Allow overriding of SMTP class
     37* Overhaul of PHPDocs
     38* Fix broken Q-encoding
     39* Czech language update (Thanks to @nemelu)
     40* Removal of excess blank lines in messages
     41* Added fake POP server and unit tests for POP-before-SMTP
     42
     43## Version 5.2.6 (April 11th 2013)
     44* Reflect move to PHPMailer GitHub organisation at https://github.com/PHPMailer/PHPMailer
     45* Fix unbumped version numbers
     46* Update packagist.org with new location
     47* Clean up Changelog
     48
     49## Version 5.2.5 (April 6th 2013)
     50* First official release after move from Google Code
     51* Fixes for qmail when sending via mail()
     52* Merge in changes from Google code 5.2.4 release
     53* Minor coding standards cleanup in SMTP class
     54* Improved unit tests, now tests S/MIME signing
     55* Travis-CI support on GitHub, runs tests with fake SMTP server
     56
     57## Version 5.2.4 (February 19, 2013)
     58* Fix tag and version bug.
     59* un-deprecate isSMTP(), isMail(), IsSendmail() and isQmail().
     60* Numerous translation updates
     61
     62## Version 5.2.3 (February 8, 2013)
     63* Fix issue with older PCREs and ValidateAddress() (Bugz: 124)
     64* Add CRAM-MD5 authentication, thanks to Elijah madden, https://github.com/okonomiyaki3000
     65* Replacement of obsolete Quoted-Printable encoder with a much better implementation
     66* Composer package definition
     67* New language added: Hebrew
     68
     69## Version 5.2.2 (December 3, 2012)
     70* Some fixes and syncs from https://github.com/Synchro/PHPMailer
     71* Add Slovak translation, thanks to Michal Tinka
     72
     73## Version 5.2.2-rc2 (November 6, 2012)
     74* Fix SMTP server rotation (Bugz: 118)
     75* Allow override of autogen'ed 'Date' header (for Drupal's
     76  og_mailinglist module)
     77* No whitespace after '-f' option (Bugz: 116)
     78* Work around potential warning (Bugz: 114)
     79
     80## Version 5.2.2-rc1 (September 28, 2012)
     81* Header encoding works with long lines (Bugz: 93)
     82* Turkish language update (Bugz: 94)
     83* undefined $pattern in EncodeQ bug squashed (Bugz: 98)
     84* use of mail() in safe_mode now works (Bugz: 96)
     85* ValidateAddress() now 'public static' so people can override the
     86  default and use their own validation scheme.
     87* ValidateAddress() no longer uses broken FILTER_VALIDATE_EMAIL
     88* Added in AUTH PLAIN SMTP authentication
     89
     90## Version 5.2.2-beta2 (August 17, 2012)
     91* Fixed Postfix VERP support (Bugz: 92)
     92* Allow action_function callbacks to pass/use
     93  the From address (passed as final param)
     94* Prevent inf look for get_lines() (Bugz: 77)
     95* New public var ($UseSendmailOptions). Only pass sendmail()
     96  options iff we really are using sendmail or something sendmail
     97  compatible. (Bugz: 75)
     98* default setting for LE returned to "\n" due to popular demand.
     99
     100## Version 5.2.2-beta1 (July 13, 2012)
     101* Expose PreSend() and PostSend() as public methods to allow
     102  for more control if serializing message sending.
     103* GetSentMIMEMessage() only constructs the message copy when
     104 needed. Save memory.
     105* Only pass params to mail() if the underlying MTA is
     106  "sendmail" (as defined as "having the string sendmail
     107  in its pathname") [#69]
     108* Attachments now work with Amazon SES and others [Bugz#70]
     109* Debug output now sent to stdout (via echo) or error_log [Bugz#5]
     110* New var: Debugoutput (for above) [Bugz#5]
     111* SMTP reads now Timeout aware (new var: Timeout=15) [Bugz#71]
     112* SMTP reads now can have a Timelimit associated with them
     113  (new var: Timelimit=30)[Bugz#71]
     114* Fix quoting issue associated with charsets
     115* default setting for LE is now RFC compliant: "\r\n"
     116* Return-Path can now be user defined (new var: ReturnPath)
     117  (the default is "" which implies no change from previous
     118  behavior, which was to use either From or Sender) [Bugz#46]
     119* X-Mailer header can now be disabled (by setting to a
     120  whitespace string, eg "  ") [Bugz#66]
     121* Bugz closed: #68, #60, #42, #43, #59, #55, #66, #48, #49,
     122               #52, #31, #41, #5. #70, #69
     123
     124## Version 5.2.1 (January 16, 2012)
     125* Closed several bugs#5
     126* Performance improvements
     127* MsgHTML() now returns the message as required.
     128* New method: GetSentMIMEMessage() (returns full copy of sent message)
     129
     130## Version 5.2 (July 19, 2011)
     131* protected MIME body and header
     132* better DKIM DNS Resource Record support
     133* better aly handling
     134* htmlfilter class added to extras
     135* moved to Apache Extras
     136
     137## Version 5.1 (October 20, 2009)
     138* fixed filename issue with AddStringAttachment (thanks to Tony)
     139* fixed "SingleTo" property, now works with Senmail, Qmail, and SMTP in
     140  addition to PHP mail()
     141* added DKIM digital signing functionality, new properties:
     142  - DKIM_domain (sets the domain name)
     143  - DKIM_private (holds DKIM private key)
     144  - DKIM_passphrase (holds your DKIM passphrase)
     145  - DKIM_selector (holds the DKIM "selector")
     146  - DKIM_identity (holds the identifying email address)
     147* added callback function support
     148  - callback function parameters include:
     149    result, to, cc, bcc, subject and body
     150  - see the test/test_callback.php file for usage.
     151* added "auto" identity functionality
     152  - can automatically add:
     153    - Return-path (if Sender not set)
     154    - Reply-To (if ReplyTo not set)
     155  - can be disabled:
     156    - $mail->SetFrom('yourname@yourdomain.com','First Last',false);
     157    - or by adding the $mail->Sender and/or $mail->ReplyTo properties
     158
     159Note: "auto" identity added to help with emails ending up in spam or junk boxes because of missing headers
     160
     161## Version 5.0.2 (May 24, 2009)
     162* Fix for missing attachments when inline graphics are present
     163* Fix for missing Cc in header when using SMTP (mail was sent,
     164  but not displayed in header -- Cc receiver only saw email To:
     165  line and no Cc line, but did get the email (To receiver
     166  saw same)
     167
     168## Version 5.0.1 (April 05, 2009)
     169* Temporary fix for missing attachments
     170
     171## Version 5.0.0 (April 02, 2009)
     172With the release of this version, we are initiating a new version numbering
     173system to differentiate from the PHP4 version of PHPMailer.
     174Most notable in this release is fully object oriented code.
     175
     176### class.smtp.php:
     177* Refactored class.smtp.php to support new exception handling
     178* code size reduced from 29.2 Kb to 25.6 Kb
     179* Removed unnecessary functions from class.smtp.php:
     180  - public function Expand($name) {
     181  - public function Help($keyword="") {
     182  - public function Noop() {
     183  - public function Send($from) {
     184  - public function SendOrMail($from) {
     185  - public function Verify($name) {
     186
     187###  class.phpmailer.php:
     188* Refactored class.phpmailer.php with new exception handling
     189* Changed processing functionality of Sendmail and Qmail so they cannot be
     190  inadvertently used
     191* removed getFile() function, just became a simple wrapper for
     192  file_get_contents()
     193* added check for PHP version (will gracefully exit if not at least PHP 5.0)
     194* enhanced code to check if an attachment source is the same as an embedded or
     195  inline graphic source to eliminate duplicate attachments
     196
     197### New /test_script
     198We have written a test script you can use to test the script as part of your
     199installation. Once you press submit, the test script will send a multi-mime
     200email with either the message you type in or an HTML email with an inline
     201graphic. Two attachments are included in the email (one of the attachments
     202is also the inline graphic so you can see that only one copy of the graphic
     203is sent in the email). The test script will also display the functional
     204script that you can copy/paste to your editor to duplicate the functionality.
     205
     206### New examples
     207All new examples in both basic and advanced modes. Advanced examples show
     208   Exception handling.
     209
     210### PHPDocumentator (phpdocs) documentation for PHPMailer version 5.0.0
     211All new documentation
     212
     213## Version 2.3 (November 06, 2008)
     214* added Arabic language (many thanks to Bahjat Al Mostafa)
     215* removed English language from language files and made it a default within
     216  class.phpmailer.php - if no language is found, it will default to use
     217  the english language translation
     218* fixed public/private declarations
     219* corrected line 1728, $basedir to $directory
     220* added $sign_cert_file to avoid improper duplicate use of $sign_key_file
     221* corrected $this->Hello on line 612 to $this->Helo
     222* changed default of $LE to "\r\n" to comply with RFC 2822. Can be set by the user
     223  if default is not acceptable
     224* removed trim() from return results in EncodeQP
     225* /test and three files it contained are removed from version 2.3
     226* fixed phpunit.php for compliance with PHP5
     227* changed $this->AltBody = $textMsg; to $this->AltBody = html_entity_decode($textMsg);
     228* We have removed the /phpdoc from the downloads. All documentation is now on
     229  the http://phpmailer.codeworxtech.com website.
     230
     231## Version 2.2.1 () July 19 2008
     232* fixed line 1092 in class.smtp.php (my apologies, error on my part)
     233
     234## Version 2.2 () July 15 2008
     235* Fixed redirect issue (display of UTF-8 in thank you redirect)
     236* fixed error in getResponse function declaration (class.pop3.php)
     237* PHPMailer now PHP6 compliant
     238* fixed line 1092 in class.smtp.php (endless loop from missing = sign)
     239
     240## Version 2.1 (Wed, June 04 2008)
     241NOTE: WE HAVE A NEW LANGUAGE VARIABLE FOR DIGITALLY SIGNED S/MIME EMAILS. IF YOU CAN HELP WITH LANGUAGES OTHER THAN ENGLISH AND SPANISH, IT WOULD BE APPRECIATED.
     242
     243* added S/MIME functionality (ability to digitally sign emails)
     244  BIG THANKS TO "sergiocambra" for posting this patch back in November 2007.
     245  The "Signed Emails" functionality adds the Sign method to pass the private key
     246  filename and the password to read it, and then email will be sent with
     247  content-type multipart/signed and with the digital signature attached.
     248* fully compatible with E_STRICT error level
     249  - Please note:
     250    In about half the test environments this development version was subjected
     251    to, an error was thrown for the date() functions used (line 1565 and 1569).
     252    This is NOT a PHPMailer error, it is the result of an incorrectly configured
     253    PHP5 installation. The fix is to modify your 'php.ini' file and include the
     254    date.timezone = America/New York
     255    directive, to your own server timezone
     256  - If you do get this error, and are unable to access your php.ini file:
     257    In your PHP script, add
     258    `date_default_timezone_set('America/Toronto');`
     259  - do not try to use
     260    `$myVar = date_default_timezone_get();`
     261    as a test, it will throw an error.
     262* added ability to define path (mainly for embedded images)
     263  function `MsgHTML($message,$basedir='')` ... where:
     264  `$basedir` is the fully qualified path
     265* fixed `MsgHTML()` function:
     266  - Embedded Images where images are specified by `<protocol>://` will not be altered or embedded
     267* fixed the return value of SMTP exit code ( pclose )
     268* addressed issue of multibyte characters in subject line and truncating
     269* added ability to have user specified Message ID
     270  (default is still that PHPMailer create a unique Message ID)
     271* corrected unidentified message type to 'application/octet-stream'
     272* fixed chunk_split() multibyte issue (thanks to Colin Brown, et al).
     273* added check for added attachments
     274* enhanced conversion of HTML to text in MsgHTML (thanks to "brunny")
     275
     276## Version 2.1.0beta2 (Sun, Dec 02 2007)
     277* implemented updated EncodeQP (thanks to coolbru, aka Marcus Bointon)
     278* finished all testing, all known bugs corrected, enhancements tested
     279
     280Note: will NOT work with PHP4.
     281
     282Please note, this is BETA software **DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS; INTENDED STRICTLY FOR TESTING**
     283
     284## Version 2.1.0beta1
     285Please note, this is BETA software
     286** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS
     287 INTENDED STRICTLY FOR TESTING
     288
     289## Version 2.0.0 rc2 (Fri, Nov 16 2007), interim release
     290* implements new property to control VERP in class.smtp.php
     291  example (requires instantiating class.smtp.php):
     292  $mail->do_verp = true;
     293* POP-before-SMTP functionality included, thanks to Richard Davey
     294  (see class.pop3.php & pop3_before_smtp_test.php for examples)
     295* included example showing how to use PHPMailer with GMAIL
     296* fixed the missing Cc in SendMail() and Mail()
     297
     298******************
     299A note on sending bulk emails:
     300
     301If the email you are sending is not personalized, consider using the
     302"undisclosed-recipient:;" strategy. That is, put all of your recipients
     303in the Bcc field and set the To field to "undisclosed-recipients:;".
     304It's a lot faster (only one send) and saves quite a bit on resources.
     305Contrary to some opinions, this will not get you listed in spam engines -
     306it's a legitimate way for you to send emails.
     307
     308A partial example for use with PHPMailer:
     309
     310```
     311$mail->AddAddress("undisclosed-recipients:;");
     312$mail->AddBCC("email1@anydomain.com,email2@anyotherdomain.com,email3@anyalternatedomain.com");
     313```
     314
     315Many email service providers restrict the number of emails that can be sent
     316in any given time period. Often that is between 50 - 60 emails maximum
     317per hour or per send session.
     318
     319If that's the case, then break up your Bcc lists into chunks that are one
     320less than your limit, and put a pause in your script.
     321*******************
     322
     323## Version 2.0.0 rc1 (Thu, Nov 08 2007), interim release
     324* dramatically simplified using inline graphics ... it's fully automated and requires no user input
     325* added automatic document type detection for attachments and pictures
     326* added MsgHTML() function to replace Body tag for HTML emails
     327* fixed the SendMail security issues (input validation vulnerability)
     328* enhanced the AddAddresses functionality so that the "Name" portion is used in the email address
     329* removed the need to use the AltBody method (set from the HTML, or default text used)
     330* set the PHP Mail() function as the default (still support SendMail, SMTP Mail)
     331* removed the need to set the IsHTML property (set automatically)
     332* added Estonian language file by Indrek P&auml;ri
     333* added header injection patch
     334* added "set" method to permit users to create their own pseudo-properties like 'X-Headers', etc.
     335  example of use:
     336
     337```
     338$mail->set('X-Priority', '3');
     339$mail->set('X-MSMail-Priority', 'Normal');
     340```
     341
     342* fixed warning message in SMTP get_lines method
     343* added TLS/SSL SMTP support. Example of use:
     344
     345```
     346$mail = new PHPMailer();
     347$mail->Mailer = "smtp";
     348$mail->Host = "smtp.example.com";
     349$mail->SMTPSecure   = "tls"; // option
     350//$mail->SMTPSecure   = "ssl";  // option
     351...
     352$mail->Send();
     353```
     354
     355* PHPMailer has been tested with PHP4 (4.4.7) and PHP5 (5.2.7)
     356* Works with PHP installed as a module or as CGI-PHP
     357NOTE: will NOT work with PHP5 in E_STRICT error mode
     358
     359## Version 1.73 (Sun, Jun 10 2005)
     360* Fixed denial of service bug: http://www.cybsec.com/vuln/PHPMailer-DOS.pdf
     361* Now has a total of 20 translations
     362* Fixed alt attachments bug: http://tinyurl.com/98u9k
     363
     364## Version 1.72 (Wed, May 25 2004)
     365* Added Dutch, Swedish, Czech, Norwegian, and Turkish translations.
     366* Received: Removed this method because spam filter programs like
     367  SpamAssassin reject this header.
     368* Fixed error count bug.
     369* SetLanguage default is now "language/".
     370* Fixed magic_quotes_runtime bug.
     371
     372## Version 1.71 (Tue, Jul 28 2003)
     373* Made several speed enhancements
     374* Added German and Italian translation files
     375* Fixed HELO/AUTH bugs on keep-alive connects
     376* Now provides an error message if language file does not load
     377* Fixed attachment EOL bug
     378* Updated some unclear documentation
     379* Added additional tests and improved others
     380
     381## Version 1.70 (Mon, Jun 20 2003)
     382* Added SMTP keep-alive support
     383* Added IsError method for error detection
     384* Added error message translation support (SetLanguage)
     385* Refactored many methods to increase library performance
     386* Hello now sends the newer EHLO message before HELO as per RFC 2821
     387* Removed the boundary class and replaced it with GetBoundary
     388* Removed queue support methods
     389* New $Hostname variable
     390* New Message-ID header
     391* Received header reformat
     392* Helo variable default changed to $Hostname
     393* Removed extra spaces in Content-Type definition (#667182)
     394* Return-Path should be set to Sender when set
     395* Adds Q or B encoding to headers when necessary
     396* quoted-encoding should now encode NULs \000
     397* Fixed encoding of body/AltBody (#553370)
     398* Adds "To: undisclosed-recipients:;" when all recipients are hidden (BCC)
     399* Multiple bug fixes
     400
     401## Version 1.65 (Fri, Aug 09 2002)
     402* Fixed non-visible attachment bug (#585097) for Outlook
     403* SMTP connections are now closed after each transaction
     404* Fixed SMTP::Expand return value
     405* Converted SMTP class documentation to phpDocumentor format
     406
     407## Version 1.62 (Wed, Jun 26 2002)
     408* Fixed multi-attach bug
     409* Set proper word wrapping
     410* Reduced memory use with attachments
     411* Added more debugging
     412* Changed documentation to phpDocumentor format
     413
     414## Version 1.60 (Sat, Mar 30 2002)
     415* Sendmail pipe and address patch (Christian Holtje)
     416* Added embedded image and read confirmation support (A. Ognio)
     417* Added unit tests
     418* Added SMTP timeout support (*nix only)
     419* Added possibly temporary PluginDir variable for SMTP class
     420* Added LE message line ending variable
     421* Refactored boundary and attachment code
     422* Eliminated SMTP class warnings
     423* Added SendToQueue method for future queuing support
     424
     425## Version 1.54 (Wed, Dec 19 2001)
     426* Add some queuing support code
     427* Fixed a pesky multi/alt bug
     428* Messages are no longer forced to have "To" addresses
     429
     430## Version 1.50 (Thu, Nov 08 2001)
     431* Fix extra lines when not using SMTP mailer
     432* Set WordWrap variable to int with a zero default
     433
     434## Version 1.47 (Tue, Oct 16 2001)
     435* Fixed Received header code format
     436* Fixed AltBody order error
     437* Fixed alternate port warning
     438
     439## Version 1.45 (Tue, Sep 25 2001)
     440* Added enhanced SMTP debug support
     441* Added support for multiple ports on SMTP
     442* Added Received header for tracing
     443* Fixed AddStringAttachment encoding
     444* Fixed possible header name quote bug
     445* Fixed wordwrap() trim bug
     446* Couple other small bug fixes
     447
     448## Version 1.41 (Wed, Aug 22 2001)
     449* Fixed AltBody bug w/o attachments
     450* Fixed rfc_date() for certain mail servers
     451
     452## Version 1.40 (Sun, Aug 12 2001)
     453* Added multipart/alternative support (AltBody)
     454* Documentation update
     455* Fixed bug in Mercury MTA
     456
     457## Version 1.29 (Fri, Aug 03 2001)
     458* Added AddStringAttachment() method
     459* Added SMTP authentication support
     460
     461## Version 1.28 (Mon, Jul 30 2001)
     462* Fixed a typo in SMTP class
     463* Fixed header issue with Imail (win32) SMTP server
     464* Made fopen() calls for attachments use "rb" to fix win32 error
     465
     466## Version 1.25 (Mon, Jul 02 2001)
     467* Added RFC 822 date fix (Patrice)
     468* Added improved error handling by adding a $ErrorInfo variable
     469* Removed MailerDebug variable (obsolete with new error handler)
     470
     471## Version 1.20 (Mon, Jun 25 2001)
     472* Added quoted-printable encoding (Patrice)
     473* Set Version as public and removed PrintVersion()
     474* Changed phpdoc to only display public variables and methods
     475
     476## Version 1.19 (Thu, Jun 21 2001)
     477* Fixed MS Mail header bug
     478* Added fix for Bcc problem with mail(). *Does not work on Win32*
     479  (See PHP bug report: http://www.php.net/bugs.php?id=11616)
     480* mail() no longer passes a fifth parameter when not needed
     481
     482## Version 1.15 (Fri, Jun 15 2001)
     483Note: these changes contributed by Patrice Fournier
     484* Changed all remaining \n to \r\n
     485* Bcc: header no longer writen to message except
     486  when sent directly to sendmail
     487* Added a small message to non-MIME compliant mail reader
     488* Added Sender variable to change the Sender email
     489  used in -f for sendmail/mail and in 'MAIL FROM' for smtp mode
     490* Changed boundary setting to a place it will be set only once
     491* Removed transfer encoding for whole message when using multipart
     492* Message body now uses Encoding in multipart messages
     493* Can set encoding and type to attachments 7bit, 8bit
     494  and binary attachment are sent as is, base64 are encoded
     495* Can set Encoding to base64 to send 8 bits body
     496  through 7 bits servers
     497
     498## Version 1.10 (Tue, Jun 12 2001)
     499* Fixed win32 mail header bug (printed out headers in message body)
     500
     501## Version 1.09 (Fri, Jun 08 2001)
     502* Changed date header to work with Netscape mail programs
     503* Altered phpdoc documentation
     504
     505## Version 1.08 (Tue, Jun 05 2001)
     506* Added enhanced error-checking
     507* Added phpdoc documentation to source
     508
     509## Version 1.06 (Fri, Jun 01 2001)
     510* Added optional name for file attachments
     511
     512## Version 1.05 (Tue, May 29 2001)
     513* Code cleanup
     514* Eliminated sendmail header warning message
     515* Fixed possible SMTP error
     516
     517## Version 1.03 (Thu, May 24 2001)
     518* Fixed problem where qmail sends out duplicate messages
     519
     520## Version 1.02 (Wed, May 23 2001)
     521* Added multiple recipient and attachment Clear* methods
     522* Added Sendmail public variable
     523* Fixed problem with loading SMTP library multiple times
     524
     525## Version 0.98 (Tue, May 22 2001)
     526* Fixed problem with redundant mail hosts sending out multiple messages
     527* Added additional error handler code
     528* Added AddCustomHeader() function
     529* Added support for Microsoft mail client headers (affects priority)
     530* Fixed small bug with Mailer variable
     531* Added PrintVersion() function
     532
     533## Version 0.92 (Tue, May 15 2001)
     534* Changed file names to class.phpmailer.php and class.smtp.php to match
     535  current PHP class trend.
     536* Fixed problem where body not being printed when a message is attached
     537* Several small bug fixes
     538
     539## Version 0.90 (Tue, April 17 2001)
     540* Initial public release
  • new file src/wp-includes/PHPMailer/class.phpmailer.php

    diff --git src/wp-includes/PHPMailer/class.phpmailer.php src/wp-includes/PHPMailer/class.phpmailer.php
    new file mode 100644
    index 0000000..fe37a93
    - +  
     1<?php
     2/**
     3 * PHPMailer - PHP email creation and transport class.
     4 * PHP Version 5.0.0
     5 * Version 5.2.7
     6 * @package PHPMailer
     7 * @link https://github.com/PHPMailer/PHPMailer/
     8 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     9 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
     10 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
     11 * @author Brent R. Matzelle (original founder)
     12 * @copyright 2013 Marcus Bointon
     13 * @copyright 2010 - 2012 Jim Jagielski
     14 * @copyright 2004 - 2009 Andy Prevost
     15 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
     16 * @note This program is distributed in the hope that it will be useful - WITHOUT
     17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     18 * FITNESS FOR A PARTICULAR PURPOSE.
     19 */
     20
     21if (version_compare(PHP_VERSION, '5.0.0', '<')) {
     22    exit("Sorry, PHPMailer will only run on PHP version 5 or greater!\n");
     23}
     24
     25/**
     26 * PHPMailer - PHP email creation and transport class.
     27 * PHP Version 5.0.0
     28 * @package PHPMailer
     29 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     30 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
     31 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
     32 * @author Brent R. Matzelle (original founder)
     33 * @copyright 2013 Marcus Bointon
     34 * @copyright 2010 - 2012 Jim Jagielski
     35 * @copyright 2004 - 2009 Andy Prevost
     36 */
     37class PHPMailer
     38{
     39    /**
     40     * The PHPMailer Version number.
     41     * @type string
     42     */
     43    public $Version = '5.2.7';
     44
     45    /**
     46     * Email priority.
     47     * Options: 1 = High, 3 = Normal, 5 = low.
     48     * @type int
     49     */
     50    public $Priority = 3;
     51
     52    /**
     53     * The character set of the message.
     54     * @type string
     55     */
     56    public $CharSet = 'iso-8859-1';
     57
     58    /**
     59     * The MIME Content-type of the message.
     60     * @type string
     61     */
     62    public $ContentType = 'text/plain';
     63
     64    /**
     65     * The message encoding.
     66     * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
     67     * @type string
     68     */
     69    public $Encoding = '8bit';
     70
     71    /**
     72     * Holds the most recent mailer error message.
     73     * @type string
     74     */
     75    public $ErrorInfo = '';
     76
     77    /**
     78     * The From email address for the message.
     79     * @type string
     80     */
     81    public $From = 'root@localhost';
     82
     83    /**
     84     * The From name of the message.
     85     * @type string
     86     */
     87    public $FromName = 'Root User';
     88
     89    /**
     90     * The Sender email (Return-Path) of the message.
     91     * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
     92     * @type string
     93     */
     94    public $Sender = '';
     95
     96    /**
     97     * The Return-Path of the message.
     98     * If empty, it will be set to either From or Sender.
     99     * @type string
     100     */
     101    public $ReturnPath = '';
     102
     103    /**
     104     * The Subject of the message.
     105     * @type string
     106     */
     107    public $Subject = '';
     108
     109    /**
     110     * An HTML or plain text message body.
     111     * If HTML then call isHTML(true).
     112     * @type string
     113     */
     114    public $Body = '';
     115
     116    /**
     117     * The plain-text message body.
     118     * This body can be read by mail clients that do not have HTML email
     119     * capability such as mutt & Eudora.
     120     * Clients that can read HTML will view the normal Body.
     121     * @type string
     122     */
     123    public $AltBody = '';
     124
     125    /**
     126     * An iCal message part body.
     127     * Only supported in simple alt or alt_inline message types
     128     * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator
     129     * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/
     130     * @link http://kigkonsult.se/iCalcreator/
     131     * @type string
     132     */
     133    public $Ical = '';
     134
     135    /**
     136     * The complete compiled MIME message body.
     137     * @access protected
     138     * @type string
     139     */
     140    protected $MIMEBody = '';
     141
     142    /**
     143     * The complete compiled MIME message headers.
     144     * @type string
     145     * @access protected
     146     */
     147    protected $MIMEHeader = '';
     148
     149    /**
     150     * Extra headers that createHeader() doesn't fold in.
     151     * @type string
     152     * @access protected
     153     */
     154    protected $mailHeader = '';
     155
     156    /**
     157     * Word-wrap the message body to this number of chars.
     158     * @type int
     159     */
     160    public $WordWrap = 0;
     161
     162    /**
     163     * Which method to use to send mail.
     164     * Options: "mail", "sendmail", or "smtp".
     165     * @type string
     166     */
     167    public $Mailer = 'mail';
     168
     169    /**
     170     * The path to the sendmail program.
     171     * @type string
     172     */
     173    public $Sendmail = '/usr/sbin/sendmail';
     174
     175    /**
     176     * Whether mail() uses a fully sendmail-compatible MTA.
     177     * One which supports sendmail's "-oi -f" options.
     178     * @type bool
     179     */
     180    public $UseSendmailOptions = true;
     181
     182    /**
     183     * Path to PHPMailer plugins.
     184     * Useful if the SMTP class is not in the PHP include path.
     185     * @type string
     186     * @deprecated Should not be needed now there is an autoloader.
     187     */
     188    public $PluginDir = '';
     189
     190    /**
     191     * The email address that a reading confirmation should be sent to.
     192     * @type string
     193     */
     194    public $ConfirmReadingTo = '';
     195
     196    /**
     197     * The hostname to use in Message-Id and Received headers
     198     * and as default HELO string.
     199     * If empty, the value returned
     200     * by SERVER_NAME is used or 'localhost.localdomain'.
     201     * @type string
     202     */
     203    public $Hostname = '';
     204
     205    /**
     206     * An ID to be used in the Message-Id header.
     207     * If empty, a unique id will be generated.
     208     * @type string
     209     */
     210    public $MessageID = '';
     211
     212    /**
     213     * The message Date to be used in the Date header.
     214     * If empty, the current date will be added.
     215     * @type string
     216     */
     217    public $MessageDate = '';
     218
     219    /**
     220     * SMTP hosts.
     221     * Either a single hostname or multiple semicolon-delimited hostnames.
     222     * You can also specify a different port
     223     * for each host by using this format: [hostname:port]
     224     * (e.g. "smtp1.example.com:25;smtp2.example.com").
     225     * Hosts will be tried in order.
     226     * @type string
     227     */
     228    public $Host = 'localhost';
     229
     230    /**
     231     * The default SMTP server port.
     232     * @type int
     233     * @Todo Why is this needed when the SMTP class takes care of it?
     234     */
     235    public $Port = 25;
     236
     237    /**
     238     * The SMTP HELO of the message.
     239     * Default is $Hostname.
     240     * @type string
     241     * @see PHPMailer::$Hostname
     242     */
     243    public $Helo = '';
     244
     245    /**
     246     * The secure connection prefix.
     247     * Options: "", "ssl" or "tls"
     248     * @type string
     249     */
     250    public $SMTPSecure = '';
     251
     252    /**
     253     * Whether to use SMTP authentication.
     254     * Uses the Username and Password properties.
     255     * @type bool
     256     * @see PHPMailer::$Username
     257     * @see PHPMailer::$Password
     258     */
     259    public $SMTPAuth = false;
     260
     261    /**
     262     * SMTP username.
     263     * @type string
     264     */
     265    public $Username = '';
     266
     267    /**
     268     * SMTP password.
     269     * @type string
     270     */
     271    public $Password = '';
     272
     273    /**
     274     * SMTP auth type.
     275     * Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5
     276     * @type string
     277     */
     278    public $AuthType = '';
     279
     280    /**
     281     * SMTP realm.
     282     * Used for NTLM auth
     283     * @type string
     284     */
     285    public $Realm = '';
     286
     287    /**
     288     * SMTP workstation.
     289     * Used for NTLM auth
     290     * @type string
     291     */
     292    public $Workstation = '';
     293
     294    /**
     295     * The SMTP server timeout in seconds.
     296     * @type int
     297     */
     298    public $Timeout = 10;
     299
     300    /**
     301     * SMTP class debug output mode.
     302     * Options: 0 = off, 1 = commands, 2 = commands and data
     303     * @type int
     304     * @see SMTP::$do_debug
     305     */
     306    public $SMTPDebug = 0;
     307
     308    /**
     309     * The function/method to use for debugging output.
     310     * Options: "echo" or "error_log"
     311     * @type string
     312     * @see SMTP::$Debugoutput
     313     */
     314    public $Debugoutput = "echo";
     315
     316    /**
     317     * Whether to keep SMTP connection open after each message.
     318     * If this is set to true then to close the connection
     319     * requires an explicit call to smtpClose().
     320     * @type bool
     321     */
     322    public $SMTPKeepAlive = false;
     323
     324    /**
     325     * Whether to split multiple to addresses into multiple messages
     326     * or send them all in one message.
     327     * @type bool
     328     */
     329    public $SingleTo = false;
     330
     331    /**
     332     * Storage for addresses when SingleTo is enabled.
     333     * @type array
     334     * @todo This should really not be public
     335     */
     336    public $SingleToArray = array();
     337
     338    /**
     339     * Whether to generate VERP addresses on send.
     340     * Only applicable when sending via SMTP.
     341     * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
     342     * @type bool
     343     */
     344    public $do_verp = false;
     345
     346    /**
     347     * Whether to allow sending messages with an empty body.
     348     * @type bool
     349     */
     350    public $AllowEmpty = false;
     351
     352    /**
     353     * The default line ending.
     354     * @note The default remains "\n". We force CRLF where we know
     355     *        it must be used via self::CRLF.
     356     * @type string
     357     */
     358    public $LE = "\n";
     359
     360    /**
     361     * DKIM selector.
     362     * @type string
     363     */
     364    public $DKIM_selector = '';
     365
     366    /**
     367     * DKIM Identity.
     368     * Usually the email address used as the source of the email
     369     * @type string
     370     */
     371    public $DKIM_identity = '';
     372
     373    /**
     374     * DKIM passphrase.
     375     * Used if your key is encrypted.
     376     * @type string
     377     */
     378    public $DKIM_passphrase = '';
     379
     380    /**
     381     * DKIM signing domain name.
     382     * @example 'example.com'
     383     * @type string
     384     */
     385    public $DKIM_domain = '';
     386
     387    /**
     388     * DKIM private key file path.
     389     * @type string
     390     */
     391    public $DKIM_private = '';
     392
     393    /**
     394     * Callback Action function name.
     395     *
     396     * The function that handles the result of the send email action.
     397     * It is called out by send() for each email sent.
     398     *
     399     * Value can be:
     400     * - 'function_name' for function names
     401     * - 'Class::Method' for static method calls
     402     * - array($object, 'Method') for calling methods on $object
     403     * See http://php.net/is_callable manual page for more details.
     404     *
     405     * Parameters:
     406     *   bool    $result        result of the send action
     407     *   string  $to            email address of the recipient
     408     *   string  $cc            cc email addresses
     409     *   string  $bcc           bcc email addresses
     410     *   string  $subject       the subject
     411     *   string  $body          the email body
     412     *   string  $from          email address of sender
     413     *
     414     * @type string
     415     */
     416    public $action_function = '';
     417
     418    /**
     419     * What to use in the X-Mailer header.
     420     * Options: null for default, whitespace for none, or a string to use
     421     * @type string
     422     */
     423    public $XMailer = '';
     424
     425    /**
     426     * An instance of the SMTP sender class.
     427     * @type SMTP
     428     * @access protected
     429     */
     430    protected $smtp = null;
     431
     432    /**
     433     * The array of 'to' addresses.
     434     * @type array
     435     * @access protected
     436     */
     437    protected $to = array();
     438
     439    /**
     440     * The array of 'cc' addresses.
     441     * @type array
     442     * @access protected
     443     */
     444    protected $cc = array();
     445
     446    /**
     447     * The array of 'bcc' addresses.
     448     * @type array
     449     * @access protected
     450     */
     451    protected $bcc = array();
     452
     453    /**
     454     * The array of reply-to names and addresses.
     455     * @type array
     456     * @access protected
     457     */
     458    protected $ReplyTo = array();
     459
     460    /**
     461     * An array of all kinds of addresses.
     462     * Includes all of $to, $cc, $bcc, $replyto
     463     * @type array
     464     * @access protected
     465     */
     466    protected $all_recipients = array();
     467
     468    /**
     469     * The array of attachments.
     470     * @type array
     471     * @access protected
     472     */
     473    protected $attachment = array();
     474
     475    /**
     476     * The array of custom headers.
     477     * @type array
     478     * @access protected
     479     */
     480    protected $CustomHeader = array();
     481
     482    /**
     483     * The most recent Message-ID (including angular brackets).
     484     * @type string
     485     * @access protected
     486     */
     487    protected $lastMessageID = '';
     488
     489    /**
     490     * The message's MIME type.
     491     * @type string
     492     * @access protected
     493     */
     494    protected $message_type = '';
     495
     496    /**
     497     * The array of MIME boundary strings.
     498     * @type array
     499     * @access protected
     500     */
     501    protected $boundary = array();
     502
     503    /**
     504     * The array of available languages.
     505     * @type array
     506     * @access protected
     507     */
     508    protected $language = array();
     509
     510    /**
     511     * The number of errors encountered.
     512     * @type integer
     513     * @access protected
     514     */
     515    protected $error_count = 0;
     516
     517    /**
     518     * The S/MIME certificate file path.
     519     * @type string
     520     * @access protected
     521     */
     522    protected $sign_cert_file = '';
     523
     524    /**
     525     * The S/MIME key file path.
     526     * @type string
     527     * @access protected
     528     */
     529    protected $sign_key_file = '';
     530
     531    /**
     532     * The S/MIME password for the key.
     533     * Used only if the key is encrypted.
     534     * @type string
     535     * @access protected
     536     */
     537    protected $sign_key_pass = '';
     538
     539    /**
     540     * Whether to throw exceptions for errors.
     541     * @type bool
     542     * @access protected
     543     */
     544    protected $exceptions = false;
     545
     546    /**
     547     * Error severity: message only, continue processing
     548     */
     549    const STOP_MESSAGE = 0;
     550
     551    /**
     552     * Error severity: message, likely ok to continue processing
     553     */
     554    const STOP_CONTINUE = 1;
     555
     556    /**
     557     * Error severity: message, plus full stop, critical error reached
     558     */
     559    const STOP_CRITICAL = 2;
     560
     561    /**
     562     * SMTP RFC standard line ending
     563     */
     564    const CRLF = "\r\n";
     565
     566    /**
     567     * Constructor
     568     * @param bool $exceptions Should we throw external exceptions?
     569     */
     570    public function __construct($exceptions = false)
     571    {
     572        $this->exceptions = ($exceptions == true);
     573        //Make sure our autoloader is loaded
     574        if (!in_array('PHPMailerAutoload', spl_autoload_functions())) {
     575            require 'PHPMailerAutoload.php';
     576        }
     577    }
     578
     579    /**
     580     * Destructor.
     581     */
     582    public function __destruct()
     583    {
     584        if ($this->Mailer == 'smtp') { //close any open SMTP connection nicely
     585            $this->smtpClose();
     586        }
     587    }
     588
     589    /**
     590     * Call mail() in a safe_mode-aware fashion.
     591     * Also, unless sendmail_path points to sendmail (or something that
     592     * claims to be sendmail), don't pass params (not a perfect fix,
     593     * but it will do)
     594     * @param string $to To
     595     * @param string $subject Subject
     596     * @param string $body Message Body
     597     * @param string $header Additional Header(s)
     598     * @param string $params Params
     599     * @access private
     600     * @return bool
     601     */
     602    private function mailPassthru($to, $subject, $body, $header, $params)
     603    {
     604        if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
     605            $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header);
     606        } else {
     607            $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header, $params);
     608        }
     609        return $rt;
     610    }
     611
     612    /**
     613     * Output debugging info via user-defined method.
     614     * Only if debug output is enabled.
     615     * @see PHPMailer::$Debugoutput
     616     * @see PHPMailer::$SMTPDebug
     617     * @param string $str
     618     */
     619    protected function edebug($str)
     620    {
     621        if (!$this->SMTPDebug) {
     622            return;
     623        }
     624        switch ($this->Debugoutput) {
     625            case 'error_log':
     626                error_log($str);
     627                break;
     628            case 'html':
     629                //Cleans up output a bit for a better looking display that's HTML-safe
     630                echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, $this->CharSet) . "<br>\n";
     631                break;
     632            case 'echo':
     633            default:
     634                //Just echoes exactly what was received
     635                echo $str;
     636        }
     637    }
     638
     639    /**
     640     * Sets message type to HTML or plain.
     641     * @param bool $ishtml True for HTML mode.
     642     * @return void
     643     */
     644    public function isHTML($ishtml = true)
     645    {
     646        if ($ishtml) {
     647            $this->ContentType = 'text/html';
     648        } else {
     649            $this->ContentType = 'text/plain';
     650        }
     651    }
     652
     653    /**
     654     * Send messages using SMTP.
     655     * @return void
     656     */
     657    public function isSMTP()
     658    {
     659        $this->Mailer = 'smtp';
     660    }
     661
     662    /**
     663     * Send messages using PHP's mail() function.
     664     * @return void
     665     */
     666    public function isMail()
     667    {
     668        $this->Mailer = 'mail';
     669    }
     670
     671    /**
     672     * Send messages using $Sendmail.
     673     * @return void
     674     */
     675    public function isSendmail()
     676    {
     677        if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
     678            $this->Sendmail = '/var/qmail/bin/sendmail';
     679        }
     680        $this->Mailer = 'sendmail';
     681    }
     682
     683    /**
     684     * Send messages using qmail.
     685     * @return void
     686     */
     687    public function isQmail()
     688    {
     689        if (stristr(ini_get('sendmail_path'), 'qmail')) {
     690            $this->Sendmail = '/var/qmail/bin/sendmail';
     691        }
     692        $this->Mailer = 'sendmail';
     693    }
     694
     695    /**
     696     * Add a "To" address.
     697     * @param string $address
     698     * @param string $name
     699     * @return bool true on success, false if address already used
     700     */
     701    public function addAddress($address, $name = '')
     702    {
     703        return $this->addAnAddress('to', $address, $name);
     704    }
     705
     706    /**
     707     * Add a "CC" address.
     708     * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
     709     * @param string $address
     710     * @param string $name
     711     * @return bool true on success, false if address already used
     712     */
     713    public function addCC($address, $name = '')
     714    {
     715        return $this->addAnAddress('cc', $address, $name);
     716    }
     717
     718    /**
     719     * Add a "BCC" address.
     720     * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
     721     * @param string $address
     722     * @param string $name
     723     * @return bool true on success, false if address already used
     724     */
     725    public function addBCC($address, $name = '')
     726    {
     727        return $this->addAnAddress('bcc', $address, $name);
     728    }
     729
     730    /**
     731     * Add a "Reply-to" address.
     732     * @param string $address
     733     * @param string $name
     734     * @return bool
     735     */
     736    public function addReplyTo($address, $name = '')
     737    {
     738        return $this->addAnAddress('Reply-To', $address, $name);
     739    }
     740
     741    /**
     742     * Add an address to one of the recipient arrays.
     743     * Addresses that have been added already return false, but do not throw exceptions
     744     * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
     745     * @param string $address The email address to send to
     746     * @param string $name
     747     * @throws phpmailerException
     748     * @return bool true on success, false if address already used or invalid in some way
     749     * @access protected
     750     */
     751    protected function addAnAddress($kind, $address, $name = '')
     752    {
     753        if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
     754            $this->setError($this->lang('Invalid recipient array') . ': ' . $kind);
     755            if ($this->exceptions) {
     756                throw new phpmailerException('Invalid recipient array: ' . $kind);
     757            }
     758            $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind);
     759            return false;
     760        }
     761        $address = trim($address);
     762        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
     763        if (!$this->validateAddress($address)) {
     764            $this->setError($this->lang('invalid_address') . ': ' . $address);
     765            if ($this->exceptions) {
     766                throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
     767            }
     768            $this->edebug($this->lang('invalid_address') . ': ' . $address);
     769            return false;
     770        }
     771        if ($kind != 'Reply-To') {
     772            if (!isset($this->all_recipients[strtolower($address)])) {
     773                array_push($this->$kind, array($address, $name));
     774                $this->all_recipients[strtolower($address)] = true;
     775                return true;
     776            }
     777        } else {
     778            if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
     779                $this->ReplyTo[strtolower($address)] = array($address, $name);
     780                return true;
     781            }
     782        }
     783        return false;
     784    }
     785
     786    /**
     787     * Set the From and FromName properties.
     788     * @param string $address
     789     * @param string $name
     790     * @param bool $auto Whether to also set the Sender address, defaults to true
     791     * @throws phpmailerException
     792     * @return bool
     793     */
     794    public function setFrom($address, $name = '', $auto = true)
     795    {
     796        $address = trim($address);
     797        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
     798        if (!$this->validateAddress($address)) {
     799            $this->setError($this->lang('invalid_address') . ': ' . $address);
     800            if ($this->exceptions) {
     801                throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
     802            }
     803            $this->edebug($this->lang('invalid_address') . ': ' . $address);
     804            return false;
     805        }
     806        $this->From = $address;
     807        $this->FromName = $name;
     808        if ($auto) {
     809            if (empty($this->Sender)) {
     810                $this->Sender = $address;
     811            }
     812        }
     813        return true;
     814    }
     815
     816    /**
     817     * Return the Message-ID header of the last email.
     818     * Technically this is the value from the last time the headers were created,
     819     * but it's also the message ID of the last sent message except in
     820     * pathological cases.
     821     * @return string
     822     */
     823    public function getLastMessageID()
     824    {
     825        return $this->lastMessageID;
     826    }
     827
     828    /**
     829     * Check that a string looks like an email address.
     830     * @param string $address The email address to check
     831     * @param string $patternselect A selector for the validation pattern to use :
     832     *   'auto' - pick best one automatically;
     833     *   'pcre8' - use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
     834     *   'pcre' - use old PCRE implementation;
     835     *   'php' - use PHP built-in FILTER_VALIDATE_EMAIL; faster, less thorough;
     836     *   'noregex' - super fast, really dumb.
     837     * @return bool
     838     * @static
     839     * @access public
     840     */
     841    public static function validateAddress($address, $patternselect = 'auto')
     842    {
     843        if ($patternselect == 'auto') {
     844            if (defined(
     845                'PCRE_VERSION'
     846            )
     847            ) { //Check this instead of extension_loaded so it works when that function is disabled
     848                if (version_compare(PCRE_VERSION, '8.0') >= 0) {
     849                    $patternselect = 'pcre8';
     850                } else {
     851                    $patternselect = 'pcre';
     852                }
     853            } else {
     854                //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension
     855                if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
     856                    $patternselect = 'php';
     857                } else {
     858                    $patternselect = 'noregex';
     859                }
     860            }
     861        }
     862        switch ($patternselect) {
     863            case 'pcre8':
     864                /**
     865                 * Conforms to RFC5322: Uses *correct* regex on which FILTER_VALIDATE_EMAIL is
     866                 * based; So why not use FILTER_VALIDATE_EMAIL? Because it was broken to
     867                 * not allow a@b type valid addresses :(
     868                 * @link http://squiloople.com/2009/12/20/email-address-validation/
     869                 * @copyright 2009-2010 Michael Rushton
     870                 * Feel free to use and redistribute this code. But please keep this copyright notice.
     871                 */
     872                return (bool)preg_match(
     873                    '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
     874                    '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
     875                    '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
     876                    '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
     877                    '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
     878                    '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
     879                    '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
     880                    '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
     881                    '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
     882                    $address
     883                );
     884                break;
     885            case 'pcre':
     886                //An older regex that doesn't need a recent PCRE
     887                return (bool)preg_match(
     888                    '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
     889                    '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
     890                    '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
     891                    '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' .
     892                    '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' .
     893                    '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' .
     894                    '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' .
     895                    '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' .
     896                    '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
     897                    '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
     898                    $address
     899                );
     900                break;
     901            case 'php':
     902            default:
     903                return (bool)filter_var($address, FILTER_VALIDATE_EMAIL);
     904                break;
     905            case 'noregex':
     906                //No PCRE! Do something _very_ approximate!
     907                //Check the address is 3 chars or longer and contains an @ that's not the first or last char
     908                return (strlen($address) >= 3
     909                    and strpos($address, '@') >= 1
     910                    and strpos($address, '@') != strlen($address) - 1);
     911                break;
     912        }
     913    }
     914
     915    /**
     916     * Create a message and send it.
     917     * Uses the sending method specified by $Mailer.
     918     * Returns false on error - Use the ErrorInfo variable to view description of the error.
     919     * @throws phpmailerException
     920     * @return bool
     921     */
     922    public function send()
     923    {
     924        try {
     925            if (!$this->preSend()) {
     926                return false;
     927            }
     928            return $this->postSend();
     929        } catch (phpmailerException $e) {
     930            $this->mailHeader = '';
     931            $this->setError($e->getMessage());
     932            if ($this->exceptions) {
     933                throw $e;
     934            }
     935            return false;
     936        }
     937    }
     938
     939    /**
     940     * Prepare a message for sending.
     941     * @throws phpmailerException
     942     * @return bool
     943     */
     944    public function preSend()
     945    {
     946        try {
     947            $this->mailHeader = "";
     948            if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
     949                throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
     950            }
     951
     952            // Set whether the message is multipart/alternative
     953            if (!empty($this->AltBody)) {
     954                $this->ContentType = 'multipart/alternative';
     955            }
     956
     957            $this->error_count = 0; // reset errors
     958            $this->setMessageType();
     959            // Refuse to send an empty message unless we are specifically allowing it
     960            if (!$this->AllowEmpty and empty($this->Body)) {
     961                throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL);
     962            }
     963
     964            $this->MIMEHeader = $this->createHeader();
     965            $this->MIMEBody = $this->createBody();
     966
     967            // To capture the complete message when using mail(), create
     968            // an extra header list which createHeader() doesn't fold in
     969            if ($this->Mailer == 'mail') {
     970                if (count($this->to) > 0) {
     971                    $this->mailHeader .= $this->addrAppend("To", $this->to);
     972                } else {
     973                    $this->mailHeader .= $this->headerLine("To", "undisclosed-recipients:;");
     974                }
     975                $this->mailHeader .= $this->headerLine(
     976                    'Subject',
     977                    $this->encodeHeader($this->secureHeader(trim($this->Subject)))
     978                );
     979            }
     980
     981            // Sign with DKIM if enabled
     982            if (!empty($this->DKIM_domain)
     983                && !empty($this->DKIM_private)
     984                && !empty($this->DKIM_selector)
     985                && !empty($this->DKIM_domain)
     986                && file_exists($this->DKIM_private)) {
     987                $header_dkim = $this->DKIM_Add(
     988                    $this->MIMEHeader . $this->mailHeader,
     989                    $this->encodeHeader($this->secureHeader($this->Subject)),
     990                    $this->MIMEBody
     991                );
     992                $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF .
     993                    str_replace("\r\n", "\n", $header_dkim) . self::CRLF;
     994            }
     995            return true;
     996
     997        } catch (phpmailerException $e) {
     998            $this->setError($e->getMessage());
     999            if ($this->exceptions) {
     1000                throw $e;
     1001            }
     1002            return false;
     1003        }
     1004    }
     1005
     1006    /**
     1007     * Actually send a message.
     1008     * Send the email via the selected mechanism
     1009     * @throws phpmailerException
     1010     * @return bool
     1011     */
     1012    public function postSend()
     1013    {
     1014        try {
     1015            // Choose the mailer and send through it
     1016            switch ($this->Mailer) {
     1017                case 'sendmail':
     1018                    return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);
     1019                case 'smtp':
     1020                    return $this->smtpSend($this->MIMEHeader, $this->MIMEBody);
     1021                case 'mail':
     1022                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
     1023                default:
     1024                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
     1025            }
     1026        } catch (phpmailerException $e) {
     1027            $this->setError($e->getMessage());
     1028            if ($this->exceptions) {
     1029                throw $e;
     1030            }
     1031            $this->edebug($e->getMessage() . "\n");
     1032        }
     1033        return false;
     1034    }
     1035
     1036    /**
     1037     * Send mail using the $Sendmail program.
     1038     * @param string $header The message headers
     1039     * @param string $body The message body
     1040     * @see PHPMailer::$Sendmail
     1041     * @throws phpmailerException
     1042     * @access protected
     1043     * @return bool
     1044     */
     1045    protected function sendmailSend($header, $body)
     1046    {
     1047        if ($this->Sender != '') {
     1048            $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
     1049        } else {
     1050            $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
     1051        }
     1052        if ($this->SingleTo === true) {
     1053            foreach ($this->SingleToArray as $val) {
     1054                if (!@$mail = popen($sendmail, 'w')) {
     1055                    throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
     1056                }
     1057                fputs($mail, "To: " . $val . "\n");
     1058                fputs($mail, $header);
     1059                fputs($mail, $body);
     1060                $result = pclose($mail);
     1061                // implement call back function if it exists
     1062                $isSent = ($result == 0) ? 1 : 0;
     1063                $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
     1064                if ($result != 0) {
     1065                    throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
     1066                }
     1067            }
     1068        } else {
     1069            if (!@$mail = popen($sendmail, 'w')) {
     1070                throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
     1071            }
     1072            fputs($mail, $header);
     1073            fputs($mail, $body);
     1074            $result = pclose($mail);
     1075            // implement call back function if it exists
     1076            $isSent = ($result == 0) ? 1 : 0;
     1077            $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
     1078            if ($result != 0) {
     1079                throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
     1080            }
     1081        }
     1082        return true;
     1083    }
     1084
     1085    /**
     1086     * Send mail using the PHP mail() function.
     1087     * @param string $header The message headers
     1088     * @param string $body The message body
     1089     * @link http://www.php.net/manual/en/book.mail.php
     1090     * @throws phpmailerException
     1091     * @access protected
     1092     * @return bool
     1093     */
     1094    protected function mailSend($header, $body)
     1095    {
     1096        $toArr = array();
     1097        foreach ($this->to as $t) {
     1098            $toArr[] = $this->addrFormat($t);
     1099        }
     1100        $to = implode(', ', $toArr);
     1101
     1102        if (empty($this->Sender)) {
     1103            $params = " ";
     1104        } else {
     1105            $params = sprintf("-f%s", $this->Sender);
     1106        }
     1107        if ($this->Sender != '' and !ini_get('safe_mode')) {
     1108            $old_from = ini_get('sendmail_from');
     1109            ini_set('sendmail_from', $this->Sender);
     1110        }
     1111        $rt = false;
     1112        if ($this->SingleTo === true && count($toArr) > 1) {
     1113            foreach ($toArr as $val) {
     1114                $rt = $this->mailPassthru($val, $this->Subject, $body, $header, $params);
     1115                // implement call back function if it exists
     1116                $isSent = ($rt == 1) ? 1 : 0;
     1117                $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
     1118            }
     1119        } else {
     1120            $rt = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
     1121            // implement call back function if it exists
     1122            $isSent = ($rt == 1) ? 1 : 0;
     1123            $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
     1124        }
     1125        if (isset($old_from)) {
     1126            ini_set('sendmail_from', $old_from);
     1127        }
     1128        if (!$rt) {
     1129            throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
     1130        }
     1131        return true;
     1132    }
     1133
     1134    /**
     1135     * Get an instance to use for SMTP operations.
     1136     * Override this function to load your own SMTP implementation
     1137     * @return SMTP
     1138     */
     1139    public function getSMTPInstance()
     1140    {
     1141        if (!is_object($this->smtp)) {
     1142            $this->smtp = new SMTP;
     1143        }
     1144        return $this->smtp;
     1145    }
     1146
     1147    /**
     1148     * Send mail via SMTP.
     1149     * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
     1150     * Uses the PHPMailerSMTP class by default.
     1151     * @see PHPMailer::getSMTPInstance() to use a different class.
     1152     * @param string $header The message headers
     1153     * @param string $body The message body
     1154     * @throws phpmailerException
     1155     * @uses SMTP
     1156     * @access protected
     1157     * @return bool
     1158     */
     1159    protected function smtpSend($header, $body)
     1160    {
     1161        $bad_rcpt = array();
     1162
     1163        if (!$this->smtpConnect()) {
     1164            throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
     1165        }
     1166        $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
     1167        if (!$this->smtp->mail($smtp_from)) {
     1168            $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
     1169            throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
     1170        }
     1171
     1172        // Attempt to send attach all recipients
     1173        foreach ($this->to as $to) {
     1174            if (!$this->smtp->recipient($to[0])) {
     1175                $bad_rcpt[] = $to[0];
     1176                $isSent = 0;
     1177            } else {
     1178                $isSent = 1;
     1179            }
     1180            $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body, $this->From);
     1181        }
     1182        foreach ($this->cc as $cc) {
     1183            if (!$this->smtp->recipient($cc[0])) {
     1184                $bad_rcpt[] = $cc[0];
     1185                $isSent = 0;
     1186            } else {
     1187                $isSent = 1;
     1188            }
     1189            $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body, $this->From);
     1190        }
     1191        foreach ($this->bcc as $bcc) {
     1192            if (!$this->smtp->recipient($bcc[0])) {
     1193                $bad_rcpt[] = $bcc[0];
     1194                $isSent = 0;
     1195            } else {
     1196                $isSent = 1;
     1197            }
     1198            $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body, $this->From);
     1199        }
     1200
     1201        if (count($bad_rcpt) > 0) { //Create error message for any bad addresses
     1202            throw new phpmailerException($this->lang('recipients_failed') . implode(', ', $bad_rcpt));
     1203        }
     1204        if (!$this->smtp->data($header . $body)) {
     1205            throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
     1206        }
     1207        if ($this->SMTPKeepAlive == true) {
     1208            $this->smtp->reset();
     1209        } else {
     1210            $this->smtp->quit();
     1211            $this->smtp->close();
     1212        }
     1213        return true;
     1214    }
     1215
     1216    /**
     1217     * Initiate a connection to an SMTP server.
     1218     * Returns false if the operation failed.
     1219     * @param array $options An array of options compatible with stream_context_create()
     1220     * @uses SMTP
     1221     * @access public
     1222     * @throws phpmailerException
     1223     * @return bool
     1224     */
     1225    public function smtpConnect($options = array())
     1226    {
     1227        if (is_null($this->smtp)) {
     1228            $this->smtp = $this->getSMTPInstance();
     1229        }
     1230
     1231        //Already connected?
     1232        if ($this->smtp->connected()) {
     1233            return true;
     1234        }
     1235
     1236        $this->smtp->setTimeout($this->Timeout);
     1237        $this->smtp->setDebugLevel($this->SMTPDebug);
     1238        $this->smtp->setDebugOutput($this->Debugoutput);
     1239        $this->smtp->setVerp($this->do_verp);
     1240        $tls = ($this->SMTPSecure == 'tls');
     1241        $ssl = ($this->SMTPSecure == 'ssl');
     1242        $hosts = explode(';', $this->Host);
     1243        $lastexception = null;
     1244
     1245        foreach ($hosts as $hostentry) {
     1246            $hostinfo = array();
     1247            $host = $hostentry;
     1248            $port = $this->Port;
     1249            if (preg_match(
     1250                '/^(.+):([0-9]+)$/',
     1251                $hostentry,
     1252                $hostinfo
     1253            )
     1254            ) { //If $hostentry contains 'address:port', override default
     1255                $host = $hostinfo[1];
     1256                $port = $hostinfo[2];
     1257            }
     1258            if ($this->smtp->connect(($ssl ? 'ssl://' : '') . $host, $port, $this->Timeout, $options)) {
     1259                try {
     1260                    if ($this->Helo) {
     1261                        $hello = $this->Helo;
     1262                    } else {
     1263                        $hello = $this->serverHostname();
     1264                    }
     1265                    $this->smtp->hello($hello);
     1266
     1267                    if ($tls) {
     1268                        if (!$this->smtp->startTLS()) {
     1269                            throw new phpmailerException($this->lang('connect_host'));
     1270                        }
     1271                        //We must resend HELO after tls negotiation
     1272                        $this->smtp->hello($hello);
     1273                    }
     1274                    if ($this->SMTPAuth) {
     1275                        if (!$this->smtp->authenticate(
     1276                            $this->Username,
     1277                            $this->Password,
     1278                            $this->AuthType,
     1279                            $this->Realm,
     1280                            $this->Workstation
     1281                        )
     1282                        ) {
     1283                            throw new phpmailerException($this->lang('authenticate'));
     1284                        }
     1285                    }
     1286                    return true;
     1287                } catch (phpmailerException $e) {
     1288                    $lastexception = $e;
     1289                    //We must have connected, but then failed TLS or Auth, so close connection nicely
     1290                    $this->smtp->quit();
     1291                }
     1292            }
     1293        }
     1294        //If we get here, all connection attempts have failed, so close connection hard
     1295        $this->smtp->close();
     1296        //As we've caught all exceptions, just report whatever the last one was
     1297        if ($this->exceptions and !is_null($lastexception)) {
     1298            throw $lastexception;
     1299        }
     1300        return false;
     1301    }
     1302
     1303    /**
     1304     * Close the active SMTP session if one exists.
     1305     * @return void
     1306     */
     1307    public function smtpClose()
     1308    {
     1309        if ($this->smtp !== null) {
     1310            if ($this->smtp->connected()) {
     1311                $this->smtp->quit();
     1312                $this->smtp->close();
     1313            }
     1314        }
     1315    }
     1316
     1317    /**
     1318     * Set the language for error messages.
     1319     * Returns false if it cannot load the language file.
     1320     * The default language is English.
     1321     * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr")
     1322     * @param string $lang_path Path to the language file directory, with trailing separator (slash)
     1323     * @return bool
     1324     * @access public
     1325     */
     1326    public function setLanguage($langcode = 'en', $lang_path = 'language/')
     1327    {
     1328        //Define full set of translatable strings
     1329        $PHPMAILER_LANG = array(
     1330            'authenticate' => 'SMTP Error: Could not authenticate.',
     1331            'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
     1332            'data_not_accepted' => 'SMTP Error: data not accepted.',
     1333            'empty_message' => 'Message body empty',
     1334            'encoding' => 'Unknown encoding: ',
     1335            'execute' => 'Could not execute: ',
     1336            'file_access' => 'Could not access file: ',
     1337            'file_open' => 'File Error: Could not open file: ',
     1338            'from_failed' => 'The following From address failed: ',
     1339            'instantiate' => 'Could not instantiate mail function.',
     1340            'invalid_address' => 'Invalid address',
     1341            'mailer_not_supported' => ' mailer is not supported.',
     1342            'provide_address' => 'You must provide at least one recipient email address.',
     1343            'recipients_failed' => 'SMTP Error: The following recipients failed: ',
     1344            'signing' => 'Signing Error: ',
     1345            'smtp_connect_failed' => 'SMTP connect() failed.',
     1346            'smtp_error' => 'SMTP server error: ',
     1347            'variable_set' => 'Cannot set or reset variable: '
     1348        );
     1349        //Overwrite language-specific strings.
     1350        //This way we'll never have missing translations - no more "language string failed to load"!
     1351        $l = true;
     1352        if ($langcode != 'en') { //There is no English translation file
     1353            $l = @include $lang_path . 'phpmailer.lang-' . $langcode . '.php';
     1354        }
     1355        $this->language = $PHPMAILER_LANG;
     1356        return ($l == true); //Returns false if language not found
     1357    }
     1358
     1359    /**
     1360     * Get the array of strings for the current language.
     1361     * @return array
     1362     */
     1363    public function getTranslations()
     1364    {
     1365        return $this->language;
     1366    }
     1367
     1368    /**
     1369     * Create recipient headers.
     1370     * @access public
     1371     * @param string $type
     1372     * @param array $addr An array of recipient,
     1373     * where each recipient is a 2-element indexed array with element 0 containing an address
     1374     * and element 1 containing a name, like:
     1375     * array(array('joe@example.com', 'Joe User'), array('zoe@example.com', 'Zoe User'))
     1376     * @return string
     1377     */
     1378    public function addrAppend($type, $addr)
     1379    {
     1380        $addresses = array();
     1381        foreach ($addr as $a) {
     1382            $addresses[] = $this->addrFormat($a);
     1383        }
     1384        return $type . ': ' . implode(', ', $addresses) . $this->LE;
     1385    }
     1386
     1387    /**
     1388     * Format an address for use in a message header.
     1389     * @access public
     1390     * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name
     1391     *      like array('joe@example.com', 'Joe User')
     1392     * @return string
     1393     */
     1394    public function addrFormat($addr)
     1395    {
     1396        if (empty($addr[1])) { // No name provided
     1397            return $this->secureHeader($addr[0]);
     1398        } else {
     1399            return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . " <" . $this->secureHeader(
     1400                $addr[0]
     1401            ) . ">";
     1402        }
     1403    }
     1404
     1405    /**
     1406     * Word-wrap message.
     1407     * For use with mailers that do not automatically perform wrapping
     1408     * and for quoted-printable encoded messages.
     1409     * Original written by philippe.
     1410     * @param string $message The message to wrap
     1411     * @param integer $length The line length to wrap to
     1412     * @param bool $qp_mode Whether to run in Quoted-Printable mode
     1413     * @access public
     1414     * @return string
     1415     */
     1416    public function wrapText($message, $length, $qp_mode = false)
     1417    {
     1418        $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
     1419        // If utf-8 encoding is used, we will need to make sure we don't
     1420        // split multibyte characters when we wrap
     1421        $is_utf8 = (strtolower($this->CharSet) == "utf-8");
     1422        $lelen = strlen($this->LE);
     1423        $crlflen = strlen(self::CRLF);
     1424
     1425        $message = $this->fixEOL($message);
     1426        if (substr($message, -$lelen) == $this->LE) {
     1427            $message = substr($message, 0, -$lelen);
     1428        }
     1429
     1430        $line = explode($this->LE, $message); // Magic. We know fixEOL uses $LE
     1431        $message = '';
     1432        for ($i = 0; $i < count($line); $i++) {
     1433            $line_part = explode(' ', $line[$i]);
     1434            $buf = '';
     1435            for ($e = 0; $e < count($line_part); $e++) {
     1436                $word = $line_part[$e];
     1437                if ($qp_mode and (strlen($word) > $length)) {
     1438                    $space_left = $length - strlen($buf) - $crlflen;
     1439                    if ($e != 0) {
     1440                        if ($space_left > 20) {
     1441                            $len = $space_left;
     1442                            if ($is_utf8) {
     1443                                $len = $this->utf8CharBoundary($word, $len);
     1444                            } elseif (substr($word, $len - 1, 1) == "=") {
     1445                                $len--;
     1446                            } elseif (substr($word, $len - 2, 1) == "=") {
     1447                                $len -= 2;
     1448                            }
     1449                            $part = substr($word, 0, $len);
     1450                            $word = substr($word, $len);
     1451                            $buf .= ' ' . $part;
     1452                            $message .= $buf . sprintf("=%s", self::CRLF);
     1453                        } else {
     1454                            $message .= $buf . $soft_break;
     1455                        }
     1456                        $buf = '';
     1457                    }
     1458                    while (strlen($word) > 0) {
     1459                        if ($length <= 0) {
     1460                            break;
     1461                        }
     1462                        $len = $length;
     1463                        if ($is_utf8) {
     1464                            $len = $this->utf8CharBoundary($word, $len);
     1465                        } elseif (substr($word, $len - 1, 1) == "=") {
     1466                            $len--;
     1467                        } elseif (substr($word, $len - 2, 1) == "=") {
     1468                            $len -= 2;
     1469                        }
     1470                        $part = substr($word, 0, $len);
     1471                        $word = substr($word, $len);
     1472
     1473                        if (strlen($word) > 0) {
     1474                            $message .= $part . sprintf("=%s", self::CRLF);
     1475                        } else {
     1476                            $buf = $part;
     1477                        }
     1478                    }
     1479                } else {
     1480                    $buf_o = $buf;
     1481                    $buf .= ($e == 0) ? $word : (' ' . $word);
     1482
     1483                    if (strlen($buf) > $length and $buf_o != '') {
     1484                        $message .= $buf_o . $soft_break;
     1485                        $buf = $word;
     1486                    }
     1487                }
     1488            }
     1489            $message .= $buf . self::CRLF;
     1490        }
     1491
     1492        return $message;
     1493    }
     1494
     1495    /**
     1496     * Find the last character boundary prior to $maxLength in a utf-8
     1497     * quoted (printable) encoded string.
     1498     * Original written by Colin Brown.
     1499     * @access public
     1500     * @param string $encodedText utf-8 QP text
     1501     * @param int $maxLength   find last character boundary prior to this length
     1502     * @return int
     1503     */
     1504    public function utf8CharBoundary($encodedText, $maxLength)
     1505    {
     1506        $foundSplitPos = false;
     1507        $lookBack = 3;
     1508        while (!$foundSplitPos) {
     1509            $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
     1510            $encodedCharPos = strpos($lastChunk, "=");
     1511            if ($encodedCharPos !== false) {
     1512                // Found start of encoded character byte within $lookBack block.
     1513                // Check the encoded byte value (the 2 chars after the '=')
     1514                $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
     1515                $dec = hexdec($hex);
     1516                if ($dec < 128) { // Single byte character.
     1517                    // If the encoded char was found at pos 0, it will fit
     1518                    // otherwise reduce maxLength to start of the encoded char
     1519                    $maxLength = ($encodedCharPos == 0) ? $maxLength :
     1520                        $maxLength - ($lookBack - $encodedCharPos);
     1521                    $foundSplitPos = true;
     1522                } elseif ($dec >= 192) { // First byte of a multi byte character
     1523                    // Reduce maxLength to split at start of character
     1524                    $maxLength = $maxLength - ($lookBack - $encodedCharPos);
     1525                    $foundSplitPos = true;
     1526                } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
     1527                    $lookBack += 3;
     1528                }
     1529            } else {
     1530                // No encoded character found
     1531                $foundSplitPos = true;
     1532            }
     1533        }
     1534        return $maxLength;
     1535    }
     1536
     1537
     1538    /**
     1539     * Set the body wrapping.
     1540     * @access public
     1541     * @return void
     1542     */
     1543    public function setWordWrap()
     1544    {
     1545        if ($this->WordWrap < 1) {
     1546            return;
     1547        }
     1548
     1549        switch ($this->message_type) {
     1550            case 'alt':
     1551            case 'alt_inline':
     1552            case 'alt_attach':
     1553            case 'alt_inline_attach':
     1554                $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap);
     1555                break;
     1556            default:
     1557                $this->Body = $this->wrapText($this->Body, $this->WordWrap);
     1558                break;
     1559        }
     1560    }
     1561
     1562    /**
     1563     * Assemble message headers.
     1564     * @access public
     1565     * @return string The assembled headers
     1566     */
     1567    public function createHeader()
     1568    {
     1569        $result = '';
     1570
     1571        // Set the boundaries
     1572        $uniq_id = md5(uniqid(time()));
     1573        $this->boundary[1] = 'b1_' . $uniq_id;
     1574        $this->boundary[2] = 'b2_' . $uniq_id;
     1575        $this->boundary[3] = 'b3_' . $uniq_id;
     1576
     1577        if ($this->MessageDate == '') {
     1578            $result .= $this->headerLine('Date', self::rfcDate());
     1579        } else {
     1580            $result .= $this->headerLine('Date', $this->MessageDate);
     1581        }
     1582
     1583        if ($this->ReturnPath) {
     1584            $result .= $this->headerLine('Return-Path', '<' . trim($this->ReturnPath) . '>');
     1585        } elseif ($this->Sender == '') {
     1586            $result .= $this->headerLine('Return-Path', '<' . trim($this->From) . '>');
     1587        } else {
     1588            $result .= $this->headerLine('Return-Path', '<' . trim($this->Sender) . '>');
     1589        }
     1590
     1591        // To be created automatically by mail()
     1592        if ($this->Mailer != 'mail') {
     1593            if ($this->SingleTo === true) {
     1594                foreach ($this->to as $t) {
     1595                    $this->SingleToArray[] = $this->addrFormat($t);
     1596                }
     1597            } else {
     1598                if (count($this->to) > 0) {
     1599                    $result .= $this->addrAppend('To', $this->to);
     1600                } elseif (count($this->cc) == 0) {
     1601                    $result .= $this->headerLine('To', 'undisclosed-recipients:;');
     1602                }
     1603            }
     1604        }
     1605
     1606        $result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName)));
     1607
     1608        // sendmail and mail() extract Cc from the header before sending
     1609        if (count($this->cc) > 0) {
     1610            $result .= $this->addrAppend('Cc', $this->cc);
     1611        }
     1612
     1613        // sendmail and mail() extract Bcc from the header before sending
     1614        if ((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
     1615            $result .= $this->addrAppend('Bcc', $this->bcc);
     1616        }
     1617
     1618        if (count($this->ReplyTo) > 0) {
     1619            $result .= $this->addrAppend('Reply-To', $this->ReplyTo);
     1620        }
     1621
     1622        // mail() sets the subject itself
     1623        if ($this->Mailer != 'mail') {
     1624            $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
     1625        }
     1626
     1627        if ($this->MessageID != '') {
     1628            $this->lastMessageID = $this->MessageID;
     1629        } else {
     1630            $this->lastMessageID = sprintf("<%s@%s>", $uniq_id, $this->ServerHostname());
     1631        }
     1632        $result .= $this->HeaderLine('Message-ID', $this->lastMessageID);
     1633        $result .= $this->headerLine('X-Priority', $this->Priority);
     1634        if ($this->XMailer == '') {
     1635            $result .= $this->headerLine(
     1636                'X-Mailer',
     1637                'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer/)'
     1638            );
     1639        } else {
     1640            $myXmailer = trim($this->XMailer);
     1641            if ($myXmailer) {
     1642                $result .= $this->headerLine('X-Mailer', $myXmailer);
     1643            }
     1644        }
     1645
     1646        if ($this->ConfirmReadingTo != '') {
     1647            $result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
     1648        }
     1649
     1650        // Add custom headers
     1651        for ($index = 0; $index < count($this->CustomHeader); $index++) {
     1652            $result .= $this->headerLine(
     1653                trim($this->CustomHeader[$index][0]),
     1654                $this->encodeHeader(trim($this->CustomHeader[$index][1]))
     1655            );
     1656        }
     1657        if (!$this->sign_key_file) {
     1658            $result .= $this->headerLine('MIME-Version', '1.0');
     1659            $result .= $this->getMailMIME();
     1660        }
     1661
     1662        return $result;
     1663    }
     1664
     1665    /**
     1666     * Get the message MIME type headers.
     1667     * @access public
     1668     * @return string
     1669     */
     1670    public function getMailMIME()
     1671    {
     1672        $result = '';
     1673        switch ($this->message_type) {
     1674            case 'inline':
     1675                $result .= $this->headerLine('Content-Type', 'multipart/related;');
     1676                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
     1677                break;
     1678            case 'attach':
     1679            case 'inline_attach':
     1680            case 'alt_attach':
     1681            case 'alt_inline_attach':
     1682                $result .= $this->headerLine('Content-Type', 'multipart/mixed;');
     1683                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
     1684                break;
     1685            case 'alt':
     1686            case 'alt_inline':
     1687                $result .= $this->headerLine('Content-Type', 'multipart/alternative;');
     1688                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
     1689                break;
     1690            default:
     1691                // Catches case 'plain': and case '':
     1692                $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
     1693                break;
     1694        }
     1695        //RFC1341 part 5 says 7bit is assumed if not specified
     1696        if ($this->Encoding != '7bit') {
     1697            $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
     1698        }
     1699
     1700        if ($this->Mailer != 'mail') {
     1701            $result .= $this->LE;
     1702        }
     1703
     1704        return $result;
     1705    }
     1706
     1707    /**
     1708     * Returns the whole MIME message.
     1709     * Includes complete headers and body.
     1710     * Only valid post PreSend().
     1711     * @see PHPMailer::PreSend()
     1712     * @access public
     1713     * @return string
     1714     */
     1715    public function getSentMIMEMessage()
     1716    {
     1717        return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
     1718    }
     1719
     1720
     1721    /**
     1722     * Assemble the message body.
     1723     * Returns an empty string on failure.
     1724     * @access public
     1725     * @throws phpmailerException
     1726     * @return string The assembled message body
     1727     */
     1728    public function createBody()
     1729    {
     1730        $body = '';
     1731
     1732        if ($this->sign_key_file) {
     1733            $body .= $this->getMailMIME() . $this->LE;
     1734        }
     1735
     1736        $this->setWordWrap();
     1737
     1738        switch ($this->message_type) {
     1739            case 'inline':
     1740                $body .= $this->getBoundary($this->boundary[1], '', '', '');
     1741                $body .= $this->encodeString($this->Body, $this->Encoding);
     1742                $body .= $this->LE . $this->LE;
     1743                $body .= $this->attachAll('inline', $this->boundary[1]);
     1744                break;
     1745            case 'attach':
     1746                $body .= $this->getBoundary($this->boundary[1], '', '', '');
     1747                $body .= $this->encodeString($this->Body, $this->Encoding);
     1748                $body .= $this->LE . $this->LE;
     1749                $body .= $this->attachAll('attachment', $this->boundary[1]);
     1750                break;
     1751            case 'inline_attach':
     1752                $body .= $this->textLine('--' . $this->boundary[1]);
     1753                $body .= $this->headerLine('Content-Type', 'multipart/related;');
     1754                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
     1755                $body .= $this->LE;
     1756                $body .= $this->getBoundary($this->boundary[2], '', '', '');
     1757                $body .= $this->encodeString($this->Body, $this->Encoding);
     1758                $body .= $this->LE . $this->LE;
     1759                $body .= $this->attachAll('inline', $this->boundary[2]);
     1760                $body .= $this->LE;
     1761                $body .= $this->attachAll('attachment', $this->boundary[1]);
     1762                break;
     1763            case 'alt':
     1764                $body .= $this->getBoundary($this->boundary[1], '', 'text/plain', '');
     1765                $body .= $this->encodeString($this->AltBody, $this->Encoding);
     1766                $body .= $this->LE . $this->LE;
     1767                $body .= $this->getBoundary($this->boundary[1], '', 'text/html', '');
     1768                $body .= $this->encodeString($this->Body, $this->Encoding);
     1769                $body .= $this->LE . $this->LE;
     1770                if (!empty($this->Ical)) {
     1771                    $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
     1772                    $body .= $this->encodeString($this->Ical, $this->Encoding);
     1773                    $body .= $this->LE . $this->LE;
     1774                }
     1775                $body .= $this->endBoundary($this->boundary[1]);
     1776                break;
     1777            case 'alt_inline':
     1778                $body .= $this->getBoundary($this->boundary[1], '', 'text/plain', '');
     1779                $body .= $this->encodeString($this->AltBody, $this->Encoding);
     1780                $body .= $this->LE . $this->LE;
     1781                $body .= $this->textLine('--' . $this->boundary[1]);
     1782                $body .= $this->headerLine('Content-Type', 'multipart/related;');
     1783                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
     1784                $body .= $this->LE;
     1785                $body .= $this->getBoundary($this->boundary[2], '', 'text/html', '');
     1786                $body .= $this->encodeString($this->Body, $this->Encoding);
     1787                $body .= $this->LE . $this->LE;
     1788                $body .= $this->attachAll('inline', $this->boundary[2]);
     1789                $body .= $this->LE;
     1790                $body .= $this->endBoundary($this->boundary[1]);
     1791                break;
     1792            case 'alt_attach':
     1793                $body .= $this->textLine('--' . $this->boundary[1]);
     1794                $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
     1795                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
     1796                $body .= $this->LE;
     1797                $body .= $this->getBoundary($this->boundary[2], '', 'text/plain', '');
     1798                $body .= $this->encodeString($this->AltBody, $this->Encoding);
     1799                $body .= $this->LE . $this->LE;
     1800                $body .= $this->getBoundary($this->boundary[2], '', 'text/html', '');
     1801                $body .= $this->encodeString($this->Body, $this->Encoding);
     1802                $body .= $this->LE . $this->LE;
     1803                $body .= $this->endBoundary($this->boundary[2]);
     1804                $body .= $this->LE;
     1805                $body .= $this->attachAll('attachment', $this->boundary[1]);
     1806                break;
     1807            case 'alt_inline_attach':
     1808                $body .= $this->textLine('--' . $this->boundary[1]);
     1809                $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
     1810                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
     1811                $body .= $this->LE;
     1812                $body .= $this->getBoundary($this->boundary[2], '', 'text/plain', '');
     1813                $body .= $this->encodeString($this->AltBody, $this->Encoding);
     1814                $body .= $this->LE . $this->LE;
     1815                $body .= $this->textLine('--' . $this->boundary[2]);
     1816                $body .= $this->headerLine('Content-Type', 'multipart/related;');
     1817                $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"');
     1818                $body .= $this->LE;
     1819                $body .= $this->getBoundary($this->boundary[3], '', 'text/html', '');
     1820                $body .= $this->encodeString($this->Body, $this->Encoding);
     1821                $body .= $this->LE . $this->LE;
     1822                $body .= $this->attachAll('inline', $this->boundary[3]);
     1823                $body .= $this->LE;
     1824                $body .= $this->endBoundary($this->boundary[2]);
     1825                $body .= $this->LE;
     1826                $body .= $this->attachAll('attachment', $this->boundary[1]);
     1827                break;
     1828            default:
     1829                // catch case 'plain' and case ''
     1830                $body .= $this->encodeString($this->Body, $this->Encoding);
     1831                break;
     1832        }
     1833
     1834        if ($this->isError()) {
     1835            $body = '';
     1836        } elseif ($this->sign_key_file) {
     1837            try {
     1838                if (!defined('PKCS7_TEXT')) {
     1839                    throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
     1840                }
     1841                $file = tempnam(sys_get_temp_dir(), 'mail');
     1842                file_put_contents($file, $body); //TODO check this worked
     1843                $signed = tempnam(sys_get_temp_dir(), 'signed');
     1844                if (@openssl_pkcs7_sign(
     1845                    $file,
     1846                    $signed,
     1847                    'file://' . realpath($this->sign_cert_file),
     1848                    array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
     1849                    null
     1850                )
     1851                ) {
     1852                    @unlink($file);
     1853                    $body = file_get_contents($signed);
     1854                    @unlink($signed);
     1855                } else {
     1856                    @unlink($file);
     1857                    @unlink($signed);
     1858                    throw new phpmailerException($this->lang('signing') . openssl_error_string());
     1859                }
     1860            } catch (phpmailerException $e) {
     1861                $body = '';
     1862                if ($this->exceptions) {
     1863                    throw $e;
     1864                }
     1865            }
     1866        }
     1867        return $body;
     1868    }
     1869
     1870    /**
     1871     * Return the start of a message boundary.
     1872     * @access protected
     1873     * @param string $boundary
     1874     * @param string $charSet
     1875     * @param string $contentType
     1876     * @param string $encoding
     1877     * @return string
     1878     */
     1879    protected function getBoundary($boundary, $charSet, $contentType, $encoding)
     1880    {
     1881        $result = '';
     1882        if ($charSet == '') {
     1883            $charSet = $this->CharSet;
     1884        }
     1885        if ($contentType == '') {
     1886            $contentType = $this->ContentType;
     1887        }
     1888        if ($encoding == '') {
     1889            $encoding = $this->Encoding;
     1890        }
     1891        $result .= $this->textLine('--' . $boundary);
     1892        $result .= sprintf("Content-Type: %s; charset=%s", $contentType, $charSet);
     1893        $result .= $this->LE;
     1894        $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
     1895        $result .= $this->LE;
     1896
     1897        return $result;
     1898    }
     1899
     1900    /**
     1901     * Return the end of a message boundary.
     1902     * @access protected
     1903     * @param string $boundary
     1904     * @return string
     1905     */
     1906    protected function endBoundary($boundary)
     1907    {
     1908        return $this->LE . '--' . $boundary . '--' . $this->LE;
     1909    }
     1910
     1911    /**
     1912     * Set the message type.
     1913     * PHPMailer only supports some preset message types,
     1914     * not arbitrary MIME structures.
     1915     * @access protected
     1916     * @return void
     1917     */
     1918    protected function setMessageType()
     1919    {
     1920        $this->message_type = array();
     1921        if ($this->alternativeExists()) {
     1922            $this->message_type[] = "alt";
     1923        }
     1924        if ($this->inlineImageExists()) {
     1925            $this->message_type[] = "inline";
     1926        }
     1927        if ($this->attachmentExists()) {
     1928            $this->message_type[] = "attach";
     1929        }
     1930        $this->message_type = implode("_", $this->message_type);
     1931        if ($this->message_type == "") {
     1932            $this->message_type = "plain";
     1933        }
     1934    }
     1935
     1936    /**
     1937     * Format a header line.
     1938     * @access public
     1939     * @param string $name
     1940     * @param string $value
     1941     * @return string
     1942     */
     1943    public function headerLine($name, $value)
     1944    {
     1945        return $name . ': ' . $value . $this->LE;
     1946    }
     1947
     1948    /**
     1949     * Return a formatted mail line.
     1950     * @access public
     1951     * @param string $value
     1952     * @return string
     1953     */
     1954    public function textLine($value)
     1955    {
     1956        return $value . $this->LE;
     1957    }
     1958
     1959    /**
     1960     * Add an attachment from a path on the filesystem.
     1961     * Returns false if the file could not be found or read.
     1962     * @param string $path Path to the attachment.
     1963     * @param string $name Overrides the attachment name.
     1964     * @param string $encoding File encoding (see $Encoding).
     1965     * @param string $type File extension (MIME) type.
     1966     * @param string $disposition Disposition to use
     1967     * @throws phpmailerException
     1968     * @return bool
     1969     */
     1970    public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')
     1971    {
     1972        try {
     1973            if (!@is_file($path)) {
     1974                throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
     1975            }
     1976
     1977            //If a MIME type is not specified, try to work it out from the file name
     1978            if ($type == '') {
     1979                $type = self::filenameToType($path);
     1980            }
     1981
     1982            $filename = basename($path);
     1983            if ($name == '') {
     1984                $name = $filename;
     1985            }
     1986
     1987            $this->attachment[] = array(
     1988                0 => $path,
     1989                1 => $filename,
     1990                2 => $name,
     1991                3 => $encoding,
     1992                4 => $type,
     1993                5 => false, // isStringAttachment
     1994                6 => $disposition,
     1995                7 => 0
     1996            );
     1997
     1998        } catch (phpmailerException $e) {
     1999            $this->setError($e->getMessage());
     2000            if ($this->exceptions) {
     2001                throw $e;
     2002            }
     2003            $this->edebug($e->getMessage() . "\n");
     2004            return false;
     2005        }
     2006        return true;
     2007    }
     2008
     2009    /**
     2010     * Return the array of attachments.
     2011     * @return array
     2012     */
     2013    public function getAttachments()
     2014    {
     2015        return $this->attachment;
     2016    }
     2017
     2018    /**
     2019     * Attach all file, string, and binary attachments to the message.
     2020     * Returns an empty string on failure.
     2021     * @access protected
     2022     * @param string $disposition_type
     2023     * @param string $boundary
     2024     * @return string
     2025     */
     2026    protected function attachAll($disposition_type, $boundary)
     2027    {
     2028        // Return text of body
     2029        $mime = array();
     2030        $cidUniq = array();
     2031        $incl = array();
     2032
     2033        // Add all attachments
     2034        foreach ($this->attachment as $attachment) {
     2035            // Check if it is a valid disposition_filter
     2036            if ($attachment[6] == $disposition_type) {
     2037                // Check for string attachment
     2038                $string = '';
     2039                $path = '';
     2040                $bString = $attachment[5];
     2041                if ($bString) {
     2042                    $string = $attachment[0];
     2043                } else {
     2044                    $path = $attachment[0];
     2045                }
     2046
     2047                $inclhash = md5(serialize($attachment));
     2048                if (in_array($inclhash, $incl)) {
     2049                    continue;
     2050                }
     2051                $incl[] = $inclhash;
     2052                $name = $attachment[2];
     2053                $encoding = $attachment[3];
     2054                $type = $attachment[4];
     2055                $disposition = $attachment[6];
     2056                $cid = $attachment[7];
     2057                if ($disposition == 'inline' && isset($cidUniq[$cid])) {
     2058                    continue;
     2059                }
     2060                $cidUniq[$cid] = true;
     2061
     2062                $mime[] = sprintf("--%s%s", $boundary, $this->LE);
     2063                $mime[] = sprintf(
     2064                    "Content-Type: %s; name=\"%s\"%s",
     2065                    $type,
     2066                    $this->encodeHeader($this->secureHeader($name)),
     2067                    $this->LE
     2068                );
     2069                $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
     2070
     2071                if ($disposition == 'inline') {
     2072                    $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
     2073                }
     2074
     2075                // If a filename contains any of these chars, it should be quoted,
     2076                // but not otherwise: RFC2183 & RFC2045 5.1
     2077                // Fixes a warning in IETF's msglint MIME checker
     2078                // Allow for bypassing the Content-Disposition header totally
     2079                if (!(empty($disposition))) {
     2080                    if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $name)) {
     2081                        $mime[] = sprintf(
     2082                            "Content-Disposition: %s; filename=\"%s\"%s",
     2083                            $disposition,
     2084                            $this->encodeHeader($this->secureHeader($name)),
     2085                            $this->LE . $this->LE
     2086                        );
     2087                    } else {
     2088                        $mime[] = sprintf(
     2089                            "Content-Disposition: %s; filename=%s%s",
     2090                            $disposition,
     2091                            $this->encodeHeader($this->secureHeader($name)),
     2092                            $this->LE . $this->LE
     2093                        );
     2094                    }
     2095                } else {
     2096                    $mime[] = $this->LE;
     2097                }
     2098
     2099                // Encode as string attachment
     2100                if ($bString) {
     2101                    $mime[] = $this->encodeString($string, $encoding);
     2102                    if ($this->isError()) {
     2103                        return '';
     2104                    }
     2105                    $mime[] = $this->LE . $this->LE;
     2106                } else {
     2107                    $mime[] = $this->encodeFile($path, $encoding);
     2108                    if ($this->isError()) {
     2109                        return '';
     2110                    }
     2111                    $mime[] = $this->LE . $this->LE;
     2112                }
     2113            }
     2114        }
     2115
     2116        $mime[] = sprintf("--%s--%s", $boundary, $this->LE);
     2117
     2118        return implode("", $mime);
     2119    }
     2120
     2121    /**
     2122     * Encode a file attachment in requested format.
     2123     * Returns an empty string on failure.
     2124     * @param string $path The full path to the file
     2125     * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
     2126     * @throws phpmailerException
     2127     * @see EncodeFile(encodeFile
     2128     * @access protected
     2129     * @return string
     2130     */
     2131    protected function encodeFile($path, $encoding = 'base64')
     2132    {
     2133        try {
     2134            if (!is_readable($path)) {
     2135                throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);
     2136            }
     2137            $magic_quotes = get_magic_quotes_runtime();
     2138            if ($magic_quotes) {
     2139                if (version_compare(PHP_VERSION, '5.3.0', '<')) {
     2140                    set_magic_quotes_runtime(0);
     2141                } else {
     2142                    ini_set('magic_quotes_runtime', 0);
     2143                }
     2144            }
     2145            $file_buffer = file_get_contents($path);
     2146            $file_buffer = $this->encodeString($file_buffer, $encoding);
     2147            if ($magic_quotes) {
     2148                if (version_compare(PHP_VERSION, '5.3.0', '<')) {
     2149                    set_magic_quotes_runtime($magic_quotes);
     2150                } else {
     2151                    ini_set('magic_quotes_runtime', $magic_quotes);
     2152                }
     2153            }
     2154            return $file_buffer;
     2155        } catch (Exception $e) {
     2156            $this->setError($e->getMessage());
     2157            return '';
     2158        }
     2159    }
     2160
     2161    /**
     2162     * Encode a string in requested format.
     2163     * Returns an empty string on failure.
     2164     * @param string $str The text to encode
     2165     * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
     2166     * @access public
     2167     * @return string
     2168     */
     2169    public function encodeString($str, $encoding = 'base64')
     2170    {
     2171        $encoded = '';
     2172        switch (strtolower($encoding)) {
     2173            case 'base64':
     2174                $encoded = chunk_split(base64_encode($str), 76, $this->LE);
     2175                break;
     2176            case '7bit':
     2177            case '8bit':
     2178                $encoded = $this->fixEOL($str);
     2179                //Make sure it ends with a line break
     2180                if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
     2181                    $encoded .= $this->LE;
     2182                }
     2183                break;
     2184            case 'binary':
     2185                $encoded = $str;
     2186                break;
     2187            case 'quoted-printable':
     2188                $encoded = $this->encodeQP($str);
     2189                break;
     2190            default:
     2191                $this->setError($this->lang('encoding') . $encoding);
     2192                break;
     2193        }
     2194        return $encoded;
     2195    }
     2196
     2197    /**
     2198     * Encode a header string optimally.
     2199     * Picks shortest of Q, B, quoted-printable or none.
     2200     * @access public
     2201     * @param string $str
     2202     * @param string $position
     2203     * @return string
     2204     */
     2205    public function encodeHeader($str, $position = 'text')
     2206    {
     2207        $x = 0;
     2208        switch (strtolower($position)) {
     2209            case 'phrase':
     2210                if (!preg_match('/[\200-\377]/', $str)) {
     2211                    // Can't use addslashes as we don't know what value has magic_quotes_sybase
     2212                    $encoded = addcslashes($str, "\0..\37\177\\\"");
     2213                    if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
     2214                        return ($encoded);
     2215                    } else {
     2216                        return ("\"$encoded\"");
     2217                    }
     2218                }
     2219                $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
     2220                break;
     2221            /** @noinspection PhpMissingBreakStatementInspection */
     2222            case 'comment':
     2223                $x = preg_match_all('/[()"]/', $str, $matches);
     2224                // Intentional fall-through
     2225            case 'text':
     2226            default:
     2227                $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
     2228                break;
     2229        }
     2230
     2231        if ($x == 0) { //There are no chars that need encoding
     2232            return ($str);
     2233        }
     2234
     2235        $maxlen = 75 - 7 - strlen($this->CharSet);
     2236        // Try to select the encoding which should produce the shortest output
     2237        if ($x > strlen($str) / 3) {
     2238            //More than a third of the content will need encoding, so B encoding will be most efficient
     2239            $encoding = 'B';
     2240            if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
     2241                // Use a custom function which correctly encodes and wraps long
     2242                // multibyte strings without breaking lines within a character
     2243                $encoded = $this->base64EncodeWrapMB($str, "\n");
     2244            } else {
     2245                $encoded = base64_encode($str);
     2246                $maxlen -= $maxlen % 4;
     2247                $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
     2248            }
     2249        } else {
     2250            $encoding = 'Q';
     2251            $encoded = $this->encodeQ($str, $position);
     2252            $encoded = $this->wrapText($encoded, $maxlen, true);
     2253            $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded));
     2254        }
     2255
     2256        $encoded = preg_replace('/^(.*)$/m', " =?" . $this->CharSet . "?$encoding?\\1?=", $encoded);
     2257        $encoded = trim(str_replace("\n", $this->LE, $encoded));
     2258
     2259        return $encoded;
     2260    }
     2261
     2262    /**
     2263     * Check if a string contains multi-byte characters.
     2264     * @access public
     2265     * @param string $str multi-byte text to wrap encode
     2266     * @return bool
     2267     */
     2268    public function hasMultiBytes($str)
     2269    {
     2270        if (function_exists('mb_strlen')) {
     2271            return (strlen($str) > mb_strlen($str, $this->CharSet));
     2272        } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
     2273            return false;
     2274        }
     2275    }
     2276
     2277    /**
     2278     * Encode and wrap long multibyte strings for mail headers
     2279     * without breaking lines within a character.
     2280     * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
     2281     * @access public
     2282     * @param string $str multi-byte text to wrap encode
     2283     * @param string $lf string to use as linefeed/end-of-line
     2284     * @return string
     2285     */
     2286    public function base64EncodeWrapMB($str, $lf = null)
     2287    {
     2288        $start = "=?" . $this->CharSet . "?B?";
     2289        $end = "?=";
     2290        $encoded = "";
     2291        if ($lf === null) {
     2292            $lf = $this->LE;
     2293        }
     2294
     2295        $mb_length = mb_strlen($str, $this->CharSet);
     2296        // Each line must have length <= 75, including $start and $end
     2297        $length = 75 - strlen($start) - strlen($end);
     2298        // Average multi-byte ratio
     2299        $ratio = $mb_length / strlen($str);
     2300        // Base64 has a 4:3 ratio
     2301        $avgLength = floor($length * $ratio * .75);
     2302
     2303        for ($i = 0; $i < $mb_length; $i += $offset) {
     2304            $lookBack = 0;
     2305            do {
     2306                $offset = $avgLength - $lookBack;
     2307                $chunk = mb_substr($str, $i, $offset, $this->CharSet);
     2308                $chunk = base64_encode($chunk);
     2309                $lookBack++;
     2310            } while (strlen($chunk) > $length);
     2311            $encoded .= $chunk . $lf;
     2312        }
     2313
     2314        // Chomp the last linefeed
     2315        $encoded = substr($encoded, 0, -strlen($lf));
     2316        return $encoded;
     2317    }
     2318
     2319    /**
     2320     * Encode a string in quoted-printable format.
     2321     * According to RFC2045 section 6.7.
     2322     * @access public
     2323     * @param string $string The text to encode
     2324     * @param integer $line_max Number of chars allowed on a line before wrapping
     2325     * @return string
     2326     * @link PHP version adapted from http://www.php.net/manual/en/function.quoted-printable-decode.php#89417
     2327     */
     2328    public function encodeQP($string, $line_max = 76)
     2329    {
     2330        if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3)
     2331            return quoted_printable_encode($string);
     2332        }
     2333        //Fall back to a pure PHP implementation
     2334        $string = str_replace(
     2335            array('%20', '%0D%0A.', '%0D%0A', '%'),
     2336            array(' ', "\r\n=2E", "\r\n", '='),
     2337            rawurlencode($string)
     2338        );
     2339        $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
     2340        return $string;
     2341    }
     2342
     2343    /**
     2344     * Backward compatibility wrapper for an old QP encoding function that was removed.
     2345     * @see PHPMailer::encodeQP()
     2346     * @access public
     2347     * @param string $string
     2348     * @param integer $line_max
     2349     * @param bool $space_conv
     2350     * @return string
     2351     * @deprecated Use encodeQP instead.
     2352     */
     2353    public function encodeQPphp(
     2354        $string,
     2355        $line_max = 76,
     2356        /** @noinspection PhpUnusedParameterInspection */ $space_conv = false
     2357    ) {
     2358        return $this->encodeQP($string, $line_max);
     2359    }
     2360
     2361    /**
     2362     * Encode a string using Q encoding.
     2363     * @link http://tools.ietf.org/html/rfc2047
     2364     * @param string $str the text to encode
     2365     * @param string $position Where the text is going to be used, see the RFC for what that means
     2366     * @access public
     2367     * @return string
     2368     */
     2369    public function encodeQ($str, $position = 'text')
     2370    {
     2371        //There should not be any EOL in the string
     2372        $pattern = '';
     2373        $encoded = str_replace(array("\r", "\n"), '', $str);
     2374        switch (strtolower($position)) {
     2375            case 'phrase':
     2376                //RFC 2047 section 5.3
     2377                $pattern = '^A-Za-z0-9!*+\/ -';
     2378                break;
     2379            /** @noinspection PhpMissingBreakStatementInspection */
     2380            case 'comment':
     2381                //RFC 2047 section 5.2
     2382                $pattern = '\(\)"';
     2383                //intentional fall-through
     2384                //for this reason we build the $pattern without including delimiters and []
     2385            case 'text':
     2386            default:
     2387                //RFC 2047 section 5.1
     2388                //Replace every high ascii, control, =, ? and _ characters
     2389                $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
     2390                break;
     2391        }
     2392        $matches = array();
     2393        if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
     2394            //If the string contains an '=', make sure it's the first thing we replace
     2395            //so as to avoid double-encoding
     2396            $s = array_search('=', $matches[0]);
     2397            if ($s !== false) {
     2398                unset($matches[0][$s]);
     2399                array_unshift($matches[0], '=');
     2400            }
     2401            foreach (array_unique($matches[0]) as $char) {
     2402                $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
     2403            }
     2404        }
     2405        //Replace every spaces to _ (more readable than =20)
     2406        return str_replace(' ', '_', $encoded);
     2407    }
     2408
     2409
     2410    /**
     2411     * Add a string or binary attachment (non-filesystem).
     2412     * This method can be used to attach ascii or binary data,
     2413     * such as a BLOB record from a database.
     2414     * @param string $string String attachment data.
     2415     * @param string $filename Name of the attachment.
     2416     * @param string $encoding File encoding (see $Encoding).
     2417     * @param string $type File extension (MIME) type.
     2418     * @param string $disposition Disposition to use
     2419     * @return void
     2420     */
     2421    public function addStringAttachment(
     2422        $string,
     2423        $filename,
     2424        $encoding = 'base64',
     2425        $type = '',
     2426        $disposition = 'attachment'
     2427    ) {
     2428        //If a MIME type is not specified, try to work it out from the file name
     2429        if ($type == '') {
     2430            $type = self::filenameToType($filename);
     2431        }
     2432        // Append to $attachment array
     2433        $this->attachment[] = array(
     2434            0 => $string,
     2435            1 => $filename,
     2436            2 => basename($filename),
     2437            3 => $encoding,
     2438            4 => $type,
     2439            5 => true, // isStringAttachment
     2440            6 => $disposition,
     2441            7 => 0
     2442        );
     2443    }
     2444
     2445    /**
     2446     * Add an embedded (inline) attachment from a file.
     2447     * This can include images, sounds, and just about any other document type.
     2448     * These differ from 'regular' attachmants in that they are intended to be
     2449     * displayed inline with the message, not just attached for download.
     2450     * This is used in HTML messages that embed the images
     2451     * the HTML refers to using the $cid value.
     2452     * @param string $path Path to the attachment.
     2453     * @param string $cid Content ID of the attachment; Use this to reference
     2454     *        the content when using an embedded image in HTML.
     2455     * @param string $name Overrides the attachment name.
     2456     * @param string $encoding File encoding (see $Encoding).
     2457     * @param string $type File MIME type.
     2458     * @param string $disposition Disposition to use
     2459     * @return bool True on successfully adding an attachment
     2460     */
     2461    public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
     2462    {
     2463        if (!@is_file($path)) {
     2464            $this->setError($this->lang('file_access') . $path);
     2465            return false;
     2466        }
     2467
     2468        //If a MIME type is not specified, try to work it out from the file name
     2469        if ($type == '') {
     2470            $type = self::filenameToType($path);
     2471        }
     2472
     2473        $filename = basename($path);
     2474        if ($name == '') {
     2475            $name = $filename;
     2476        }
     2477
     2478        // Append to $attachment array
     2479        $this->attachment[] = array(
     2480            0 => $path,
     2481            1 => $filename,
     2482            2 => $name,
     2483            3 => $encoding,
     2484            4 => $type,
     2485            5 => false, // isStringAttachment
     2486            6 => $disposition,
     2487            7 => $cid
     2488        );
     2489        return true;
     2490    }
     2491
     2492    /**
     2493     * Add an embedded stringified attachment.
     2494     * This can include images, sounds, and just about any other document type.
     2495     * Be sure to set the $type to an image type for images:
     2496     * JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'.
     2497     * @param string $string The attachment binary data.
     2498     * @param string $cid Content ID of the attachment; Use this to reference
     2499     *        the content when using an embedded image in HTML.
     2500     * @param string $name
     2501     * @param string $encoding File encoding (see $Encoding).
     2502     * @param string $type MIME type.
     2503     * @param string $disposition Disposition to use
     2504     * @return bool True on successfully adding an attachment
     2505     */
     2506    public function addStringEmbeddedImage(
     2507        $string,
     2508        $cid,
     2509        $name = '',
     2510        $encoding = 'base64',
     2511        $type = '',
     2512        $disposition = 'inline'
     2513    ) {
     2514        //If a MIME type is not specified, try to work it out from the name
     2515        if ($type == '') {
     2516            $type = self::filenameToType($name);
     2517        }
     2518
     2519        // Append to $attachment array
     2520        $this->attachment[] = array(
     2521            0 => $string,
     2522            1 => $name,
     2523            2 => $name,
     2524            3 => $encoding,
     2525            4 => $type,
     2526            5 => true, // isStringAttachment
     2527            6 => $disposition,
     2528            7 => $cid
     2529        );
     2530        return true;
     2531    }
     2532
     2533    /**
     2534     * Check if an inline attachment is present.
     2535     * @access public
     2536     * @return bool
     2537     */
     2538    public function inlineImageExists()
     2539    {
     2540        foreach ($this->attachment as $attachment) {
     2541            if ($attachment[6] == 'inline') {
     2542                return true;
     2543            }
     2544        }
     2545        return false;
     2546    }
     2547
     2548    /**
     2549     * Check if an attachment (non-inline) is present.
     2550     * @return bool
     2551     */
     2552    public function attachmentExists()
     2553    {
     2554        foreach ($this->attachment as $attachment) {
     2555            if ($attachment[6] == 'attachment') {
     2556                return true;
     2557            }
     2558        }
     2559        return false;
     2560    }
     2561
     2562    /**
     2563     * Check if this message has an alternative body set.
     2564     * @return bool
     2565     */
     2566    public function alternativeExists()
     2567    {
     2568        return !empty($this->AltBody);
     2569    }
     2570
     2571    /**
     2572     * Clear all To recipients.
     2573     * @return void
     2574     */
     2575    public function clearAddresses()
     2576    {
     2577        foreach ($this->to as $to) {
     2578            unset($this->all_recipients[strtolower($to[0])]);
     2579        }
     2580        $this->to = array();
     2581    }
     2582
     2583    /**
     2584     * Clear all CC recipients.
     2585     * @return void
     2586     */
     2587    public function clearCCs()
     2588    {
     2589        foreach ($this->cc as $cc) {
     2590            unset($this->all_recipients[strtolower($cc[0])]);
     2591        }
     2592        $this->cc = array();
     2593    }
     2594
     2595    /**
     2596     * Clear all BCC recipients.
     2597     * @return void
     2598     */
     2599    public function clearBCCs()
     2600    {
     2601        foreach ($this->bcc as $bcc) {
     2602            unset($this->all_recipients[strtolower($bcc[0])]);
     2603        }
     2604        $this->bcc = array();
     2605    }
     2606
     2607    /**
     2608     * Clear all ReplyTo recipients.
     2609     * @return void
     2610     */
     2611    public function clearReplyTos()
     2612    {
     2613        $this->ReplyTo = array();
     2614    }
     2615
     2616    /**
     2617     * Clear all recipient types.
     2618     * @return void
     2619     */
     2620    public function clearAllRecipients()
     2621    {
     2622        $this->to = array();
     2623        $this->cc = array();
     2624        $this->bcc = array();
     2625        $this->all_recipients = array();
     2626    }
     2627
     2628    /**
     2629     * Clear all filesystem, string, and binary attachments.
     2630     * @return void
     2631     */
     2632    public function clearAttachments()
     2633    {
     2634        $this->attachment = array();
     2635    }
     2636
     2637    /**
     2638     * Clear all custom headers.
     2639     * @return void
     2640     */
     2641    public function clearCustomHeaders()
     2642    {
     2643        $this->CustomHeader = array();
     2644    }
     2645
     2646    /**
     2647     * Add an error message to the error container.
     2648     * @access protected
     2649     * @param string $msg
     2650     * @return void
     2651     */
     2652    protected function setError($msg)
     2653    {
     2654        $this->error_count++;
     2655        if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
     2656            $lasterror = $this->smtp->getError();
     2657            if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
     2658                $msg .= '<p>' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
     2659            }
     2660        }
     2661        $this->ErrorInfo = $msg;
     2662    }
     2663
     2664    /**
     2665     * Return an RFC 822 formatted date.
     2666     * @access public
     2667     * @return string
     2668     * @static
     2669     */
     2670    public static function rfcDate()
     2671    {
     2672        //Set the time zone to whatever the default is to avoid 500 errors
     2673        //Will default to UTC if it's not set properly in php.ini
     2674        date_default_timezone_set(@date_default_timezone_get());
     2675        return date('D, j M Y H:i:s O');
     2676    }
     2677
     2678    /**
     2679     * Get the server hostname.
     2680     * Returns 'localhost.localdomain' if unknown.
     2681     * @access protected
     2682     * @return string
     2683     */
     2684    protected function serverHostname()
     2685    {
     2686        if (!empty($this->Hostname)) {
     2687            $result = $this->Hostname;
     2688        } elseif (isset($_SERVER['SERVER_NAME'])) {
     2689            $result = $_SERVER['SERVER_NAME'];
     2690        } else {
     2691            $result = 'localhost.localdomain';
     2692        }
     2693
     2694        return $result;
     2695    }
     2696
     2697    /**
     2698     * Get an error message in the current language.
     2699     * @access protected
     2700     * @param string $key
     2701     * @return string
     2702     */
     2703    protected function lang($key)
     2704    {
     2705        if (count($this->language) < 1) {
     2706            $this->setLanguage('en'); // set the default language
     2707        }
     2708
     2709        if (isset($this->language[$key])) {
     2710            return $this->language[$key];
     2711        } else {
     2712            return 'Language string failed to load: ' . $key;
     2713        }
     2714    }
     2715
     2716    /**
     2717     * Check if an error occurred.
     2718     * @access public
     2719     * @return bool True if an error did occur.
     2720     */
     2721    public function isError()
     2722    {
     2723        return ($this->error_count > 0);
     2724    }
     2725
     2726    /**
     2727     * Ensure consistent line endings in a string.
     2728     * Changes every end of line from CRLF, CR or LF to $this->LE.
     2729     * @access public
     2730     * @param string $str String to fixEOL
     2731     * @return string
     2732     */
     2733    public function fixEOL($str)
     2734    {
     2735        // Normalise to \n
     2736        $nstr = str_replace(array("\r\n", "\r"), "\n", $str);
     2737        // Now convert LE as needed
     2738        if ($this->LE !== "\n") {
     2739            $nstr = str_replace("\n", $this->LE, $nstr);
     2740        }
     2741        return $nstr;
     2742    }
     2743
     2744    /**
     2745     * Add a custom header.
     2746     * $name value can be overloaded to contain
     2747     * both header name and value (name:value)
     2748     * @access public
     2749     * @param string $name Custom header name
     2750     * @param string $value Header value
     2751     * @return void
     2752     */
     2753    public function addCustomHeader($name, $value = null)
     2754    {
     2755        if ($value === null) {
     2756            // Value passed in as name:value
     2757            $this->CustomHeader[] = explode(':', $name, 2);
     2758        } else {
     2759            $this->CustomHeader[] = array($name, $value);
     2760        }
     2761    }
     2762
     2763    /**
     2764     * Create a message from an HTML string.
     2765     * Automatically makes modifications for inline images and backgrounds
     2766     * and creates a plain-text version by converting the HTML.
     2767     * Overwrites any existing values in $this->Body and $this->AltBody
     2768     * @access public
     2769     * @param string $message HTML message string
     2770     * @param string $basedir baseline directory for path
     2771     * @param bool $advanced Whether to use the advanced HTML to text converter
     2772     * @return string $message
     2773     */
     2774    public function msgHTML($message, $basedir = '', $advanced = false)
     2775    {
     2776        preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images);
     2777        if (isset($images[2])) {
     2778            foreach ($images[2] as $i => $url) {
     2779                // do not change urls for absolute images (thanks to corvuscorax)
     2780                if (!preg_match('#^[A-z]+://#', $url)) {
     2781                    $filename = basename($url);
     2782                    $directory = dirname($url);
     2783                    if ($directory == '.') {
     2784                        $directory = '';
     2785                    }
     2786                    $cid = md5($url) . '@phpmailer.0'; //RFC2392 S 2
     2787                    if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
     2788                        $basedir .= '/';
     2789                    }
     2790                    if (strlen($directory) > 1 && substr($directory, -1) != '/') {
     2791                        $directory .= '/';
     2792                    }
     2793                    if ($this->addEmbeddedImage(
     2794                        $basedir . $directory . $filename,
     2795                        $cid,
     2796                        $filename,
     2797                        'base64',
     2798                        self::_mime_types(self::mb_pathinfo($filename, PATHINFO_EXTENSION))
     2799                    )
     2800                    ) {
     2801                        $message = preg_replace(
     2802                            "/" . $images[1][$i] . "=[\"']" . preg_quote($url, '/') . "[\"']/Ui",
     2803                            $images[1][$i] . "=\"cid:" . $cid . "\"",
     2804                            $message
     2805                        );
     2806                    }
     2807                }
     2808            }
     2809        }
     2810        $this->isHTML(true);
     2811        if (empty($this->AltBody)) {
     2812            $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
     2813        }
     2814        //Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
     2815        $this->Body = $this->normalizeBreaks($message);
     2816        $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
     2817        return $this->Body;
     2818    }
     2819
     2820    /**
     2821     * Convert an HTML string into plain text.
     2822     * @param string $html The HTML text to convert
     2823     * @param bool $advanced Should this use the more complex html2text converter or just a simple one?
     2824     * @return string
     2825     */
     2826    public function html2text($html, $advanced = false)
     2827    {
     2828        if ($advanced) {
     2829            require_once 'extras/class.html2text.php';
     2830            $h = new html2text($html);
     2831            return $h->get_text();
     2832        }
     2833        return html_entity_decode(
     2834            trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))),
     2835            ENT_QUOTES,
     2836            $this->CharSet
     2837        );
     2838    }
     2839
     2840    /**
     2841     * Get the MIME type for a file extension.
     2842     * @param string $ext File extension
     2843     * @access public
     2844     * @return string MIME type of file.
     2845     * @static
     2846     */
     2847    public static function _mime_types($ext = '')
     2848    {
     2849        $mimes = array(
     2850            'xl' => 'application/excel',
     2851            'hqx' => 'application/mac-binhex40',
     2852            'cpt' => 'application/mac-compactpro',
     2853            'bin' => 'application/macbinary',
     2854            'doc' => 'application/msword',
     2855            'word' => 'application/msword',
     2856            'class' => 'application/octet-stream',
     2857            'dll' => 'application/octet-stream',
     2858            'dms' => 'application/octet-stream',
     2859            'exe' => 'application/octet-stream',
     2860            'lha' => 'application/octet-stream',
     2861            'lzh' => 'application/octet-stream',
     2862            'psd' => 'application/octet-stream',
     2863            'sea' => 'application/octet-stream',
     2864            'so' => 'application/octet-stream',
     2865            'oda' => 'application/oda',
     2866            'pdf' => 'application/pdf',
     2867            'ai' => 'application/postscript',
     2868            'eps' => 'application/postscript',
     2869            'ps' => 'application/postscript',
     2870            'smi' => 'application/smil',
     2871            'smil' => 'application/smil',
     2872            'mif' => 'application/vnd.mif',
     2873            'xls' => 'application/vnd.ms-excel',
     2874            'ppt' => 'application/vnd.ms-powerpoint',
     2875            'wbxml' => 'application/vnd.wap.wbxml',
     2876            'wmlc' => 'application/vnd.wap.wmlc',
     2877            'dcr' => 'application/x-director',
     2878            'dir' => 'application/x-director',
     2879            'dxr' => 'application/x-director',
     2880            'dvi' => 'application/x-dvi',
     2881            'gtar' => 'application/x-gtar',
     2882            'php3' => 'application/x-httpd-php',
     2883            'php4' => 'application/x-httpd-php',
     2884            'php' => 'application/x-httpd-php',
     2885            'phtml' => 'application/x-httpd-php',
     2886            'phps' => 'application/x-httpd-php-source',
     2887            'js' => 'application/x-javascript',
     2888            'swf' => 'application/x-shockwave-flash',
     2889            'sit' => 'application/x-stuffit',
     2890            'tar' => 'application/x-tar',
     2891            'tgz' => 'application/x-tar',
     2892            'xht' => 'application/xhtml+xml',
     2893            'xhtml' => 'application/xhtml+xml',
     2894            'zip' => 'application/zip',
     2895            'mid' => 'audio/midi',
     2896            'midi' => 'audio/midi',
     2897            'mp2' => 'audio/mpeg',
     2898            'mp3' => 'audio/mpeg',
     2899            'mpga' => 'audio/mpeg',
     2900            'aif' => 'audio/x-aiff',
     2901            'aifc' => 'audio/x-aiff',
     2902            'aiff' => 'audio/x-aiff',
     2903            'ram' => 'audio/x-pn-realaudio',
     2904            'rm' => 'audio/x-pn-realaudio',
     2905            'rpm' => 'audio/x-pn-realaudio-plugin',
     2906            'ra' => 'audio/x-realaudio',
     2907            'wav' => 'audio/x-wav',
     2908            'bmp' => 'image/bmp',
     2909            'gif' => 'image/gif',
     2910            'jpeg' => 'image/jpeg',
     2911            'jpe' => 'image/jpeg',
     2912            'jpg' => 'image/jpeg',
     2913            'png' => 'image/png',
     2914            'tiff' => 'image/tiff',
     2915            'tif' => 'image/tiff',
     2916            'eml' => 'message/rfc822',
     2917            'css' => 'text/css',
     2918            'html' => 'text/html',
     2919            'htm' => 'text/html',
     2920            'shtml' => 'text/html',
     2921            'log' => 'text/plain',
     2922            'text' => 'text/plain',
     2923            'txt' => 'text/plain',
     2924            'rtx' => 'text/richtext',
     2925            'rtf' => 'text/rtf',
     2926            'xml' => 'text/xml',
     2927            'xsl' => 'text/xml',
     2928            'mpeg' => 'video/mpeg',
     2929            'mpe' => 'video/mpeg',
     2930            'mpg' => 'video/mpeg',
     2931            'mov' => 'video/quicktime',
     2932            'qt' => 'video/quicktime',
     2933            'rv' => 'video/vnd.rn-realvideo',
     2934            'avi' => 'video/x-msvideo',
     2935            'movie' => 'video/x-sgi-movie'
     2936        );
     2937        return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]: 'application/octet-stream');
     2938    }
     2939
     2940    /**
     2941     * Map a file name to a MIME type.
     2942     * Defaults to 'application/octet-stream', i.e.. arbitrary binary data.
     2943     * @param string $filename A file name or full path, does not need to exist as a file
     2944     * @return string
     2945     * @static
     2946     */
     2947    public static function filenameToType($filename)
     2948    {
     2949        //In case the path is a URL, strip any query string before getting extension
     2950        $qpos = strpos($filename, '?');
     2951        if ($qpos !== false) {
     2952            $filename = substr($filename, 0, $qpos);
     2953        }
     2954        $pathinfo = self::mb_pathinfo($filename);
     2955        return self::_mime_types($pathinfo['extension']);
     2956    }
     2957
     2958    /**
     2959     * Multi-byte-safe pathinfo replacement.
     2960     * Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe.
     2961     * Works similarly to the one in PHP >= 5.2.0
     2962     * @link http://www.php.net/manual/en/function.pathinfo.php#107461
     2963     * @param string $path A filename or path, does not need to exist as a file
     2964     * @param integer|string $options Either a PATHINFO_* constant,
     2965     *      or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2
     2966     * @return string|array
     2967     * @static
     2968     */
     2969    public static function mb_pathinfo($path, $options = null)
     2970    {
     2971        $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
     2972        $m = array();
     2973        preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $m);
     2974        if (array_key_exists(1, $m)) {
     2975            $ret['dirname'] = $m[1];
     2976        }
     2977        if (array_key_exists(2, $m)) {
     2978            $ret['basename'] = $m[2];
     2979        }
     2980        if (array_key_exists(5, $m)) {
     2981            $ret['extension'] = $m[5];
     2982        }
     2983        if (array_key_exists(3, $m)) {
     2984            $ret['filename'] = $m[3];
     2985        }
     2986        switch ($options) {
     2987            case PATHINFO_DIRNAME:
     2988            case 'dirname':
     2989                return $ret['dirname'];
     2990                break;
     2991            case PATHINFO_BASENAME:
     2992            case 'basename':
     2993                return $ret['basename'];
     2994                break;
     2995            case PATHINFO_EXTENSION:
     2996            case 'extension':
     2997                return $ret['extension'];
     2998                break;
     2999            case PATHINFO_FILENAME:
     3000            case 'filename':
     3001                return $ret['filename'];
     3002                break;
     3003            default:
     3004                return $ret;
     3005        }
     3006    }
     3007
     3008    /**
     3009     * Set or reset instance properties.
     3010     *
     3011     * Usage Example:
     3012     * $page->set('X-Priority', '3');
     3013     *
     3014     * @access public
     3015     * @param string $name
     3016     * @param mixed $value
     3017     * NOTE: will not work with arrays, there are no arrays to set/reset
     3018     * @throws phpmailerException
     3019     * @return bool
     3020     * @todo Should this not be using __set() magic function?
     3021     */
     3022    public function set($name, $value = '')
     3023    {
     3024        try {
     3025            if (isset($this->$name)) {
     3026                $this->$name = $value;
     3027            } else {
     3028                throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL);
     3029            }
     3030        } catch (Exception $e) {
     3031            $this->setError($e->getMessage());
     3032            if ($e->getCode() == self::STOP_CRITICAL) {
     3033                return false;
     3034            }
     3035        }
     3036        return true;
     3037    }
     3038
     3039    /**
     3040     * Strip newlines to prevent header injection.
     3041     * @access public
     3042     * @param string $str
     3043     * @return string
     3044     */
     3045    public function secureHeader($str)
     3046    {
     3047        return trim(str_replace(array("\r", "\n"), '', $str));
     3048    }
     3049
     3050    /**
     3051     * Normalize line breaks in a string.
     3052     * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format.
     3053     * Defaults to CRLF (for message bodies) and preserves consecutive breaks.
     3054     * @param string $text
     3055     * @param string $breaktype What kind of line break to use, defaults to CRLF
     3056     * @return string
     3057     * @access public
     3058     * @static
     3059     */
     3060    public static function normalizeBreaks($text, $breaktype = "\r\n")
     3061    {
     3062        return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text);
     3063    }
     3064
     3065
     3066    /**
     3067     * Set the private key file and password for S/MIME signing.
     3068     * @access public
     3069     * @param string $cert_filename
     3070     * @param string $key_filename
     3071     * @param string $key_pass Password for private key
     3072     */
     3073    public function sign($cert_filename, $key_filename, $key_pass)
     3074    {
     3075        $this->sign_cert_file = $cert_filename;
     3076        $this->sign_key_file = $key_filename;
     3077        $this->sign_key_pass = $key_pass;
     3078    }
     3079
     3080    /**
     3081     * Quoted-Printable-encode a DKIM header.
     3082     * @access public
     3083     * @param string $txt
     3084     * @return string
     3085     */
     3086    public function DKIM_QP($txt)
     3087    {
     3088        $line = '';
     3089        for ($i = 0; $i < strlen($txt); $i++) {
     3090            $ord = ord($txt[$i]);
     3091            if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
     3092                $line .= $txt[$i];
     3093            } else {
     3094                $line .= "=" . sprintf("%02X", $ord);
     3095            }
     3096        }
     3097        return $line;
     3098    }
     3099
     3100    /**
     3101     * Generate a DKIM signature.
     3102     * @access public
     3103     * @param string $s Header
     3104     * @throws phpmailerException
     3105     * @return string
     3106     */
     3107    public function DKIM_Sign($s)
     3108    {
     3109        if (!defined('PKCS7_TEXT')) {
     3110            if ($this->exceptions) {
     3111                throw new phpmailerException($this->lang("signing") . ' OpenSSL extension missing.');
     3112            }
     3113            return '';
     3114        }
     3115        $privKeyStr = file_get_contents($this->DKIM_private);
     3116        if ($this->DKIM_passphrase != '') {
     3117            $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
     3118        } else {
     3119            $privKey = $privKeyStr;
     3120        }
     3121        if (openssl_sign($s, $signature, $privKey)) {
     3122            return base64_encode($signature);
     3123        }
     3124        return '';
     3125    }
     3126
     3127    /**
     3128     * Generate a DKIM canonicalization header.
     3129     * @access public
     3130     * @param string $s Header
     3131     * @return string
     3132     */
     3133    public function DKIM_HeaderC($s)
     3134    {
     3135        $s = preg_replace("/\r\n\s+/", " ", $s);
     3136        $lines = explode("\r\n", $s);
     3137        foreach ($lines as $key => $line) {
     3138            list($heading, $value) = explode(":", $line, 2);
     3139            $heading = strtolower($heading);
     3140            $value = preg_replace("/\s+/", " ", $value); // Compress useless spaces
     3141            $lines[$key] = $heading . ":" . trim($value); // Don't forget to remove WSP around the value
     3142        }
     3143        $s = implode("\r\n", $lines);
     3144        return $s;
     3145    }
     3146
     3147    /**
     3148     * Generate a DKIM canonicalization body.
     3149     * @access public
     3150     * @param string $body Message Body
     3151     * @return string
     3152     */
     3153    public function DKIM_BodyC($body)
     3154    {
     3155        if ($body == '') {
     3156            return "\r\n";
     3157        }
     3158        // stabilize line endings
     3159        $body = str_replace("\r\n", "\n", $body);
     3160        $body = str_replace("\n", "\r\n", $body);
     3161        // END stabilize line endings
     3162        while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
     3163            $body = substr($body, 0, strlen($body) - 2);
     3164        }
     3165        return $body;
     3166    }
     3167
     3168    /**
     3169     * Create the DKIM header and body in a new message header.
     3170     * @access public
     3171     * @param string $headers_line Header lines
     3172     * @param string $subject Subject
     3173     * @param string $body Body
     3174     * @return string
     3175     */
     3176    public function DKIM_Add($headers_line, $subject, $body)
     3177    {
     3178        $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
     3179        $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
     3180        $DKIMquery = 'dns/txt'; // Query method
     3181        $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
     3182        $subject_header = "Subject: $subject";
     3183        $headers = explode($this->LE, $headers_line);
     3184        $from_header = '';
     3185        $to_header = '';
     3186        $current = '';
     3187        foreach ($headers as $header) {
     3188            if (strpos($header, 'From:') === 0) {
     3189                $from_header = $header;
     3190                $current = 'from_header';
     3191            } elseif (strpos($header, 'To:') === 0) {
     3192                $to_header = $header;
     3193                $current = 'to_header';
     3194            } else {
     3195                if ($current && strpos($header, ' =?') === 0) {
     3196                    $current .= $header;
     3197                } else {
     3198                    $current = '';
     3199                }
     3200            }
     3201        }
     3202        $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
     3203        $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
     3204        $subject = str_replace(
     3205            '|',
     3206            '=7C',
     3207            $this->DKIM_QP($subject_header)
     3208        ); // Copied header fields (dkim-quoted-printable)
     3209        $body = $this->DKIM_BodyC($body);
     3210        $DKIMlen = strlen($body); // Length of body
     3211        $DKIMb64 = base64_encode(pack("H*", sha1($body))); // Base64 of packed binary SHA-1 hash of body
     3212        $ident = ($this->DKIM_identity == '') ? '' : " i=" . $this->DKIM_identity . ";";
     3213        $dkimhdrs = "DKIM-Signature: v=1; a=" .
     3214            $DKIMsignatureType . "; q=" .
     3215            $DKIMquery . "; l=" .
     3216            $DKIMlen . "; s=" .
     3217            $this->DKIM_selector .
     3218            ";\r\n" .
     3219            "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n" .
     3220            "\th=From:To:Subject;\r\n" .
     3221            "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n" .
     3222            "\tz=$from\r\n" .
     3223            "\t|$to\r\n" .
     3224            "\t|$subject;\r\n" .
     3225            "\tbh=" . $DKIMb64 . ";\r\n" .
     3226            "\tb=";
     3227        $toSign = $this->DKIM_HeaderC(
     3228            $from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs
     3229        );
     3230        $signed = $this->DKIM_Sign($toSign);
     3231        return $dkimhdrs . $signed . "\r\n";
     3232    }
     3233
     3234    /**
     3235     * Perform a callback.
     3236     * @param bool $isSent
     3237     * @param string $to
     3238     * @param string $cc
     3239     * @param string $bcc
     3240     * @param string $subject
     3241     * @param string $body
     3242     * @param string $from
     3243     */
     3244    protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from = null)
     3245    {
     3246        if (!empty($this->action_function) && is_callable($this->action_function)) {
     3247            $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
     3248            call_user_func_array($this->action_function, $params);
     3249        }
     3250    }
     3251}
     3252
     3253/**
     3254 * PHPMailer exception handler
     3255 * @package PHPMailer
     3256 */
     3257class phpmailerException extends Exception
     3258{
     3259    /**
     3260     * Prettify error message output
     3261     * @return string
     3262     */
     3263    public function errorMessage()
     3264    {
     3265        $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
     3266        return $errorMsg;
     3267    }
     3268}
  • new file src/wp-includes/PHPMailer/class.pop3.php

    diff --git src/wp-includes/PHPMailer/class.pop3.php src/wp-includes/PHPMailer/class.pop3.php
    new file mode 100644
    index 0000000..042b93a
    - +  
     1<?php
     2/**
     3 * PHPMailer POP-Before-SMTP Authentication Class.
     4 * PHP Version 5.0.0
     5 * Version 5.2.7
     6 * @package PHPMailer
     7 * @link https://github.com/PHPMailer/PHPMailer/
     8 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     9 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
     10 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
     11 * @author Brent R. Matzelle (original founder)
     12 * @copyright 2013 Marcus Bointon
     13 * @copyright 2010 - 2012 Jim Jagielski
     14 * @copyright 2004 - 2009 Andy Prevost
     15 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
     16 * @note This program is distributed in the hope that it will be useful - WITHOUT
     17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     18 * FITNESS FOR A PARTICULAR PURPOSE.
     19 */
     20
     21/**
     22 * PHPMailer POP-Before-SMTP Authentication Class.
     23 * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
     24 * Does not support APOP.
     25 * @package PHPMailer
     26 * @author Richard Davey (original author) <rich@corephp.co.uk>
     27 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     28 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
     29 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
     30 */
     31
     32class POP3
     33{
     34    /**
     35     * The POP3 PHPMailer Version number.
     36     * @type string
     37     * @access public
     38     */
     39    public $Version = '5.2.7';
     40
     41    /**
     42     * Default POP3 port number.
     43     * @type int
     44     * @access public
     45     */
     46    public $POP3_PORT = 110;
     47
     48    /**
     49     * Default timeout in seconds.
     50     * @type int
     51     * @access public
     52     */
     53    public $POP3_TIMEOUT = 30;
     54
     55    /**
     56     * POP3 Carriage Return + Line Feed.
     57     * @type string
     58     * @access public
     59     * @deprecated Use the constant instead
     60     */
     61    public $CRLF = "\r\n";
     62
     63    /**
     64     * Debug display level.
     65     * Options: 0 = no, 1+ = yes
     66     * @type int
     67     * @access public
     68     */
     69    public $do_debug = 0;
     70
     71    /**
     72     * POP3 mail server hostname.
     73     * @type string
     74     * @access public
     75     */
     76    public $host;
     77
     78    /**
     79     * POP3 port number.
     80     * @type int
     81     * @access public
     82     */
     83    public $port;
     84
     85    /**
     86     * POP3 Timeout Value in seconds.
     87     * @type int
     88     * @access public
     89     */
     90    public $tval;
     91
     92    /**
     93     * POP3 username
     94     * @type string
     95     * @access public
     96     */
     97    public $username;
     98
     99    /**
     100     * POP3 password.
     101     * @type string
     102     * @access public
     103     */
     104    public $password;
     105
     106    /**
     107     * Resource handle for the POP3 connection socket.
     108     * @type resource
     109     * @access private
     110     */
     111    private $pop_conn;
     112
     113    /**
     114     * Are we connected?
     115     * @type bool
     116     * @access private
     117     */
     118    private $connected;
     119
     120    /**
     121     * Error container.
     122     * @type array
     123     * @access private
     124     */
     125    private $error;
     126
     127    /**
     128     * Line break constant
     129     */
     130    const CRLF = "\r\n";
     131
     132    /**
     133     * Constructor.
     134     * @access public
     135     */
     136    public function __construct()
     137    {
     138        $this->pop_conn = 0;
     139        $this->connected = false;
     140        $this->error = null;
     141    }
     142
     143    /**
     144     * Simple static wrapper for all-in-one POP before SMTP
     145     * @param $host
     146     * @param bool $port
     147     * @param bool $tval
     148     * @param string $username
     149     * @param string $password
     150     * @param int $debug_level
     151     * @return bool
     152     */
     153    public static function popBeforeSmtp(
     154        $host,
     155        $port = false,
     156        $tval = false,
     157        $username = '',
     158        $password = '',
     159        $debug_level = 0
     160    ) {
     161        $pop = new POP3;
     162        return $pop->authorise($host, $port, $tval, $username, $password, $debug_level);
     163    }
     164
     165    /**
     166     * Authenticate with a POP3 server.
     167     * A connect, login, disconnect sequence
     168     * appropriate for POP-before SMTP authorisation.
     169     * @access public
     170     * @param string $host
     171     * @param bool|int $port
     172     * @param bool|int $tval
     173     * @param string $username
     174     * @param string $password
     175     * @param int $debug_level
     176     * @return bool
     177     */
     178    public function authorise($host, $port = false, $tval = false, $username = '', $password = '', $debug_level = 0)
     179    {
     180        $this->host = $host;
     181        // If no port value provided, use default
     182        if ($port === false) {
     183            $this->port = $this->POP3_PORT;
     184        } else {
     185            $this->port = $port;
     186        }
     187        // If no timeout value provided, use default
     188        if ($tval === false) {
     189            $this->tval = $this->POP3_TIMEOUT;
     190        } else {
     191            $this->tval = $tval;
     192        }
     193        $this->do_debug = $debug_level;
     194        $this->username = $username;
     195        $this->password = $password;
     196        //  Refresh the error log
     197        $this->error = null;
     198        //  connect
     199        $result = $this->connect($this->host, $this->port, $this->tval);
     200        if ($result) {
     201            $login_result = $this->login($this->username, $this->password);
     202            if ($login_result) {
     203                $this->disconnect();
     204                return true;
     205            }
     206        }
     207        // We need to disconnect regardless of whether the login succeeded
     208        $this->disconnect();
     209        return false;
     210    }
     211
     212    /**
     213     * Connect to a POP3 server.
     214     * @access public
     215     * @param string $host
     216     * @param bool|int $port
     217     * @param integer $tval
     218     * @return boolean
     219     */
     220    public function connect($host, $port = false, $tval = 30)
     221    {
     222        //  Are we already connected?
     223        if ($this->connected) {
     224            return true;
     225        }
     226
     227        //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
     228        //Rather than suppress it with @fsockopen, capture it cleanly instead
     229        set_error_handler(array($this, 'catchWarning'));
     230
     231        //  connect to the POP3 server
     232        $this->pop_conn = fsockopen(
     233            $host, //  POP3 Host
     234            $port, //  Port #
     235            $errno, //  Error Number
     236            $errstr, //  Error Message
     237            $tval
     238        ); //  Timeout (seconds)
     239        //  Restore the error handler
     240        restore_error_handler();
     241        //  Does the Error Log now contain anything?
     242        if ($this->error && $this->do_debug >= 1) {
     243            $this->displayErrors();
     244        }
     245        //  Did we connect?
     246        if ($this->pop_conn == false) {
     247            //  It would appear not...
     248            $this->error = array(
     249                'error' => "Failed to connect to server $host on port $port",
     250                'errno' => $errno,
     251                'errstr' => $errstr
     252            );
     253            if ($this->do_debug >= 1) {
     254                $this->displayErrors();
     255            }
     256            return false;
     257        }
     258
     259        //  Increase the stream time-out
     260        //  Check for PHP 4.3.0 or later
     261        if (version_compare(phpversion(), '5.0.0', 'ge')) {
     262            stream_set_timeout($this->pop_conn, $tval, 0);
     263        } else {
     264            //  Does not work on Windows
     265            if (substr(PHP_OS, 0, 3) !== 'WIN') {
     266                socket_set_timeout($this->pop_conn, $tval, 0);
     267            }
     268        }
     269
     270        //  Get the POP3 server response
     271        $pop3_response = $this->getResponse();
     272        //  Check for the +OK
     273        if ($this->checkResponse($pop3_response)) {
     274            //  The connection is established and the POP3 server is talking
     275            $this->connected = true;
     276            return true;
     277        }
     278        return false;
     279    }
     280
     281    /**
     282     * Log in to the POP3 server.
     283     * Does not support APOP (RFC 2828, 4949).
     284     * @access public
     285     * @param string $username
     286     * @param string $password
     287     * @return boolean
     288     */
     289    public function login($username = '', $password = '')
     290    {
     291        if ($this->connected == false) {
     292            $this->error = 'Not connected to POP3 server';
     293
     294            if ($this->do_debug >= 1) {
     295                $this->displayErrors();
     296            }
     297        }
     298        if (empty($username)) {
     299            $username = $this->username;
     300        }
     301        if (empty($password)) {
     302            $password = $this->password;
     303        }
     304
     305        // Send the Username
     306        $this->sendString("USER $username" . self::CRLF);
     307        $pop3_response = $this->getResponse();
     308        if ($this->checkResponse($pop3_response)) {
     309            // Send the Password
     310            $this->sendString("PASS $password" . self::CRLF);
     311            $pop3_response = $this->getResponse();
     312            if ($this->checkResponse($pop3_response)) {
     313                return true;
     314            }
     315        }
     316        return false;
     317    }
     318
     319    /**
     320     * Disconnect from the POP3 server.
     321     * @access public
     322     */
     323    public function disconnect()
     324    {
     325        $this->sendString('QUIT');
     326        //The QUIT command may cause the daemon to exit, which will kill our connection
     327        //So ignore errors here
     328        @fclose($this->pop_conn);
     329    }
     330
     331    /**
     332     * Get a response from the POP3 server.
     333     * $size is the maximum number of bytes to retrieve
     334     * @param integer $size
     335     * @return string
     336     * @access private
     337     */
     338    private function getResponse($size = 128)
     339    {
     340        $r = fgets($this->pop_conn, $size);
     341        if ($this->do_debug >= 1) {
     342            echo "Server -> Client: $r";
     343        }
     344        return $r;
     345    }
     346
     347    /**
     348     * Send raw data to the POP3 server.
     349     * @param string $string
     350     * @return integer
     351     * @access private
     352     */
     353    private function sendString($string)
     354    {
     355        if ($this->pop_conn) {
     356            if ($this->do_debug >= 2) { //Show client messages when debug >= 2
     357                echo "Client -> Server: $string";
     358            }
     359            return fwrite($this->pop_conn, $string, strlen($string));
     360        }
     361        return 0;
     362    }
     363
     364    /**
     365     * Checks the POP3 server response.
     366     * Looks for for +OK or -ERR.
     367     * @param string $string
     368     * @return boolean
     369     * @access private
     370     */
     371    private function checkResponse($string)
     372    {
     373        if (substr($string, 0, 3) !== '+OK') {
     374            $this->error = array(
     375                'error' => "Server reported an error: $string",
     376                'errno' => 0,
     377                'errstr' => ''
     378            );
     379            if ($this->do_debug >= 1) {
     380                $this->displayErrors();
     381            }
     382            return false;
     383        } else {
     384            return true;
     385        }
     386    }
     387
     388    /**
     389     * Display errors if debug is enabled.
     390     * @access private
     391     */
     392    private function displayErrors()
     393    {
     394        echo '<pre>';
     395        foreach ($this->error as $single_error) {
     396            print_r($single_error);
     397        }
     398        echo '</pre>';
     399    }
     400
     401    /**
     402     * POP3 connection error handler.
     403     * @param integer $errno
     404     * @param string $errstr
     405     * @param string $errfile
     406     * @param integer $errline
     407     * @access private
     408     */
     409    private function catchWarning($errno, $errstr, $errfile, $errline)
     410    {
     411        $this->error[] = array(
     412            'error' => "Connecting to the POP3 server raised a PHP warning: ",
     413            'errno' => $errno,
     414            'errstr' => $errstr,
     415            'errfile' => $errfile,
     416            'errline' => $errline
     417        );
     418    }
     419}
  • new file src/wp-includes/PHPMailer/class.smtp.php

    diff --git src/wp-includes/PHPMailer/class.smtp.php src/wp-includes/PHPMailer/class.smtp.php
    new file mode 100644
    index 0000000..e6b4522
    - +  
     1<?php
     2/**
     3 * PHPMailer RFC821 SMTP email transport class.
     4 * Version 5.2.7
     5 * PHP version 5.0.0
     6 * @category  PHP
     7 * @package   PHPMailer
     8 * @link      https://github.com/PHPMailer/PHPMailer/
     9 * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     10 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
     11 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
     12 * @copyright 2013 Marcus Bointon
     13 * @copyright 2004 - 2008 Andy Prevost
     14 * @copyright 2010 - 2012 Jim Jagielski
     15 * @license   http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
     16 */
     17
     18/**
     19 * PHPMailer RFC821 SMTP email transport class.
     20 *
     21 * Implements RFC 821 SMTP commands
     22 * and provides some utility methods for sending mail to an SMTP server.
     23 *
     24 * PHP Version 5.0.0
     25 *
     26 * @category PHP
     27 * @package  PHPMailer
     28 * @link     https://github.com/PHPMailer/PHPMailer/blob/master/class.smtp.php
     29 * @author   Chris Ryan <unknown@example.com>
     30 * @author   Marcus Bointon <phpmailer@synchromedia.co.uk>
     31 * @license  http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
     32 */
     33
     34class SMTP
     35{
     36    /**
     37     * The PHPMailer SMTP Version number.
     38     */
     39    const VERSION = '5.2.7';
     40
     41    /**
     42     * SMTP line break constant.
     43     */
     44    const CRLF = "\r\n";
     45
     46    /**
     47     * The SMTP port to use if one is not specified.
     48     */
     49    const DEFAULT_SMTP_PORT = 25;
     50
     51    /**
     52     * The PHPMailer SMTP Version number.
     53     * @type string
     54     * @deprecated This should be a constant
     55     * @see SMTP::VERSION
     56     */
     57    public $Version = '5.2.7';
     58
     59    /**
     60     * SMTP server port number.
     61     * @type int
     62     * @deprecated This is only ever ued as default value, so should be a constant
     63     * @see SMTP::DEFAULT_SMTP_PORT
     64     */
     65    public $SMTP_PORT = 25;
     66
     67    /**
     68     * SMTP reply line ending
     69     * @type string
     70     * @deprecated Use the class constant instead
     71     * @see SMTP::CRLF
     72     */
     73    public $CRLF = "\r\n";
     74
     75    /**
     76     * Debug output level.
     77     * Options: 0 for no output, 1 for commands, 2 for data and commands
     78     * @type int
     79     */
     80    public $do_debug = 0;
     81
     82    /**
     83     * The function/method to use for debugging output.
     84     * Options: 'echo', 'html' or 'error_log'
     85     * @type string
     86     */
     87    public $Debugoutput = 'echo';
     88
     89    /**
     90     * Whether to use VERP.
     91     * @type bool
     92     */
     93    public $do_verp = false;
     94
     95    /**
     96     * The SMTP timeout value for reads, in seconds.
     97     * @type int
     98     */
     99    public $Timeout = 15;
     100
     101    /**
     102     * The SMTP timelimit value for reads, in seconds.
     103     * @type int
     104     */
     105    public $Timelimit = 30;
     106
     107    /**
     108     * The socket for the server connection.
     109     * @type resource
     110     */
     111    protected $smtp_conn;
     112
     113    /**
     114     * Error message, if any, for the last call.
     115     * @type string
     116     */
     117    protected $error = '';
     118
     119    /**
     120     * The reply the server sent to us for HELO.
     121     * @type string
     122     */
     123    protected $helo_rply = '';
     124
     125    /**
     126     * The most recent reply received from the server.
     127     * @type string
     128     */
     129    protected $last_reply = '';
     130
     131    /**
     132     * Constructor.
     133     * @access public
     134     */
     135    public function __construct()
     136    {
     137        $this->smtp_conn = 0;
     138        $this->error = null;
     139        $this->helo_rply = null;
     140
     141        $this->do_debug = 0;
     142    }
     143
     144    /**
     145     * Output debugging info via a user-selected method.
     146     * @param string $str Debug string to output
     147     * @return void
     148     */
     149    protected function edebug($str)
     150    {
     151        switch ($this->Debugoutput) {
     152            case 'error_log':
     153                //Don't output, just log
     154                error_log($str);
     155                break;
     156            case 'html':
     157                //Cleans up output a bit for a better looking, HTML-safe output
     158                echo htmlentities(
     159                    preg_replace('/[\r\n]+/', '', $str),
     160                    ENT_QUOTES,
     161                    'UTF-8'
     162                )
     163                . "<br>\n";
     164                break;
     165            case 'echo':
     166            default:
     167                //Just echoes whatever was received
     168                echo $str;
     169        }
     170    }
     171
     172    /**
     173     * Connect to an SMTP server.
     174     * @param string $host    SMTP server IP or host name
     175     * @param int $port    The port number to connect to
     176     * @param int $timeout How long to wait for the connection to open
     177     * @param array $options An array of options for stream_context_create()
     178     * @access public
     179     * @return bool
     180     */
     181    public function connect($host, $port = null, $timeout = 30, $options = array())
     182    {
     183        // Clear errors to avoid confusion
     184        $this->error = null;
     185
     186        // Make sure we are __not__ connected
     187        if ($this->connected()) {
     188            // Already connected, generate error
     189            $this->error = array('error' => 'Already connected to a server');
     190            return false;
     191        }
     192
     193        if (empty($port)) {
     194            $port = self::DEFAULT_SMTP_PORT;
     195        }
     196
     197        // Connect to the SMTP server
     198        $errno = 0;
     199        $errstr = '';
     200        $socket_context = stream_context_create($options);
     201        //Suppress errors; connection failures are handled at a higher level
     202        $this->smtp_conn = @stream_socket_client(
     203            $host . ":" . $port,
     204            $errno,
     205            $errstr,
     206            $timeout,
     207            STREAM_CLIENT_CONNECT,
     208            $socket_context
     209        );
     210
     211        // Verify we connected properly
     212        if (empty($this->smtp_conn)) {
     213            $this->error = array(
     214                'error' => 'Failed to connect to server',
     215                'errno' => $errno,
     216                'errstr' => $errstr
     217            );
     218            if ($this->do_debug >= 1) {
     219                $this->edebug(
     220                    'SMTP -> ERROR: ' . $this->error['error']
     221                    . ": $errstr ($errno)"
     222                );
     223            }
     224            return false;
     225        }
     226
     227        // SMTP server can take longer to respond, give longer timeout for first read
     228        // Windows does not have support for this timeout function
     229        if (substr(PHP_OS, 0, 3) != 'WIN') {
     230            $max = ini_get('max_execution_time');
     231            if ($max != 0 && $timeout > $max) { // Don't bother if unlimited
     232                @set_time_limit($timeout);
     233            }
     234            stream_set_timeout($this->smtp_conn, $timeout, 0);
     235        }
     236
     237        // Get any announcement
     238        $announce = $this->get_lines();
     239
     240        if ($this->do_debug >= 2) {
     241            $this->edebug('SMTP -> FROM SERVER:' . $announce);
     242        }
     243
     244        return true;
     245    }
     246
     247    /**
     248     * Initiate a TLS (encrypted) session.
     249     * @access public
     250     * @return bool
     251     */
     252    public function startTLS()
     253    {
     254        if (!$this->sendCommand("STARTTLS", "STARTTLS", 220)) {
     255            return false;
     256        }
     257        // Begin encrypted connection
     258        if (!stream_socket_enable_crypto(
     259            $this->smtp_conn,
     260            true,
     261            STREAM_CRYPTO_METHOD_TLS_CLIENT
     262        )
     263        ) {
     264            return false;
     265        }
     266        return true;
     267    }
     268
     269    /**
     270     * Perform SMTP authentication.
     271     * Must be run after hello().
     272     * @see hello()
     273     * @param string $username    The user name
     274     * @param string $password    The password
     275     * @param string $authtype    The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5)
     276     * @param string $realm       The auth realm for NTLM
     277     * @param string $workstation The auth workstation for NTLM
     278     * @access public
     279     * @return bool True if successfully authenticated.
     280     */
     281    public function authenticate(
     282        $username,
     283        $password,
     284        $authtype = 'LOGIN',
     285        $realm = '',
     286        $workstation = ''
     287    ) {
     288        if (empty($authtype)) {
     289            $authtype = 'LOGIN';
     290        }
     291
     292        switch ($authtype) {
     293            case 'PLAIN':
     294                // Start authentication
     295                if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
     296                    return false;
     297                }
     298                // Send encoded username and password
     299                if (!$this->sendCommand(
     300                    'User & Password',
     301                    base64_encode("\0" . $username . "\0" . $password),
     302                    235
     303                )
     304                ) {
     305                    return false;
     306                }
     307                break;
     308            case 'LOGIN':
     309                // Start authentication
     310                if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
     311                    return false;
     312                }
     313                if (!$this->sendCommand("Username", base64_encode($username), 334)) {
     314                    return false;
     315                }
     316                if (!$this->sendCommand("Password", base64_encode($password), 235)) {
     317                    return false;
     318                }
     319                break;
     320            case 'NTLM':
     321                /*
     322                 * ntlm_sasl_client.php
     323                 * Bundled with Permission
     324                 *
     325                 * How to telnet in windows:
     326                 * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx
     327                 * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
     328                 */
     329                require_once 'extras/ntlm_sasl_client.php';
     330                $temp = new stdClass();
     331                $ntlm_client = new ntlm_sasl_client_class;
     332                //Check that functions are available
     333                if (!$ntlm_client->Initialize($temp)) {
     334                    $this->error = array('error' => $temp->error);
     335                    if ($this->do_debug >= 1) {
     336                        $this->edebug(
     337                            'You need to enable some modules in your php.ini file: '
     338                            . $this->error['error']
     339                        );
     340                    }
     341                    return false;
     342                }
     343                //msg1
     344                $msg1 = $ntlm_client->TypeMsg1($realm, $workstation); //msg1
     345
     346                if (!$this->sendCommand(
     347                    'AUTH NTLM',
     348                    'AUTH NTLM ' . base64_encode($msg1),
     349                    334
     350                )
     351                ) {
     352                    return false;
     353                }
     354
     355                //Though 0 based, there is a white space after the 3 digit number
     356                //msg2
     357                $challenge = substr($this->last_reply, 3);
     358                $challenge = base64_decode($challenge);
     359                $ntlm_res = $ntlm_client->NTLMResponse(
     360                    substr($challenge, 24, 8),
     361                    $password
     362                );
     363                //msg3
     364                $msg3 = $ntlm_client->TypeMsg3(
     365                    $ntlm_res,
     366                    $username,
     367                    $realm,
     368                    $workstation
     369                );
     370                // send encoded username
     371                return $this->sendCommand('Username', base64_encode($msg3), 235);
     372                break;
     373            case 'CRAM-MD5':
     374                // Start authentication
     375                if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
     376                    return false;
     377                }
     378                // Get the challenge
     379                $challenge = base64_decode(substr($this->last_reply, 4));
     380
     381                // Build the response
     382                $response = $username . ' ' . $this->hmac($challenge, $password);
     383
     384                // send encoded credentials
     385                return $this->sendCommand('Username', base64_encode($response), 235);
     386                break;
     387        }
     388        return true;
     389    }
     390
     391    /**
     392     * Calculate an MD5 HMAC hash.
     393     * Works like hash_hmac('md5', $data, $key)
     394     * in case that function is not available
     395     * @param string $data The data to hash
     396     * @param string $key  The key to hash with
     397     * @access protected
     398     * @return string
     399     */
     400    protected function hmac($data, $key)
     401    {
     402        if (function_exists('hash_hmac')) {
     403            return hash_hmac('md5', $data, $key);
     404        }
     405
     406        // The following borrowed from
     407        // http://php.net/manual/en/function.mhash.php#27225
     408
     409        // RFC 2104 HMAC implementation for php.
     410        // Creates an md5 HMAC.
     411        // Eliminates the need to install mhash to compute a HMAC
     412        // Hacked by Lance Rushing
     413
     414        $b = 64; // byte length for md5
     415        if (strlen($key) > $b) {
     416            $key = pack('H*', md5($key));
     417        }
     418        $key = str_pad($key, $b, chr(0x00));
     419        $ipad = str_pad('', $b, chr(0x36));
     420        $opad = str_pad('', $b, chr(0x5c));
     421        $k_ipad = $key ^ $ipad;
     422        $k_opad = $key ^ $opad;
     423
     424        return md5($k_opad . pack('H*', md5($k_ipad . $data)));
     425    }
     426
     427    /**
     428     * Check connection state.
     429     * @access public
     430     * @return bool True if connected.
     431     */
     432    public function connected()
     433    {
     434        if (!empty($this->smtp_conn)) {
     435            $sock_status = stream_get_meta_data($this->smtp_conn);
     436            if ($sock_status['eof']) {
     437                // the socket is valid but we are not connected
     438                if ($this->do_debug >= 1) {
     439                    $this->edebug(
     440                        'SMTP -> NOTICE: EOF caught while checking if connected'
     441                    );
     442                }
     443                $this->close();
     444                return false;
     445            }
     446            return true; // everything looks good
     447        }
     448        return false;
     449    }
     450
     451    /**
     452     * Close the socket and clean up the state of the class.
     453     * Don't use this function without first trying to use QUIT.
     454     * @see quit()
     455     * @access public
     456     * @return void
     457     */
     458    public function close()
     459    {
     460        $this->error = null; // so there is no confusion
     461        $this->helo_rply = null;
     462        if (!empty($this->smtp_conn)) {
     463            // close the connection and cleanup
     464            fclose($this->smtp_conn);
     465            $this->smtp_conn = 0;
     466        }
     467    }
     468
     469    /**
     470     * Send an SMTP DATA command.
     471     * Issues a data command and sends the msg_data to the server,
     472     * finializing the mail transaction. $msg_data is the message
     473     * that is to be send with the headers. Each header needs to be
     474     * on a single line followed by a <CRLF> with the message headers
     475     * and the message body being separated by and additional <CRLF>.
     476     * Implements rfc 821: DATA <CRLF>
     477     * @param string $msg_data Message data to send
     478     * @access public
     479     * @return bool
     480     */
     481    public function data($msg_data)
     482    {
     483        if (!$this->sendCommand('DATA', 'DATA', 354)) {
     484            return false;
     485        }
     486
     487        /* The server is ready to accept data!
     488         * according to rfc821 we should not send more than 1000
     489         * including the CRLF
     490         * characters on a single line so we will break the data up
     491         * into lines by \r and/or \n then if needed we will break
     492         * each of those into smaller lines to fit within the limit.
     493         * in addition we will be looking for lines that start with
     494         * a period '.' and append and additional period '.' to that
     495         * line. NOTE: this does not count towards limit.
     496         */
     497
     498        // Normalize the line breaks before exploding
     499        $msg_data = str_replace("\r\n", "\n", $msg_data);
     500        $msg_data = str_replace("\r", "\n", $msg_data);
     501        $lines = explode("\n", $msg_data);
     502
     503        /* We need to find a good way to determine if headers are
     504         * in the msg_data or if it is a straight msg body
     505         * currently I am assuming rfc822 definitions of msg headers
     506         * and if the first field of the first line (':' separated)
     507         * does not contain a space then it _should_ be a header
     508         * and we can process all lines before a blank "" line as
     509         * headers.
     510         */
     511
     512        $field = substr($lines[0], 0, strpos($lines[0], ':'));
     513        $in_headers = false;
     514        if (!empty($field) && !strstr($field, ' ')) {
     515            $in_headers = true;
     516        }
     517
     518        //RFC 2822 section 2.1.1 limit
     519        $max_line_length = 998;
     520
     521        foreach ($lines as $line) {
     522            $lines_out = null;
     523            if ($line == '' && $in_headers) {
     524                $in_headers = false;
     525            }
     526            // ok we need to break this line up into several smaller lines
     527            while (strlen($line) > $max_line_length) {
     528                $pos = strrpos(substr($line, 0, $max_line_length), ' ');
     529
     530                // Patch to fix DOS attack
     531                if (!$pos) {
     532                    $pos = $max_line_length - 1;
     533                    $lines_out[] = substr($line, 0, $pos);
     534                    $line = substr($line, $pos);
     535                } else {
     536                    $lines_out[] = substr($line, 0, $pos);
     537                    $line = substr($line, $pos + 1);
     538                }
     539
     540                /* If processing headers add a LWSP-char to the front of new line
     541                 * rfc822 on long msg headers
     542                 */
     543                if ($in_headers) {
     544                    $line = "\t" . $line;
     545                }
     546            }
     547            $lines_out[] = $line;
     548
     549            // send the lines to the server
     550            while (list(, $line_out) = @each($lines_out)) {
     551                if (strlen($line_out) > 0) {
     552                    if (substr($line_out, 0, 1) == '.') {
     553                        $line_out = '.' . $line_out;
     554                    }
     555                }
     556                $this->client_send($line_out . self::CRLF);
     557            }
     558        }
     559
     560        // Message data has been sent, complete the command
     561        return $this->sendCommand('DATA END', '.', 250);
     562    }
     563
     564    /**
     565     * Send an SMTP HELO or EHLO command.
     566     * Used to identify the sending server to the receiving server.
     567     * This makes sure that client and server are in a known state.
     568     * Implements from RFC 821: HELO <SP> <domain> <CRLF>
     569     * and RFC 2821 EHLO.
     570     * @param string $host The host name or IP to connect to
     571     * @access public
     572     * @return bool
     573     */
     574    public function hello($host = '')
     575    {
     576        // Try extended hello first (RFC 2821)
     577        if (!$this->sendHello('EHLO', $host)) {
     578            if (!$this->sendHello('HELO', $host)) {
     579                return false;
     580            }
     581        }
     582
     583        return true;
     584    }
     585
     586    /**
     587     * Send an SMTP HELO or EHLO command.
     588     * Low-level implementation used by hello()
     589     * @see hello()
     590     * @param string $hello The HELO string
     591     * @param string $host  The hostname to say we are
     592     * @access protected
     593     * @return bool
     594     */
     595    protected function sendHello($hello, $host)
     596    {
     597        $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
     598        $this->helo_rply = $this->last_reply;
     599        return $noerror;
     600    }
     601
     602    /**
     603     * Send an SMTP MAIL command.
     604     * Starts a mail transaction from the email address specified in
     605     * $from. Returns true if successful or false otherwise. If True
     606     * the mail transaction is started and then one or more recipient
     607     * commands may be called followed by a data command.
     608     * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
     609     * @param string $from Source address of this message
     610     * @access public
     611     * @return bool
     612     */
     613    public function mail($from)
     614    {
     615        $useVerp = ($this->do_verp ? ' XVERP' : '');
     616        return $this->sendCommand(
     617            'MAIL FROM',
     618            'MAIL FROM:<' . $from . '>' . $useVerp,
     619            250
     620        );
     621    }
     622
     623    /**
     624     * Send an SMTP QUIT command.
     625     * Closes the socket if there is no error or the $close_on_error argument is true.
     626     * Implements from rfc 821: QUIT <CRLF>
     627     * @param bool $close_on_error Should the connection close if an error occurs?
     628     * @access public
     629     * @return bool
     630     */
     631    public function quit($close_on_error = true)
     632    {
     633        $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
     634        $e = $this->error; //Save any error
     635        if ($noerror or $close_on_error) {
     636            $this->close();
     637            $this->error = $e; //Restore any error from the quit command
     638        }
     639        return $noerror;
     640    }
     641
     642    /**
     643     * Send an SMTP RCPT command.
     644     * Sets the TO argument to $to.
     645     * Returns true if the recipient was accepted false if it was rejected.
     646     * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
     647     * @param string $to The address the message is being sent to
     648     * @access public
     649     * @return bool
     650     */
     651    public function recipient($to)
     652    {
     653        return $this->sendCommand(
     654            'RCPT TO ',
     655            'RCPT TO:<' . $to . '>',
     656            array(250, 251)
     657        );
     658    }
     659
     660    /**
     661     * Send an SMTP RSET command.
     662     * Abort any transaction that is currently in progress.
     663     * Implements rfc 821: RSET <CRLF>
     664     * @access public
     665     * @return bool True on success.
     666     */
     667    public function reset()
     668    {
     669        return $this->sendCommand('RSET', 'RSET', 250);
     670    }
     671
     672    /**
     673     * Send a command to an SMTP server and check its return code.
     674     * @param string $command       The command name - not sent to the server
     675     * @param string $commandstring The actual command to send
     676     * @param int|array $expect     One or more expected integer success codes
     677     * @access protected
     678     * @return bool True on success.
     679     */
     680    protected function sendCommand($command, $commandstring, $expect)
     681    {
     682        if (!$this->connected()) {
     683            $this->error = array(
     684                "error" => "Called $command without being connected"
     685            );
     686            return false;
     687        }
     688        $this->client_send($commandstring . self::CRLF);
     689
     690        $reply = $this->get_lines();
     691        $code = substr($reply, 0, 3);
     692
     693        if ($this->do_debug >= 2) {
     694            $this->edebug('SMTP -> FROM SERVER:' . $reply);
     695        }
     696
     697        if (!in_array($code, (array)$expect)) {
     698            $this->last_reply = null;
     699            $this->error = array(
     700                "error" => "$command command failed",
     701                "smtp_code" => $code,
     702                "detail" => substr($reply, 4)
     703            );
     704            if ($this->do_debug >= 1) {
     705                $this->edebug(
     706                    'SMTP -> ERROR: ' . $this->error['error'] . ': ' . $reply
     707                );
     708            }
     709            return false;
     710        }
     711
     712        $this->last_reply = $reply;
     713        $this->error = null;
     714        return true;
     715    }
     716
     717    /**
     718     * Send an SMTP SAML command.
     719     * Starts a mail transaction from the email address specified in $from.
     720     * Returns true if successful or false otherwise. If True
     721     * the mail transaction is started and then one or more recipient
     722     * commands may be called followed by a data command. This command
     723     * will send the message to the users terminal if they are logged
     724     * in and send them an email.
     725     * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
     726     * @param string $from The address the message is from
     727     * @access public
     728     * @return bool
     729     */
     730    public function sendAndMail($from)
     731    {
     732        return $this->sendCommand("SAML", "SAML FROM:$from", 250);
     733    }
     734
     735    /**
     736     * Send an SMTP VRFY command.
     737     * @param string $name The name to verify
     738     * @access public
     739     * @return bool
     740     */
     741    public function verify($name)
     742    {
     743        return $this->sendCommand("VRFY", "VRFY $name", array(250, 251));
     744    }
     745
     746    /**
     747     * Send an SMTP NOOP command.
     748     * Used to keep keep-alives alive, doesn't actually do anything
     749     * @access public
     750     * @return bool
     751     */
     752    public function noop()
     753    {
     754        return $this->sendCommand("NOOP", "NOOP", 250);
     755    }
     756
     757    /**
     758     * Send an SMTP TURN command.
     759     * This is an optional command for SMTP that this class does not support.
     760     * This method is here to make the RFC821 Definition
     761     * complete for this class and __may__ be implemented in future
     762     * Implements from rfc 821: TURN <CRLF>
     763     * @access public
     764     * @return bool
     765     */
     766    public function turn()
     767    {
     768        $this->error = array(
     769            'error' => 'The SMTP TURN command is not implemented'
     770        );
     771        if ($this->do_debug >= 1) {
     772            $this->edebug('SMTP -> NOTICE: ' . $this->error['error']);
     773        }
     774        return false;
     775    }
     776
     777    /**
     778     * Send raw data to the server.
     779     * @param string $data The data to send
     780     * @access public
     781     * @return int|bool The number of bytes sent to the server or FALSE on error
     782     */
     783    public function client_send($data)
     784    {
     785        if ($this->do_debug >= 1) {
     786            $this->edebug("CLIENT -> SMTP: $data");
     787        }
     788        return fwrite($this->smtp_conn, $data);
     789    }
     790
     791    /**
     792     * Get the latest error.
     793     * @access public
     794     * @return array
     795     */
     796    public function getError()
     797    {
     798        return $this->error;
     799    }
     800
     801    /**
     802     * Get the last reply from the server.
     803     * @access public
     804     * @return string
     805     */
     806    public function getLastReply()
     807    {
     808        return $this->last_reply;
     809    }
     810
     811    /**
     812     * Read the SMTP server's response.
     813     * Either before eof or socket timeout occurs on the operation.
     814     * With SMTP we can tell if we have more lines to read if the
     815     * 4th character is '-' symbol. If it is a space then we don't
     816     * need to read anything else.
     817     * @access protected
     818     * @return string
     819     */
     820    protected function get_lines()
     821    {
     822        $data = '';
     823        $endtime = 0;
     824        // If the connection is bad, give up now
     825        if (!is_resource($this->smtp_conn)) {
     826            return $data;
     827        }
     828        stream_set_timeout($this->smtp_conn, $this->Timeout);
     829        if ($this->Timelimit > 0) {
     830            $endtime = time() + $this->Timelimit;
     831        }
     832        while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
     833            $str = @fgets($this->smtp_conn, 515);
     834            if ($this->do_debug >= 4) {
     835                $this->edebug("SMTP -> get_lines(): \$data was \"$data\"");
     836                $this->edebug("SMTP -> get_lines(): \$str is \"$str\"");
     837            }
     838            $data .= $str;
     839            if ($this->do_debug >= 4) {
     840                $this->edebug("SMTP -> get_lines(): \$data is \"$data\"");
     841            }
     842            // if 4th character is a space, we are done reading, break the loop
     843            if (substr($str, 3, 1) == ' ') {
     844                break;
     845            }
     846            // Timed-out? Log and break
     847            $info = stream_get_meta_data($this->smtp_conn);
     848            if ($info['timed_out']) {
     849                if ($this->do_debug >= 4) {
     850                    $this->edebug(
     851                        'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)'
     852                    );
     853                }
     854                break;
     855            }
     856            // Now check if reads took too long
     857            if ($endtime) {
     858                if (time() > $endtime) {
     859                    if ($this->do_debug >= 4) {
     860                        $this->edebug(
     861                            'SMTP -> get_lines(): timelimit reached ('
     862                            . $this->Timelimit . ' sec)'
     863                        );
     864                    }
     865                    break;
     866                }
     867            }
     868        }
     869        return $data;
     870    }
     871
     872    /**
     873     * Enable or disable VERP address generation.
     874     * @param bool $enabled
     875     */
     876    public function setVerp($enabled = false)
     877    {
     878        $this->do_verp = $enabled;
     879    }
     880
     881    /**
     882     * Get VERP address generation mode.
     883     * @return bool
     884     */
     885    public function getVerp()
     886    {
     887        return $this->do_verp;
     888    }
     889
     890    /**
     891     * Set debug output method.
     892     * @param string $method The function/method to use for debugging output.
     893     */
     894    public function setDebugOutput($method = 'echo')
     895    {
     896        $this->Debugoutput = $method;
     897    }
     898
     899    /**
     900     * Get debug output method.
     901     * @return string
     902     */
     903    public function getDebugOutput()
     904    {
     905        return $this->Debugoutput;
     906    }
     907
     908    /**
     909     * Set debug output level.
     910     * @param int $level
     911     */
     912    public function setDebugLevel($level = 0)
     913    {
     914        $this->do_debug = $level;
     915    }
     916
     917    /**
     918     * Get debug output level.
     919     * @return int
     920     */
     921    public function getDebugLevel()
     922    {
     923        return $this->do_debug;
     924    }
     925
     926    /**
     927     * Set SMTP timeout.
     928     * @param int $timeout
     929     */
     930    public function setTimeout($timeout = 0)
     931    {
     932        $this->Timeout = $timeout;
     933    }
     934
     935    /**
     936     * Get SMTP timeout.
     937     * @return int
     938     */
     939    public function getTimeout()
     940    {
     941        return $this->Timeout;
     942    }
     943}
  • new file src/wp-includes/PHPMailer/composer.json

    diff --git src/wp-includes/PHPMailer/composer.json src/wp-includes/PHPMailer/composer.json
    new file mode 100644
    index 0000000..086f381
    - +  
     1{
     2    "name": "phpmailer/phpmailer",
     3    "type": "library",
     4    "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
     5    "authors": [
     6        {
     7            "name": "Jim Jagielski",
     8            "email": "jimjag@gmail.com"
     9        },
     10        {
     11            "name": "Marcus Bointon",
     12            "email": "phpmailer@synchromedia.co.uk"
     13        },
     14        {
     15            "name": "Andy Prevost",
     16            "email": "codeworxtech@users.sourceforge.net"
     17        },
     18        {
     19            "name": "Brent R. Matzelle"
     20        }
     21    ],
     22    "require": {
     23        "php": ">=5.0.0"
     24    },
     25    "require-dev": {
     26        "phpdocumentor/phpdocumentor": "*",
     27        "phpunit/phpunit": "*"
     28    },
     29    "autoload": {
     30        "classmap": ["class.phpmailer.php", "class.pop3.php", "class.smtp.php"]
     31    },
     32    "license": "LGPL-2.1"
     33}
     34 No newline at end of file
  • new file src/wp-includes/PHPMailer/extras/EasyPeasyICS.php

    diff --git src/wp-includes/PHPMailer/extras/EasyPeasyICS.php src/wp-includes/PHPMailer/extras/EasyPeasyICS.php
    new file mode 100644
    index 0000000..f076895
    - +  
     1<?php
     2
     3/* ------------------------------------------------------------------------ */
     4/* EasyPeasyICS
     5/* ------------------------------------------------------------------------ */
     6/* Manuel Reinhard, manu@sprain.ch
     7/* Twitter: @sprain
     8/* Web: www.sprain.ch
     9/*
     10/* Built with inspiration by
     11/" http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355
     12/* ------------------------------------------------------------------------ */
     13/* History:
     14/* 2010/12/17 - Manuel Reinhard - when it all started
     15/* ------------------------------------------------------------------------ */ 
     16
     17class EasyPeasyICS {
     18
     19        protected $calendarName;
     20        protected $events = array();
     21       
     22
     23        /**
     24         * Constructor
     25         * @param string $calendarName
     26         */     
     27        public function __construct($calendarName=""){
     28                $this->calendarName = $calendarName;
     29        }//function
     30
     31
     32        /**
     33         * Add event to calendar
     34         * @param string $calendarName
     35         */     
     36        public function addEvent($start, $end, $summary="", $description="", $url=""){
     37                $this->events[] = array(
     38                        "start" => $start,
     39                        "end"   => $end,
     40                        "summary" => $summary,
     41                        "description" => $description,
     42                        "url" => $url
     43                );
     44        }//function
     45       
     46       
     47        public function render($output = true){
     48               
     49                //start Variable
     50                $ics = "";
     51       
     52                //Add header
     53                $ics .= "BEGIN:VCALENDAR
     54METHOD:PUBLISH
     55VERSION:2.0
     56X-WR-CALNAME:".$this->calendarName."
     57PRODID:-//hacksw/handcal//NONSGML v1.0//EN";
     58               
     59                //Add events
     60                foreach($this->events as $event){
     61                        $ics .= "
     62BEGIN:VEVENT
     63UID:". md5(uniqid(mt_rand(), true)) ."@EasyPeasyICS.php
     64DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
     65DTSTART:".gmdate('Ymd', $event["start"])."T".gmdate('His', $event["start"])."Z
     66DTEND:".gmdate('Ymd', $event["end"])."T".gmdate('His', $event["end"])."Z
     67SUMMARY:".str_replace("\n", "\\n", $event['summary'])."
     68DESCRIPTION:".str_replace("\n", "\\n", $event['description'])."
     69URL;VALUE=URI:".$event['url']."
     70END:VEVENT";
     71                }//foreach
     72               
     73               
     74                //Footer
     75                $ics .= "
     76END:VCALENDAR";
     77
     78
     79                if ($output) {
     80                        //Output
     81                        header('Content-type: text/calendar; charset=utf-8');
     82                        header('Content-Disposition: inline; filename='.$this->calendarName.'.ics');
     83                        echo $ics;
     84                } else {
     85                        return $ics;
     86                }
     87
     88        }//function
     89
     90}//class
     91 No newline at end of file
  • new file src/wp-includes/PHPMailer/extras/class.html2text.php

    diff --git src/wp-includes/PHPMailer/extras/class.html2text.php src/wp-includes/PHPMailer/extras/class.html2text.php
    new file mode 100644
    index 0000000..4dcd5ac
    - +  
     1<?php
     2/*************************************************************************
     3 *                                                                       *
     4 * Converts HTML to formatted plain text                                 *
     5 *                                                                       *
     6 * Portions Copyright (c) 2005-2007 Jon Abernathy <jon@chuggnutt.com>    *
     7 * This version from https://github.com/mtibben/html2text                *
     8 *                                                                       *
     9 * This script is free software; you can redistribute it and/or modify   *
     10 * it under the terms of the GNU General Public License as published by  *
     11 * the Free Software Foundation; either version 2 of the License, or     *
     12 * (at your option) any later version.                                   *
     13 *                                                                       *
     14 * The GNU General Public License can be found at                        *
     15 * http://www.gnu.org/copyleft/gpl.html.                                 *
     16 *                                                                       *
     17 * This script is distributed in the hope that it will be useful,        *
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          *
     20 * GNU General Public License for more details.                          *
     21 *                                                                       *
     22 *************************************************************************/
     23
     24
     25class html2text
     26{
     27
     28    /**
     29     *  Contains the HTML content to convert.
     30     *
     31     *  @var string $html
     32     *  @access public
     33     */
     34    public $html;
     35
     36    /**
     37     *  Contains the converted, formatted text.
     38     *
     39     *  @var string $text
     40     *  @access public
     41     */
     42    public $text;
     43
     44    /**
     45     *  Maximum width of the formatted text, in columns.
     46     *
     47     *  Set this value to 0 (or less) to ignore word wrapping
     48     *  and not constrain text to a fixed-width column.
     49     *
     50     *  @var integer $width
     51     *  @access public
     52     */
     53    public $width = 70;
     54
     55    /**
     56     *  List of preg* regular expression patterns to search for,
     57     *  used in conjunction with $replace.
     58     *
     59     *  @var array $search
     60     *  @access public
     61     *  @see $replace
     62     */
     63    public $search = array(
     64        "/\r/",                                  // Non-legal carriage return
     65        "/[\n\t]+/",                             // Newlines and tabs
     66        '/<head[^>]*>.*?<\/head>/i',             // <head>
     67        '/<script[^>]*>.*?<\/script>/i',         // <script>s -- which strip_tags supposedly has problems with
     68        '/<style[^>]*>.*?<\/style>/i',           // <style>s -- which strip_tags supposedly has problems with
     69        '/<p[^>]*>/i',                           // <P>
     70        '/<br[^>]*>/i',                          // <br>
     71        '/<i[^>]*>(.*?)<\/i>/i',                 // <i>
     72        '/<em[^>]*>(.*?)<\/em>/i',               // <em>
     73        '/(<ul[^>]*>|<\/ul>)/i',                 // <ul> and </ul>
     74        '/(<ol[^>]*>|<\/ol>)/i',                 // <ol> and </ol>
     75        '/<li[^>]*>(.*?)<\/li>/i',               // <li> and </li>
     76        '/<li[^>]*>/i',                          // <li>
     77        '/<hr[^>]*>/i',                          // <hr>
     78        '/<div[^>]*>/i',                         // <div>
     79        '/(<table[^>]*>|<\/table>)/i',           // <table> and </table>
     80        '/(<tr[^>]*>|<\/tr>)/i',                 // <tr> and </tr>
     81        '/<td[^>]*>(.*?)<\/td>/i',               // <td> and </td>
     82        '/<span class="_html2text_ignore">.+?<\/span>/i'  // <span class="_html2text_ignore">...</span>
     83    );
     84
     85    /**
     86     *  List of pattern replacements corresponding to patterns searched.
     87     *
     88     *  @var array $replace
     89     *  @access public
     90     *  @see $search
     91     */
     92    public $replace = array(
     93        '',                                     // Non-legal carriage return
     94        ' ',                                    // Newlines and tabs
     95        '',                                     // <head>
     96        '',                                     // <script>s -- which strip_tags supposedly has problems with
     97        '',                                     // <style>s -- which strip_tags supposedly has problems with
     98        "\n\n",                                 // <P>
     99        "\n",                                   // <br>
     100        '_\\1_',                                // <i>
     101        '_\\1_',                                // <em>
     102        "\n\n",                                 // <ul> and </ul>
     103        "\n\n",                                 // <ol> and </ol>
     104        "\t* \\1\n",                            // <li> and </li>
     105        "\n\t* ",                               // <li>
     106        "\n-------------------------\n",        // <hr>
     107        "<div>\n",                              // <div>
     108        "\n\n",                                 // <table> and </table>
     109        "\n",                                   // <tr> and </tr>
     110        "\t\t\\1\n",                            // <td> and </td>
     111        ""                                      // <span class="_html2text_ignore">...</span>
     112    );
     113
     114    /**
     115     *  List of preg* regular expression patterns to search for,
     116     *  used in conjunction with $ent_replace.
     117     *
     118     *  @var array $ent_search
     119     *  @access public
     120     *  @see $ent_replace
     121     */
     122    public $ent_search = array(
     123        '/&(nbsp|#160);/i',                      // Non-breaking space
     124        '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i',
     125        // Double quotes
     126        '/&(apos|rsquo|lsquo|#8216|#8217);/i',   // Single quotes
     127        '/&gt;/i',                               // Greater-than
     128        '/&lt;/i',                               // Less-than
     129        '/&(copy|#169);/i',                      // Copyright
     130        '/&(trade|#8482|#153);/i',               // Trademark
     131        '/&(reg|#174);/i',                       // Registered
     132        '/&(mdash|#151|#8212);/i',               // mdash
     133        '/&(ndash|minus|#8211|#8722);/i',        // ndash
     134        '/&(bull|#149|#8226);/i',                // Bullet
     135        '/&(pound|#163);/i',                     // Pound sign
     136        '/&(euro|#8364);/i',                     // Euro sign
     137        '/&(amp|#38);/i',                        // Ampersand: see _converter()
     138        '/[ ]{2,}/',                             // Runs of spaces, post-handling
     139    );
     140
     141    /**
     142     *  List of pattern replacements corresponding to patterns searched.
     143     *
     144     *  @var array $ent_replace
     145     *  @access public
     146     *  @see $ent_search
     147     */
     148    public $ent_replace = array(
     149        ' ',                                    // Non-breaking space
     150        '"',                                    // Double quotes
     151        "'",                                    // Single quotes
     152        '>',
     153        '<',
     154        '(c)',
     155        '(tm)',
     156        '(R)',
     157        '--',
     158        '-',
     159        '*',
     160        '£',
     161        'EUR',                                  // Euro sign. € ?
     162        '|+|amp|+|',                            // Ampersand: see _converter()
     163        ' ',                                    // Runs of spaces, post-handling
     164    );
     165
     166    /**
     167     *  List of preg* regular expression patterns to search for
     168     *  and replace using callback function.
     169     *
     170     *  @var array $callback_search
     171     *  @access public
     172     */
     173    public $callback_search = array(
     174        '/<(a) [^>]*href=("|\')([^"\']+)\2([^>]*)>(.*?)<\/a>/i', // <a href="">
     175        '/<(h)[123456]( [^>]*)?>(.*?)<\/h[123456]>/i',         // h1 - h6
     176        '/<(b)( [^>]*)?>(.*?)<\/b>/i',                         // <b>
     177        '/<(strong)( [^>]*)?>(.*?)<\/strong>/i',               // <strong>
     178        '/<(th)( [^>]*)?>(.*?)<\/th>/i',                       // <th> and </th>
     179    );
     180
     181    /**
     182     *  List of preg* regular expression patterns to search for in PRE body,
     183     *  used in conjunction with $pre_replace.
     184     *
     185     *  @var array $pre_search
     186     *  @access public
     187     *  @see $pre_replace
     188     */
     189    public $pre_search = array(
     190        "/\n/",
     191        "/\t/",
     192        '/ /',
     193        '/<pre[^>]*>/',
     194        '/<\/pre>/'
     195    );
     196
     197    /**
     198     *  List of pattern replacements corresponding to patterns searched for PRE body.
     199     *
     200     *  @var array $pre_replace
     201     *  @access public
     202     *  @see $pre_search
     203     */
     204    public $pre_replace = array(
     205        '<br>',
     206        '&nbsp;&nbsp;&nbsp;&nbsp;',
     207        '&nbsp;',
     208        '',
     209        ''
     210    );
     211
     212    /**
     213     *  Contains a list of HTML tags to allow in the resulting text.
     214     *
     215     *  @var string $allowed_tags
     216     *  @access public
     217     *  @see set_allowed_tags()
     218     */
     219    public $allowed_tags = '';
     220
     221    /**
     222     *  Contains the base URL that relative links should resolve to.
     223     *
     224     *  @var string $url
     225     *  @access public
     226     */
     227    public $url;
     228
     229    /**
     230     *  Indicates whether content in the $html variable has been converted yet.
     231     *
     232     *  @var boolean $_converted
     233     *  @access private
     234     *  @see $html, $text
     235     */
     236    private $_converted = false;
     237
     238    /**
     239     *  Contains URL addresses from links to be rendered in plain text.
     240     *
     241     *  @var array $_link_list
     242     *  @access private
     243     *  @see _build_link_list()
     244     */
     245    private $_link_list = array();
     246
     247
     248    /**
     249     *  Various configuration options (able to be set in the constructor)
     250     *
     251     *  @var array $_options
     252     *  @access private
     253     */
     254    private $_options = array(
     255
     256        // 'none'
     257        // 'inline' (show links inline)
     258        // 'nextline' (show links on the next line)
     259        // 'table' (if a table of link URLs should be listed after the text.
     260        'do_links' => 'inline',
     261
     262        //  Maximum width of the formatted text, in columns.
     263        //  Set this value to 0 (or less) to ignore word wrapping
     264        //  and not constrain text to a fixed-width column.
     265        'width' => 70,
     266    );
     267
     268
     269    /**
     270     *  Constructor.
     271     *
     272     *  If the HTML source string (or file) is supplied, the class
     273     *  will instantiate with that source propagated, all that has
     274     *  to be done it to call get_text().
     275     *
     276     *  @param string $source HTML content
     277     *  @param boolean $from_file Indicates $source is a file to pull content from
     278     *  @param array $options Set configuration options
     279     *  @access public
     280     *  @return void
     281     */
     282    public function __construct( $source = '', $from_file = false, $options = array() )
     283    {
     284        $this->_options = array_merge($this->_options, $options);
     285
     286        if ( !empty($source) ) {
     287            $this->set_html($source, $from_file);
     288        }
     289
     290        $this->set_base_url();
     291    }
     292
     293    /**
     294     *  Loads source HTML into memory, either from $source string or a file.
     295     *
     296     *  @param string $source HTML content
     297     *  @param boolean $from_file Indicates $source is a file to pull content from
     298     *  @access public
     299     *  @return void
     300     */
     301    public function set_html( $source, $from_file = false )
     302    {
     303        if ( $from_file && file_exists($source) ) {
     304            $this->html = file_get_contents($source);
     305        }
     306        else
     307            $this->html = $source;
     308
     309        $this->_converted = false;
     310    }
     311
     312    /**
     313     *  Returns the text, converted from HTML.
     314     *
     315     *  @access public
     316     *  @return string
     317     */
     318    public function get_text()
     319    {
     320        if ( !$this->_converted ) {
     321            $this->_convert();
     322        }
     323
     324        return $this->text;
     325    }
     326
     327    /**
     328     *  Prints the text, converted from HTML.
     329     *
     330     *  @access public
     331     *  @return void
     332     */
     333    public function print_text()
     334    {
     335        print $this->get_text();
     336    }
     337
     338    /**
     339     *  Alias to print_text(), operates identically.
     340     *
     341     *  @access public
     342     *  @return void
     343     *  @see print_text()
     344     */
     345    public function p()
     346    {
     347        print $this->get_text();
     348    }
     349
     350    /**
     351     *  Sets the allowed HTML tags to pass through to the resulting text.
     352     *
     353     *  Tags should be in the form "<p>", with no corresponding closing tag.
     354     *
     355     *  @access public
     356     *  @return void
     357     */
     358    public function set_allowed_tags( $allowed_tags = '' )
     359    {
     360        if ( !empty($allowed_tags) ) {
     361            $this->allowed_tags = $allowed_tags;
     362        }
     363    }
     364
     365    /**
     366     *  Sets a base URL to handle relative links.
     367     *
     368     *  @access public
     369     *  @return void
     370     */
     371    public function set_base_url( $url = '' )
     372    {
     373        if ( empty($url) ) {
     374            if ( !empty($_SERVER['HTTP_HOST']) ) {
     375                $this->url = 'http://' . $_SERVER['HTTP_HOST'];
     376            } else {
     377                $this->url = '';
     378            }
     379        } else {
     380            // Strip any trailing slashes for consistency (relative
     381            // URLs may already start with a slash like "/file.html")
     382            if ( substr($url, -1) == '/' ) {
     383                $url = substr($url, 0, -1);
     384            }
     385            $this->url = $url;
     386        }
     387    }
     388
     389    /**
     390     *  Workhorse function that does actual conversion (calls _converter() method).
     391     *
     392     *  @access private
     393     *  @return void
     394     */
     395    private function _convert()
     396    {
     397        // Variables used for building the link list
     398        $this->_link_list = array();
     399
     400        $text = trim(stripslashes($this->html));
     401
     402        // Convert HTML to TXT
     403        $this->_converter($text);
     404
     405        // Add link list
     406        if (!empty($this->_link_list)) {
     407            $text .= "\n\nLinks:\n------\n";
     408            foreach ($this->_link_list as $idx => $url) {
     409                $text .= '[' . ($idx+1) . '] ' . $url . "\n";
     410            }
     411        }
     412
     413        $this->text = $text;
     414
     415        $this->_converted = true;
     416    }
     417
     418    /**
     419     *  Workhorse function that does actual conversion.
     420     *
     421     *  First performs custom tag replacement specified by $search and
     422     *  $replace arrays. Then strips any remaining HTML tags, reduces whitespace
     423     *  and newlines to a readable format, and word wraps the text to
     424     *  $this->_options['width'] characters.
     425     *
     426     *  @param string Reference to HTML content string
     427     *
     428     *  @access private
     429     *  @return void
     430     */
     431    private function _converter(&$text)
     432    {
     433        // Convert <BLOCKQUOTE> (before PRE!)
     434        $this->_convert_blockquotes($text);
     435
     436        // Convert <PRE>
     437        $this->_convert_pre($text);
     438
     439        // Run our defined tags search-and-replace
     440        $text = preg_replace($this->search, $this->replace, $text);
     441
     442        // Run our defined tags search-and-replace with callback
     443        $text = preg_replace_callback($this->callback_search, array($this, '_preg_callback'), $text);
     444
     445        // Strip any other HTML tags
     446        $text = strip_tags($text, $this->allowed_tags);
     447
     448        // Run our defined entities/characters search-and-replace
     449        $text = preg_replace($this->ent_search, $this->ent_replace, $text);
     450
     451        // Replace known html entities
     452        $text = html_entity_decode($text, ENT_QUOTES);
     453
     454        // Remove unknown/unhandled entities (this cannot be done in search-and-replace block)
     455        $text = preg_replace('/&([a-zA-Z0-9]{2,6}|#[0-9]{2,4});/', '', $text);
     456
     457        // Convert "|+|amp|+|" into "&", need to be done after handling of unknown entities
     458        // This properly handles situation of "&amp;quot;" in input string
     459        $text = str_replace('|+|amp|+|', '&', $text);
     460
     461        // Bring down number of empty lines to 2 max
     462        $text = preg_replace("/\n\s+\n/", "\n\n", $text);
     463        $text = preg_replace("/[\n]{3,}/", "\n\n", $text);
     464
     465        // remove leading empty lines (can be produced by eg. P tag on the beginning)
     466        $text = ltrim($text, "\n");
     467
     468        // Wrap the text to a readable format
     469        // for PHP versions >= 4.0.2. Default width is 75
     470        // If width is 0 or less, don't wrap the text.
     471        if ( $this->_options['width'] > 0 ) {
     472            $text = wordwrap($text, $this->_options['width']);
     473        }
     474    }
     475
     476    /**
     477     *  Helper function called by preg_replace() on link replacement.
     478     *
     479     *  Maintains an internal list of links to be displayed at the end of the
     480     *  text, with numeric indices to the original point in the text they
     481     *  appeared. Also makes an effort at identifying and handling absolute
     482     *  and relative links.
     483     *
     484     *  @param string $link URL of the link
     485     *  @param string $display Part of the text to associate number with
     486     *  @access private
     487     *  @return string
     488     */
     489    private function _build_link_list( $link, $display, $link_override = null)
     490    {
     491        $link_method = ($link_override) ? $link_override : $this->_options['do_links'];
     492        if ($link_method == 'none')
     493            return $display;
     494
     495
     496        // Ignored link types
     497        if (preg_match('!^(javascript:|mailto:|#)!i', $link)) {
     498            return $display;
     499        }
     500        if (preg_match('!^([a-z][a-z0-9.+-]+:)!i', $link)) {
     501            $url = $link;
     502        }
     503        else {
     504            $url = $this->url;
     505            if (substr($link, 0, 1) != '/') {
     506                $url .= '/';
     507            }
     508            $url .= "$link";
     509        }
     510
     511        if ($link_method == 'table')
     512        {
     513            if (($index = array_search($url, $this->_link_list)) === false) {
     514                $index = count($this->_link_list);
     515                $this->_link_list[] = $url;
     516            }
     517
     518            return $display . ' [' . ($index+1) . ']';
     519        }
     520        elseif ($link_method == 'nextline')
     521        {
     522            return $display . "\n[" . $url . ']';
     523        }
     524        else // link_method defaults to inline
     525        {
     526            return $display . ' [' . $url . ']';
     527        }
     528    }
     529
     530    /**
     531     *  Helper function for PRE body conversion.
     532     *
     533     *  @param string HTML content
     534     *  @access private
     535     */
     536    private function _convert_pre(&$text)
     537    {
     538        // get the content of PRE element
     539        while (preg_match('/<pre[^>]*>(.*)<\/pre>/ismU', $text, $matches)) {
     540            $this->pre_content = $matches[1];
     541
     542            // Run our defined tags search-and-replace with callback
     543            $this->pre_content = preg_replace_callback($this->callback_search,
     544                array($this, '_preg_callback'), $this->pre_content);
     545
     546            // convert the content
     547            $this->pre_content = sprintf('<div><br>%s<br></div>',
     548                preg_replace($this->pre_search, $this->pre_replace, $this->pre_content));
     549            // replace the content (use callback because content can contain $0 variable)
     550            $text = preg_replace_callback('/<pre[^>]*>.*<\/pre>/ismU',
     551                array($this, '_preg_pre_callback'), $text, 1);
     552
     553            // free memory
     554            $this->pre_content = '';
     555        }
     556    }
     557
     558    /**
     559     *  Helper function for BLOCKQUOTE body conversion.
     560     *
     561     *  @param string HTML content
     562     *  @access private
     563     */
     564    private function _convert_blockquotes(&$text)
     565    {
     566        if (preg_match_all('/<\/*blockquote[^>]*>/i', $text, $matches, PREG_OFFSET_CAPTURE)) {
     567            $level = 0;
     568            $diff = 0;
     569            $start = 0;
     570            $taglen = 0;
     571            foreach ($matches[0] as $m) {
     572                if ($m[0][0] == '<' && $m[0][1] == '/') {
     573                    $level--;
     574                    if ($level < 0) {
     575                        $level = 0; // malformed HTML: go to next blockquote
     576                    }
     577                    else if ($level > 0) {
     578                        // skip inner blockquote
     579                    }
     580                    else {
     581                        $end  = $m[1];
     582                        $len  = $end - $taglen - $start;
     583                        // Get blockquote content
     584                        $body = substr($text, $start + $taglen - $diff, $len);
     585
     586                        // Set text width
     587                        $p_width = $this->_options['width'];
     588                        if ($this->_options['width'] > 0) $this->_options['width'] -= 2;
     589                        // Convert blockquote content
     590                        $body = trim($body);
     591                        $this->_converter($body);
     592                        // Add citation markers and create PRE block
     593                        $body = preg_replace('/((^|\n)>*)/', '\\1> ', trim($body));
     594                        $body = '<pre>' . htmlspecialchars($body) . '</pre>';
     595                        // Re-set text width
     596                        $this->_options['width'] = $p_width;
     597                        // Replace content
     598                        $text = substr($text, 0, $start - $diff)
     599                            . $body . substr($text, $end + strlen($m[0]) - $diff);
     600
     601                        $diff = $len + $taglen + strlen($m[0]) - strlen($body);
     602                        unset($body);
     603                    }
     604                }
     605                else {
     606                    if ($level == 0) {
     607                        $start = $m[1];
     608                        $taglen = strlen($m[0]);
     609                    }
     610                    $level ++;
     611                }
     612            }
     613        }
     614    }
     615
     616    /**
     617     *  Callback function for preg_replace_callback use.
     618     *
     619     *  @param  array PREG matches
     620     *  @return string
     621     */
     622    private function _preg_callback($matches)
     623    {
     624        switch (strtolower($matches[1])) {
     625            case 'b':
     626            case 'strong':
     627                return $this->_toupper($matches[3]);
     628            case 'th':
     629                return $this->_toupper("\t\t". $matches[3] ."\n");
     630            case 'h':
     631                return $this->_toupper("\n\n". $matches[3] ."\n\n");
     632            case 'a':
     633                // override the link method
     634                $link_override = null;
     635                if (preg_match("/_html2text_link_(\w+)/", $matches[4], $link_override_match))
     636                {
     637                    $link_override = $link_override_match[1];
     638                }
     639                // Remove spaces in URL (#1487805)
     640                $url = str_replace(' ', '', $matches[3]);
     641                return $this->_build_link_list($url, $matches[5], $link_override);
     642        }
     643    }
     644
     645    /**
     646     *  Callback function for preg_replace_callback use in PRE content handler.
     647     *
     648     *  @param  array PREG matches
     649     *  @return string
     650     */
     651    private function _preg_pre_callback($matches)
     652    {
     653        return $this->pre_content;
     654    }
     655
     656    /**
     657     * Strtoupper function with HTML tags and entities handling.
     658     *
     659     * @param string $str Text to convert
     660     * @return string Converted text
     661     */
     662    private function _toupper($str)
     663    {
     664        // string can containg HTML tags
     665        $chunks = preg_split('/(<[^>]*>)/', $str, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
     666
     667        // convert toupper only the text between HTML tags
     668        foreach ($chunks as $idx => $chunk) {
     669            if ($chunk[0] != '<') {
     670                $chunks[$idx] = $this->_strtoupper($chunk);
     671            }
     672        }
     673
     674        return implode($chunks);
     675    }
     676
     677    /**
     678     * Strtoupper multibyte wrapper function with HTML entities handling.
     679     *
     680     * @param string $str Text to convert
     681     * @return string Converted text
     682     */
     683    private function _strtoupper($str)
     684    {
     685        $str = html_entity_decode($str, ENT_COMPAT);
     686
     687        if (function_exists('mb_strtoupper'))
     688            $str = mb_strtoupper($str);
     689        else
     690            $str = strtoupper($str);
     691
     692        $str = htmlspecialchars($str, ENT_COMPAT);
     693
     694        return $str;
     695    }
     696}
     697 No newline at end of file
  • new file src/wp-includes/PHPMailer/extras/htmlfilter.php

    diff --git src/wp-includes/PHPMailer/extras/htmlfilter.php src/wp-includes/PHPMailer/extras/htmlfilter.php
    new file mode 100644
    index 0000000..a5ce589
    - +  
     1<?php
     2/**
     3 * htmlfilter.inc
     4 * ---------------
     5 * This set of functions allows you to filter html in order to remove
     6 * any malicious tags from it. Useful in cases when you need to filter
     7 * user input for any cross-site-scripting attempts.
     8 *
     9 * Copyright (C) 2002-2004 by Duke University
     10 *
     11 * This library is free software; you can redistribute it and/or
     12 * modify it under the terms of the GNU Lesser General Public
     13 * License as published by the Free Software Foundation; either
     14 * version 2.1 of the License, or (at your option) any later version.
     15 *
     16 * This library is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19 * Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public
     22 * License along with this library; if not, write to the Free Software
     23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 
     24 * 02110-1301  USA
     25 *
     26 * @Author      Konstantin Riabitsev <icon@linux.duke.edu>
     27 * @Version 1.1 ($Date: 2011-07-04 14:02:23 -0400 (Mon, 04 Jul 2011) $)
     28 */
     29
     30/**
     31 * @Author  Jim Jagielski <jim@jaguNET.com / jimjag@gmail.com>
     32 */
     33
     34/**
     35 * This function returns the final tag out of the tag name, an array
     36 * of attributes, and the type of the tag. This function is called by
     37 * tln_sanitize internally.
     38 *
     39 * @param  $tagname      the name of the tag.
     40 * @param  $attary       the array of attributes and their values
     41 * @param  $tagtype      The type of the tag (see in comments).
     42 * @return                       a string with the final tag representation.
     43 */
     44function tln_tagprint($tagname, $attary, $tagtype){
     45        $me = 'tln_tagprint';
     46        if ($tagtype == 2){
     47                $fulltag = '</' . $tagname . '>';
     48        } else {
     49                $fulltag = '<' . $tagname;
     50                if (is_array($attary) && sizeof($attary)){
     51                        $atts = Array();
     52                        while (list($attname, $attvalue) = each($attary)){
     53                                array_push($atts, "$attname=$attvalue");
     54                        }
     55                        $fulltag .= ' ' . join(' ', $atts);
     56                }
     57                if ($tagtype == 3){
     58                        $fulltag .= ' /';
     59                }
     60                $fulltag .= '>';
     61        }
     62        return $fulltag;
     63}
     64
     65/**
     66 * A small helper function to use with array_walk. Modifies a by-ref
     67 * value and makes it lowercase.
     68 *
     69 * @param  $val a value passed by-ref.
     70 * @return              void since it modifies a by-ref value.
     71 */
     72function 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 */
     86function tln_skipspace($body, $offset){
     87        $me = 'tln_skipspace';
     88        preg_match('/^(\s*)/s', substr($body, $offset), $matches);
     89        if (sizeof($matches[1])){
     90                $count = strlen($matches[1]);
     91                $offset += $count;
     92        }
     93        return $offset;
     94}
     95
     96/**
     97 * This function looks for the next character within a string.  It's
     98 * really just a glorified "strpos", except it catches the failures
     99 * nicely.
     100 *
     101 * @param  $body   The string to look for needle in.
     102 * @param  $offset Start looking from this position.
     103 * @param  $needle The character/string to look for.
     104 * @return                 location of the next occurrence of the needle, or
     105 *                                 strlen($body) if needle wasn't found.
     106 */
     107function 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 */
     129function 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 */
     159function tln_getnxtag($body, $offset){
     160        $me = 'tln_getnxtag';
     161        if ($offset > strlen($body)){
     162                return false;
     163        }
     164        $lt = tln_findnxstr($body, $offset, '<');
     165        if ($lt == strlen($body)){
     166                return false;
     167        }
     168        /**
     169         * We are here:
     170         * blah blah <tag attribute="value">
     171         * \---------^
     172         */
     173        $pos = tln_skipspace($body, $lt + 1);
     174        if ($pos >= strlen($body)){
     175                return Array(false, false, false, $lt, strlen($body));
     176        }
     177        /**
     178         * There are 3 kinds of tags:
     179         * 1. Opening tag, e.g.:
     180         *        <a href="blah">
     181         * 2. Closing tag, e.g.:
     182         *        </a>
     183         * 3. XHTML-style content-less tag, e.g.:
     184         *        <img src="blah"/>
     185         */
     186        $tagtype = false;
     187        switch (substr($body, $pos, 1)){
     188        case '/':
     189                $tagtype = 2;
     190                $pos++;
     191                break;
     192        case '!':
     193                /**
     194                 * A comment or an SGML declaration.
     195                 */
     196                if (substr($body, $pos+1, 2) == '--'){
     197                        $gt = strpos($body, '-->', $pos);
     198                        if ($gt === false){
     199                                $gt = strlen($body);
     200                        } else {
     201                                $gt += 2;
     202                        }
     203                        return Array(false, false, false, $lt, $gt);
     204                } else {
     205                        $gt = tln_findnxstr($body, $pos, '>');
     206                        return Array(false, false, false, $lt, $gt);
     207                }
     208                break;
     209        default:
     210                /**
     211                 * Assume tagtype 1 for now. If it's type 3, we'll switch values
     212                 * later.
     213                 */
     214                $tagtype = 1;
     215                break;
     216        }
     217       
     218        $tag_start = $pos;
     219        $tagname = '';
     220        /**
     221         * Look for next [\W-_], which will indicate the end of the tag name.
     222         */
     223        $regary = tln_findnxreg($body, $pos, '[^\w\-_]');
     224        if ($regary == false){
     225                return Array(false, false, false, $lt, strlen($body));
     226        }
     227        list($pos, $tagname, $match) = $regary;
     228        $tagname = strtolower($tagname);
     229       
     230        /**
     231         * $match can be either of these:
     232         * '>'  indicating the end of the tag entirely.
     233         * '\s' indicating the end of the tag name.
     234         * '/'  indicating that this is type-3 xhtml tag.
     235         *
     236         * Whatever else we find there indicates an invalid tag.
     237         */
     238        switch ($match){
     239        case '/':
     240                /**
     241                 * This is an xhtml-style tag with a closing / at the
     242                 * end, like so: <img src="blah"/>. Check if it's followed
     243                 * by the closing bracket. If not, then this tag is invalid
     244                 */
     245                if (substr($body, $pos, 2) == '/>'){
     246                        $pos++;
     247                        $tagtype = 3;
     248                } else {
     249                        $gt = tln_findnxstr($body, $pos, '>');
     250                        $retary = Array(false, false, false, $lt, $gt);
     251                        return $retary;
     252                }
     253        case '>':
     254                return Array($tagname, false, $tagtype, $lt, $pos);
     255                break;
     256        default:
     257                /**
     258                 * Check if it's whitespace
     259                 */
     260                if (preg_match('/\s/', $match)){
     261                } else {
     262                        /**
     263                         * This is an invalid tag! Look for the next closing ">".
     264                         */
     265                        $gt = tln_findnxstr($body, $lt, '>');
     266                        return Array(false, false, false, $lt, $gt);
     267                }
     268        }
     269       
     270        /**
     271         * At this point we're here:
     272         * <tagname      attribute='blah'>
     273         * \-------^
     274         *
     275         * At this point we loop in order to find all attributes.
     276         */
     277        $attname = '';
     278        $atttype = false;
     279        $attary = Array();
     280       
     281        while ($pos <= strlen($body)){
     282                $pos = tln_skipspace($body, $pos);
     283                if ($pos == strlen($body)){
     284                        /**
     285                         * Non-closed tag.
     286                         */
     287                        return Array(false, false, false, $lt, $pos);
     288                }
     289                /**
     290                 * See if we arrived at a ">" or "/>", which means that we reached
     291                 * the end of the tag.
     292                 */
     293                $matches = Array();
     294                preg_match('%^(\s*)(>|/>)%s', substr($body, $pos), $matches);
     295                if (isset($matches[0]) && $matches[0]){
     296                        /**
     297                         * Yep. So we did.
     298                         */
     299                        $pos += strlen($matches[1]);
     300                        if ($matches[2] == '/>'){
     301                                $tagtype = 3;
     302                                $pos++;
     303                        }
     304                        return Array($tagname, $attary, $tagtype, $lt, $pos);
     305                }
     306               
     307                /**
     308                 * There are several types of attributes, with optional
     309                 * [:space:] between members.
     310                 * Type 1:
     311                 *       attrname[:space:]=[:space:]'CDATA'
     312                 * Type 2:
     313                 *       attrname[:space:]=[:space:]"CDATA"
     314                 * Type 3:
     315                 *       attr[:space:]=[:space:]CDATA
     316                 * Type 4:
     317                 *       attrname
     318                 *
     319                 * We leave types 1 and 2 the same, type 3 we check for
     320                 * '"' and convert to "&quot" if needed, then wrap in
     321                 * double quotes. Type 4 we convert into:
     322                 * attrname="yes".
     323                 */
     324                $regary = tln_findnxreg($body, $pos, '[^\w\-_]');
     325                if ($regary == false){
     326                        /**
     327                         * Looks like body ended before the end of tag.
     328                         */
     329                        return Array(false, false, false, $lt, strlen($body));
     330                }
     331                list($pos, $attname, $match) = $regary;
     332                $attname = strtolower($attname);
     333                /**
     334                 * We arrived at the end of attribute name. Several things possible
     335                 * here:
     336                 * '>'  means the end of the tag and this is attribute type 4
     337                 * '/'  if followed by '>' means the same thing as above
     338                 * '\s' means a lot of things -- look what it's followed by.
     339                 *              anything else means the attribute is invalid.
     340                 */
     341                switch($match){
     342                case '/':
     343                        /**
     344                         * This is an xhtml-style tag with a closing / at the
     345                         * end, like so: <img src="blah"/>. Check if it's followed
     346                         * by the closing bracket. If not, then this tag is invalid
     347                         */
     348                        if (substr($body, $pos, 2) == '/>'){
     349                                $pos++;
     350                                $tagtype = 3;
     351                        } else {
     352                                $gt = tln_findnxstr($body, $pos, '>');
     353                                $retary = Array(false, false, false, $lt, $gt);
     354                                return $retary;
     355                        }
     356                case '>':
     357                        $attary{$attname} = '"yes"';
     358                        return Array($tagname, $attary, $tagtype, $lt, $pos);
     359                        break;
     360                default:
     361                        /**
     362                         * Skip whitespace and see what we arrive at.
     363                         */
     364                        $pos = tln_skipspace($body, $pos);
     365                        $char = substr($body, $pos, 1);
     366                        /**
     367                         * Two things are valid here:
     368                         * '=' means this is attribute type 1 2 or 3.
     369                         * \w means this was attribute type 4.
     370                         * anything else we ignore and re-loop. End of tag and
     371                         * invalid stuff will be caught by our checks at the beginning
     372                         * of the loop.
     373                         */
     374                        if ($char == '='){
     375                                $pos++;
     376                                $pos = tln_skipspace($body, $pos);
     377                                /**
     378                                 * Here are 3 possibilities:
     379                                 * "'"  attribute type 1
     380                                 * '"'  attribute type 2
     381                                 * everything else is the content of tag type 3
     382                                 */
     383                                $quot = substr($body, $pos, 1);
     384                                if ($quot == '\''){
     385                                        $regary = tln_findnxreg($body, $pos+1, '\'');
     386                                        if ($regary == false){
     387                                                return Array(false, false, false, $lt, strlen($body));
     388                                        }
     389                                        list($pos, $attval, $match) = $regary;
     390                                        $pos++;
     391                                        $attary{$attname} = '\'' . $attval . '\'';
     392                                } else if ($quot == '"'){
     393                                        $regary = tln_findnxreg($body, $pos+1, '\"');
     394                                        if ($regary == false){
     395                                                return Array(false, false, false, $lt, strlen($body));
     396                                        }
     397                                        list($pos, $attval, $match) = $regary;
     398                                        $pos++;
     399                                        $attary{$attname} = '"' . $attval . '"';
     400                                } else {
     401                                        /**
     402                                         * These are hateful. Look for \s, or >.
     403                                         */
     404                                        $regary = tln_findnxreg($body, $pos, '[\s>]');
     405                                        if ($regary == false){
     406                                                return Array(false, false, false, $lt, strlen($body));
     407                                        }
     408                                        list($pos, $attval, $match) = $regary;
     409                                        /**
     410                                         * If it's ">" it will be caught at the top.
     411                                         */
     412                                        $attval = preg_replace('/\"/s', '&quot;', $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 */
     444function 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 */
     472function 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, '/\&#0*(\d+);*/s');
     485                $m = $m || tln_deent($attvalue, '/\&#x0*((\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 */
     499function 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 */
     517function 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 */
     592function tln_sanitize($body,
     593                                  $tag_list,
     594                                  $rm_tags_with_content,
     595                                  $self_closing_tags,
     596                                  $force_tag_closing,
     597                                  $rm_attnames,
     598                                  $bad_attvals,
     599                                  $add_attr_to_tag
     600                                  )
     601{
     602        $me = 'tln_sanitize';
     603        /**
     604         * Normalize rm_tags and rm_tags_with_content.
     605         */
     606        $rm_tags = array_shift($tag_list);
     607        @array_walk($tag_list, 'tln_casenormalize');
     608        @array_walk($rm_tags_with_content, 'tln_casenormalize');
     609        @array_walk($self_closing_tags, 'tln_casenormalize');
     610        /**
     611         * See if tag_list is of tags to remove or tags to allow.
     612         * false  means remove these tags
     613         * true   means allow these tags
     614         */
     615        $curpos = 0;
     616        $open_tags = Array();
     617        $trusted = "<!-- begin tln_sanitized html -->\n";
     618        $skip_content = false;
     619        /**
     620         * Take care of netscape's stupid javascript entities like
     621         * &{alert('boo')};
     622         */
     623        $body = preg_replace('/&(\{.*?\};)/si', '&amp;\\1', $body);
     624        while (($curtag = tln_getnxtag($body, $curpos)) != FALSE){
     625                list($tagname, $attary, $tagtype, $lt, $gt) = $curtag;
     626                $free_content = substr($body, $curpos, $lt - $curpos);
     627                if ($skip_content == false){
     628                        $trusted .= $free_content;
     629                } else {
     630                }
     631                if ($tagname != FALSE){
     632                        if ($tagtype == 2){
     633                                if ($skip_content == $tagname){
     634                                        /**
     635                                         * Got to the end of tag we needed to remove.
     636                                         */
     637                                        $tagname = false;
     638                                        $skip_content = false;
     639                                } else {
     640                                        if ($skip_content == false){
     641                                                if (isset($open_tags{$tagname}) &&
     642                                                        $open_tags{$tagname} > 0){
     643                                                        $open_tags{$tagname}--;
     644                                                } else {
     645                                                        $tagname = false;
     646                                                }
     647                                        } else {
     648                                        }
     649                                }
     650                        } else {
     651                                /**
     652                                 * $rm_tags_with_content
     653                                 */
     654                                if ($skip_content == false){
     655                                        /**
     656                                         * See if this is a self-closing type and change
     657                                         * tagtype appropriately.
     658                                         */
     659                                        if ($tagtype == 1
     660                                                && in_array($tagname, $self_closing_tags)){
     661                                                $tagtype = 3;
     662                                        }
     663                                        /**
     664                                         * See if we should skip this tag and any content
     665                                         * inside it.
     666                                         */
     667                                        if ($tagtype == 1
     668                                                && in_array($tagname, $rm_tags_with_content)){
     669                                                $skip_content = $tagname;
     670                                        } else {
     671                                                if (($rm_tags == false
     672                                                         && in_array($tagname, $tag_list)) ||
     673                                                        ($rm_tags == true
     674                                                         && !in_array($tagname, $tag_list))){
     675                                                        $tagname = false;
     676                                                } else {
     677                                                        if ($tagtype == 1){
     678                                                                if (isset($open_tags{$tagname})){
     679                                                                        $open_tags{$tagname}++;
     680                                                                } else {
     681                                                                        $open_tags{$tagname} = 1;
     682                                                                }
     683                                                        }
     684                                                        /**
     685                                                         * This is where we run other checks.
     686                                                         */
     687                                                        if (is_array($attary) && sizeof($attary) > 0){
     688                                                                $attary = tln_fixatts($tagname,
     689                                                                                                  $attary,
     690                                                                                                  $rm_attnames,
     691                                                                                                  $bad_attvals,
     692                                                                                                  $add_attr_to_tag);
     693                                                        }
     694                                                }
     695                                        }
     696                                } else {
     697                                }
     698                        }
     699                        if ($tagname != false && $skip_content == false){
     700                                $trusted .= tln_tagprint($tagname, $attary, $tagtype);
     701                        }
     702                } else {
     703                }
     704                $curpos = $gt + 1;
     705        }
     706        $trusted .= substr($body, $curpos, strlen($body) - $curpos);
     707        if ($force_tag_closing == true){
     708                foreach ($open_tags as $tagname=>$opentimes){
     709                        while ($opentimes > 0){
     710                                $trusted .= '</' . $tagname . '>';
     711                                $opentimes--;
     712                        }
     713                }
     714                $trusted .= "\n";
     715        }
     716        $trusted .= "<!-- end tln_sanitized html -->\n";
     717        return $trusted;
     718}
     719
     720//
     721// Use the nifty htmlfilter library
     722//
     723
     724
     725function HTMLFilter($body, $trans_image_path, $block_external_images = false) {
     726
     727        $tag_list = Array(
     728                false,
     729                "object",
     730                "meta",
     731                "html",
     732                "head",
     733                "base",
     734                "link",
     735                "frame",
     736                "iframe",
     737                "plaintext",
     738                "marquee"
     739        );
     740
     741        $rm_tags_with_content = Array(
     742                "script",
     743                "applet",
     744                "embed",
     745                "title",
     746                "frameset",
     747                "xmp",
     748                "xml"
     749        );
     750
     751        $self_closing_tags =  Array(
     752                "img",
     753                "br",
     754                "hr",
     755                "input",
     756                "outbind"
     757        );
     758
     759        $force_tag_closing = true;
     760
     761        $rm_attnames = Array(
     762                "/.*/" =>
     763                        Array(
     764                                // "/target/i",
     765                                "/^on.*/i",
     766                                "/^dynsrc/i",
     767                                "/^data.*/i",
     768                                "/^lowsrc.*/i"
     769                        )
     770        );
     771
     772        $bad_attvals = Array(
     773                "/.*/" =>
     774                Array(
     775                        "/^src|background/i" =>
     776                        Array(
     777                                Array(
     778                                        "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si",
     779                                        "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si",
     780                                        "/^([\'\"])\s*about\s*:.*([\'\"])/si"
     781                                ),
     782                                Array(
     783                                        "\\1$trans_image_path\\2",
     784                                        "\\1$trans_image_path\\2",
     785                                        "\\1$trans_image_path\\2",
     786                                        "\\1$trans_image_path\\2"
     787                                )
     788                        ),
     789                        "/^href|action/i" =>
     790                        Array(
     791                                Array(
     792                                        "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si",
     793                                        "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si",
     794                                        "/^([\'\"])\s*about\s*:.*([\'\"])/si"
     795                                ),
     796                                Array(
     797                                        "\\1#\\1",
     798                                        "\\1#\\1",
     799                                        "\\1#\\1",
     800                                        "\\1#\\1"
     801                                )
     802                        ),
     803                        "/^style/i" =>
     804                        Array(
     805                                Array(
     806                                        "/expression/i",
     807                                        "/binding/i",
     808                                        "/behaviou*r/i",
     809                                        "/include-source/i",
     810                                        "/position\s*:\s*absolute/i",
     811                                        "/url\s*\(\s*([\'\"])\s*\S+script\s*:.*([\'\"])\s*\)/si",
     812                                        "/url\s*\(\s*([\'\"])\s*mocha\s*:.*([\'\"])\s*\)/si",
     813                                        "/url\s*\(\s*([\'\"])\s*about\s*:.*([\'\"])\s*\)/si",
     814                                        "/(.*)\s*:\s*url\s*\(\s*([\'\"]*)\s*\S+script\s*:.*([\'\"]*)\s*\)/si"
     815                                ),
     816                                Array(
     817                                        "idiocy",
     818                                        "idiocy",
     819                                        "idiocy",
     820                                        "idiocy",
     821                                        "",
     822                                        "url(\\1#\\1)",
     823                                        "url(\\1#\\1)",
     824                                        "url(\\1#\\1)",
     825                                        "url(\\1#\\1)",
     826                                        "url(\\1#\\1)",
     827                                        "\\1:url(\\2#\\3)"
     828                                )
     829                        )
     830                )
     831        );
     832
     833        if ($block_external_images){
     834                array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[0],
     835                                '/^([\'\"])\s*https*:.*([\'\"])/si');
     836                array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[1],
     837                                "\\1$trans_image_path\\1");
     838                array_push($bad_attvals{'/.*/'}{'/^style/i'}[0],
     839                                '/url\(([\'\"])\s*https*:.*([\'\"])\)/si');
     840                array_push($bad_attvals{'/.*/'}{'/^style/i'}[1],
     841                                "url(\\1$trans_image_path\\1)");
     842        }
     843
     844        $add_attr_to_tag = Array(
     845                "/^a$/i" =>
     846                        Array('target'=>'"_blank"')
     847        );
     848
     849        $trusted = tln_sanitize($body,
     850                        $tag_list,
     851                        $rm_tags_with_content,
     852                        $self_closing_tags,
     853                        $force_tag_closing,
     854                        $rm_attnames,
     855                        $bad_attvals,
     856                        $add_attr_to_tag
     857                        );
     858        return $trusted;
     859}
     860
     861?>
  • new file src/wp-includes/PHPMailer/extras/ntlm_sasl_client.php

    diff --git src/wp-includes/PHPMailer/extras/ntlm_sasl_client.php src/wp-includes/PHPMailer/extras/ntlm_sasl_client.php
    new file mode 100644
    index 0000000..b21ccce
    - +  
     1<?php
     2/*
     3 * ntlm_sasl_client.php
     4 *
     5 * @(#) $Id: ntlm_sasl_client.php,v 1.3 2004/11/17 08:00:37 mlemos Exp $
     6 *
     7 **
     8 ** Source: http://www.phpclasses.org/browse/file/7495.html
     9 ** License: BSD (http://www.phpclasses.org/package/1888-PHP-Single-API-for-standard-authentication-mechanisms.html)
     10 ** Bundled with Permission
     11 **
     12 */
     13
     14define("SASL_NTLM_STATE_START",             0);
     15define("SASL_NTLM_STATE_IDENTIFY_DOMAIN",   1);
     16define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
     17define("SASL_NTLM_STATE_DONE",              3);
     18
     19class ntlm_sasl_client_class
     20{
     21        var $credentials=array();
     22        var $state=SASL_NTLM_STATE_START;
     23
     24        Function Initialize(&$client)
     25        {
     26                if(!function_exists($function="mcrypt_encrypt")
     27                || !function_exists($function="mhash"))
     28                {
     29                        $extensions=array(
     30                                "mcrypt_encrypt"=>"mcrypt",
     31                                "mhash"=>"mhash"
     32                        );
     33                        $client->error="the extension ".$extensions[$function]." required by the NTLM SASL client class is not available in this PHP configuration";
     34                        return(0);
     35                }
     36                return(1);
     37        }
     38
     39        Function ASCIIToUnicode($ascii)
     40        {
     41                for($unicode="",$a=0;$a<strlen($ascii);$a++)
     42                        $unicode.=substr($ascii,$a,1).chr(0);
     43                return($unicode);
     44        }
     45
     46        Function TypeMsg1($domain,$workstation)
     47        {
     48                $domain_length=strlen($domain);
     49                $workstation_length=strlen($workstation);
     50                $workstation_offset=32;
     51                $domain_offset=$workstation_offset+$workstation_length;
     52                return(
     53                        "NTLMSSP\0".
     54                        "\x01\x00\x00\x00".
     55                        "\x07\x32\x00\x00".
     56                        pack("v",$domain_length).
     57                        pack("v",$domain_length).
     58                        pack("V",$domain_offset).
     59                        pack("v",$workstation_length).
     60                        pack("v",$workstation_length).
     61                        pack("V",$workstation_offset).
     62                        $workstation.
     63                        $domain
     64                );
     65        }
     66
     67        Function NTLMResponse($challenge,$password)
     68        {
     69                $unicode=$this->ASCIIToUnicode($password);
     70                $md4=mhash(MHASH_MD4,$unicode);
     71                $padded=$md4.str_repeat(chr(0),21-strlen($md4));
     72                $iv_size=mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB);
     73                $iv=mcrypt_create_iv($iv_size,MCRYPT_RAND);
     74                for($response="",$third=0;$third<21;$third+=7)
     75                {
     76                        for($packed="",$p=$third;$p<$third+7;$p++)
     77                                $packed.=str_pad(decbin(ord(substr($padded,$p,1))),8,"0",STR_PAD_LEFT);
     78                        for($key="",$p=0;$p<strlen($packed);$p+=7)
     79                        {
     80                                $s=substr($packed,$p,7);
     81                                $b=$s.((substr_count($s,"1") % 2) ? "0" : "1");
     82                                $key.=chr(bindec($b));
     83                        }
     84                        $ciphertext=mcrypt_encrypt(MCRYPT_DES,$key,$challenge,MCRYPT_MODE_ECB,$iv);
     85                        $response.=$ciphertext;
     86                }
     87                return $response;
     88        }
     89
     90        Function TypeMsg3($ntlm_response,$user,$domain,$workstation)
     91        {
     92                $domain_unicode=$this->ASCIIToUnicode($domain);
     93                $domain_length=strlen($domain_unicode);
     94                $domain_offset=64;
     95                $user_unicode=$this->ASCIIToUnicode($user);
     96                $user_length=strlen($user_unicode);
     97                $user_offset=$domain_offset+$domain_length;
     98                $workstation_unicode=$this->ASCIIToUnicode($workstation);
     99                $workstation_length=strlen($workstation_unicode);
     100                $workstation_offset=$user_offset+$user_length;
     101                $lm="";
     102                $lm_length=strlen($lm);
     103                $lm_offset=$workstation_offset+$workstation_length;
     104                $ntlm=$ntlm_response;
     105                $ntlm_length=strlen($ntlm);
     106                $ntlm_offset=$lm_offset+$lm_length;
     107                $session="";
     108                $session_length=strlen($session);
     109                $session_offset=$ntlm_offset+$ntlm_length;
     110                return(
     111                        "NTLMSSP\0".
     112                        "\x03\x00\x00\x00".
     113                        pack("v",$lm_length).
     114                        pack("v",$lm_length).
     115                        pack("V",$lm_offset).
     116                        pack("v",$ntlm_length).
     117                        pack("v",$ntlm_length).
     118                        pack("V",$ntlm_offset).
     119                        pack("v",$domain_length).
     120                        pack("v",$domain_length).
     121                        pack("V",$domain_offset).
     122                        pack("v",$user_length).
     123                        pack("v",$user_length).
     124                        pack("V",$user_offset).
     125                        pack("v",$workstation_length).
     126                        pack("v",$workstation_length).
     127                        pack("V",$workstation_offset).
     128                        pack("v",$session_length).
     129                        pack("v",$session_length).
     130                        pack("V",$session_offset).
     131                        "\x01\x02\x00\x00".
     132                        $domain_unicode.
     133                        $user_unicode.
     134                        $workstation_unicode.
     135                        $lm.
     136                        $ntlm
     137                );
     138        }
     139
     140        Function Start(&$client, &$message, &$interactions)
     141        {
     142                if($this->state!=SASL_NTLM_STATE_START)
     143                {
     144                        $client->error="NTLM authentication state is not at the start";
     145                        return(SASL_FAIL);
     146                }
     147                $this->credentials=array(
     148                        "user"=>"",
     149                        "password"=>"",
     150                        "realm"=>"",
     151                        "workstation"=>""
     152                );
     153                $defaults=array();
     154                $status=$client->GetCredentials($this->credentials,$defaults,$interactions);
     155                if($status==SASL_CONTINUE)
     156                        $this->state=SASL_NTLM_STATE_IDENTIFY_DOMAIN;
     157                Unset($message);
     158                return($status);
     159        }
     160
     161        Function Step(&$client, $response, &$message, &$interactions)
     162        {
     163                switch($this->state)
     164                {
     165                        case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
     166                                $message=$this->TypeMsg1($this->credentials["realm"],$this->credentials["workstation"]);
     167                                $this->state=SASL_NTLM_STATE_RESPOND_CHALLENGE;
     168                                break;
     169                        case SASL_NTLM_STATE_RESPOND_CHALLENGE:
     170                                $ntlm_response=$this->NTLMResponse(substr($response,24,8),$this->credentials["password"]);
     171                                $message=$this->TypeMsg3($ntlm_response,$this->credentials["user"],$this->credentials["realm"],$this->credentials["workstation"]);
     172                                $this->state=SASL_NTLM_STATE_DONE;
     173                                break;
     174                        case SASL_NTLM_STATE_DONE:
     175                                $client->error="NTLM authentication was finished without success";
     176                                return(SASL_FAIL);
     177                        default:
     178                                $client->error="invalid NTLM authentication step state";
     179                                return(SASL_FAIL);
     180                }
     181                return(SASL_CONTINUE);
     182        }
     183};
     184
     185?>
     186 No newline at end of file
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-ar.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ar.php src/wp-includes/PHPMailer/language/phpmailer.lang-ar.php
    new file mode 100644
    index 0000000..67364e9
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Arabic Version, UTF-8
     5* by : bahjat al mostafa <bahjat983@hotmail.com>
     6*/
     7
     8$PHPMAILER_LANG['authenticate']         = 'SMTP Error: لم نستطع تأكيد الهوية.';
     9$PHPMAILER_LANG['connect_host']         = 'SMTP Error: لم نستطع الاتصال بمخدم SMTP.';
     10$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Error: لم يتم قبول المعلومات .';
     11//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     12$PHPMAILER_LANG['encoding']             = 'ترميز غير معروف: ';
     13$PHPMAILER_LANG['execute']              = 'لم أستطع تنفيذ : ';
     14$PHPMAILER_LANG['file_access']          = 'لم نستطع الوصول للملف: ';
     15$PHPMAILER_LANG['file_open']            = 'File Error: لم نستطع فتح الملف: ';
     16$PHPMAILER_LANG['from_failed']          = 'البريد التالي لم نستطع ارسال البريد له : ';
     17$PHPMAILER_LANG['instantiate']          = 'لم نستطع توفير خدمة البريد.';
     18//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     19$PHPMAILER_LANG['mailer_not_supported'] = ' mailer غير مدعوم.';
     20//$PHPMAILER_LANG['provide_address']      = 'You must provide at least one recipient email address.';
     21$PHPMAILER_LANG['recipients_failed']    = 'SMTP Error: الأخطاء التالية ' .
     22                                          'فشل في الارسال لكل من : ';
     23$PHPMAILER_LANG['signing']              = 'خطأ في التوقيع: ';
     24//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     25//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     26//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-br.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-br.php src/wp-includes/PHPMailer/language/phpmailer.lang-br.php
    new file mode 100644
    index 0000000..87ecbdf
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Portuguese Version
     5* By Paulo Henrique Garcia - paulo@controllerweb.com.br
     6* Edited by Lucas Guimarães - lucas@lucasguimaraes.com
     7*/
     8
     9$PHPMAILER_LANG['authenticate']         = 'Erro de SMTP: Não foi possível autenticar.';
     10$PHPMAILER_LANG['connect_host']         = 'Erro de SMTP: Não foi possível conectar com o servidor SMTP.';
     11$PHPMAILER_LANG['data_not_accepted']    = 'Erro de SMTP: Dados rejeitados.';
     12$PHPMAILER_LANG['empty_message']        = 'Corpo da mensagem vazio';
     13$PHPMAILER_LANG['encoding']             = 'Codificação desconhecida: ';
     14$PHPMAILER_LANG['execute']              = 'Não foi possível executar: ';
     15$PHPMAILER_LANG['file_access']          = 'Não foi possível acessar o arquivo: ';
     16$PHPMAILER_LANG['file_open']            = 'Erro de Arquivo: Não foi possível abrir o arquivo: ';
     17$PHPMAILER_LANG['from_failed']          = 'Os endereços dos remententes a seguir falharam: ';
     18$PHPMAILER_LANG['instantiate']          = 'Não foi possível iniciar uma instância da função mail.';
     19$PHPMAILER_LANG['invalid_address']      = 'Não enviando, endereço de e-mail inválido: ';
     20$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';
     21$PHPMAILER_LANG['provide_address']      = 'Você deve fornecer pelo menos um endereço de destinatário de e-mail.';
     22$PHPMAILER_LANG['recipients_failed']    = 'Erro de SMTP: Os endereços de destinatário a seguir falharam: ';
     23$PHPMAILER_LANG['signing']              = 'Erro ao assinar: ';
     24$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() falhou.';
     25$PHPMAILER_LANG['smtp_error']           = 'Erro de servidor SMTP: ';
     26$PHPMAILER_LANG['variable_set']         = 'Não foi possível definir ou resetar a variável: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-ca.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ca.php src/wp-includes/PHPMailer/language/phpmailer.lang-ca.php
    new file mode 100644
    index 0000000..dc563e7
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Catalan Version
     5* By Ivan: web AT microstudi DOT com
     6*/
     7
     8$PHPMAILER_LANG['authenticate']         = 'Error SMTP: No s\'hapogut autenticar.';
     9$PHPMAILER_LANG['connect_host']         = 'Error SMTP: No es pot connectar al servidor SMTP.';
     10$PHPMAILER_LANG['data_not_accepted']    = 'Error SMTP: Dades no acceptades.';
     11//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     12$PHPMAILER_LANG['encoding']             = 'Codificació desconeguda: ';
     13$PHPMAILER_LANG['execute']              = 'No es pot executar: ';
     14$PHPMAILER_LANG['file_access']          = 'No es pot accedir a l\'arxiu: ';
     15$PHPMAILER_LANG['file_open']            = 'Error d\'Arxiu: No es pot obrir l\'arxiu: ';
     16$PHPMAILER_LANG['from_failed']          = 'La(s) següent(s) adreces de remitent han fallat: ';
     17$PHPMAILER_LANG['instantiate']          = 'No s\'ha pogut crear una instància de la funció Mail.';
     18//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     19$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no està suportat';
     20$PHPMAILER_LANG['provide_address']      = 'S\'ha de proveir almenys una adreça d\'email com a destinatari.';
     21$PHPMAILER_LANG['recipients_failed']    = 'Error SMTP: Els següents destinataris han fallat: ';
     22//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     23//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     24//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     25//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-ch.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ch.php src/wp-includes/PHPMailer/language/phpmailer.lang-ch.php
    new file mode 100644
    index 0000000..d28eba6
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Chinese Version
     5* By LiuXin: www.80x86.cn/blog/
     6*/
     7
     8$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:身份验证失败。';
     9$PHPMAILER_LANG['connect_host'] = 'SMTP 错误: 不能连接SMTP主机。';
     10$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误: 数据不可接受。';
     11//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     12$PHPMAILER_LANG['encoding'] = '未知编码:';
     13$PHPMAILER_LANG['execute'] = '不能执行: ';
     14$PHPMAILER_LANG['file_access'] = '不能访问文件:';
     15$PHPMAILER_LANG['file_open'] = '文件错误:不能打开文件:';
     16$PHPMAILER_LANG['from_failed'] = '下面的发送地址邮件发送失败了: ';
     17$PHPMAILER_LANG['instantiate'] = '不能实现mail方法。';
     18//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     19$PHPMAILER_LANG['mailer_not_supported'] = ' 您所选择的发送邮件的方法并不支持。';
     20$PHPMAILER_LANG['provide_address'] = '您必须提供至少一个 收信人的email地址。';
     21$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误: 下面的 收件人失败了: ';
     22//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     23//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     24//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     25//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-cz.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-cz.php src/wp-includes/PHPMailer/language/phpmailer.lang-cz.php
    new file mode 100644
    index 0000000..6da3bd8
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Czech Version
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'Chyba SMTP: Autentizace selhala.';
     8$PHPMAILER_LANG['connect_host']         = 'Chyba SMTP: Nelze navázat spojení se SMTP serverem.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'Chyba SMTP: Data nebyla přijata.';
     10$PHPMAILER_LANG['empty_message']        = 'Prázdné tělo zprávy';
     11$PHPMAILER_LANG['encoding']             = 'Neznámé kódování: ';
     12$PHPMAILER_LANG['execute']              = 'Nelze provést: ';
     13$PHPMAILER_LANG['file_access']          = 'Nelze získat přístup k souboru: ';
     14$PHPMAILER_LANG['file_open']            = 'Chyba souboru: Nelze otevřít soubor pro čtení: ';
     15$PHPMAILER_LANG['from_failed']          = 'Následující adresa odesílatele je nesprávná: ';
     16$PHPMAILER_LANG['instantiate']          = 'Nelze vytvořit instanci emailové funkce.';
     17$PHPMAILER_LANG['invalid_address']      = 'Neplatná adresa: ';
     18$PHPMAILER_LANG['mailer_not_supported'] = ' mailer není podporován.';
     19$PHPMAILER_LANG['provide_address']      = 'Musíte zadat alespoň jednu emailovou adresu příjemce.';
     20$PHPMAILER_LANG['recipients_failed']    = 'Chyba SMTP: Následující adresy příjemců nejsou správně: ';
     21$PHPMAILER_LANG['signing']              = 'Chyba přihlašování: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() selhal.';
     23$PHPMAILER_LANG['smtp_error']           = 'Chyba SMTP serveru: ';
     24$PHPMAILER_LANG['variable_set']         = 'Nelze nastavit nebo změnit proměnnou: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-de.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-de.php src/wp-includes/PHPMailer/language/phpmailer.lang-de.php
    new file mode 100644
    index 0000000..ba17a92
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* German Version
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'SMTP Fehler: Authentifizierung fehlgeschlagen.';
     8$PHPMAILER_LANG['connect_host']         = 'SMTP Fehler: Konnte keine Verbindung zum SMTP-Host herstellen.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Fehler: Daten werden nicht akzeptiert.';
     10$PHPMAILER_LANG['empty_message']        = 'E-Mail Inhalt ist leer.';
     11$PHPMAILER_LANG['encoding']             = 'Unbekanntes Encoding-Format: ';
     12$PHPMAILER_LANG['execute']              = 'Konnte folgenden Befehl nicht ausführen: ';
     13$PHPMAILER_LANG['file_access']          = 'Zugriff auf folgende Datei fehlgeschlagen: ';
     14$PHPMAILER_LANG['file_open']            = 'Datei Fehler: konnte folgende Datei nicht öffnen: ';
     15$PHPMAILER_LANG['from_failed']          = 'Die folgende Absenderadresse ist nicht korrekt: ';
     16$PHPMAILER_LANG['instantiate']          = 'Mail Funktion konnte nicht initialisiert werden.';
     17$PHPMAILER_LANG['invalid_address']        = 'E-Mail wird nicht gesendet, die Adresse ist ungültig.';
     18$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wird nicht unterstützt.';
     19$PHPMAILER_LANG['provide_address']      = 'Bitte geben Sie mindestens eine Empfänger E-Mailadresse an.';
     20$PHPMAILER_LANG['recipients_failed']    = 'SMTP Fehler: Die folgenden Empfänger sind nicht korrekt: ';
     21$PHPMAILER_LANG['signing']              = 'Fehler beim Signieren: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'Verbindung zu SMTP Server fehlgeschlagen.';
     23$PHPMAILER_LANG['smtp_error']           = 'Fehler vom SMTP Server: ';
     24$PHPMAILER_LANG['variable_set']         = 'Kann Variable nicht setzen oder zurücksetzen: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-dk.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-dk.php src/wp-includes/PHPMailer/language/phpmailer.lang-dk.php
    new file mode 100644
    index 0000000..fdb0b17
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Danish Version
     5* Author: Mikael Stokkebro <info@stokkebro.dk>
     6*/
     7
     8$PHPMAILER_LANG['authenticate']         = 'SMTP fejl: Kunne ikke logge på.';
     9$PHPMAILER_LANG['connect_host']         = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.';
     10$PHPMAILER_LANG['data_not_accepted']    = 'SMTP fejl: Data kunne ikke accepteres.';
     11//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     12$PHPMAILER_LANG['encoding']             = 'Ukendt encode-format: ';
     13$PHPMAILER_LANG['execute']              = 'Kunne ikke køre: ';
     14$PHPMAILER_LANG['file_access']          = 'Ingen adgang til fil: ';
     15$PHPMAILER_LANG['file_open']            = 'Fil fejl: Kunne ikke åbne filen: ';
     16$PHPMAILER_LANG['from_failed']          = 'Følgende afsenderadresse er forkert: ';
     17$PHPMAILER_LANG['instantiate']          = 'Kunne ikke initialisere email funktionen.';
     18//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     19$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.';
     20$PHPMAILER_LANG['provide_address']      = 'Du skal indtaste mindst en modtagers emailadresse.';
     21$PHPMAILER_LANG['recipients_failed']    = 'SMTP fejl: Følgende modtagere er forkerte: ';
     22//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     23//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     24//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     25//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-eo.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-eo.php src/wp-includes/PHPMailer/language/phpmailer.lang-eo.php
    new file mode 100644
    index 0000000..799b331
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Esperanto version
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'Eraro de servilo SMTP : aŭtentigo malsukcesis.';
     8$PHPMAILER_LANG['connect_host']         = 'Eraro de servilo SMTP : konektado al servilo malsukcesis.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'Eraro de servilo SMTP : neĝustaj datumoj.';
     10$PHPMAILER_LANG['empty_message']        = 'Teksto de mesaĝo mankas.';
     11$PHPMAILER_LANG['encoding']             = 'Nekonata kodoprezento: ';
     12$PHPMAILER_LANG['execute']              = 'Lanĉi rulumadon ne eblis: ';
     13$PHPMAILER_LANG['file_access']          = 'Aliro al dosiero ne sukcesis: ';
     14$PHPMAILER_LANG['file_open']            = 'Eraro de dosiero: malfermo neeblas: ';
     15$PHPMAILER_LANG['from_failed']          = 'Jena adreso de sendinto malsukcesis: ';
     16$PHPMAILER_LANG['instantiate']          = 'Genero de retmesaĝa funkcio neeblis.';
     17$PHPMAILER_LANG['invalid_address']      = 'Retadreso ne validas: ';
     18$PHPMAILER_LANG['mailer_not_supported'] = ' mesaĝilo ne subtenata.';
     19$PHPMAILER_LANG['provide_address']      = 'Vi devas tajpi almenaŭ unu recevontan retadreson.';
     20$PHPMAILER_LANG['recipients_failed']    = 'Eraro de servilo SMTP : la jenaj poŝtrecivuloj kaŭzis eraron: ';
     21$PHPMAILER_LANG['signing']              = 'Eraro de subskribo: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP konektado malsukcesis.';
     23$PHPMAILER_LANG['smtp_error']           = 'Eraro de servilo SMTP : ';
     24$PHPMAILER_LANG['variable_set']         = 'Variablo ne pravalorizeblas aŭ ne repravalorizeblas: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-es.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-es.php src/wp-includes/PHPMailer/language/phpmailer.lang-es.php
    new file mode 100644
    index 0000000..b81520f
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Spanish version
     5* Versión en español
     6* Edited by Matt Sturdy - matt.sturdy@gmail.com
     7*/
     8
     9$PHPMAILER_LANG['authenticate']         = 'Error SMTP: No se pudo autentificar.';
     10$PHPMAILER_LANG['connect_host']         = 'Error SMTP: No se pudo conectar al servidor SMTP.';
     11$PHPMAILER_LANG['data_not_accepted']    = 'Error SMTP: Datos no aceptados.';
     12$PHPMAILER_LANG['empty_message']        = 'Cuerpo del mensaje vacío';
     13$PHPMAILER_LANG['encoding']             = 'Codificación desconocida: ';
     14$PHPMAILER_LANG['execute']              = 'No se pudo ejecutar: ';
     15$PHPMAILER_LANG['file_access']          = 'No se pudo acceder al archivo: ';
     16$PHPMAILER_LANG['file_open']            = 'Error de Archivo: No se pudo abrir el archivo: ';
     17$PHPMAILER_LANG['from_failed']          = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
     18$PHPMAILER_LANG['instantiate']          = 'No se pudo crear una instancia de la función Mail.';
     19$PHPMAILER_LANG['invalid_address']      = 'No se pudo enviar: dirección de email inválido: ';
     20$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.';
     21$PHPMAILER_LANG['provide_address']      = 'Debe proveer al menos una dirección de email como destino.';
     22$PHPMAILER_LANG['recipients_failed']    = 'Error SMTP: Los siguientes destinos fallaron: ';
     23$PHPMAILER_LANG['signing']              = 'Error al firmar: ';
     24$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() se falló.';
     25$PHPMAILER_LANG['smtp_error']           = 'Error del servidor SMTP: ';
     26$PHPMAILER_LANG['variable_set']         = 'No se pudo ajustar o reajustar la variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-et.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-et.php src/wp-includes/PHPMailer/language/phpmailer.lang-et.php
    new file mode 100644
    index 0000000..eee4e58
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Estonian Version
     5* By Indrek Päri
     6* Revised By Elan Ruusamäe <glen@delfi.ee>
     7*/
     8
     9$PHPMAILER_LANG['authenticate']         = 'SMTP Viga: Autoriseerimise viga.';
     10$PHPMAILER_LANG['connect_host']         = 'SMTP Viga: Ei õnnestunud luua ühendust SMTP serveriga.';
     11$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Viga: Vigased andmed.';
     12$PHPMAILER_LANG['empty_message']        = 'Tühi kirja sisu';
     13$PHPMAILER_LANG["encoding"]             = 'Tundmatu kodeering: ';
     14$PHPMAILER_LANG['execute']              = 'Tegevus ebaõnnestus: ';
     15$PHPMAILER_LANG['file_access']          = 'Pole piisavalt õiguseid järgneva faili avamiseks: ';
     16$PHPMAILER_LANG['file_open']            = 'Faili Viga: Faili avamine ebaõnnestus: ';
     17$PHPMAILER_LANG['from_failed']          = 'Järgnev saatja e-posti aadress on vigane: ';
     18$PHPMAILER_LANG['instantiate']          = 'mail funktiooni käivitamine ebaõnnestus.';
     19$PHPMAILER_LANG['invalid_address']        = 'Saatmine peatatud, e-posti address vigane: ';
     20$PHPMAILER_LANG['provide_address']      = 'Te peate määrama vähemalt ühe saaja e-posti aadressi.';
     21$PHPMAILER_LANG['mailer_not_supported'] = ' maileri tugi puudub.';
     22$PHPMAILER_LANG['recipients_failed']    = 'SMTP Viga: Järgnevate saajate e-posti aadressid on vigased: ';
     23$PHPMAILER_LANG["signing"]              = 'Viga allkirjastamisel: ';
     24$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() ebaõnnestus.';
     25$PHPMAILER_LANG['smtp_error']           = 'SMTP serveri viga: ';
     26$PHPMAILER_LANG['variable_set']         = 'Ei õnnestunud määrata või lähtestada muutujat: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-fa.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-fa.php src/wp-includes/PHPMailer/language/phpmailer.lang-fa.php
    new file mode 100644
    index 0000000..49aad1b
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Persian/Farsi Version, UTF-8
     5* By: Ali Jazayeri <jaza.ali@gmail.com>
     6*/
     7
     8$PHPMAILER_LANG['authenticate']         = 'SMTP Error: احراز هویت با شکست مواجه شد.';
     9$PHPMAILER_LANG['connect_host']         = 'SMTP Error: اتصال به سرور SMTP برقرار نشد.';
     10$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Error: داده ها نادرست هستند.';
     11$PHPMAILER_LANG['empty_message']        = 'بخش متن پیام خالی است.';
     12$PHPMAILER_LANG['encoding']             = 'رمزگذاری ناشناخته: ';
     13$PHPMAILER_LANG['execute']              = 'امکان اجرا وجود ندارد: ';
     14$PHPMAILER_LANG['file_access']          = 'امکان دسترسی به فایل وجود ندارد: ';
     15$PHPMAILER_LANG['file_open']            = 'File Error: امکان بازکردن فایل وجود ندارد: ';
     16$PHPMAILER_LANG['from_failed']          = 'آدرس فرستنده اشتباه است: ';
     17$PHPMAILER_LANG['instantiate']          = 'امکان معرفی تابع ایمیل وجود ندارد.';
     18$PHPMAILER_LANG['invalid_address']      = 'آدرس ایمیل معتبر نیست: ';
     19$PHPMAILER_LANG['mailer_not_supported'] = ' mailer پشتیبانی نمی شود.';
     20$PHPMAILER_LANG['provide_address']      = 'باید حداقل یک آدرس گیرنده وارد کنید.';
     21$PHPMAILER_LANG['recipients_failed']    = 'SMTP Error: ارسال به آدرس گیرنده با خطا مواجه شد: ';
     22$PHPMAILER_LANG['signing']              = 'خطا در امضا: ';
     23$PHPMAILER_LANG['smtp_connect_failed']  = 'خطا در اتصال به SMTP.';
     24$PHPMAILER_LANG['smtp_error']           = 'خطا در SMTP Server: ';
     25$PHPMAILER_LANG['variable_set']         = 'امکان ارسال یا ارسال مجدد متغیرها وجود ندارد: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-fi.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-fi.php src/wp-includes/PHPMailer/language/phpmailer.lang-fi.php
    new file mode 100644
    index 0000000..16a02e1
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Finnish Version
     5* By Jyry Kuukanen
     6*/
     7
     8$PHPMAILER_LANG['authenticate']         = 'SMTP-virhe: käyttäjätunnistus epäonnistui.';
     9$PHPMAILER_LANG['connect_host']         = 'SMTP-virhe: yhteys palvelimeen ei onnistu.';
     10$PHPMAILER_LANG['data_not_accepted']    = 'SMTP-virhe: data on virheellinen.';
     11//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     12$PHPMAILER_LANG['encoding']             = 'Tuntematon koodaustyyppi: ';
     13$PHPMAILER_LANG['execute']              = 'Suoritus epäonnistui: ';
     14$PHPMAILER_LANG['file_access']          = 'Seuraavaan tiedostoon ei ole oikeuksia: ';
     15$PHPMAILER_LANG['file_open']            = 'Tiedostovirhe: Ei voida avata tiedostoa: ';
     16$PHPMAILER_LANG['from_failed']          = 'Seuraava lähettäjän osoite on virheellinen: ';
     17$PHPMAILER_LANG['instantiate']          = 'mail-funktion luonti epäonnistui.';
     18//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     19$PHPMAILER_LANG['mailer_not_supported'] = 'postivälitintyyppiä ei tueta.';
     20$PHPMAILER_LANG['provide_address']      = 'Aseta vähintään yksi vastaanottajan sähk&ouml;postiosoite.';
     21$PHPMAILER_LANG['recipients_failed']    = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.';
     22$PHPMAILER_LANG['encoding']             = 'Tuntematon koodaustyyppi: ';
     23//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     24//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     25//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     26//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-fo.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-fo.php src/wp-includes/PHPMailer/language/phpmailer.lang-fo.php
    new file mode 100644
    index 0000000..fc5d6d5
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Faroese Version [language of the Faroe Islands, a Danish dominion]
     5* This file created: 11-06-2004
     6* Supplied by Dávur Sørensen [www.profo-webdesign.dk]
     7*/
     8
     9$PHPMAILER_LANG['authenticate']         = 'SMTP feilur: Kundi ikki góðkenna.';
     10$PHPMAILER_LANG['connect_host']         = 'SMTP feilur: Kundi ikki knýta samband við SMTP vert.';
     11$PHPMAILER_LANG['data_not_accepted']    = 'SMTP feilur: Data ikki góðkent.';
     12//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     13$PHPMAILER_LANG['encoding']             = 'Ókend encoding: ';
     14$PHPMAILER_LANG['execute']              = 'Kundi ikki útføra: ';
     15$PHPMAILER_LANG['file_access']          = 'Kundi ikki tilganga fílu: ';
     16$PHPMAILER_LANG['file_open']            = 'Fílu feilur: Kundi ikki opna fílu: ';
     17$PHPMAILER_LANG['from_failed']          = 'fylgjandi Frá/From adressa miseydnaðist: ';
     18$PHPMAILER_LANG['instantiate']          = 'Kuni ikki instantiera mail funktión.';
     19//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     20$PHPMAILER_LANG['mailer_not_supported'] = ' er ikki supporterað.';
     21$PHPMAILER_LANG['provide_address']      = 'Tú skal uppgeva minst móttakara-emailadressu(r).';
     22$PHPMAILER_LANG['recipients_failed']    = 'SMTP Feilur: Fylgjandi móttakarar miseydnaðust: ';
     23//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     24//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     25//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     26//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-fr.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-fr.php src/wp-includes/PHPMailer/language/phpmailer.lang-fr.php
    new file mode 100644
    index 0000000..2d23cf5
    - +  
     1<?php
     2/**
     3 * PHPMailer language file: refer to English translation for definitive list
     4 * French Version
     5 * Some French punctuation requires a thin non-breaking space (U+202F) character before it,
     6 * for example before a colon or exclamation mark.
     7 * There is one of these characters between these quotes: " "
     8 * @link http://unicode.org/udhr/n/notes_fra.html
     9 *
     10 */
     11
     12$PHPMAILER_LANG['authenticate']         = 'Erreur SMTP : échec de l\'authentification.';
     13$PHPMAILER_LANG['connect_host']         = 'Erreur SMTP : impossible de se connecter au serveur SMTP.';
     14$PHPMAILER_LANG['data_not_accepted']    = 'Erreur SMTP : données incorrectes.';
     15$PHPMAILER_LANG['empty_message']        = 'Corps de message vide.';
     16$PHPMAILER_LANG['encoding']             = 'Encodage inconnu : ';
     17$PHPMAILER_LANG['execute']              = 'Impossible de lancer l\'exécution : ';
     18$PHPMAILER_LANG['file_access']          = 'Impossible d\'accéder au fichier : ';
     19$PHPMAILER_LANG['file_open']            = 'Erreur de fichier : ouverture impossible : ';
     20$PHPMAILER_LANG['from_failed']          = 'L\'adresse d\'expéditeur suivante a échouée : ';
     21$PHPMAILER_LANG['instantiate']          = 'Impossible d\'instancier la fonction mail.';
     22$PHPMAILER_LANG['invalid_address']      = 'L\'adresse courriel n\'est pas valide : ';
     23$PHPMAILER_LANG['mailer_not_supported'] = ' client de messagerie non supporté.';
     24$PHPMAILER_LANG['provide_address']      = 'Vous devez fournir au moins une adresse de destinataire.';
     25$PHPMAILER_LANG['recipients_failed']    = 'Erreur SMTP : les destinataires suivants sont en erreur : ';
     26$PHPMAILER_LANG['signing']              = 'Erreur de signature : ';
     27$PHPMAILER_LANG['smtp_connect_failed']  = 'Échec de la connexion SMTP.';
     28$PHPMAILER_LANG['smtp_error']           = 'Erreur du serveur SMTP : ';
     29$PHPMAILER_LANG['variable_set']         = 'Ne peut initialiser ou réinitialiser une variable : ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-he.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-he.php src/wp-includes/PHPMailer/language/phpmailer.lang-he.php
    new file mode 100644
    index 0000000..e30b596
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Hebrew Version, UTF-8
     5* by : Ronny Sherer <ronny@hoojima.com>
     6*/
     7
     8$PHPMAILER_LANG['authenticate']         = 'שגיאת SMTP: פעולת האימות נכשלה.';
     9$PHPMAILER_LANG['connect_host']         = 'שגיאת SMTP: לא הצלחתי להתחבר לשרת SMTP.';
     10$PHPMAILER_LANG['data_not_accepted']    = 'שגיאת SMTP: מידע לא התקבל.';
     11$PHPMAILER_LANG['empty_message']        = 'גוף ההודעה ריק';
     12$PHPMAILER_LANG['invalid_address']      = 'כתובת שגויה';
     13$PHPMAILER_LANG['encoding']             = 'קידוד לא מוכר: ';
     14$PHPMAILER_LANG['execute']              = 'לא הצלחתי להפעיל את: ';
     15$PHPMAILER_LANG['file_access']          = 'לא ניתן לגשת לקובץ: ';
     16$PHPMAILER_LANG['file_open']            = 'שגיאת קובץ: לא ניתן לגשת לקובץ: ';
     17$PHPMAILER_LANG['from_failed']          = 'כתובות הנמענים הבאות נכשלו: ';
     18$PHPMAILER_LANG['instantiate']          = 'לא הצלחתי להפעיל את פונקציית המייל.';
     19$PHPMAILER_LANG['mailer_not_supported'] = ' אינה נתמכת.';
     20$PHPMAILER_LANG['provide_address']      = 'חובה לספק לפחות כתובת אחת של מקבל המייל.';
     21$PHPMAILER_LANG['recipients_failed']    = 'שגיאת SMTP: הנמענים הבאים נכשלו: ';
     22$PHPMAILER_LANG['signing']              = 'שגיאת חתימה: ';
     23$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     24$PHPMAILER_LANG['smtp_error']           = 'שגיאת שרת SMTP: ';
     25$PHPMAILER_LANG['variable_set']         = 'לא ניתן לקבוע או לשנות את המשתנה: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-hu.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-hu.php src/wp-includes/PHPMailer/language/phpmailer.lang-hu.php
    new file mode 100644
    index 0000000..d8d1926
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Hungarian Version by @dominicus-75
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'SMTP hiba: az azonosítás sikertelen.';
     8$PHPMAILER_LANG['connect_host']         = 'SMTP hiba: nem lehet kapcsolódni az SMTP-szerverhez.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'SMTP hiba: adatok visszautasítva.';
     10$PHPMAILER_LANG['empty_message']        = 'Üres az üzenettörzs.';
     11$PHPMAILER_LANG['encoding']             = 'Ismeretlen kódolás: ';
     12$PHPMAILER_LANG['execute']              = 'Nem lehet végrehajtani: ';
     13$PHPMAILER_LANG['file_access']          = 'A következő fájl nem elérhető: ';
     14$PHPMAILER_LANG['file_open']            = 'Fájl hiba: a következő fájlt nem lehet megnyitni: ';
     15$PHPMAILER_LANG['from_failed']          = 'A feladóként megadott következő cím hibás: ';
     16$PHPMAILER_LANG['instantiate']          = 'A PHP mail() függvényt nem sikerült végrehajtani.';
     17$PHPMAILER_LANG['invalid_address']      = 'Érvénytelen cím: ';
     18$PHPMAILER_LANG['mailer_not_supported'] = ' a mailer-osztály nem támogatott.';
     19$PHPMAILER_LANG['provide_address']      = 'Legalább egy címzettet fel kell tüntetni.';
     20$PHPMAILER_LANG['recipients_failed']    = 'SMTP hiba: a címzettként megadott következő címek hibásak: ';
     21$PHPMAILER_LANG['signing']              = 'Hibás aláírás: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'Hiba az SMTP-kapcsolatban.';
     23$PHPMAILER_LANG['smtp_error']           = 'SMTP-szerver hiba: ';
     24$PHPMAILER_LANG['variable_set']         = 'A következő változók beállítása nem sikerült: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-it.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-it.php src/wp-includes/PHPMailer/language/phpmailer.lang-it.php
    new file mode 100644
    index 0000000..27ab0ea
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Italian version
     5* @package PHPMailer
     6* @author Ilias Bartolini <brain79@inwind.it>, Stefano Sabatini <sabas88@gmail.com>
     7*/
     8
     9$PHPMAILER_LANG['authenticate']         = 'SMTP Error: Impossibile autenticarsi.';
     10$PHPMAILER_LANG['connect_host']         = 'SMTP Error: Impossibile connettersi all\'host SMTP.';
     11$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Error: Dati non accettati dal server.';
     12$PHPMAILER_LANG['empty_message']        = 'Il corpo del messaggio è vuoto';
     13$PHPMAILER_LANG['encoding']             = 'Codifica dei caratteri sconosciuta: ';
     14$PHPMAILER_LANG['execute']              = 'Impossibile eseguire l\'operazione: ';
     15$PHPMAILER_LANG['file_access']          = 'Impossibile accedere al file: ';
     16$PHPMAILER_LANG['file_open']            = 'File Error: Impossibile aprire il file: ';
     17$PHPMAILER_LANG['from_failed']          = 'I seguenti indirizzi mittenti hanno generato errore: ';
     18$PHPMAILER_LANG['instantiate']          = 'Impossibile istanziare la funzione mail';
     19$PHPMAILER_LANG['invalid_address']        = 'Impossibile inviare, l\'indirizzo email non è valido: ';
     20$PHPMAILER_LANG['provide_address']      = 'Deve essere fornito almeno un indirizzo ricevente';
     21$PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato';
     22$PHPMAILER_LANG['recipients_failed']    = 'SMTP Error: I seguenti indirizzi destinatari hanno generato un errore: ';
     23$PHPMAILER_LANG['signing']              = 'Errore nella firma: ';
     24$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() fallita.';
     25$PHPMAILER_LANG['smtp_error']           = 'Errore del server SMTP: ';
     26$PHPMAILER_LANG['variable_set']         = 'Impossibile impostare o resettare la variabile: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-ja.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ja.php src/wp-includes/PHPMailer/language/phpmailer.lang-ja.php
    new file mode 100644
    index 0000000..ca6de90
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Japanese Version
     5* By Mitsuhiro Yoshida - http://mitstek.com/
     6* Modified by Yoshi Sakai - http://bluemooninc.jp/
     7*/
     8
     9$PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。';
     10$PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。';
     11$PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。';
     12//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     13$PHPMAILER_LANG['encoding'] = '不明なエンコーディング: ';
     14$PHPMAILER_LANG['execute'] = '実行できませんでした: ';
     15$PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: ';
     16$PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: ';
     17$PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: ';
     18$PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。';
     19//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     20$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。';
     21$PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。';
     22$PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: ';
     23//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     24//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     25//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     26//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-lt.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-lt.php src/wp-includes/PHPMailer/language/phpmailer.lang-lt.php
    new file mode 100644
    index 0000000..5dba58a
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Lithuanian version by Dainius Kaupaitis <dk@sum.lt>
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'SMTP klaida: autentifikacija nepavyko.';
     8$PHPMAILER_LANG['connect_host']         = 'SMTP klaida: nepavyksta prisijungti prie SMTP stoties.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'SMTP klaida: duomenys nepriimti.';
     10$PHPMAILER_LANG['empty_message']        = 'Laiško turinys tuščias';
     11$PHPMAILER_LANG['encoding']             = 'Neatpažinta koduotė: ';
     12$PHPMAILER_LANG['execute']              = 'Nepavyko įvykdyti komandos: ';
     13$PHPMAILER_LANG['file_access']          = 'Byla nepasiekiama: ';
     14$PHPMAILER_LANG['file_open']            = 'Bylos klaida: Nepavyksta atidaryti: ';
     15$PHPMAILER_LANG['from_failed']          = 'Neteisingas siuntėjo adresas: ';
     16$PHPMAILER_LANG['instantiate']          = 'Nepavyko paleisti mail funkcijos.';
     17$PHPMAILER_LANG['invalid_address']      = 'Neteisingas adresas';
     18$PHPMAILER_LANG['mailer_not_supported'] = ' pašto stotis nepalaikoma.';
     19$PHPMAILER_LANG['provide_address']      = 'Nurodykite bent vieną gavėjo adresą.';
     20$PHPMAILER_LANG['recipients_failed']    = 'SMTP klaida: nepavyko išsiųsti šiems gavėjams: ';
     21$PHPMAILER_LANG['signing']              = 'Prisijungimo klaida: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP susijungimo klaida';
     23$PHPMAILER_LANG['smtp_error']           = 'SMTP stoties klaida: ';
     24$PHPMAILER_LANG['variable_set']         = 'Nepavyko priskirti reikšmės kintamajam: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-nl.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-nl.php src/wp-includes/PHPMailer/language/phpmailer.lang-nl.php
    new file mode 100644
    index 0000000..c86d769
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to class.phpmailer.php for definitive list.
     4* Dutch Version by Tuxion <team@tuxion.nl>
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'SMTP-fout: authenticatie mislukt.';//SMTP Error: Could not authenticate.
     8$PHPMAILER_LANG['connect_host']         = 'SMTP-fout: kon niet verbinden met SMTP-host.';//SMTP Error: Could not connect to SMTP host.
     9$PHPMAILER_LANG['data_not_accepted']    = 'SMTP-fout: data niet geaccepteerd.';//SMTP Error: Data not accepted.
     10$PHPMAILER_LANG['empty_message']        = 'Berichttekst is leeg';//Message body empty
     11$PHPMAILER_LANG['encoding']             = 'Onbekende codering: ';//Unknown encoding:
     12$PHPMAILER_LANG['execute']              = 'Kon niet uitvoeren: ';//Could not execute:
     13$PHPMAILER_LANG['file_access']          = 'Kreeg geen toegang tot bestand: ';//Could not access file:
     14$PHPMAILER_LANG['file_open']            = 'Bestandsfout: kon bestand niet openen: ';//File Error: Could not open file:
     15$PHPMAILER_LANG['from_failed']          = 'Het volgende afzendersadres is mislukt: ';//The following From address failed:
     16$PHPMAILER_LANG['instantiate']          = 'Kon mailfunctie niet initialiseren.';//Could not instantiate mail function.
     17$PHPMAILER_LANG['invalid_address']      = 'Ongeldig adres';//Invalid address
     18$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';// mailer is not supported.
     19$PHPMAILER_LANG['provide_address']      = 'Er moet minstens één ontvanger worden opgegeven.';//You must provide at least one recipient email address.
     20$PHPMAILER_LANG['recipients_failed']    = 'SMTP-fout: de volgende ontvangers zijn mislukt: ';//SMTP Error: The following recipients failed:
     21$PHPMAILER_LANG['signing']              = 'Signeerfout: ';//Signing Error:
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Verbinding mislukt.';
     23$PHPMAILER_LANG['smtp_error']           = 'SMTP-serverfout: ';//SMTP server error:
     24$PHPMAILER_LANG['variable_set']         = 'Kan de volgende variablen niet instellen of resetten: ';//Cannot set or reset variable:
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-no.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-no.php src/wp-includes/PHPMailer/language/phpmailer.lang-no.php
    new file mode 100644
    index 0000000..e697520
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Norwegian Version
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'SMTP Feil: Kunne ikke authentisere.';
     8$PHPMAILER_LANG['connect_host']         = 'SMTP Feil: Kunne ikke koble til SMTP host.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Feil: Data ble ikke akseptert.';
     10$PHPMAILER_LANG['empty_message']        = 'Meldingsinnholdet er tomt';
     11$PHPMAILER_LANG['encoding']             = 'Ukjent tegnkoding: ';
     12$PHPMAILER_LANG['execute']              = 'Kunne ikke utføre: ';
     13$PHPMAILER_LANG['file_access']          = 'Får ikke tilgang til filen: ';
     14$PHPMAILER_LANG['file_open']            = 'Fil feil: Kunne ikke åpne filen: ';
     15$PHPMAILER_LANG['from_failed']          = 'Følgende avsenderadresse feilet: ';
     16$PHPMAILER_LANG['instantiate']          = 'Kunne ikke initialisere mailfunksjonen.';
     17$PHPMAILER_LANG['invalid_address']      = 'Meldingen ble ikke sendt, følgende adresse er ugyldig: ';
     18$PHPMAILER_LANG['provide_address']      = 'Du må angi minst en mottakeradresse.';
     19$PHPMAILER_LANG['mailer_not_supported'] = ' mailer er ikke supportert.';
     20$PHPMAILER_LANG['recipients_failed']    = 'SMTP Feil: Følgende mottagere feilet: ';
     21$PHPMAILER_LANG['signing']              = 'Signeringsfeil: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() feilet.';
     23$PHPMAILER_LANG['smtp_error']           = 'SMTP-serverfeil: ';
     24$PHPMAILER_LANG['variable_set']         = 'Kan ikke sette eller resette variabelen: ';
     25 No newline at end of file
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-pl.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-pl.php src/wp-includes/PHPMailer/language/phpmailer.lang-pl.php
    new file mode 100644
    index 0000000..5a4ad38
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Polish Version
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'Błąd SMTP: Nie można przeprowadzić autentykacji.';
     8$PHPMAILER_LANG['connect_host']         = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'Błąd SMTP: Dane nie zostały przyjęte.';
     10$PHPMAILER_LANG['empty_message']        = 'Wiadomość jest pusta.';
     11$PHPMAILER_LANG['encoding']             = 'Nieznany sposób kodowania znaków: ';
     12$PHPMAILER_LANG['execute']              = 'Nie można uruchomić: ';
     13$PHPMAILER_LANG['file_access']          = 'Brak dostępu do pliku: ';
     14$PHPMAILER_LANG['file_open']            = 'Nie można otworzyć pliku: ';
     15$PHPMAILER_LANG['from_failed']          = 'Następujący adres Nadawcy jest nieprawidłowy: ';
     16$PHPMAILER_LANG['instantiate']          = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
     17$PHPMAILER_LANG['invalid_address']      = 'Nie można wysłać wiadomości, następujący adres Odbiorcy jest nieprawidłowy: ';
     18$PHPMAILER_LANG['provide_address']      = 'Należy podać prawidłowy adres email Odbiorcy.';
     19$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
     20$PHPMAILER_LANG['recipients_failed']    = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi: ';
     21$PHPMAILER_LANG['signing']              = 'Błąd podpisywania wiadomości: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() zakończone niepowodzeniem.';
     23$PHPMAILER_LANG['smtp_error']           = 'Błąd SMTP: ';
     24$PHPMAILER_LANG['variable_set']         = 'Nie można zmienić zmiennej: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-ro.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ro.php src/wp-includes/PHPMailer/language/phpmailer.lang-ro.php
    new file mode 100644
    index 0000000..1727cef
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Romanian Version
     5* @package PHPMailer
     6* @author Catalin Constantin <catalin@dazoot.ro>
     7*/
     8
     9$PHPMAILER_LANG['authenticate']         = 'Eroare SMTP: Nu a functionat autentificarea.';
     10$PHPMAILER_LANG['connect_host']         = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.';
     11$PHPMAILER_LANG['data_not_accepted']    = 'Eroare SMTP: Continutul mailului nu a fost acceptat.';
     12//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     13$PHPMAILER_LANG['encoding']             = 'Encodare necunoscuta: ';
     14$PHPMAILER_LANG['execute']              = 'Nu pot executa:  ';
     15$PHPMAILER_LANG['file_access']          = 'Nu pot accesa fisierul: ';
     16$PHPMAILER_LANG['file_open']            = 'Eroare de fisier: Nu pot deschide fisierul: ';
     17$PHPMAILER_LANG['from_failed']          = 'Urmatoarele adrese From au dat eroare: ';
     18$PHPMAILER_LANG['instantiate']          = 'Nu am putut instantia functia mail.';
     19//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     20$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.';
     21$PHPMAILER_LANG['provide_address']      = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).';
     22$PHPMAILER_LANG['recipients_failed']    = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: ';
     23//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     24//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     25//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     26//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-ru.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-ru.php src/wp-includes/PHPMailer/language/phpmailer.lang-ru.php
    new file mode 100644
    index 0000000..9e583da
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Russian Version by Alexey Chumakov <alex@chumakov.ru>
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'Ошибка SMTP: ошибка авторизации.';
     8$PHPMAILER_LANG['connect_host']         = 'Ошибка SMTP: не удается подключиться к серверу SMTP.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'Ошибка SMTP: данные не приняты.';
     10$PHPMAILER_LANG['encoding']             = 'Неизвестный вид кодировки: ';
     11$PHPMAILER_LANG['execute']              = 'Невозможно выполнить команду: ';
     12$PHPMAILER_LANG['file_access']          = 'Нет доступа к файлу: ';
     13$PHPMAILER_LANG['file_open']            = 'Файловая ошибка: не удается открыть файл: ';
     14$PHPMAILER_LANG['from_failed']          = 'Неверный адрес отправителя: ';
     15$PHPMAILER_LANG['instantiate']          = 'Невозможно запустить функцию mail.';
     16$PHPMAILER_LANG['provide_address']      = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.';
     17$PHPMAILER_LANG['mailer_not_supported'] = ' - почтовый сервер не поддерживается.';
     18$PHPMAILER_LANG['recipients_failed']    = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: ';
     19$PHPMAILER_LANG['empty_message']        = 'Пустое тело сообщения';
     20$PHPMAILER_LANG['invalid_address']        = 'Не отослано, неправильный формат email адреса: ';
     21$PHPMAILER_LANG['signing']              = 'Ошибка подписывания: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'Ошибка соединения с SMTP-сервером';
     23$PHPMAILER_LANG['smtp_error']           = 'Ошибка SMTP-сервера: ';
     24$PHPMAILER_LANG['variable_set']         = 'Невозможно установить или переустановить переменную: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-se.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-se.php src/wp-includes/PHPMailer/language/phpmailer.lang-se.php
    new file mode 100644
    index 0000000..65d1979
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Swedish Version
     5* Author: Johan Linnér <johan@linner.biz>
     6*/
     7
     8$PHPMAILER_LANG['authenticate']         = 'SMTP fel: Kunde inte autentisera.';
     9$PHPMAILER_LANG['connect_host']         = 'SMTP fel: Kunde inte ansluta till SMTP-server.';
     10$PHPMAILER_LANG['data_not_accepted']    = 'SMTP fel: Data accepterades inte.';
     11//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     12$PHPMAILER_LANG['encoding']             = 'Okänt encode-format: ';
     13$PHPMAILER_LANG['execute']              = 'Kunde inte köra: ';
     14$PHPMAILER_LANG['file_access']          = 'Ingen åtkomst till fil: ';
     15$PHPMAILER_LANG['file_open']            = 'Fil fel: Kunde inte öppna fil: ';
     16$PHPMAILER_LANG['from_failed']          = 'Följande avsändaradress är felaktig: ';
     17$PHPMAILER_LANG['instantiate']          = 'Kunde inte initiera e-postfunktion.';
     18//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     19$PHPMAILER_LANG['provide_address']      = 'Du måste ange minst en mottagares e-postadress.';
     20$PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.';
     21$PHPMAILER_LANG['recipients_failed']    = 'SMTP fel: Följande mottagare är felaktig: ';
     22//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     23//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     24//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     25//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-sk.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-sk.php src/wp-includes/PHPMailer/language/phpmailer.lang-sk.php
    new file mode 100644
    index 0000000..1722a5f
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Slovak Version
     5* Author: Michal Tinka <michaltinka@gmail.com>
     6*/
     7
     8$PHPMAILER_LANG['authenticate']         = 'SMTP Error: Chyba autentifikácie.';
     9$PHPMAILER_LANG['connect_host']         = 'SMTP Error: Nebolo možné nadviazať spojenie so SMTP serverom.';
     10$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Error: Dáta neboli prijaté';
     11$PHPMAILER_LANG['empty_message']        = 'Prázdne telo správy.';
     12$PHPMAILER_LANG['encoding']             = 'Neznáme kódovanie: ';
     13$PHPMAILER_LANG['execute']              = 'Nedá sa vykonať: ';
     14$PHPMAILER_LANG['file_access']          = 'Súbor nebol nájdený: ';
     15$PHPMAILER_LANG['file_open']            = 'File Error: Súbor sa otvoriť pre čítanie: ';
     16$PHPMAILER_LANG['from_failed']          = 'Následujúca adresa From je nesprávna: ';
     17$PHPMAILER_LANG['instantiate']          = 'Nedá sa vytvoriť inštancia emailovej funkcie.';
     18$PHPMAILER_LANG['invalid_address']        = 'Neodoslané, emailová adresa je nesprávna: ';
     19$PHPMAILER_LANG['mailer_not_supported'] = ' emailový klient nieje podporovaný.';
     20$PHPMAILER_LANG['provide_address']      = 'Musíte zadať aspoň jednu emailovú adresu príjemcu.';
     21$PHPMAILER_LANG['recipients_failed']    = 'SMTP Error: Adresy príjemcov niesu správne ';
     22$PHPMAILER_LANG['signing']              = 'Chyba prihlasovania: ';
     23$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() zlyhalo.';
     24$PHPMAILER_LANG['smtp_error']           = 'SMTP chyba serveru: ';
     25$PHPMAILER_LANG['variable_set']         = 'Nemožno nastaviť alebo resetovať premennú: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-tr.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-tr.php src/wp-includes/PHPMailer/language/phpmailer.lang-tr.php
    new file mode 100644
    index 0000000..abba081
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Turkish version
     5* Türkçe Versiyonu
     6* ÝZYAZILIM - Elçin Özel - Can Yýlmaz - Mehmet Benlioðlu
     7*/
     8
     9$PHPMAILER_LANG['authenticate']         = 'SMTP Hatası: Doğrulanamıyor.';
     10$PHPMAILER_LANG['connect_host']         = 'SMTP Hatası: SMTP hosta bağlanılamıyor.';
     11$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Hatası: Veri kabul edilmedi.';
     12$PHPMAILER_LANG['empty_message']        = 'Mesaj içeriği boş';
     13$PHPMAILER_LANG['encoding']             = 'Bilinmeyen şifreleme: ';
     14$PHPMAILER_LANG['execute']              = 'Çalıtırılamıyor: ';
     15$PHPMAILER_LANG['file_access']          = 'Dosyaya erişilemiyor: ';
     16$PHPMAILER_LANG['file_open']            = 'Dosya Hatası: Dosya açılamıyor: ';
     17$PHPMAILER_LANG['from_failed']          = 'Başarısız olan gönderici adresi: ';
     18$PHPMAILER_LANG['instantiate']          = 'Örnek mail fonksiyonu oluşturulamadı.';
     19$PHPMAILER_LANG['invalid_address']        = 'Gönderilmedi, email adresi geçersiz: ';
     20$PHPMAILER_LANG['provide_address']      = 'En az bir tane mail adresi belirtmek zorundasınız alıcının email adresi.';
     21$PHPMAILER_LANG['mailer_not_supported'] = ' mailler desteklenmemektedir.';
     22$PHPMAILER_LANG['recipients_failed']    = 'SMTP Hatası: alıcılara ulaımadı: ';
     23$PHPMAILER_LANG['signing']              = 'İmzalama hatası: ';
     24$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP bağlantı() başarısız.';
     25$PHPMAILER_LANG['smtp_error']           = 'SMTP sunucu hatası: ';
     26$PHPMAILER_LANG['variable_set']         = 'Ayarlanamıyor yada sıfırlanamıyor: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-uk.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-uk.php src/wp-includes/PHPMailer/language/phpmailer.lang-uk.php
    new file mode 100644
    index 0000000..112bba8
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Ukrainian Version by Yuriy Rudyy <yrudyy@prs.net.ua>
     5*/
     6
     7$PHPMAILER_LANG['authenticate']         = 'Помилка SMTP: помилка авторизації.';
     8$PHPMAILER_LANG['connect_host']         = 'Помилка SMTP: не вдається підєднатися до серверу SMTP.';
     9$PHPMAILER_LANG['data_not_accepted']    = 'Помилка SMTP: дані не прийняті.';
     10$PHPMAILER_LANG['encoding']             = 'Невідомий тип кодування: ';
     11$PHPMAILER_LANG['execute']              = 'Неможливо виконати команду: ';
     12$PHPMAILER_LANG['file_access']          = 'Немає доступу до файлу: ';
     13$PHPMAILER_LANG['file_open']            = 'Помилка файлової системи: не вдається відкрити файл: ';
     14$PHPMAILER_LANG['from_failed']          = 'Невірна адреса відправника: ';
     15$PHPMAILER_LANG['instantiate']          = 'Неможливо запустити функцію mail.';
     16$PHPMAILER_LANG['provide_address']      = 'Будь-ласка, введіть хоча б одну адресу e-mail отримувача.';
     17$PHPMAILER_LANG['mailer_not_supported'] = ' - поштовий сервер не підтримується.';
     18$PHPMAILER_LANG['recipients_failed']    = 'Помилка SMTP: відправти наступним отрмувачам не вдалася: ';
     19$PHPMAILER_LANG['empty_message']        = 'Пусте тіло повідомлення';
     20$PHPMAILER_LANG['invalid_address']      = 'Не відправлено, невірний формат email адреси: ';
     21$PHPMAILER_LANG['signing']              = 'Помилка підпису: ';
     22$PHPMAILER_LANG['smtp_connect_failed']  = 'Помилка зєднання із SMTP-сервером';
     23$PHPMAILER_LANG['smtp_error']           = 'Помилка SMTP-сервера: ';
     24$PHPMAILER_LANG['variable_set']         = 'Неможливо встановити або перевстановити змінну: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-zh.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-zh.php src/wp-includes/PHPMailer/language/phpmailer.lang-zh.php
    new file mode 100644
    index 0000000..b0e8f4e
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Traditional Chinese Version
     5* @author liqwei <liqwei@liqwei.com>
     6*/
     7
     8$PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登錄失敗。';
     9$PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連接到 SMTP 主機。';
     10$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 錯誤:數據不被接受。';
     11//$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     12$PHPMAILER_LANG['encoding'] = '未知編碼: ';
     13$PHPMAILER_LANG['file_access'] = '無法訪問文件:';
     14$PHPMAILER_LANG['file_open'] = '文件錯誤:無法打開文件:';
     15$PHPMAILER_LANG['from_failed'] = '發送地址錯誤:';
     16$PHPMAILER_LANG['execute'] = '無法執行:';
     17$PHPMAILER_LANG['instantiate'] = '未知函數調用。';
     18//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     19$PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。';
     20$PHPMAILER_LANG['mailer_not_supported'] = '發信客戶端不被支持。';
     21$PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:收件人地址錯誤:';
     22//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     23//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     24//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     25//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • new file src/wp-includes/PHPMailer/language/phpmailer.lang-zh_cn.php

    diff --git src/wp-includes/PHPMailer/language/phpmailer.lang-zh_cn.php src/wp-includes/PHPMailer/language/phpmailer.lang-zh_cn.php
    new file mode 100644
    index 0000000..78eb9ac
    - +  
     1<?php
     2/**
     3* PHPMailer language file: refer to English translation for definitive list
     4* Simplified Chinese Version
     5* @author liqwei <liqwei@liqwei.com>
     6*/
     7
     8$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。';
     9$PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。';
     10$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。';
     11//$P$PHPMAILER_LANG['empty_message']        = 'Message body empty';
     12$PHPMAILER_LANG['encoding'] = '未知编码: ';
     13$PHPMAILER_LANG['execute'] = '无法执行:';
     14$PHPMAILER_LANG['file_access'] = '无法访问文件:';
     15$PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:';
     16$PHPMAILER_LANG['from_failed'] = '发送地址错误:';
     17$PHPMAILER_LANG['instantiate'] = '未知函数调用。';
     18//$PHPMAILER_LANG['invalid_address']        = 'Not sending, email address is invalid: ';
     19$PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。';
     20$PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。';
     21$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:';
     22//$PHPMAILER_LANG['signing']              = 'Signing Error: ';
     23//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';
     24//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';
     25//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';
  • src/wp-includes/class-phpmailer.php

    diff --git src/wp-includes/class-phpmailer.php src/wp-includes/class-phpmailer.php
    index 238474e..e4d2d1b 100644
     
    11<?php
    2 /*~ class.phpmailer.php
    3 .---------------------------------------------------------------------------.
    4 |  Software: PHPMailer - PHP email class                                    |
    5 |   Version: 5.2.4                                                          |
    6 |      Site: https://code.google.com/a/apache-extras.org/p/phpmailer/       |
    7 | ------------------------------------------------------------------------- |
    8 |     Admin: Jim Jagielski (project admininistrator)                        |
    9 |   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
    10 |          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         |
    11 |          : Jim Jagielski (jimjag) jimjag@gmail.com                        |
    12 |   Founder: Brent R. Matzelle (original founder)                           |
    13 | Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved.              |
    14 | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               |
    15 | Copyright (c) 2001-2003, Brent R. Matzelle                                |
    16 | ------------------------------------------------------------------------- |
    17 |   License: Distributed under the Lesser General Public License (LGPL)     |
    18 |            http://www.gnu.org/copyleft/lesser.html                        |
    19 | This program is distributed in the hope that it will be useful - WITHOUT  |
    20 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
    21 | FITNESS FOR A PARTICULAR PURPOSE.                                         |
    22 '---------------------------------------------------------------------------'
    23 */
    24 
    25 /**
    26  * PHPMailer - PHP email creation and transport class
    27  * NOTE: Requires PHP version 5 or later
    28  * @package PHPMailer
    29  * @author Andy Prevost
    30  * @author Marcus Bointon
    31  * @author Jim Jagielski
    32  * @copyright 2010 - 2012 Jim Jagielski
    33  * @copyright 2004 - 2009 Andy Prevost
    34  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
    35  */
    36 
    37 if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n");
    38 
    392/**
    40  * PHP email creation and transport class
    41  * @package PHPMailer
     3 * Backwards compatible shim for PHPMailer library.
     4 *
     5 * @package WordPress
    426 */
    43 class PHPMailer {
    44 
    45   /////////////////////////////////////////////////
    46   // PROPERTIES, PUBLIC
    47   /////////////////////////////////////////////////
    48 
    49   /**
    50    * Email priority (1 = High, 3 = Normal, 5 = low).
    51    * @var int
    52    */
    53   public $Priority          = 3;
    54 
    55   /**
    56    * Sets the CharSet of the message.
    57    * @var string
    58    */
    59   public $CharSet           = 'iso-8859-1';
    60 
    61   /**
    62    * Sets the Content-type of the message.
    63    * @var string
    64    */
    65   public $ContentType       = 'text/plain';
    66 
    67   /**
    68    * Sets the Encoding of the message. Options for this are
    69    *  "8bit", "7bit", "binary", "base64", and "quoted-printable".
    70    * @var string
    71    */
    72   public $Encoding          = '8bit';
    73 
    74   /**
    75    * Holds the most recent mailer error message.
    76    * @var string
    77    */
    78   public $ErrorInfo         = '';
    79 
    80   /**
    81    * Sets the From email address for the message.
    82    * @var string
    83    */
    84   public $From              = 'root@localhost';
    85 
    86   /**
    87    * Sets the From name of the message.
    88    * @var string
    89    */
    90   public $FromName          = 'Root User';
    91 
    92   /**
    93    * Sets the Sender email (Return-Path) of the message.  If not empty,
    94    * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
    95    * @var string
    96    */
    97   public $Sender            = '';
    98 
    99   /**
    100    * Sets the Return-Path of the message.  If empty, it will
    101    * be set to either From or Sender.
    102    * @var string
    103    */
    104   public $ReturnPath        = '';
    105 
    106   /**
    107    * Sets the Subject of the message.
    108    * @var string
    109    */
    110   public $Subject           = '';
    111 
    112   /**
    113    * Sets the Body of the message.  This can be either an HTML or text body.
    114    * If HTML then run IsHTML(true).
    115    * @var string
    116    */
    117   public $Body              = '';
    118 
    119   /**
    120    * Sets the text-only body of the message.  This automatically sets the
    121    * email to multipart/alternative.  This body can be read by mail
    122    * clients that do not have HTML email capability such as mutt. Clients
    123    * that can read HTML will view the normal Body.
    124    * @var string
    125    */
    126   public $AltBody           = '';
    127 
    128   /**
    129    * Stores the complete compiled MIME message body.
    130    * @var string
    131    * @access protected
    132    */
    133   protected $MIMEBody       = '';
    134 
    135   /**
    136    * Stores the complete compiled MIME message headers.
    137    * @var string
    138    * @access protected
    139    */
    140   protected $MIMEHeader     = '';
    141 
    142   /**
    143    * Stores the extra header list which CreateHeader() doesn't fold in
    144    * @var string
    145    * @access protected
    146   */
    147   protected $mailHeader     = '';
    148 
    149   /**
    150    * Sets word wrapping on the body of the message to a given number of
    151    * characters.
    152    * @var int
    153    */
    154   public $WordWrap          = 0;
    155 
    156   /**
    157    * Method to send mail: ("mail", "sendmail", or "smtp").
    158    * @var string
    159    */
    160   public $Mailer            = 'mail';
    161 
    162   /**
    163    * Sets the path of the sendmail program.
    164    * @var string
    165    */
    166   public $Sendmail          = '/usr/sbin/sendmail';
    167 
    168   /**
    169    * Determine if mail() uses a fully sendmail compatible MTA that
    170    * supports sendmail's "-oi -f" options
    171    * @var boolean
    172    */
    173   public $UseSendmailOptions    = true;
    174  
    175   /**
    176    * Path to PHPMailer plugins.  Useful if the SMTP class
    177    * is in a different directory than the PHP include path.
    178    * @var string
    179    */
    180   public $PluginDir         = '';
    181 
    182   /**
    183    * Sets the email address that a reading confirmation will be sent.
    184    * @var string
    185    */
    186   public $ConfirmReadingTo  = '';
    187 
    188   /**
    189    * Sets the hostname to use in Message-Id and Received headers
    190    * and as default HELO string. If empty, the value returned
    191    * by SERVER_NAME is used or 'localhost.localdomain'.
    192    * @var string
    193    */
    194   public $Hostname          = '';
    195 
    196   /**
    197    * Sets the message ID to be used in the Message-Id header.
    198    * If empty, a unique id will be generated.
    199    * @var string
    200    */
    201   public $MessageID         = '';
    202 
    203   /**
    204    * Sets the message Date to be used in the Date header.
    205    * If empty, the current date will be added.
    206    * @var string
    207    */
    208   public $MessageDate       = '';
    209 
    210   /////////////////////////////////////////////////
    211   // PROPERTIES FOR SMTP
    212   /////////////////////////////////////////////////
    213 
    214   /**
    215    * Sets the SMTP hosts.
    216    *
    217    * All hosts must be separated by a
    218    * semicolon.  You can also specify a different port
    219    * for each host by using this format: [hostname:port]
    220    * (e.g. "smtp1.example.com:25;smtp2.example.com").
    221    * Hosts will be tried in order.
    222    * @var string
    223    */
    224   public $Host          = 'localhost';
    225 
    226   /**
    227    * Sets the default SMTP server port.
    228    * @var int
    229    */
    230   public $Port          = 25;
    231 
    232   /**
    233    * Sets the SMTP HELO of the message (Default is $Hostname).
    234    * @var string
    235    */
    236   public $Helo          = '';
    237 
    238   /**
    239    * Sets connection prefix. Options are "", "ssl" or "tls"
    240    * @var string
    241    */
    242   public $SMTPSecure    = '';
    243 
    244   /**
    245    * Sets SMTP authentication. Utilizes the Username and Password variables.
    246    * @var bool
    247    */
    248   public $SMTPAuth      = false;
    249 
    250   /**
    251    * Sets SMTP username.
    252    * @var string
    253    */
    254   public $Username      = '';
    255 
    256   /**
    257    * Sets SMTP password.
    258    * @var string
    259    */
    260   public $Password      = '';
    261 
    262   /**
    263    *  Sets SMTP auth type. Options are LOGIN | PLAIN | NTLM  (default LOGIN)
    264    *  @var string
    265    */
    266   public $AuthType      = '';
    267  
    268   /**
    269    *  Sets SMTP realm.
    270    *  @var string
    271    */
    272   public $Realm         = '';
    273 
    274   /**
    275    *  Sets SMTP workstation.
    276    *  @var string
    277    */
    278   public $Workstation   = '';
    279 
    280   /**
    281    * Sets the SMTP server timeout in seconds.
    282    * This function will not work with the win32 version.
    283    * @var int
    284    */
    285   public $Timeout       = 10;
    286 
    287   /**
    288    * Sets SMTP class debugging on or off.
    289    * @var bool
    290    */
    291   public $SMTPDebug     = false;
    292 
    293   /**
    294    * Sets the function/method to use for debugging output.
    295    * Right now we only honor "echo" or "error_log"
    296    * @var string
    297    */
    298   public $Debugoutput     = "echo";
    299 
    300   /**
    301    * Prevents the SMTP connection from being closed after each mail
    302    * sending.  If this is set to true then to close the connection
    303    * requires an explicit call to SmtpClose().
    304    * @var bool
    305    */
    306   public $SMTPKeepAlive = false;
    307 
    308   /**
    309    * Provides the ability to have the TO field process individual
    310    * emails, instead of sending to entire TO addresses
    311    * @var bool
    312    */
    313   public $SingleTo      = false;
    314 
    315    /**
    316    * If SingleTo is true, this provides the array to hold the email addresses
    317    * @var bool
    318    */
    319   public $SingleToArray = array();
    320 
    321  /**
    322    * Provides the ability to change the generic line ending
    323    * NOTE: The default remains '\n'. We force CRLF where we KNOW
    324    *        it must be used via self::CRLF
    325    * @var string
    326    */
    327   public $LE              = "\n";
    328 
    329    /**
    330    * Used with DKIM Signing
    331    * required parameter if DKIM is enabled
    332    *
    333    * domain selector example domainkey
    334    * @var string
    335    */
    336   public $DKIM_selector   = '';
    337 
    338   /**
    339    * Used with DKIM Signing
    340    * required if DKIM is enabled, in format of email address 'you@yourdomain.com' typically used as the source of the email
    341    * @var string
    342    */
    343   public $DKIM_identity   = '';
    344 
    345   /**
    346    * Used with DKIM Signing
    347    * optional parameter if your private key requires a passphras
    348    * @var string
    349    */
    350   public $DKIM_passphrase   = '';
    351 
    352   /**
    353    * Used with DKIM Singing
    354    * required if DKIM is enabled, in format of email address 'domain.com'
    355    * @var string
    356    */
    357   public $DKIM_domain     = '';
    358 
    359   /**
    360    * Used with DKIM Signing
    361    * required if DKIM is enabled, path to private key file
    362    * @var string
    363    */
    364   public $DKIM_private    = '';
    365 
    366   /**
    367    * Callback Action function name.
    368    * The function that handles the result of the send email action.
    369    * It is called out by Send() for each email sent.
    370    *
    371    * Value can be:
    372    * - 'function_name' for function names
    373    * - 'Class::Method' for static method calls
    374    * - array($object, 'Method') for calling methods on $object
    375    * See http://php.net/is_callable manual page for more details.
    376    *
    377    * Parameters:
    378    *   bool    $result        result of the send action
    379    *   string  $to            email address of the recipient
    380    *   string  $cc            cc email addresses
    381    *   string  $bcc           bcc email addresses
    382    *   string  $subject       the subject
    383    *   string  $body          the email body
    384    *   string  $from          email address of sender
    385    * @var string
    386    */
    387   public $action_function = ''; //'callbackAction';
    388 
    389   /**
    390    * Sets the PHPMailer Version number
    391    * @var string
    392    */
    393   public $Version         = '5.2.4';
    394 
    395   /**
    396    * What to use in the X-Mailer header
    397    * @var string NULL for default, whitespace for None, or actual string to use
    398    */
    399   public $XMailer         = '';
    400 
    401   /////////////////////////////////////////////////
    402   // PROPERTIES, PRIVATE AND PROTECTED
    403   /////////////////////////////////////////////////
    404 
    405   /**
    406    * @var SMTP An instance of the SMTP sender class
    407    * @access protected
    408    */
    409   protected   $smtp           = null;
    410   /**
    411    * @var array An array of 'to' addresses
    412    * @access protected
    413    */
    414   protected   $to             = array();
    415   /**
    416    * @var array An array of 'cc' addresses
    417    * @access protected
    418    */
    419   protected   $cc             = array();
    420   /**
    421    * @var array An array of 'bcc' addresses
    422    * @access protected
    423    */
    424   protected   $bcc            = array();
    425   /**
    426    * @var array An array of reply-to name and address
    427    * @access protected
    428    */
    429   protected   $ReplyTo        = array();
    430   /**
    431    * @var array An array of all kinds of addresses: to, cc, bcc, replyto
    432    * @access protected
    433    */
    434   protected   $all_recipients = array();
    435   /**
    436    * @var array An array of attachments
    437    * @access protected
    438    */
    439   protected   $attachment     = array();
    440   /**
    441    * @var array An array of custom headers
    442    * @access protected
    443    */
    444   protected   $CustomHeader   = array();
    445   /**
    446    * @var string The message's MIME type
    447    * @access protected
    448    */
    449   protected   $message_type   = '';
    450   /**
    451    * @var array An array of MIME boundary strings
    452    * @access protected
    453    */
    454   protected   $boundary       = array();
    455   /**
    456    * @var array An array of available languages
    457    * @access protected
    458    */
    459   protected   $language       = array();
    460   /**
    461    * @var integer The number of errors encountered
    462    * @access protected
    463    */
    464   protected   $error_count    = 0;
    465   /**
    466    * @var string The filename of a DKIM certificate file
    467    * @access protected
    468    */
    469   protected   $sign_cert_file = '';
    470   /**
    471    * @var string The filename of a DKIM key file
    472    * @access protected
    473    */
    474   protected   $sign_key_file  = '';
    475   /**
    476    * @var string The password of a DKIM key
    477    * @access protected
    478    */
    479   protected   $sign_key_pass  = '';
    480   /**
    481    * @var boolean Whether to throw exceptions for errors
    482    * @access protected
    483    */
    484   protected   $exceptions     = false;
    485 
    486   /////////////////////////////////////////////////
    487   // CONSTANTS
    488   /////////////////////////////////////////////////
    489 
    490   const STOP_MESSAGE  = 0; // message only, continue processing
    491   const STOP_CONTINUE = 1; // message?, likely ok to continue processing
    492   const STOP_CRITICAL = 2; // message, plus full stop, critical error reached
    493   const CRLF = "\r\n";     // SMTP RFC specified EOL
    494  
    495   /////////////////////////////////////////////////
    496   // METHODS, VARIABLES
    497   /////////////////////////////////////////////////
    498 
    499   /**
    500    * Calls actual mail() function, but in a safe_mode aware fashion
    501    * Also, unless sendmail_path points to sendmail (or something that
    502    * claims to be sendmail), don't pass params (not a perfect fix,
    503    * but it will do)
    504    * @param string $to To
    505    * @param string $subject Subject
    506    * @param string $body Message Body
    507    * @param string $header Additional Header(s)
    508    * @param string $params Params
    509    * @access private
    510    * @return bool
    511    */
    512   private function mail_passthru($to, $subject, $body, $header, $params) {
    513     if ( ini_get('safe_mode') || !($this->UseSendmailOptions) ) {
    514         $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($subject)), $body, $header);
    515     } else {
    516         $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($subject)), $body, $header, $params);
    517     }
    518     return $rt;
    519   }
    520 
    521   /**
    522    * Outputs debugging info via user-defined method
    523    * @param string $str
    524    */
    525   private function edebug($str) {
    526     if ($this->Debugoutput == "error_log") {
    527         error_log($str);
    528     } else {
    529         echo $str;
    530     }
    531   }
    532 
    533   /**
    534    * Constructor
    535    * @param boolean $exceptions Should we throw external exceptions?
    536    */
    537   public function __construct($exceptions = false) {
    538     $this->exceptions = ($exceptions == true);
    539   }
    540 
    541   /**
    542    * Sets message type to HTML.
    543    * @param bool $ishtml
    544    * @return void
    545    */
    546   public function IsHTML($ishtml = true) {
    547     if ($ishtml) {
    548       $this->ContentType = 'text/html';
    549     } else {
    550       $this->ContentType = 'text/plain';
    551     }
    552   }
    553 
    554   /**
    555    * Sets Mailer to send message using SMTP.
    556    * @return void
    557    */
    558   public function IsSMTP() {
    559     $this->Mailer = 'smtp';
    560   }
    561 
    562   /**
    563    * Sets Mailer to send message using PHP mail() function.
    564    * @return void
    565    */
    566   public function IsMail() {
    567     $this->Mailer = 'mail';
    568   }
    569 
    570   /**
    571    * Sets Mailer to send message using the $Sendmail program.
    572    * @return void
    573    */
    574   public function IsSendmail() {
    575     if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
    576       $this->Sendmail = '/var/qmail/bin/sendmail';
    577     }
    578     $this->Mailer = 'sendmail';
    579   }
    580 
    581   /**
    582    * Sets Mailer to send message using the qmail MTA.
    583    * @return void
    584    */
    585   public function IsQmail() {
    586     if (stristr(ini_get('sendmail_path'), 'qmail')) {
    587       $this->Sendmail = '/var/qmail/bin/sendmail';
    588     }
    589     $this->Mailer = 'sendmail';
    590   }
    591 
    592   /////////////////////////////////////////////////
    593   // METHODS, RECIPIENTS
    594   /////////////////////////////////////////////////
    595 
    596   /**
    597    * Adds a "To" address.
    598    * @param string $address
    599    * @param string $name
    600    * @return boolean true on success, false if address already used
    601    */
    602   public function AddAddress($address, $name = '') {
    603     return $this->AddAnAddress('to', $address, $name);
    604   }
    605 
    606   /**
    607    * Adds a "Cc" address.
    608    * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
    609    * @param string $address
    610    * @param string $name
    611    * @return boolean true on success, false if address already used
    612    */
    613   public function AddCC($address, $name = '') {
    614     return $this->AddAnAddress('cc', $address, $name);
    615   }
    616 
    617   /**
    618    * Adds a "Bcc" address.
    619    * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
    620    * @param string $address
    621    * @param string $name
    622    * @return boolean true on success, false if address already used
    623    */
    624   public function AddBCC($address, $name = '') {
    625     return $this->AddAnAddress('bcc', $address, $name);
    626   }
    627 
    628   /**
    629    * Adds a "Reply-to" address.
    630    * @param string $address
    631    * @param string $name
    632    * @return boolean
    633    */
    634   public function AddReplyTo($address, $name = '') {
    635     return $this->AddAnAddress('Reply-To', $address, $name);
    636   }
    637 
    638   /**
    639    * Adds an address to one of the recipient arrays
    640    * Addresses that have been added already return false, but do not throw exceptions
    641    * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
    642    * @param string $address The email address to send to
    643    * @param string $name
    644    * @throws phpmailerException
    645    * @return boolean true on success, false if address already used or invalid in some way
    646    * @access protected
    647    */
    648   protected function AddAnAddress($kind, $address, $name = '') {
    649     if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
    650       $this->SetError($this->Lang('Invalid recipient array').': '.$kind);
    651       if ($this->exceptions) {
    652         throw new phpmailerException('Invalid recipient array: ' . $kind);
    653       }
    654       if ($this->SMTPDebug) {
    655         $this->edebug($this->Lang('Invalid recipient array').': '.$kind);
    656       }
    657       return false;
    658     }
    659     $address = trim($address);
    660     $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
    661     if (!$this->ValidateAddress($address)) {
    662       $this->SetError($this->Lang('invalid_address').': '. $address);
    663       if ($this->exceptions) {
    664         throw new phpmailerException($this->Lang('invalid_address').': '.$address);
    665       }
    666       if ($this->SMTPDebug) {
    667         $this->edebug($this->Lang('invalid_address').': '.$address);
    668       }
    669       return false;
    670     }
    671     if ($kind != 'Reply-To') {
    672       if (!isset($this->all_recipients[strtolower($address)])) {
    673         array_push($this->$kind, array($address, $name));
    674         $this->all_recipients[strtolower($address)] = true;
    675         return true;
    676       }
    677     } else {
    678       if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
    679         $this->ReplyTo[strtolower($address)] = array($address, $name);
    680       return true;
    681     }
    682   }
    683   return false;
    684 }
    685 
    686 /**
    687  * Set the From and FromName properties
    688  * @param string $address
    689  * @param string $name
    690  * @param int $auto Also set Reply-To and Sender
    691    * @throws phpmailerException
    692  * @return boolean
    693  */
    694   public function SetFrom($address, $name = '', $auto = 1) {
    695     $address = trim($address);
    696     $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
    697     if (!$this->ValidateAddress($address)) {
    698       $this->SetError($this->Lang('invalid_address').': '. $address);
    699       if ($this->exceptions) {
    700         throw new phpmailerException($this->Lang('invalid_address').': '.$address);
    701       }
    702       if ($this->SMTPDebug) {
    703         $this->edebug($this->Lang('invalid_address').': '.$address);
    704       }
    705       return false;
    706     }
    707     $this->From = $address;
    708     $this->FromName = $name;
    709     if ($auto) {
    710       if (empty($this->ReplyTo)) {
    711         $this->AddAnAddress('Reply-To', $address, $name);
    712       }
    713       if (empty($this->Sender)) {
    714         $this->Sender = $address;
    715       }
    716     }
    717     return true;
    718   }
    719 
    720   /**
    721    * Check that a string looks roughly like an email address should
    722    * Static so it can be used without instantiation, public so people can overload
    723    * Conforms to RFC5322: Uses *correct* regex on which FILTER_VALIDATE_EMAIL is
    724    * based; So why not use FILTER_VALIDATE_EMAIL? Because it was broken to
    725    * not allow a@b type valid addresses :(
    726    * Some Versions of PHP break on the regex though, likely due to PCRE, so use
    727    * the older validation method for those users. (http://php.net/manual/en/pcre.installation.php)
    728    * @link http://squiloople.com/2009/12/20/email-address-validation/
    729    * @copyright regex Copyright Michael Rushton 2009-10 | http://squiloople.com/ | Feel free to use and redistribute this code. But please keep this copyright notice.
    730    * @param string $address The email address to check
    731    * @return boolean
    732    * @static
    733    * @access public
    734    */
    735   public static function ValidateAddress($address) {
    736         if ((defined('PCRE_VERSION')) && (version_compare(PCRE_VERSION, '8.0') >= 0)) {
    737           return preg_match('/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[     ])+|(?>[        ]*\x0D\x0A)?[   ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){7,})((?6)(?>:(?6)){0,5})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){5,})(?8)?::(?>((?6)(?>:(?6)){0,3}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', $address);
    738         } elseif (function_exists('filter_var')) { //Introduced in PHP 5.2
    739         if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
    740           return false;
    741         } else {
    742           return true;
    743         }
    744     } else {
    745         return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
    746         }
    747   }
    748 
    749   /////////////////////////////////////////////////
    750   // METHODS, MAIL SENDING
    751   /////////////////////////////////////////////////
    752 
    753   /**
    754    * Creates message and assigns Mailer. If the message is
    755    * not sent successfully then it returns false.  Use the ErrorInfo
    756    * variable to view description of the error.
    757    * @throws phpmailerException
    758    * @return bool
    759    */
    760   public function Send() {
    761     try {
    762       if(!$this->PreSend()) return false;
    763       return $this->PostSend();
    764     } catch (phpmailerException $e) {
    765       $this->mailHeader = '';
    766       $this->SetError($e->getMessage());
    767       if ($this->exceptions) {
    768         throw $e;
    769       }
    770       return false;
    771     }
    772   }
    773 
    774   /**
    775    * Prep mail by constructing all message entities
    776    * @throws phpmailerException
    777    * @return bool
    778    */
    779   public function PreSend() {
    780     try {
    781       $this->mailHeader = "";
    782       if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
    783         throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL);
    784       }
    785 
    786       // Set whether the message is multipart/alternative
    787       if(!empty($this->AltBody)) {
    788         $this->ContentType = 'multipart/alternative';
    789       }
    790 
    791       $this->error_count = 0; // reset errors
    792       $this->SetMessageType();
    793       //Refuse to send an empty message
    794       if (empty($this->Body)) {
    795         throw new phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL);
    796       }
    797 
    798       $this->MIMEHeader = $this->CreateHeader();
    799       $this->MIMEBody = $this->CreateBody();
    800 
    801       // To capture the complete message when using mail(), create
    802       // an extra header list which CreateHeader() doesn't fold in
    803       if ($this->Mailer == 'mail') {
    804         if (count($this->to) > 0) {
    805           $this->mailHeader .= $this->AddrAppend("To", $this->to);
    806         } else {
    807           $this->mailHeader .= $this->HeaderLine("To", "undisclosed-recipients:;");
    808         }
    809         $this->mailHeader .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader(trim($this->Subject))));
    810         // if(count($this->cc) > 0) {
    811             // $this->mailHeader .= $this->AddrAppend("Cc", $this->cc);
    812         // }
    813       }
    814 
    815       // digitally sign with DKIM if enabled
    816       if (!empty($this->DKIM_domain) && !empty($this->DKIM_private) && !empty($this->DKIM_selector) && !empty($this->DKIM_domain) && file_exists($this->DKIM_private)) {
    817         $header_dkim = $this->DKIM_Add($this->MIMEHeader, $this->EncodeHeader($this->SecureHeader($this->Subject)), $this->MIMEBody);
    818         $this->MIMEHeader = str_replace("\r\n", "\n", $header_dkim) . $this->MIMEHeader;
    819       }
    820 
    821       return true;
    822 
    823     } catch (phpmailerException $e) {
    824       $this->SetError($e->getMessage());
    825       if ($this->exceptions) {
    826         throw $e;
    827       }
    828       return false;
    829     }
    830   }
    831 
    832   /**
    833    * Actual Email transport function
    834    * Send the email via the selected mechanism
    835    * @throws phpmailerException
    836    * @return bool
    837    */
    838   public function PostSend() {
    839     try {
    840       // Choose the mailer and send through it
    841       switch($this->Mailer) {
    842         case 'sendmail':
    843           return $this->SendmailSend($this->MIMEHeader, $this->MIMEBody);
    844         case 'smtp':
    845           return $this->SmtpSend($this->MIMEHeader, $this->MIMEBody);
    846         case 'mail':
    847           return $this->MailSend($this->MIMEHeader, $this->MIMEBody);
    848         default:
    849           return $this->MailSend($this->MIMEHeader, $this->MIMEBody);
    850       }
    851     } catch (phpmailerException $e) {
    852       $this->SetError($e->getMessage());
    853       if ($this->exceptions) {
    854         throw $e;
    855       }
    856       if ($this->SMTPDebug) {
    857         $this->edebug($e->getMessage()."\n");
    858       }
    859     }
    860     return false;
    861   }
    862 
    863   /**
    864    * Sends mail using the $Sendmail program.
    865    * @param string $header The message headers
    866    * @param string $body The message body
    867    * @throws phpmailerException
    868    * @access protected
    869    * @return bool
    870    */
    871   protected function SendmailSend($header, $body) {
    872     if ($this->Sender != '') {
    873       $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
    874     } else {
    875       $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
    876     }
    877     if ($this->SingleTo === true) {
    878       foreach ($this->SingleToArray as $val) {
    879         if(!@$mail = popen($sendmail, 'w')) {
    880           throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
    881         }
    882         fputs($mail, "To: " . $val . "\n");
    883         fputs($mail, $header);
    884         fputs($mail, $body);
    885         $result = pclose($mail);
    886         // implement call back function if it exists
    887         $isSent = ($result == 0) ? 1 : 0;
    888         $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
    889         if($result != 0) {
    890           throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
    891         }
    892       }
    893     } else {
    894       if(!@$mail = popen($sendmail, 'w')) {
    895         throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
    896       }
    897       fputs($mail, $header);
    898       fputs($mail, $body);
    899       $result = pclose($mail);
    900       // implement call back function if it exists
    901       $isSent = ($result == 0) ? 1 : 0;
    902       $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body);
    903       if($result != 0) {
    904         throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
    905       }
    906     }
    907     return true;
    908   }
    909 
    910   /**
    911    * Sends mail using the PHP mail() function.
    912    * @param string $header The message headers
    913    * @param string $body The message body
    914      * @throws phpmailerException
    915    * @access protected
    916    * @return bool
    917    */
    918   protected function MailSend($header, $body) {
    919     $toArr = array();
    920     foreach($this->to as $t) {
    921       $toArr[] = $this->AddrFormat($t);
    922     }
    923     $to = implode(', ', $toArr);
    924 
    925     if (empty($this->Sender)) {
    926       $params = " ";
    927     } else {
    928       $params = sprintf("-f%s", $this->Sender);
    929     }
    930     if ($this->Sender != '' and !ini_get('safe_mode')) {
    931       $old_from = ini_get('sendmail_from');
    932       ini_set('sendmail_from', $this->Sender);
    933     }
    934       $rt = false;
    935     if ($this->SingleTo === true && count($toArr) > 1) {
    936       foreach ($toArr as $val) {
    937         $rt = $this->mail_passthru($val, $this->Subject, $body, $header, $params);
    938         // implement call back function if it exists
    939         $isSent = ($rt == 1) ? 1 : 0;
    940         $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
    941       }
    942     } else {
    943       $rt = $this->mail_passthru($to, $this->Subject, $body, $header, $params);
    944       // implement call back function if it exists
    945       $isSent = ($rt == 1) ? 1 : 0;
    946       $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
    947     }
    948     if (isset($old_from)) {
    949       ini_set('sendmail_from', $old_from);
    950     }
    951     if(!$rt) {
    952       throw new phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL);
    953     }
    954     return true;
    955   }
    956 
    957   /**
    958    * Sends mail via SMTP using PhpSMTP
    959    * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
    960    * @param string $header The message headers
    961    * @param string $body The message body
    962    * @throws phpmailerException
    963    * @uses SMTP
    964    * @access protected
    965    * @return bool
    966    */
    967   protected function SmtpSend($header, $body) {
    968     require_once $this->PluginDir . 'class-smtp.php';
    969     $bad_rcpt = array();
    970 
    971     if(!$this->SmtpConnect()) {
    972       throw new phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL);
    973     }
    974     $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
    975     if(!$this->smtp->Mail($smtp_from)) {
    976       $this->SetError($this->Lang('from_failed') . $smtp_from . " : " . implode(",",$this->smtp->getError())) ;
    977       throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
    978     }
    979 
    980     // Attempt to send attach all recipients
    981     foreach($this->to as $to) {
    982       if (!$this->smtp->Recipient($to[0])) {
    983         $bad_rcpt[] = $to[0];
    984         // implement call back function if it exists
    985         $isSent = 0;
    986         $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body);
    987       } else {
    988         // implement call back function if it exists
    989         $isSent = 1;
    990         $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body);
    991       }
    992     }
    993     foreach($this->cc as $cc) {
    994       if (!$this->smtp->Recipient($cc[0])) {
    995         $bad_rcpt[] = $cc[0];
    996         // implement call back function if it exists
    997         $isSent = 0;
    998         $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body);
    999       } else {
    1000         // implement call back function if it exists
    1001         $isSent = 1;
    1002         $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body);
    1003       }
    1004     }
    1005     foreach($this->bcc as $bcc) {
    1006       if (!$this->smtp->Recipient($bcc[0])) {
    1007         $bad_rcpt[] = $bcc[0];
    1008         // implement call back function if it exists
    1009         $isSent = 0;
    1010         $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body);
    1011       } else {
    1012         // implement call back function if it exists
    1013         $isSent = 1;
    1014         $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body);
    1015       }
    1016     }
    1017 
    1018 
    1019     if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses
    1020       $badaddresses = implode(', ', $bad_rcpt);
    1021       throw new phpmailerException($this->Lang('recipients_failed') . $badaddresses);
    1022     }
    1023     if(!$this->smtp->Data($header . $body)) {
    1024       throw new phpmailerException($this->Lang('data_not_accepted'), self::STOP_CRITICAL);
    1025     }
    1026     if($this->SMTPKeepAlive == true) {
    1027       $this->smtp->Reset();
    1028     } else {
    1029         $this->smtp->Quit();
    1030         $this->smtp->Close();
    1031     }
    1032     return true;
    1033   }
    1034 
    1035   /**
    1036    * Initiates a connection to an SMTP server.
    1037    * Returns false if the operation failed.
    1038    * @uses SMTP
    1039    * @access public
    1040    * @throws phpmailerException
    1041    * @return bool
    1042    */
    1043   public function SmtpConnect() {
    1044     if(is_null($this->smtp)) {
    1045       $this->smtp = new SMTP;
    1046     }
    1047 
    1048     $this->smtp->Timeout = $this->Timeout;
    1049     $this->smtp->do_debug = $this->SMTPDebug;
    1050     $hosts = explode(';', $this->Host);
    1051     $index = 0;
    1052     $connection = $this->smtp->Connected();
    1053 
    1054     // Retry while there is no connection
    1055     try {
    1056       while($index < count($hosts) && !$connection) {
    1057         $hostinfo = array();
    1058         if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {
    1059           $host = $hostinfo[1];
    1060           $port = $hostinfo[2];
    1061         } else {
    1062           $host = $hosts[$index];
    1063           $port = $this->Port;
    1064         }
    1065 
    1066         $tls = ($this->SMTPSecure == 'tls');
    1067         $ssl = ($this->SMTPSecure == 'ssl');
    1068 
    1069         if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) {
    1070 
    1071           $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname());
    1072           $this->smtp->Hello($hello);
    1073 
    1074           if ($tls) {
    1075             if (!$this->smtp->StartTLS()) {
    1076               throw new phpmailerException($this->Lang('connect_host'));
    1077             }
    1078 
    1079             //We must resend HELO after tls negotiation
    1080             $this->smtp->Hello($hello);
    1081           }
    1082 
    1083           $connection = true;
    1084           if ($this->SMTPAuth) {
    1085             if (!$this->smtp->Authenticate($this->Username, $this->Password, $this->AuthType,
    1086                                            $this->Realm, $this->Workstation)) {
    1087               throw new phpmailerException($this->Lang('authenticate'));
    1088             }
    1089           }
    1090         }
    1091         $index++;
    1092       if (!$connection) {
    1093         throw new phpmailerException($this->Lang('connect_host'));
    1094       }
    1095       }
    1096     } catch (phpmailerException $e) {
    1097       $this->smtp->Reset();
    1098       if ($this->exceptions) {
    1099         throw $e;
    1100       }
    1101     }
    1102     return true;
    1103   }
    1104 
    1105   /**
    1106    * Closes the active SMTP session if one exists.
    1107    * @return void
    1108    */
    1109   public function SmtpClose() {
    1110     if ($this->smtp !== null) {
    1111       if($this->smtp->Connected()) {
    1112         $this->smtp->Quit();
    1113         $this->smtp->Close();
    1114       }
    1115     }
    1116   }
    1117 
    1118   /**
    1119   * Sets the language for all class error messages.
    1120   * Returns false if it cannot load the language file.  The default language is English.
    1121   * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br")
    1122   * @param string $lang_path Path to the language file directory
    1123    * @return bool
    1124   * @access public
    1125   */
    1126   function SetLanguage($langcode = 'en', $lang_path = 'language/') {
    1127     //Define full set of translatable strings
    1128     $PHPMAILER_LANG = array(
    1129       'authenticate'         => 'SMTP Error: Could not authenticate.',
    1130       'connect_host'         => 'SMTP Error: Could not connect to SMTP host.',
    1131       'data_not_accepted'    => 'SMTP Error: Data not accepted.',
    1132       'empty_message'        => 'Message body empty',
    1133       'encoding'             => 'Unknown encoding: ',
    1134       'execute'              => 'Could not execute: ',
    1135       'file_access'          => 'Could not access file: ',
    1136       'file_open'            => 'File Error: Could not open file: ',
    1137       'from_failed'          => 'The following From address failed: ',
    1138       'instantiate'          => 'Could not instantiate mail function.',
    1139       'invalid_address'      => 'Invalid address',
    1140       'mailer_not_supported' => ' mailer is not supported.',
    1141       'provide_address'      => 'You must provide at least one recipient email address.',
    1142       'recipients_failed'    => 'SMTP Error: The following recipients failed: ',
    1143       'signing'              => 'Signing Error: ',
    1144       'smtp_connect_failed'  => 'SMTP Connect() failed.',
    1145       'smtp_error'           => 'SMTP server error: ',
    1146       'variable_set'         => 'Cannot set or reset variable: '
    1147     );
    1148     //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"!
    1149     $l = true;
    1150     if ($langcode != 'en') { //There is no English translation file
    1151       $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php';
    1152     }
    1153     $this->language = $PHPMAILER_LANG;
    1154     return ($l == true); //Returns false if language not found
    1155   }
    1156 
    1157   /**
    1158   * Return the current array of language strings
    1159   * @return array
    1160   */
    1161   public function GetTranslations() {
    1162     return $this->language;
    1163   }
    1164 
    1165   /////////////////////////////////////////////////
    1166   // METHODS, MESSAGE CREATION
    1167   /////////////////////////////////////////////////
    1168 
    1169   /**
    1170    * Creates recipient headers.
    1171    * @access public
    1172    * @param string $type
    1173    * @param array $addr
    1174    * @return string
    1175    */
    1176   public function AddrAppend($type, $addr) {
    1177     $addr_str = $type . ': ';
    1178     $addresses = array();
    1179     foreach ($addr as $a) {
    1180       $addresses[] = $this->AddrFormat($a);
    1181     }
    1182     $addr_str .= implode(', ', $addresses);
    1183     $addr_str .= $this->LE;
    1184 
    1185     return $addr_str;
    1186   }
    1187 
    1188   /**
    1189    * Formats an address correctly.
    1190    * @access public
    1191    * @param string $addr
    1192    * @return string
    1193    */
    1194   public function AddrFormat($addr) {
    1195     if (empty($addr[1])) {
    1196       return $this->SecureHeader($addr[0]);
    1197     } else {
    1198       return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
    1199     }
    1200   }
    1201 
    1202   /**
    1203    * Wraps message for use with mailers that do not
    1204    * automatically perform wrapping and for quoted-printable.
    1205    * Original written by philippe.
    1206    * @param string $message The message to wrap
    1207    * @param integer $length The line length to wrap to
    1208    * @param boolean $qp_mode Whether to run in Quoted-Printable mode
    1209    * @access public
    1210    * @return string
    1211    */
    1212   public function WrapText($message, $length, $qp_mode = false) {
    1213     $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
    1214     // If utf-8 encoding is used, we will need to make sure we don't
    1215     // split multibyte characters when we wrap
    1216     $is_utf8 = (strtolower($this->CharSet) == "utf-8");
    1217     $lelen = strlen($this->LE);
    1218     $crlflen = strlen(self::CRLF);
    1219 
    1220     $message = $this->FixEOL($message);
    1221     if (substr($message, -$lelen) == $this->LE) {
    1222       $message = substr($message, 0, -$lelen);
    1223     }
    1224 
    1225     $line = explode($this->LE, $message);   // Magic. We know FixEOL uses $LE
    1226     $message = '';
    1227     for ($i = 0 ;$i < count($line); $i++) {
    1228       $line_part = explode(' ', $line[$i]);
    1229       $buf = '';
    1230       for ($e = 0; $e<count($line_part); $e++) {
    1231         $word = $line_part[$e];
    1232         if ($qp_mode and (strlen($word) > $length)) {
    1233           $space_left = $length - strlen($buf) - $crlflen;
    1234           if ($e != 0) {
    1235             if ($space_left > 20) {
    1236               $len = $space_left;
    1237               if ($is_utf8) {
    1238                 $len = $this->UTF8CharBoundary($word, $len);
    1239               } elseif (substr($word, $len - 1, 1) == "=") {
    1240                 $len--;
    1241               } elseif (substr($word, $len - 2, 1) == "=") {
    1242                 $len -= 2;
    1243               }
    1244               $part = substr($word, 0, $len);
    1245               $word = substr($word, $len);
    1246               $buf .= ' ' . $part;
    1247               $message .= $buf . sprintf("=%s", self::CRLF);
    1248             } else {
    1249               $message .= $buf . $soft_break;
    1250             }
    1251             $buf = '';
    1252           }
    1253           while (strlen($word) > 0) {
    1254             $len = $length;
    1255             if ($is_utf8) {
    1256               $len = $this->UTF8CharBoundary($word, $len);
    1257             } elseif (substr($word, $len - 1, 1) == "=") {
    1258               $len--;
    1259             } elseif (substr($word, $len - 2, 1) == "=") {
    1260               $len -= 2;
    1261             }
    1262             $part = substr($word, 0, $len);
    1263             $word = substr($word, $len);
    1264 
    1265             if (strlen($word) > 0) {
    1266               $message .= $part . sprintf("=%s", self::CRLF);
    1267             } else {
    1268               $buf = $part;
    1269             }
    1270           }
    1271         } else {
    1272           $buf_o = $buf;
    1273           $buf .= ($e == 0) ? $word : (' ' . $word);
    12747
    1275           if (strlen($buf) > $length and $buf_o != '') {
    1276             $message .= $buf_o . $soft_break;
    1277             $buf = $word;
    1278           }
    1279         }
    1280       }
    1281       $message .= $buf . self::CRLF;
    1282     }
    1283 
    1284     return $message;
    1285   }
    1286 
    1287   /**
    1288    * Finds last character boundary prior to maxLength in a utf-8
    1289    * quoted (printable) encoded string.
    1290    * Original written by Colin Brown.
    1291    * @access public
    1292    * @param string $encodedText utf-8 QP text
    1293    * @param int    $maxLength   find last character boundary prior to this length
    1294    * @return int
    1295    */
    1296   public function UTF8CharBoundary($encodedText, $maxLength) {
    1297     $foundSplitPos = false;
    1298     $lookBack = 3;
    1299     while (!$foundSplitPos) {
    1300       $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
    1301       $encodedCharPos = strpos($lastChunk, "=");
    1302       if ($encodedCharPos !== false) {
    1303         // Found start of encoded character byte within $lookBack block.
    1304         // Check the encoded byte value (the 2 chars after the '=')
    1305         $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
    1306         $dec = hexdec($hex);
    1307         if ($dec < 128) { // Single byte character.
    1308           // If the encoded char was found at pos 0, it will fit
    1309           // otherwise reduce maxLength to start of the encoded char
    1310           $maxLength = ($encodedCharPos == 0) ? $maxLength :
    1311           $maxLength - ($lookBack - $encodedCharPos);
    1312           $foundSplitPos = true;
    1313         } elseif ($dec >= 192) { // First byte of a multi byte character
    1314           // Reduce maxLength to split at start of character
    1315           $maxLength = $maxLength - ($lookBack - $encodedCharPos);
    1316           $foundSplitPos = true;
    1317         } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
    1318           $lookBack += 3;
    1319         }
    1320       } else {
    1321         // No encoded character found
    1322         $foundSplitPos = true;
    1323       }
    1324     }
    1325     return $maxLength;
    1326   }
    1327 
    1328 
    1329   /**
    1330    * Set the body wrapping.
    1331    * @access public
    1332    * @return void
    1333    */
    1334   public function SetWordWrap() {
    1335     if($this->WordWrap < 1) {
    1336       return;
    1337     }
    1338 
    1339     switch($this->message_type) {
    1340       case 'alt':
    1341       case 'alt_inline':
    1342       case 'alt_attach':
    1343       case 'alt_inline_attach':
    1344         $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
    1345         break;
    1346       default:
    1347         $this->Body = $this->WrapText($this->Body, $this->WordWrap);
    1348         break;
    1349     }
    1350   }
    1351 
    1352   /**
    1353    * Assembles message header.
    1354    * @access public
    1355    * @return string The assembled header
    1356    */
    1357   public function CreateHeader() {
    1358     $result = '';
    1359 
    1360     // Set the boundaries
    1361     $uniq_id = md5(uniqid(time()));
    1362     $this->boundary[1] = 'b1_' . $uniq_id;
    1363     $this->boundary[2] = 'b2_' . $uniq_id;
    1364     $this->boundary[3] = 'b3_' . $uniq_id;
    1365 
    1366     if ($this->MessageDate == '') {
    1367       $result .= $this->HeaderLine('Date', self::RFCDate());
    1368     } else {
    1369       $result .= $this->HeaderLine('Date', $this->MessageDate);
    1370     }
    1371 
    1372     if ($this->ReturnPath) {
    1373       $result .= $this->HeaderLine('Return-Path', trim($this->ReturnPath));
    1374     } elseif ($this->Sender == '') {
    1375       $result .= $this->HeaderLine('Return-Path', trim($this->From));
    1376     } else {
    1377       $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
    1378     }
    1379 
    1380     // To be created automatically by mail()
    1381     if($this->Mailer != 'mail') {
    1382       if ($this->SingleTo === true) {
    1383         foreach($this->to as $t) {
    1384           $this->SingleToArray[] = $this->AddrFormat($t);
    1385         }
    1386       } else {
    1387         if(count($this->to) > 0) {
    1388           $result .= $this->AddrAppend('To', $this->to);
    1389         } elseif (count($this->cc) == 0) {
    1390           $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
    1391         }
    1392       }
    1393     }
    1394 
    1395     $from = array();
    1396     $from[0][0] = trim($this->From);
    1397     $from[0][1] = $this->FromName;
    1398     $result .= $this->AddrAppend('From', $from);
    1399 
    1400     // sendmail and mail() extract Cc from the header before sending
    1401     if(count($this->cc) > 0) {
    1402       $result .= $this->AddrAppend('Cc', $this->cc);
    1403     }
    1404 
    1405     // sendmail and mail() extract Bcc from the header before sending
    1406     if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
    1407       $result .= $this->AddrAppend('Bcc', $this->bcc);
    1408     }
    1409 
    1410     if(count($this->ReplyTo) > 0) {
    1411       $result .= $this->AddrAppend('Reply-To', $this->ReplyTo);
    1412     }
    1413 
    1414     // mail() sets the subject itself
    1415     if($this->Mailer != 'mail') {
    1416       $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
    1417     }
    1418 
    1419     if($this->MessageID != '') {
    1420       $result .= $this->HeaderLine('Message-ID', $this->MessageID);
    1421     } else {
    1422       $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
    1423     }
    1424     $result .= $this->HeaderLine('X-Priority', $this->Priority);
    1425     if ($this->XMailer == '') {
    1426         $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (http://code.google.com/a/apache-extras.org/p/phpmailer/)');
    1427     } else {
    1428       $myXmailer = trim($this->XMailer);
    1429       if ($myXmailer) {
    1430         $result .= $this->HeaderLine('X-Mailer', $myXmailer);
    1431       }
    1432     }
    1433 
    1434     if($this->ConfirmReadingTo != '') {
    1435       $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
    1436     }
    1437 
    1438     // Add custom headers
    1439     for($index = 0; $index < count($this->CustomHeader); $index++) {
    1440       $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
    1441     }
    1442     if (!$this->sign_key_file) {
    1443       $result .= $this->HeaderLine('MIME-Version', '1.0');
    1444       $result .= $this->GetMailMIME();
    1445     }
    1446 
    1447     return $result;
    1448   }
    1449 
    1450   /**
    1451    * Returns the message MIME.
    1452    * @access public
    1453    * @return string
    1454    */
    1455   public function GetMailMIME() {
    1456     $result = '';
    1457     switch($this->message_type) {
    1458       case 'inline':
    1459         $result .= $this->HeaderLine('Content-Type', 'multipart/related;');
    1460         $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
    1461         break;
    1462       case 'attach':
    1463       case 'inline_attach':
    1464       case 'alt_attach':
    1465       case 'alt_inline_attach':
    1466         $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
    1467         $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
    1468         break;
    1469       case 'alt':
    1470       case 'alt_inline':
    1471         $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
    1472         $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
    1473         break;
    1474       default:
    1475         // Catches case 'plain': and case '':
    1476         $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
    1477         $result .= $this->TextLine('Content-Type: '.$this->ContentType.'; charset='.$this->CharSet);
    1478         break;
    1479     }
    1480 
    1481     if($this->Mailer != 'mail') {
    1482       $result .= $this->LE;
    1483     }
    1484 
    1485     return $result;
    1486   }
    1487 
    1488   /**
    1489    * Returns the MIME message (headers and body). Only really valid post PreSend().
    1490    * @access public
    1491    * @return string
    1492    */
    1493   public function GetSentMIMEMessage() {
    1494     return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
    1495   }
    1496 
    1497 
    1498   /**
    1499    * Assembles the message body.  Returns an empty string on failure.
    1500    * @access public
    1501    * @throws phpmailerException
    1502    * @return string The assembled message body
    1503    */
    1504   public function CreateBody() {
    1505     $body = '';
    1506 
    1507     if ($this->sign_key_file) {
    1508       $body .= $this->GetMailMIME().$this->LE;
    1509     }
    1510 
    1511     $this->SetWordWrap();
    1512 
    1513     switch($this->message_type) {
    1514       case 'inline':
    1515         $body .= $this->GetBoundary($this->boundary[1], '', '', '');
    1516         $body .= $this->EncodeString($this->Body, $this->Encoding);
    1517         $body .= $this->LE.$this->LE;
    1518         $body .= $this->AttachAll("inline", $this->boundary[1]);
    1519         break;
    1520       case 'attach':
    1521         $body .= $this->GetBoundary($this->boundary[1], '', '', '');
    1522         $body .= $this->EncodeString($this->Body, $this->Encoding);
    1523         $body .= $this->LE.$this->LE;
    1524         $body .= $this->AttachAll("attachment", $this->boundary[1]);
    1525         break;
    1526       case 'inline_attach':
    1527         $body .= $this->TextLine("--" . $this->boundary[1]);
    1528         $body .= $this->HeaderLine('Content-Type', 'multipart/related;');
    1529         $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"');
    1530         $body .= $this->LE;
    1531         $body .= $this->GetBoundary($this->boundary[2], '', '', '');
    1532         $body .= $this->EncodeString($this->Body, $this->Encoding);
    1533         $body .= $this->LE.$this->LE;
    1534         $body .= $this->AttachAll("inline", $this->boundary[2]);
    1535         $body .= $this->LE;
    1536         $body .= $this->AttachAll("attachment", $this->boundary[1]);
    1537         break;
    1538       case 'alt':
    1539         $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
    1540         $body .= $this->EncodeString($this->AltBody, $this->Encoding);
    1541         $body .= $this->LE.$this->LE;
    1542         $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
    1543         $body .= $this->EncodeString($this->Body, $this->Encoding);
    1544         $body .= $this->LE.$this->LE;
    1545         $body .= $this->EndBoundary($this->boundary[1]);
    1546         break;
    1547       case 'alt_inline':
    1548         $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
    1549         $body .= $this->EncodeString($this->AltBody, $this->Encoding);
    1550         $body .= $this->LE.$this->LE;
    1551         $body .= $this->TextLine("--" . $this->boundary[1]);
    1552         $body .= $this->HeaderLine('Content-Type', 'multipart/related;');
    1553         $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"');
    1554         $body .= $this->LE;
    1555         $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '');
    1556         $body .= $this->EncodeString($this->Body, $this->Encoding);
    1557         $body .= $this->LE.$this->LE;
    1558         $body .= $this->AttachAll("inline", $this->boundary[2]);
    1559         $body .= $this->LE;
    1560         $body .= $this->EndBoundary($this->boundary[1]);
    1561         break;
    1562       case 'alt_attach':
    1563         $body .= $this->TextLine("--" . $this->boundary[1]);
    1564         $body .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
    1565         $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"');
    1566         $body .= $this->LE;
    1567         $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '');
    1568         $body .= $this->EncodeString($this->AltBody, $this->Encoding);
    1569         $body .= $this->LE.$this->LE;
    1570         $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '');
    1571         $body .= $this->EncodeString($this->Body, $this->Encoding);
    1572         $body .= $this->LE.$this->LE;
    1573         $body .= $this->EndBoundary($this->boundary[2]);
    1574         $body .= $this->LE;
    1575         $body .= $this->AttachAll("attachment", $this->boundary[1]);
    1576         break;
    1577       case 'alt_inline_attach':
    1578         $body .= $this->TextLine("--" . $this->boundary[1]);
    1579         $body .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
    1580         $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"');
    1581         $body .= $this->LE;
    1582         $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '');
    1583         $body .= $this->EncodeString($this->AltBody, $this->Encoding);
    1584         $body .= $this->LE.$this->LE;
    1585         $body .= $this->TextLine("--" . $this->boundary[2]);
    1586         $body .= $this->HeaderLine('Content-Type', 'multipart/related;');
    1587         $body .= $this->TextLine("\tboundary=\"" . $this->boundary[3] . '"');
    1588         $body .= $this->LE;
    1589         $body .= $this->GetBoundary($this->boundary[3], '', 'text/html', '');
    1590         $body .= $this->EncodeString($this->Body, $this->Encoding);
    1591         $body .= $this->LE.$this->LE;
    1592         $body .= $this->AttachAll("inline", $this->boundary[3]);
    1593         $body .= $this->LE;
    1594         $body .= $this->EndBoundary($this->boundary[2]);
    1595         $body .= $this->LE;
    1596         $body .= $this->AttachAll("attachment", $this->boundary[1]);
    1597         break;
    1598       default:
    1599         // catch case 'plain' and case ''
    1600         $body .= $this->EncodeString($this->Body, $this->Encoding);
    1601         break;
    1602     }
    1603 
    1604     if ($this->IsError()) {
    1605       $body = '';
    1606     } elseif ($this->sign_key_file) {
    1607       try {
    1608         $file = tempnam('', 'mail');
    1609         file_put_contents($file, $body); //TODO check this worked
    1610         $signed = tempnam("", "signed");
    1611         if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) {
    1612           @unlink($file);
    1613           $body = file_get_contents($signed);
    1614           @unlink($signed);
    1615         } else {
    1616           @unlink($file);
    1617           @unlink($signed);
    1618           throw new phpmailerException($this->Lang("signing").openssl_error_string());
    1619         }
    1620       } catch (phpmailerException $e) {
    1621         $body = '';
    1622         if ($this->exceptions) {
    1623           throw $e;
    1624         }
    1625       }
    1626     }
    1627 
    1628     return $body;
    1629   }
    1630 
    1631   /**
    1632    * Returns the start of a message boundary.
    1633    * @access protected
    1634    * @param string $boundary
    1635    * @param string $charSet
    1636    * @param string $contentType
    1637    * @param string $encoding
    1638    * @return string
    1639    */
    1640   protected function GetBoundary($boundary, $charSet, $contentType, $encoding) {
    1641     $result = '';
    1642     if($charSet == '') {
    1643       $charSet = $this->CharSet;
    1644     }
    1645     if($contentType == '') {
    1646       $contentType = $this->ContentType;
    1647     }
    1648     if($encoding == '') {
    1649       $encoding = $this->Encoding;
    1650     }
    1651     $result .= $this->TextLine('--' . $boundary);
    1652     $result .= sprintf("Content-Type: %s; charset=%s", $contentType, $charSet);
    1653     $result .= $this->LE;
    1654     $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
    1655     $result .= $this->LE;
    1656 
    1657     return $result;
    1658   }
    1659 
    1660   /**
    1661    * Returns the end of a message boundary.
    1662    * @access protected
    1663    * @param string $boundary
    1664    * @return string
    1665    */
    1666   protected function EndBoundary($boundary) {
    1667     return $this->LE . '--' . $boundary . '--' . $this->LE;
    1668   }
    1669 
    1670   /**
    1671    * Sets the message type.
    1672    * @access protected
    1673    * @return void
    1674    */
    1675   protected function SetMessageType() {
    1676     $this->message_type = array();
    1677     if($this->AlternativeExists()) $this->message_type[] = "alt";
    1678     if($this->InlineImageExists()) $this->message_type[] = "inline";
    1679     if($this->AttachmentExists()) $this->message_type[] = "attach";
    1680     $this->message_type = implode("_", $this->message_type);
    1681     if($this->message_type == "") $this->message_type = "plain";
    1682   }
    1683 
    1684   /**
    1685    *  Returns a formatted header line.
    1686    * @access public
    1687    * @param string $name
    1688    * @param string $value
    1689    * @return string
    1690    */
    1691   public function HeaderLine($name, $value) {
    1692     return $name . ': ' . $value . $this->LE;
    1693   }
    1694 
    1695   /**
    1696    * Returns a formatted mail line.
    1697    * @access public
    1698    * @param string $value
    1699    * @return string
    1700    */
    1701   public function TextLine($value) {
    1702     return $value . $this->LE;
    1703   }
    1704 
    1705   /////////////////////////////////////////////////
    1706   // CLASS METHODS, ATTACHMENTS
    1707   /////////////////////////////////////////////////
    1708 
    1709   /**
    1710    * Adds an attachment from a path on the filesystem.
    1711    * Returns false if the file could not be found
    1712    * or accessed.
    1713    * @param string $path Path to the attachment.
    1714    * @param string $name Overrides the attachment name.
    1715    * @param string $encoding File encoding (see $Encoding).
    1716    * @param string $type File extension (MIME) type.
    1717    * @throws phpmailerException
    1718    * @return bool
    1719    */
    1720   public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
    1721     try {
    1722       if ( !@is_file($path) ) {
    1723         throw new phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE);
    1724       }
    1725       $filename = basename($path);
    1726       if ( $name == '' ) {
    1727         $name = $filename;
    1728       }
    1729 
    1730       $this->attachment[] = array(
    1731         0 => $path,
    1732         1 => $filename,
    1733         2 => $name,
    1734         3 => $encoding,
    1735         4 => $type,
    1736         5 => false,  // isStringAttachment
    1737         6 => 'attachment',
    1738         7 => 0
    1739       );
    1740 
    1741     } catch (phpmailerException $e) {
    1742       $this->SetError($e->getMessage());
    1743       if ($this->exceptions) {
    1744         throw $e;
    1745       }
    1746       if ($this->SMTPDebug) {
    1747         $this->edebug($e->getMessage()."\n");
    1748       }
    1749       if ( $e->getCode() == self::STOP_CRITICAL ) {
    1750         return false;
    1751       }
    1752     }
    1753     return true;
    1754   }
    1755 
    1756   /**
    1757   * Return the current array of attachments
    1758   * @return array
    1759   */
    1760   public function GetAttachments() {
    1761     return $this->attachment;
    1762   }
    1763 
    1764   /**
    1765    * Attaches all fs, string, and binary attachments to the message.
    1766    * Returns an empty string on failure.
    1767    * @access protected
    1768    * @param string $disposition_type
    1769    * @param string $boundary
    1770    * @return string
    1771    */
    1772   protected function AttachAll($disposition_type, $boundary) {
    1773     // Return text of body
    1774     $mime = array();
    1775     $cidUniq = array();
    1776     $incl = array();
    1777 
    1778     // Add all attachments
    1779     foreach ($this->attachment as $attachment) {
    1780       // CHECK IF IT IS A VALID DISPOSITION_FILTER
    1781       if($attachment[6] == $disposition_type) {
    1782         // Check for string attachment
    1783         $string = '';
    1784         $path = '';
    1785         $bString = $attachment[5];
    1786         if ($bString) {
    1787           $string = $attachment[0];
    1788         } else {
    1789           $path = $attachment[0];
    1790         }
    1791 
    1792         $inclhash = md5(serialize($attachment));
    1793         if (in_array($inclhash, $incl)) { continue; }
    1794         $incl[]      = $inclhash;
    1795         $filename    = $attachment[1];
    1796         $name        = $attachment[2];
    1797         $encoding    = $attachment[3];
    1798         $type        = $attachment[4];
    1799         $disposition = $attachment[6];
    1800         $cid         = $attachment[7];
    1801         if ( $disposition == 'inline' && isset($cidUniq[$cid]) ) { continue; }
    1802         $cidUniq[$cid] = true;
    1803 
    1804         $mime[] = sprintf("--%s%s", $boundary, $this->LE);
    1805         $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
    1806         $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
    1807 
    1808         if($disposition == 'inline') {
    1809           $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
    1810         }
    1811 
    1812         $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE);
    1813 
    1814         // Encode as string attachment
    1815         if($bString) {
    1816           $mime[] = $this->EncodeString($string, $encoding);
    1817           if($this->IsError()) {
    1818             return '';
    1819           }
    1820           $mime[] = $this->LE.$this->LE;
    1821         } else {
    1822           $mime[] = $this->EncodeFile($path, $encoding);
    1823           if($this->IsError()) {
    1824             return '';
    1825           }
    1826           $mime[] = $this->LE.$this->LE;
    1827         }
    1828       }
    1829     }
    1830 
    1831     $mime[] = sprintf("--%s--%s", $boundary, $this->LE);
    1832 
    1833     return implode("", $mime);
    1834   }
    1835 
    1836   /**
    1837    * Encodes attachment in requested format.
    1838    * Returns an empty string on failure.
    1839    * @param string $path The full path to the file
    1840    * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
    1841    * @throws phpmailerException
    1842    * @see EncodeFile()
    1843    * @access protected
    1844    * @return string
    1845    */
    1846   protected function EncodeFile($path, $encoding = 'base64') {
    1847     try {
    1848       if (!is_readable($path)) {
    1849         throw new phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE);
    1850       }
    1851       //  if (!function_exists('get_magic_quotes')) {
    1852       //    function get_magic_quotes() {
    1853       //      return false;
    1854       //    }
    1855       //  }
    1856       $magic_quotes = get_magic_quotes_runtime();
    1857       if ($magic_quotes) {
    1858         if (version_compare(PHP_VERSION, '5.3.0', '<')) {
    1859           set_magic_quotes_runtime(0);
    1860         } else {
    1861           ini_set('magic_quotes_runtime', 0);
    1862         }
    1863       }
    1864       $file_buffer  = file_get_contents($path);
    1865       $file_buffer  = $this->EncodeString($file_buffer, $encoding);
    1866       if ($magic_quotes) {
    1867         if (version_compare(PHP_VERSION, '5.3.0', '<')) {
    1868           set_magic_quotes_runtime($magic_quotes);
    1869         } else {
    1870           ini_set('magic_quotes_runtime', $magic_quotes);
    1871         }
    1872       }
    1873       return $file_buffer;
    1874     } catch (Exception $e) {
    1875       $this->SetError($e->getMessage());
    1876       return '';
    1877     }
    1878   }
    1879 
    1880   /**
    1881    * Encodes string to requested format.
    1882    * Returns an empty string on failure.
    1883    * @param string $str The text to encode
    1884    * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
    1885    * @access public
    1886    * @return string
    1887    */
    1888   public function EncodeString($str, $encoding = 'base64') {
    1889     $encoded = '';
    1890     switch(strtolower($encoding)) {
    1891       case 'base64':
    1892         $encoded = chunk_split(base64_encode($str), 76, $this->LE);
    1893         break;
    1894       case '7bit':
    1895       case '8bit':
    1896         $encoded = $this->FixEOL($str);
    1897         //Make sure it ends with a line break
    1898         if (substr($encoded, -(strlen($this->LE))) != $this->LE)
    1899           $encoded .= $this->LE;
    1900         break;
    1901       case 'binary':
    1902         $encoded = $str;
    1903         break;
    1904       case 'quoted-printable':
    1905         $encoded = $this->EncodeQP($str);
    1906         break;
    1907       default:
    1908         $this->SetError($this->Lang('encoding') . $encoding);
    1909         break;
    1910     }
    1911     return $encoded;
    1912   }
    1913 
    1914   /**
    1915    * Encode a header string to best (shortest) of Q, B, quoted or none.
    1916    * @access public
    1917    * @param string $str
    1918    * @param string $position
    1919    * @return string
    1920    */
    1921   public function EncodeHeader($str, $position = 'text') {
    1922     $x = 0;
    1923 
    1924     switch (strtolower($position)) {
    1925       case 'phrase':
    1926         if (!preg_match('/[\200-\377]/', $str)) {
    1927           // Can't use addslashes as we don't know what value has magic_quotes_sybase
    1928           $encoded = addcslashes($str, "\0..\37\177\\\"");
    1929           if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
    1930             return ($encoded);
    1931           } else {
    1932             return ("\"$encoded\"");
    1933           }
    1934         }
    1935         $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
    1936         break;
    1937       case 'comment':
    1938         $x = preg_match_all('/[()"]/', $str, $matches);
    1939         // Fall-through
    1940       case 'text':
    1941       default:
    1942         $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
    1943         break;
    1944     }
    1945 
    1946     if ($x == 0) {
    1947       return ($str);
    1948     }
    1949 
    1950     $maxlen = 75 - 7 - strlen($this->CharSet);
    1951     // Try to select the encoding which should produce the shortest output
    1952     if (strlen($str)/3 < $x) {
    1953       $encoding = 'B';
    1954       if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
    1955         // Use a custom function which correctly encodes and wraps long
    1956         // multibyte strings without breaking lines within a character
    1957         $encoded = $this->Base64EncodeWrapMB($str, "\n");
    1958       } else {
    1959         $encoded = base64_encode($str);
    1960         $maxlen -= $maxlen % 4;
    1961         $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
    1962       }
    1963     } else {
    1964       $encoding = 'Q';
    1965       $encoded = $this->EncodeQ($str, $position);
    1966       $encoded = $this->WrapText($encoded, $maxlen, true);
    1967       $encoded = str_replace('='.self::CRLF, "\n", trim($encoded));
    1968     }
    1969 
    1970     $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
    1971     $encoded = trim(str_replace("\n", $this->LE, $encoded));
    1972 
    1973     return $encoded;
    1974   }
    1975 
    1976   /**
    1977    * Checks if a string contains multibyte characters.
    1978    * @access public
    1979    * @param string $str multi-byte text to wrap encode
    1980    * @return bool
    1981    */
    1982   public function HasMultiBytes($str) {
    1983     if (function_exists('mb_strlen')) {
    1984       return (strlen($str) > mb_strlen($str, $this->CharSet));
    1985     } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
    1986       return false;
    1987     }
    1988   }
    1989 
    1990   /**
    1991    * Correctly encodes and wraps long multibyte strings for mail headers
    1992    * without breaking lines within a character.
    1993    * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
    1994    * @access public
    1995    * @param string $str multi-byte text to wrap encode
    1996    * @param string $lf string to use as linefeed/end-of-line
    1997    * @return string
    1998    */
    1999   public function Base64EncodeWrapMB($str, $lf=null) {
    2000     $start = "=?".$this->CharSet."?B?";
    2001     $end = "?=";
    2002     $encoded = "";
    2003     if ($lf === null) {
    2004       $lf = $this->LE;
    2005     }
    2006 
    2007     $mb_length = mb_strlen($str, $this->CharSet);
    2008     // Each line must have length <= 75, including $start and $end
    2009     $length = 75 - strlen($start) - strlen($end);
    2010     // Average multi-byte ratio
    2011     $ratio = $mb_length / strlen($str);
    2012     // Base64 has a 4:3 ratio
    2013     $offset = $avgLength = floor($length * $ratio * .75);
    2014 
    2015     for ($i = 0; $i < $mb_length; $i += $offset) {
    2016       $lookBack = 0;
    2017 
    2018       do {
    2019         $offset = $avgLength - $lookBack;
    2020         $chunk = mb_substr($str, $i, $offset, $this->CharSet);
    2021         $chunk = base64_encode($chunk);
    2022         $lookBack++;
    2023       }
    2024       while (strlen($chunk) > $length);
    2025 
    2026       $encoded .= $chunk . $lf;
    2027     }
    2028 
    2029     // Chomp the last linefeed
    2030     $encoded = substr($encoded, 0, -strlen($lf));
    2031     return $encoded;
    2032   }
    2033 
    2034   /**
    2035   * Encode string to quoted-printable.
    2036   * Only uses standard PHP, slow, but will always work
    2037   * @access public
    2038    * @param string $input
    2039   * @param integer $line_max Number of chars allowed on a line before wrapping
    2040    * @param bool $space_conv
    2041    * @internal param string $string the text to encode
    2042   * @return string
    2043   */
    2044   public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) {
    2045     $hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
    2046     $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
    2047     $eol = "\r\n";
    2048     $escape = '=';
    2049     $output = '';
    2050     while( list(, $line) = each($lines) ) {
    2051       $linlen = strlen($line);
    2052       $newline = '';
    2053       for($i = 0; $i < $linlen; $i++) {
    2054         $c = substr( $line, $i, 1 );
    2055         $dec = ord( $c );
    2056         if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
    2057           $c = '=2E';
    2058         }
    2059         if ( $dec == 32 ) {
    2060           if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
    2061             $c = '=20';
    2062           } else if ( $space_conv ) {
    2063             $c = '=20';
    2064           }
    2065         } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
    2066           $h2 = (integer)floor($dec/16);
    2067           $h1 = (integer)floor($dec%16);
    2068           $c = $escape.$hex[$h2].$hex[$h1];
    2069         }
    2070         if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
    2071           $output .= $newline.$escape.$eol; //  soft line break; " =\r\n" is okay
    2072           $newline = '';
    2073           // check if newline first character will be point or not
    2074           if ( $dec == 46 ) {
    2075             $c = '=2E';
    2076           }
    2077         }
    2078         $newline .= $c;
    2079       } // end of for
    2080       $output .= $newline.$eol;
    2081     } // end of while
    2082     return $output;
    2083   }
    2084 
    2085   /**
    2086   * Encode string to RFC2045 (6.7) quoted-printable format
    2087   * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version
    2088   * Also results in same content as you started with after decoding
    2089   * @see EncodeQPphp()
    2090   * @access public
    2091   * @param string $string the text to encode
    2092   * @param integer $line_max Number of chars allowed on a line before wrapping
    2093   * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function
    2094   * @return string
    2095   * @author Marcus Bointon
    2096   */
    2097   public function EncodeQP($string, $line_max = 76, $space_conv = false) {
    2098     if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3)
    2099       return quoted_printable_encode($string);
    2100     }
    2101     $filters = stream_get_filters();
    2102     if (!in_array('convert.*', $filters)) { //Got convert stream filter?
    2103       return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation
    2104     }
    2105     $fp = fopen('php://temp/', 'r+');
    2106     $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks
    2107     $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE);
    2108     $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params);
    2109     fputs($fp, $string);
    2110     rewind($fp);
    2111     $out = stream_get_contents($fp);
    2112     stream_filter_remove($s);
    2113     $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange
    2114     fclose($fp);
    2115     return $out;
    2116   }
    2117 
    2118   /**
    2119    * Encode string to q encoding.
    2120    * @link http://tools.ietf.org/html/rfc2047
    2121    * @param string $str the text to encode
    2122    * @param string $position Where the text is going to be used, see the RFC for what that means
    2123    * @access public
    2124    * @return string
    2125    */
    2126   public function EncodeQ($str, $position = 'text') {
    2127     //There should not be any EOL in the string
    2128         $pattern="";
    2129     $encoded = str_replace(array("\r", "\n"), '', $str);
    2130     switch (strtolower($position)) {
    2131       case 'phrase':
    2132         $pattern = '^A-Za-z0-9!*+\/ -';
    2133         break;
    2134 
    2135       case 'comment':
    2136         $pattern = '\(\)"';
    2137         //note that we dont break here!
    2138         //for this reason we build the $pattern withoud including delimiters and []
    2139 
    2140       case 'text':
    2141       default:
    2142         //Replace every high ascii, control =, ? and _ characters
    2143         //We put \075 (=) as first value to make sure it's the first one in being converted, preventing double encode
    2144         $pattern = '\075\000-\011\013\014\016-\037\077\137\177-\377' . $pattern;
    2145         break;
    2146     }
    2147    
    2148     if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
    2149       foreach (array_unique($matches[0]) as $char) {
    2150         $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
    2151       }
    2152     }
    2153    
    2154     //Replace every spaces to _ (more readable than =20)
    2155     return str_replace(' ', '_', $encoded);
    2156 }
    2157 
    2158 
    2159   /**
    2160    * Adds a string or binary attachment (non-filesystem) to the list.
    2161    * This method can be used to attach ascii or binary data,
    2162    * such as a BLOB record from a database.
    2163    * @param string $string String attachment data.
    2164    * @param string $filename Name of the attachment.
    2165    * @param string $encoding File encoding (see $Encoding).
    2166    * @param string $type File extension (MIME) type.
    2167    * @return void
    2168    */
    2169   public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
    2170     // Append to $attachment array
    2171     $this->attachment[] = array(
    2172       0 => $string,
    2173       1 => $filename,
    2174       2 => basename($filename),
    2175       3 => $encoding,
    2176       4 => $type,
    2177       5 => true,  // isStringAttachment
    2178       6 => 'attachment',
    2179       7 => 0
    2180     );
    2181   }
    2182 
    2183   /**
    2184    * Adds an embedded attachment.  This can include images, sounds, and
    2185    * just about any other document.  Make sure to set the $type to an
    2186    * image type.  For JPEG images use "image/jpeg" and for GIF images
    2187    * use "image/gif".
    2188    * @param string $path Path to the attachment.
    2189    * @param string $cid Content ID of the attachment.  Use this to identify
    2190    *        the Id for accessing the image in an HTML form.
    2191    * @param string $name Overrides the attachment name.
    2192    * @param string $encoding File encoding (see $Encoding).
    2193    * @param string $type File extension (MIME) type.
    2194    * @return bool
    2195    */
    2196   public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
    2197 
    2198     if ( !@is_file($path) ) {
    2199       $this->SetError($this->Lang('file_access') . $path);
    2200       return false;
    2201     }
    2202 
    2203     $filename = basename($path);
    2204     if ( $name == '' ) {
    2205       $name = $filename;
    2206     }
    2207 
    2208     // Append to $attachment array
    2209     $this->attachment[] = array(
    2210       0 => $path,
    2211       1 => $filename,
    2212       2 => $name,
    2213       3 => $encoding,
    2214       4 => $type,
    2215       5 => false,  // isStringAttachment
    2216       6 => 'inline',
    2217       7 => $cid
    2218     );
    2219 
    2220     return true;
    2221   }
    2222 
    2223   /**
    2224    * Adds an embedded stringified attachment.  This can include images, sounds, and
    2225    * just about any other document.  Make sure to set the $type to an
    2226    * image type.  For JPEG images use "image/jpeg" and for GIF images
    2227    * use "image/gif".
    2228    * @param string $string The attachment.
    2229    * @param string $cid Content ID of the attachment.  Use this to identify
    2230    *        the Id for accessing the image in an HTML form.
    2231    * @param string $name Overrides the attachment name.
    2232    * @param string $encoding File encoding (see $Encoding).
    2233    * @param string $type File extension (MIME) type.
    2234    * @return bool
    2235    */
    2236   public function AddStringEmbeddedImage($string, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
    2237     // Append to $attachment array
    2238     $this->attachment[] = array(
    2239       0 => $string,
    2240       1 => $name,
    2241       2 => $name,
    2242       3 => $encoding,
    2243       4 => $type,
    2244       5 => true,  // isStringAttachment
    2245       6 => 'inline',
    2246       7 => $cid
    2247     );
    2248   }
    2249 
    2250   /**
    2251    * Returns true if an inline attachment is present.
    2252    * @access public
    2253    * @return bool
    2254    */
    2255   public function InlineImageExists() {
    2256     foreach($this->attachment as $attachment) {
    2257       if ($attachment[6] == 'inline') {
    2258         return true;
    2259       }
    2260     }
    2261     return false;
    2262   }
    2263 
    2264   /**
    2265    * Returns true if an attachment (non-inline) is present.
    2266    * @return bool
    2267    */
    2268   public function AttachmentExists() {
    2269     foreach($this->attachment as $attachment) {
    2270       if ($attachment[6] == 'attachment') {
    2271         return true;
    2272       }
    2273     }
    2274     return false;
    2275   }
    2276 
    2277   /**
    2278    * Does this message have an alternative body set?
    2279    * @return bool
    2280    */
    2281   public function AlternativeExists() {
    2282     return !empty($this->AltBody);
    2283   }
    2284 
    2285   /////////////////////////////////////////////////
    2286   // CLASS METHODS, MESSAGE RESET
    2287   /////////////////////////////////////////////////
    2288 
    2289   /**
    2290    * Clears all recipients assigned in the TO array.  Returns void.
    2291    * @return void
    2292    */
    2293   public function ClearAddresses() {
    2294     foreach($this->to as $to) {
    2295       unset($this->all_recipients[strtolower($to[0])]);
    2296     }
    2297     $this->to = array();
    2298   }
    2299 
    2300   /**
    2301    * Clears all recipients assigned in the CC array.  Returns void.
    2302    * @return void
    2303    */
    2304   public function ClearCCs() {
    2305     foreach($this->cc as $cc) {
    2306       unset($this->all_recipients[strtolower($cc[0])]);
    2307     }
    2308     $this->cc = array();
    2309   }
    2310 
    2311   /**
    2312    * Clears all recipients assigned in the BCC array.  Returns void.
    2313    * @return void
    2314    */
    2315   public function ClearBCCs() {
    2316     foreach($this->bcc as $bcc) {
    2317       unset($this->all_recipients[strtolower($bcc[0])]);
    2318     }
    2319     $this->bcc = array();
    2320   }
    2321 
    2322   /**
    2323    * Clears all recipients assigned in the ReplyTo array.  Returns void.
    2324    * @return void
    2325    */
    2326   public function ClearReplyTos() {
    2327     $this->ReplyTo = array();
    2328   }
    2329 
    2330   /**
    2331    * Clears all recipients assigned in the TO, CC and BCC
    2332    * array.  Returns void.
    2333    * @return void
    2334    */
    2335   public function ClearAllRecipients() {
    2336     $this->to = array();
    2337     $this->cc = array();
    2338     $this->bcc = array();
    2339     $this->all_recipients = array();
    2340   }
    2341 
    2342   /**
    2343    * Clears all previously set filesystem, string, and binary
    2344    * attachments.  Returns void.
    2345    * @return void
    2346    */
    2347   public function ClearAttachments() {
    2348     $this->attachment = array();
    2349   }
    2350 
    2351   /**
    2352    * Clears all custom headers.  Returns void.
    2353    * @return void
    2354    */
    2355   public function ClearCustomHeaders() {
    2356     $this->CustomHeader = array();
    2357   }
    2358 
    2359   /////////////////////////////////////////////////
    2360   // CLASS METHODS, MISCELLANEOUS
    2361   /////////////////////////////////////////////////
    2362 
    2363   /**
    2364    * Adds the error message to the error container.
    2365    * @access protected
    2366    * @param string $msg
    2367    * @return void
    2368    */
    2369   protected function SetError($msg) {
    2370     $this->error_count++;
    2371     if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
    2372       $lasterror = $this->smtp->getError();
    2373       if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
    2374         $msg .= '<p>' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
    2375       }
    2376     }
    2377     $this->ErrorInfo = $msg;
    2378   }
    2379 
    2380   /**
    2381    * Returns the proper RFC 822 formatted date.
    2382    * @access public
    2383    * @return string
    2384    * @static
    2385    */
    2386   public static function RFCDate() {
    2387     $tz = date('Z');
    2388     $tzs = ($tz < 0) ? '-' : '+';
    2389     $tz = abs($tz);
    2390     $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
    2391     $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
    2392 
    2393     return $result;
    2394   }
    2395 
    2396   /**
    2397    * Returns the server hostname or 'localhost.localdomain' if unknown.
    2398    * @access protected
    2399    * @return string
    2400    */
    2401   protected function ServerHostname() {
    2402     if (!empty($this->Hostname)) {
    2403       $result = $this->Hostname;
    2404     } elseif (isset($_SERVER['SERVER_NAME'])) {
    2405       $result = $_SERVER['SERVER_NAME'];
    2406     } else {
    2407       $result = 'localhost.localdomain';
    2408     }
    2409 
    2410     return $result;
    2411   }
    2412 
    2413   /**
    2414    * Returns a message in the appropriate language.
    2415    * @access protected
    2416    * @param string $key
    2417    * @return string
    2418    */
    2419   protected function Lang($key) {
    2420     if(count($this->language) < 1) {
    2421       $this->SetLanguage('en'); // set the default language
    2422     }
    2423 
    2424     if(isset($this->language[$key])) {
    2425       return $this->language[$key];
    2426     } else {
    2427       return 'Language string failed to load: ' . $key;
    2428     }
    2429   }
    2430 
    2431   /**
    2432    * Returns true if an error occurred.
    2433    * @access public
    2434    * @return bool
    2435    */
    2436   public function IsError() {
    2437     return ($this->error_count > 0);
    2438   }
    2439 
    2440   /**
    2441    * Changes every end of line from CRLF, CR or LF to $this->LE.
    2442    * @access public
    2443    * @param string $str String to FixEOL
    2444    * @return string
    2445    */
    2446   public function FixEOL($str) {
    2447         // condense down to \n
    2448         $nstr = str_replace(array("\r\n", "\r"), "\n", $str);
    2449         // Now convert LE as needed
    2450         if ($this->LE !== "\n") {
    2451                 $nstr = str_replace("\n", $this->LE, $nstr);
    2452         }
    2453     return  $nstr;
    2454   }
    2455 
    2456   /**
    2457    * Adds a custom header. $name value can be overloaded to contain
    2458    * both header name and value (name:value)
    2459    * @access public
    2460    * @param string $name custom header name
    2461    * @param string $value header value
    2462    * @return void
    2463    */
    2464   public function AddCustomHeader($name, $value=null) {
    2465         if ($value === null) {
    2466                 // Value passed in as name:value
    2467                 $this->CustomHeader[] = explode(':', $name, 2);
    2468         } else {
    2469                 $this->CustomHeader[] = array($name, $value);
    2470         }
    2471   }
    2472 
    2473   /**
    2474    * Evaluates the message and returns modifications for inline images and backgrounds
    2475    * @access public
    2476    * @param string $message Text to be HTML modified
    2477    * @param string $basedir baseline directory for path
    2478    * @return string $message
    2479    */
    2480   public function MsgHTML($message, $basedir = '') {
    2481     preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images);
    2482     if(isset($images[2])) {
    2483       foreach($images[2] as $i => $url) {
    2484         // do not change urls for absolute images (thanks to corvuscorax)
    2485         if (!preg_match('#^[A-z]+://#', $url)) {
    2486           $filename = basename($url);
    2487           $directory = dirname($url);
    2488           if ($directory == '.') {
    2489             $directory = '';
    2490           }
    2491           $cid = 'cid:' . md5($url);
    2492           $ext = pathinfo($filename, PATHINFO_EXTENSION);
    2493           $mimeType  = self::_mime_types($ext);
    2494           if ( strlen($basedir) > 1 && substr($basedir, -1) != '/') { $basedir .= '/'; }
    2495           if ( strlen($directory) > 1 && substr($directory, -1) != '/') { $directory .= '/'; }
    2496           if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($url), $filename, 'base64', $mimeType) ) {
    2497             $message = preg_replace("/".$images[1][$i]."=[\"']".preg_quote($url, '/')."[\"']/Ui", $images[1][$i]."=\"".$cid."\"", $message);
    2498           }
    2499         }
    2500       }
    2501     }
    2502     $this->IsHTML(true);
    2503     $this->Body = $message;
    2504     if (empty($this->AltBody)) {
    2505         $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message)));
    2506         if (!empty($textMsg)) {
    2507             $this->AltBody = html_entity_decode($textMsg, ENT_QUOTES, $this->CharSet);
    2508         }
    2509     }
    2510     if (empty($this->AltBody)) {
    2511       $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
    2512     }
    2513     return $message;
    2514   }
    2515 
    2516   /**
    2517    * Gets the MIME type of the embedded or inline image
    2518    * @param string $ext File extension
    2519    * @access public
    2520    * @return string MIME type of ext
    2521    * @static
    2522    */
    2523   public static function _mime_types($ext = '') {
    2524     $mimes = array(
    2525       'xl'    =>  'application/excel',
    2526       'hqx'   =>  'application/mac-binhex40',
    2527       'cpt'   =>  'application/mac-compactpro',
    2528       'bin'   =>  'application/macbinary',
    2529       'doc'   =>  'application/msword',
    2530       'word'  =>  'application/msword',
    2531       'class' =>  'application/octet-stream',
    2532       'dll'   =>  'application/octet-stream',
    2533       'dms'   =>  'application/octet-stream',
    2534       'exe'   =>  'application/octet-stream',
    2535       'lha'   =>  'application/octet-stream',
    2536       'lzh'   =>  'application/octet-stream',
    2537       'psd'   =>  'application/octet-stream',
    2538       'sea'   =>  'application/octet-stream',
    2539       'so'    =>  'application/octet-stream',
    2540       'oda'   =>  'application/oda',
    2541       'pdf'   =>  'application/pdf',
    2542       'ai'    =>  'application/postscript',
    2543       'eps'   =>  'application/postscript',
    2544       'ps'    =>  'application/postscript',
    2545       'smi'   =>  'application/smil',
    2546       'smil'  =>  'application/smil',
    2547       'mif'   =>  'application/vnd.mif',
    2548       'xls'   =>  'application/vnd.ms-excel',
    2549       'ppt'   =>  'application/vnd.ms-powerpoint',
    2550       'wbxml' =>  'application/vnd.wap.wbxml',
    2551       'wmlc'  =>  'application/vnd.wap.wmlc',
    2552       'dcr'   =>  'application/x-director',
    2553       'dir'   =>  'application/x-director',
    2554       'dxr'   =>  'application/x-director',
    2555       'dvi'   =>  'application/x-dvi',
    2556       'gtar'  =>  'application/x-gtar',
    2557       'php3'  =>  'application/x-httpd-php',
    2558       'php4'  =>  'application/x-httpd-php',
    2559       'php'   =>  'application/x-httpd-php',
    2560       'phtml' =>  'application/x-httpd-php',
    2561       'phps'  =>  'application/x-httpd-php-source',
    2562       'js'    =>  'application/x-javascript',
    2563       'swf'   =>  'application/x-shockwave-flash',
    2564       'sit'   =>  'application/x-stuffit',
    2565       'tar'   =>  'application/x-tar',
    2566       'tgz'   =>  'application/x-tar',
    2567       'xht'   =>  'application/xhtml+xml',
    2568       'xhtml' =>  'application/xhtml+xml',
    2569       'zip'   =>  'application/zip',
    2570       'mid'   =>  'audio/midi',
    2571       'midi'  =>  'audio/midi',
    2572       'mp2'   =>  'audio/mpeg',
    2573       'mp3'   =>  'audio/mpeg',
    2574       'mpga'  =>  'audio/mpeg',
    2575       'aif'   =>  'audio/x-aiff',
    2576       'aifc'  =>  'audio/x-aiff',
    2577       'aiff'  =>  'audio/x-aiff',
    2578       'ram'   =>  'audio/x-pn-realaudio',
    2579       'rm'    =>  'audio/x-pn-realaudio',
    2580       'rpm'   =>  'audio/x-pn-realaudio-plugin',
    2581       'ra'    =>  'audio/x-realaudio',
    2582       'wav'   =>  'audio/x-wav',
    2583       'bmp'   =>  'image/bmp',
    2584       'gif'   =>  'image/gif',
    2585       'jpeg'  =>  'image/jpeg',
    2586       'jpe'   =>  'image/jpeg',
    2587       'jpg'   =>  'image/jpeg',
    2588       'png'   =>  'image/png',
    2589       'tiff'  =>  'image/tiff',
    2590       'tif'   =>  'image/tiff',
    2591       'eml'   =>  'message/rfc822',
    2592       'css'   =>  'text/css',
    2593       'html'  =>  'text/html',
    2594       'htm'   =>  'text/html',
    2595       'shtml' =>  'text/html',
    2596       'log'   =>  'text/plain',
    2597       'text'  =>  'text/plain',
    2598       'txt'   =>  'text/plain',
    2599       'rtx'   =>  'text/richtext',
    2600       'rtf'   =>  'text/rtf',
    2601       'xml'   =>  'text/xml',
    2602       'xsl'   =>  'text/xml',
    2603       'mpeg'  =>  'video/mpeg',
    2604       'mpe'   =>  'video/mpeg',
    2605       'mpg'   =>  'video/mpeg',
    2606       'mov'   =>  'video/quicktime',
    2607       'qt'    =>  'video/quicktime',
    2608       'rv'    =>  'video/vnd.rn-realvideo',
    2609       'avi'   =>  'video/x-msvideo',
    2610       'movie' =>  'video/x-sgi-movie'
    2611     );
    2612     return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
    2613   }
    2614 
    2615   /**
    2616   * Set (or reset) Class Objects (variables)
    2617   *
    2618   * Usage Example:
    2619   * $page->set('X-Priority', '3');
    2620   *
    2621   * @access public
    2622   * @param string $name Parameter Name
    2623   * @param mixed $value Parameter Value
    2624   * NOTE: will not work with arrays, there are no arrays to set/reset
    2625    * @throws phpmailerException
    2626    * @return bool
    2627   * @todo Should this not be using __set() magic function?
    2628   */
    2629   public function set($name, $value = '') {
    2630     try {
    2631       if (isset($this->$name) ) {
    2632         $this->$name = $value;
    2633       } else {
    2634         throw new phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL);
    2635       }
    2636     } catch (Exception $e) {
    2637       $this->SetError($e->getMessage());
    2638       if ($e->getCode() == self::STOP_CRITICAL) {
    2639         return false;
    2640       }
    2641     }
    2642     return true;
    2643   }
    2644 
    2645   /**
    2646    * Strips newlines to prevent header injection.
    2647    * @access public
    2648    * @param string $str String
    2649    * @return string
    2650    */
    2651   public function SecureHeader($str) {
    2652     return trim(str_replace(array("\r", "\n"), '', $str));
    2653   }
    2654 
    2655   /**
    2656    * Set the private key file and password to sign the message.
    2657    *
    2658    * @access public
    2659    * @param $cert_filename
    2660    * @param string $key_filename Parameter File Name
    2661    * @param string $key_pass Password for private key
    2662    */
    2663   public function Sign($cert_filename, $key_filename, $key_pass) {
    2664     $this->sign_cert_file = $cert_filename;
    2665     $this->sign_key_file = $key_filename;
    2666     $this->sign_key_pass = $key_pass;
    2667   }
    2668 
    2669   /**
    2670    * Set the private key file and password to sign the message.
    2671    *
    2672    * @access public
    2673    * @param string $txt
    2674    * @return string
    2675    */
    2676   public function DKIM_QP($txt) {
    2677     $line = '';
    2678     for ($i = 0; $i < strlen($txt); $i++) {
    2679       $ord = ord($txt[$i]);
    2680       if ( ((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E)) ) {
    2681         $line .= $txt[$i];
    2682       } else {
    2683         $line .= "=".sprintf("%02X", $ord);
    2684       }
    2685     }
    2686     return $line;
    2687   }
    2688 
    2689   /**
    2690    * Generate DKIM signature
    2691    *
    2692    * @access public
    2693    * @param string $s Header
    2694    * @return string
    2695    */
    2696   public function DKIM_Sign($s) {
    2697     $privKeyStr = file_get_contents($this->DKIM_private);
    2698     if ($this->DKIM_passphrase != '') {
    2699       $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
    2700     } else {
    2701       $privKey = $privKeyStr;
    2702     }
    2703     if (openssl_sign($s, $signature, $privKey)) {
    2704       return base64_encode($signature);
    2705     }
    2706     return '';
    2707   }
    2708 
    2709   /**
    2710    * Generate DKIM Canonicalization Header
    2711    *
    2712    * @access public
    2713    * @param string $s Header
    2714    * @return string
    2715    */
    2716   public function DKIM_HeaderC($s) {
    2717     $s = preg_replace("/\r\n\s+/", " ", $s);
    2718     $lines = explode("\r\n", $s);
    2719     foreach ($lines as $key => $line) {
    2720       list($heading, $value) = explode(":", $line, 2);
    2721       $heading = strtolower($heading);
    2722       $value = preg_replace("/\s+/", " ", $value) ; // Compress useless spaces
    2723       $lines[$key] = $heading.":".trim($value) ; // Don't forget to remove WSP around the value
    2724     }
    2725     $s = implode("\r\n", $lines);
    2726     return $s;
    2727   }
    2728 
    2729   /**
    2730    * Generate DKIM Canonicalization Body
    2731    *
    2732    * @access public
    2733    * @param string $body Message Body
    2734    * @return string
    2735    */
    2736   public function DKIM_BodyC($body) {
    2737     if ($body == '') return "\r\n";
    2738     // stabilize line endings
    2739     $body = str_replace("\r\n", "\n", $body);
    2740     $body = str_replace("\n", "\r\n", $body);
    2741     // END stabilize line endings
    2742     while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
    2743       $body = substr($body, 0, strlen($body) - 2);
    2744     }
    2745     return $body;
    2746   }
    2747 
    2748   /**
    2749    * Create the DKIM header, body, as new header
    2750    *
    2751    * @access public
    2752    * @param string $headers_line Header lines
    2753    * @param string $subject Subject
    2754    * @param string $body Body
    2755    * @return string
    2756    */
    2757   public function DKIM_Add($headers_line, $subject, $body) {
    2758     $DKIMsignatureType    = 'rsa-sha1'; // Signature & hash algorithms
    2759     $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
    2760     $DKIMquery            = 'dns/txt'; // Query method
    2761     $DKIMtime             = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
    2762     $subject_header       = "Subject: $subject";
    2763     $headers              = explode($this->LE, $headers_line);
    2764         $from_header          = "";
    2765         $to_header            = "";
    2766     foreach($headers as $header) {
    2767       if (strpos($header, 'From:') === 0) {
    2768         $from_header = $header;
    2769       } elseif (strpos($header, 'To:') === 0) {
    2770         $to_header = $header;
    2771       }
    2772     }
    2773     $from     = str_replace('|', '=7C', $this->DKIM_QP($from_header));
    2774     $to       = str_replace('|', '=7C', $this->DKIM_QP($to_header));
    2775     $subject  = str_replace('|', '=7C', $this->DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable
    2776     $body     = $this->DKIM_BodyC($body);
    2777     $DKIMlen  = strlen($body) ; // Length of body
    2778     $DKIMb64  = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body
    2779     $ident    = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";";
    2780     $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n".
    2781                 "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n".
    2782                 "\th=From:To:Subject;\r\n".
    2783                 "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n".
    2784                 "\tz=$from\r\n".
    2785                 "\t|$to\r\n".
    2786                 "\t|$subject;\r\n".
    2787                 "\tbh=" . $DKIMb64 . ";\r\n".
    2788                 "\tb=";
    2789     $toSign   = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs);
    2790     $signed   = $this->DKIM_Sign($toSign);
    2791     return "X-PHPMAILER-DKIM: code.google.com/a/apache-extras.org/p/phpmailer/\r\n".$dkimhdrs.$signed."\r\n";
    2792   }
    2793 
    2794   /**
    2795    * Perform callback
    2796    * @param boolean $isSent
    2797    * @param string $to
    2798    * @param string $cc
    2799    * @param string $bcc
    2800    * @param string $subject
    2801    * @param string $body
    2802    * @param string $from
    2803    */
    2804   protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from=null) {
    2805     if (!empty($this->action_function) && is_callable($this->action_function)) {
    2806       $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
    2807       call_user_func_array($this->action_function, $params);
    2808     }
    2809   }
    2810 }
    2811 
    2812 /**
    2813  * Exception handler for PHPMailer
    2814  * @package PHPMailer
    2815  */
    2816 class phpmailerException extends Exception {
    2817   /**
    2818    * Prettify error message output
    2819    * @return string
    2820    */
    2821   public function errorMessage() {
    2822     $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
    2823     return $errorMsg;
    2824   }
    2825 }
    2826 ?>
     8require_once( 'PHPMailer/PHPMailerAutoload.php' );
  • src/wp-includes/class-smtp.php

    diff --git src/wp-includes/class-smtp.php src/wp-includes/class-smtp.php
    index 72361bb..e4d2d1b 100644
     
    11<?php
    2 /*~ class.smtp.php
    3 .---------------------------------------------------------------------------.
    4 |  Software: PHPMailer - PHP email class                                    |
    5 |   Version: 5.2.4                                                          |
    6 |      Site: https://code.google.com/a/apache-extras.org/p/phpmailer/       |
    7 | ------------------------------------------------------------------------- |
    8 |     Admin: Jim Jagielski (project admininistrator)                        |
    9 |   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
    10 |          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         |
    11 |          : Jim Jagielski (jimjag) jimjag@gmail.com                        |
    12 |   Founder: Brent R. Matzelle (original founder)                           |
    13 | Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved.              |
    14 | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               |
    15 | Copyright (c) 2001-2003, Brent R. Matzelle                                |
    16 | ------------------------------------------------------------------------- |
    17 |   License: Distributed under the Lesser General Public License (LGPL)     |
    18 |            http://www.gnu.org/copyleft/lesser.html                        |
    19 | This program is distributed in the hope that it will be useful - WITHOUT  |
    20 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
    21 | FITNESS FOR A PARTICULAR PURPOSE.                                         |
    22 '---------------------------------------------------------------------------'
    23 */
    24 
    25 /**
    26  * PHPMailer - PHP SMTP email transport class
    27  * NOTE: Designed for use with PHP version 5 and up
    28  * @package PHPMailer
    29  * @author Andy Prevost
    30  * @author Marcus Bointon
    31  * @copyright 2004 - 2008 Andy Prevost
    32  * @author Jim Jagielski
    33  * @copyright 2010 - 2012 Jim Jagielski
    34  * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
    35  */
    36 
    372/**
    38  * PHP RFC821 SMTP client
     3 * Backwards compatible shim for PHPMailer library.
    394 *
    40  * Implements all the RFC 821 SMTP commands except TURN which will always return a not implemented error.
    41  * SMTP also provides some utility methods for sending mail to an SMTP server.
    42  * @author Chris Ryan
    43  * @package PHPMailer
     5 * @package WordPress
    446 */
    457
    46 class SMTP {
    47   /**
    48    *  SMTP server port
    49    *  @var int
    50    */
    51   public $SMTP_PORT = 25;
    52 
    53   /**
    54    *  SMTP reply line ending (don't change)
    55    *  @var string
    56    */
    57   public $CRLF = "\r\n";
    58 
    59   /**
    60    *  Sets whether debugging is turned on
    61    *  @var bool
    62    */
    63   public $do_debug;       // the level of debug to perform
    64 
    65   /**
    66    * Sets the function/method to use for debugging output.
    67    * Right now we only honor "echo" or "error_log"
    68    * @var string
    69    */
    70   public $Debugoutput     = "echo";
    71 
    72   /**
    73    *  Sets VERP use on/off (default is off)
    74    *  @var bool
    75    */
    76   public $do_verp = false;
    77 
    78   /**
    79    * Sets the SMTP timeout value for reads, in seconds
    80    * @var int
    81    */
    82   public $Timeout         = 15;
    83 
    84   /**
    85    * Sets the SMTP timelimit value for reads, in seconds
    86    * @var int
    87    */
    88   public $Timelimit       = 30;
    89 
    90   /**
    91    * Sets the SMTP PHPMailer Version number
    92    * @var string
    93    */
    94   public $Version         = '5.2.4';
    95 
    96   /////////////////////////////////////////////////
    97   // PROPERTIES, PRIVATE AND PROTECTED
    98   /////////////////////////////////////////////////
    99 
    100   /**
    101    * @var resource The socket to the server
    102    */
    103   private $smtp_conn;
    104   /**
    105    * @var string Error message, if any, for the last call
    106    */
    107   private $error;
    108   /**
    109    * @var string The reply the server sent to us for HELO
    110    */
    111   private $helo_rply;
    112 
    113   /**
    114    * Outputs debugging info via user-defined method
    115    * @param string $str
    116    */
    117   private function edebug($str) {
    118     if ($this->Debugoutput == "error_log") {
    119         error_log($str);
    120     } else {
    121         echo $str;
    122     }
    123   }
    124 
    125   /**
    126    * Initialize the class so that the data is in a known state.
    127    * @access public
    128    * @return SMTP
    129    */
    130   public function __construct() {
    131     $this->smtp_conn = 0;
    132     $this->error = null;
    133     $this->helo_rply = null;
    134 
    135     $this->do_debug = 0;
    136   }
    137 
    138   /////////////////////////////////////////////////
    139   // CONNECTION FUNCTIONS
    140   /////////////////////////////////////////////////
    141 
    142   /**
    143    * Connect to the server specified on the port specified.
    144    * If the port is not specified use the default SMTP_PORT.
    145    * If tval is specified then a connection will try and be
    146    * established with the server for that number of seconds.
    147    * If tval is not specified the default is 30 seconds to
    148    * try on the connection.
    149    *
    150    * SMTP CODE SUCCESS: 220
    151    * SMTP CODE FAILURE: 421
    152    * @access public
    153    * @param string $host
    154    * @param int $port
    155    * @param int $tval
    156    * @return bool
    157    */
    158   public function Connect($host, $port = 0, $tval = 30) {
    159     // set the error val to null so there is no confusion
    160     $this->error = null;
    161 
    162     // make sure we are __not__ connected
    163     if($this->connected()) {
    164       // already connected, generate error
    165       $this->error = array("error" => "Already connected to a server");
    166       return false;
    167     }
    168 
    169     if(empty($port)) {
    170       $port = $this->SMTP_PORT;
    171     }
    172 
    173     // connect to the smtp server
    174     $this->smtp_conn = @fsockopen($host,    // the host of the server
    175                                  $port,    // the port to use
    176                                  $errno,   // error number if any
    177                                  $errstr,  // error message if any
    178                                  $tval);   // give up after ? secs
    179     // verify we connected properly
    180     if(empty($this->smtp_conn)) {
    181       $this->error = array("error" => "Failed to connect to server",
    182                            "errno" => $errno,
    183                            "errstr" => $errstr);
    184       if($this->do_debug >= 1) {
    185         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />');
    186       }
    187       return false;
    188     }
    189 
    190     // SMTP server can take longer to respond, give longer timeout for first read
    191     // Windows does not have support for this timeout function
    192     if(substr(PHP_OS, 0, 3) != "WIN") {
    193      $max = ini_get('max_execution_time');
    194      if ($max != 0 && $tval > $max) { // don't bother if unlimited
    195       @set_time_limit($tval);
    196      }
    197      stream_set_timeout($this->smtp_conn, $tval, 0);
    198     }
    199 
    200     // get any announcement
    201     $announce = $this->get_lines();
    202 
    203     if($this->do_debug >= 2) {
    204       $this->edebug("SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />');
    205     }
    206 
    207     return true;
    208   }
    209 
    210   /**
    211    * Initiate a TLS communication with the server.
    212    *
    213    * SMTP CODE 220 Ready to start TLS
    214    * SMTP CODE 501 Syntax error (no parameters allowed)
    215    * SMTP CODE 454 TLS not available due to temporary reason
    216    * @access public
    217    * @return bool success
    218    */
    219   public function StartTLS() {
    220     $this->error = null; # to avoid confusion
    221 
    222     if(!$this->connected()) {
    223       $this->error = array("error" => "Called StartTLS() without being connected");
    224       return false;
    225     }
    226 
    227     fputs($this->smtp_conn,"STARTTLS" . $this->CRLF);
    228 
    229     $rply = $this->get_lines();
    230     $code = substr($rply,0,3);
    231 
    232     if($this->do_debug >= 2) {
    233       $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
    234     }
    235 
    236     if($code != 220) {
    237       $this->error =
    238          array("error"     => "STARTTLS not accepted from server",
    239                "smtp_code" => $code,
    240                "smtp_msg"  => substr($rply,4));
    241       if($this->do_debug >= 1) {
    242         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    243       }
    244       return false;
    245     }
    246 
    247     // Begin encrypted connection
    248     if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
    249       return false;
    250     }
    251 
    252     return true;
    253   }
    254 
    255   /**
    256    * Performs SMTP authentication.  Must be run after running the
    257    * Hello() method.  Returns true if successfully authenticated.
    258    * @access public
    259    * @param string $username
    260    * @param string $password
    261    * @param string $authtype
    262    * @param string $realm
    263    * @param string $workstation
    264    * @return bool
    265    */
    266   public function Authenticate($username, $password, $authtype='LOGIN', $realm='', $workstation='') {
    267     if (empty($authtype)) {
    268       $authtype = 'LOGIN';
    269     }
    270 
    271     switch ($authtype) {
    272       case 'PLAIN':
    273         // Start authentication
    274         fputs($this->smtp_conn,"AUTH PLAIN" . $this->CRLF);
    275    
    276         $rply = $this->get_lines();
    277         $code = substr($rply,0,3);
    278    
    279         if($code != 334) {
    280           $this->error =
    281             array("error" => "AUTH not accepted from server",
    282                   "smtp_code" => $code,
    283                   "smtp_msg" => substr($rply,4));
    284           if($this->do_debug >= 1) {
    285             $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    286           }
    287           return false;
    288         }
    289         // Send encoded username and password
    290         fputs($this->smtp_conn, base64_encode("\0".$username."\0".$password) . $this->CRLF);
    291 
    292         $rply = $this->get_lines();
    293         $code = substr($rply,0,3);
    294    
    295         if($code != 235) {
    296           $this->error =
    297             array("error" => "Authentication not accepted from server",
    298                   "smtp_code" => $code,
    299                   "smtp_msg" => substr($rply,4));
    300           if($this->do_debug >= 1) {
    301             $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    302           }
    303           return false;
    304         }
    305         break;
    306       case 'LOGIN':
    307         // Start authentication
    308         fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
    309    
    310         $rply = $this->get_lines();
    311         $code = substr($rply,0,3);
    312    
    313         if($code != 334) {
    314           $this->error =
    315             array("error" => "AUTH not accepted from server",
    316                   "smtp_code" => $code,
    317                   "smtp_msg" => substr($rply,4));
    318           if($this->do_debug >= 1) {
    319             $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    320           }
    321           return false;
    322         }
    323    
    324         // Send encoded username
    325         fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
    326    
    327         $rply = $this->get_lines();
    328         $code = substr($rply,0,3);
    329    
    330         if($code != 334) {
    331           $this->error =
    332             array("error" => "Username not accepted from server",
    333                   "smtp_code" => $code,
    334                   "smtp_msg" => substr($rply,4));
    335           if($this->do_debug >= 1) {
    336             $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    337           }
    338           return false;
    339         }
    340    
    341         // Send encoded password
    342         fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
    343    
    344         $rply = $this->get_lines();
    345         $code = substr($rply,0,3);
    346    
    347         if($code != 235) {
    348           $this->error =
    349             array("error" => "Password not accepted from server",
    350                   "smtp_code" => $code,
    351                   "smtp_msg" => substr($rply,4));
    352           if($this->do_debug >= 1) {
    353             $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    354           }
    355           return false;
    356         }
    357         break;
    358       case 'NTLM':
    359         /*
    360          * ntlm_sasl_client.php
    361          ** Bundled with Permission
    362          **
    363          ** How to telnet in windows: http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx
    364          ** PROTOCOL Documentation http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
    365          */
    366         require_once('ntlm_sasl_client.php');
    367         $temp = new stdClass();
    368         $ntlm_client = new ntlm_sasl_client_class;
    369         if(! $ntlm_client->Initialize($temp)){//let's test if every function its available
    370             $this->error = array("error" => $temp->error);
    371             if($this->do_debug >= 1) {
    372                 $this->edebug("You need to enable some modules in your php.ini file: " . $this->error["error"] . $this->CRLF);
    373             }
    374             return false;
    375         }
    376         $msg1 = $ntlm_client->TypeMsg1($realm, $workstation);//msg1
    377        
    378         fputs($this->smtp_conn,"AUTH NTLM " . base64_encode($msg1) . $this->CRLF);
    379 
    380         $rply = $this->get_lines();
    381         $code = substr($rply,0,3);
    382        
    383 
    384         if($code != 334) {
    385             $this->error =
    386                 array("error" => "AUTH not accepted from server",
    387                       "smtp_code" => $code,
    388                       "smtp_msg" => substr($rply,4));
    389             if($this->do_debug >= 1) {
    390                 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF);
    391             }
    392             return false;
    393         }
    394        
    395         $challange = substr($rply,3);//though 0 based, there is a white space after the 3 digit number....//msg2
    396         $challange = base64_decode($challange);
    397         $ntlm_res = $ntlm_client->NTLMResponse(substr($challange,24,8),$password);
    398         $msg3 = $ntlm_client->TypeMsg3($ntlm_res,$username,$realm,$workstation);//msg3
    399         // Send encoded username
    400         fputs($this->smtp_conn, base64_encode($msg3) . $this->CRLF);
    401 
    402         $rply = $this->get_lines();
    403         $code = substr($rply,0,3);
    404 
    405         if($code != 235) {
    406             $this->error =
    407                 array("error" => "Could not authenticate",
    408                       "smtp_code" => $code,
    409                       "smtp_msg" => substr($rply,4));
    410             if($this->do_debug >= 1) {
    411                 $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF);
    412             }
    413             return false;
    414         }
    415         break;
    416     }
    417     return true;
    418   }
    419 
    420   /**
    421    * Returns true if connected to a server otherwise false
    422    * @access public
    423    * @return bool
    424    */
    425   public function Connected() {
    426     if(!empty($this->smtp_conn)) {
    427       $sock_status = socket_get_status($this->smtp_conn);
    428       if($sock_status["eof"]) {
    429         // the socket is valid but we are not connected
    430         if($this->do_debug >= 1) {
    431             $this->edebug("SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected");
    432         }
    433         $this->Close();
    434         return false;
    435       }
    436       return true; // everything looks good
    437     }
    438     return false;
    439   }
    440 
    441   /**
    442    * Closes the socket and cleans up the state of the class.
    443    * It is not considered good to use this function without
    444    * first trying to use QUIT.
    445    * @access public
    446    * @return void
    447    */
    448   public function Close() {
    449     $this->error = null; // so there is no confusion
    450     $this->helo_rply = null;
    451     if(!empty($this->smtp_conn)) {
    452       // close the connection and cleanup
    453       fclose($this->smtp_conn);
    454       $this->smtp_conn = 0;
    455     }
    456   }
    457 
    458   /////////////////////////////////////////////////
    459   // SMTP COMMANDS
    460   /////////////////////////////////////////////////
    461 
    462   /**
    463    * Issues a data command and sends the msg_data to the server
    464    * finializing the mail transaction. $msg_data is the message
    465    * that is to be send with the headers. Each header needs to be
    466    * on a single line followed by a <CRLF> with the message headers
    467    * and the message body being seperated by and additional <CRLF>.
    468    *
    469    * Implements rfc 821: DATA <CRLF>
    470    *
    471    * SMTP CODE INTERMEDIATE: 354
    472    *     [data]
    473    *     <CRLF>.<CRLF>
    474    *     SMTP CODE SUCCESS: 250
    475    *     SMTP CODE FAILURE: 552,554,451,452
    476    * SMTP CODE FAILURE: 451,554
    477    * SMTP CODE ERROR  : 500,501,503,421
    478    * @access public
    479    * @param string $msg_data
    480    * @return bool
    481    */
    482   public function Data($msg_data) {
    483     $this->error = null; // so no confusion is caused
    484 
    485     if(!$this->connected()) {
    486       $this->error = array(
    487               "error" => "Called Data() without being connected");
    488       return false;
    489     }
    490 
    491     fputs($this->smtp_conn,"DATA" . $this->CRLF);
    492 
    493     $rply = $this->get_lines();
    494     $code = substr($rply,0,3);
    495 
    496     if($this->do_debug >= 2) {
    497       $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
    498     }
    499 
    500     if($code != 354) {
    501       $this->error =
    502         array("error" => "DATA command not accepted from server",
    503               "smtp_code" => $code,
    504               "smtp_msg" => substr($rply,4));
    505       if($this->do_debug >= 1) {
    506         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    507       }
    508       return false;
    509     }
    510 
    511     /* the server is ready to accept data!
    512      * according to rfc 821 we should not send more than 1000
    513      * including the CRLF
    514      * characters on a single line so we will break the data up
    515      * into lines by \r and/or \n then if needed we will break
    516      * each of those into smaller lines to fit within the limit.
    517      * in addition we will be looking for lines that start with
    518      * a period '.' and append and additional period '.' to that
    519      * line. NOTE: this does not count towards limit.
    520      */
    521 
    522     // normalize the line breaks so we know the explode works
    523     $msg_data = str_replace("\r\n","\n",$msg_data);
    524     $msg_data = str_replace("\r","\n",$msg_data);
    525     $lines = explode("\n",$msg_data);
    526 
    527     /* we need to find a good way to determine is headers are
    528      * in the msg_data or if it is a straight msg body
    529      * currently I am assuming rfc 822 definitions of msg headers
    530      * and if the first field of the first line (':' sperated)
    531      * does not contain a space then it _should_ be a header
    532      * and we can process all lines before a blank "" line as
    533      * headers.
    534      */
    535 
    536     $field = substr($lines[0],0,strpos($lines[0],":"));
    537     $in_headers = false;
    538     if(!empty($field) && !strstr($field," ")) {
    539       $in_headers = true;
    540     }
    541 
    542     $max_line_length = 998; // used below; set here for ease in change
    543 
    544     while(list(,$line) = @each($lines)) {
    545       $lines_out = null;
    546       if($line == "" && $in_headers) {
    547         $in_headers = false;
    548       }
    549       // ok we need to break this line up into several smaller lines
    550       while(strlen($line) > $max_line_length) {
    551         $pos = strrpos(substr($line,0,$max_line_length)," ");
    552 
    553         // Patch to fix DOS attack
    554         if(!$pos) {
    555           $pos = $max_line_length - 1;
    556           $lines_out[] = substr($line,0,$pos);
    557           $line = substr($line,$pos);
    558         } else {
    559           $lines_out[] = substr($line,0,$pos);
    560           $line = substr($line,$pos + 1);
    561         }
    562 
    563         /* if processing headers add a LWSP-char to the front of new line
    564          * rfc 822 on long msg headers
    565          */
    566         if($in_headers) {
    567           $line = "\t" . $line;
    568         }
    569       }
    570       $lines_out[] = $line;
    571 
    572       // send the lines to the server
    573       while(list(,$line_out) = @each($lines_out)) {
    574         if(strlen($line_out) > 0)
    575         {
    576           if(substr($line_out, 0, 1) == ".") {
    577             $line_out = "." . $line_out;
    578           }
    579         }
    580         fputs($this->smtp_conn,$line_out . $this->CRLF);
    581       }
    582     }
    583 
    584     // message data has been sent
    585     fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
    586 
    587     $rply = $this->get_lines();
    588     $code = substr($rply,0,3);
    589 
    590     if($this->do_debug >= 2) {
    591       $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
    592     }
    593 
    594     if($code != 250) {
    595       $this->error =
    596         array("error" => "DATA not accepted from server",
    597               "smtp_code" => $code,
    598               "smtp_msg" => substr($rply,4));
    599       if($this->do_debug >= 1) {
    600         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    601       }
    602       return false;
    603     }
    604     return true;
    605   }
    606 
    607   /**
    608    * Sends the HELO command to the smtp server.
    609    * This makes sure that we and the server are in
    610    * the same known state.
    611    *
    612    * Implements from rfc 821: HELO <SP> <domain> <CRLF>
    613    *
    614    * SMTP CODE SUCCESS: 250
    615    * SMTP CODE ERROR  : 500, 501, 504, 421
    616    * @access public
    617    * @param string $host
    618    * @return bool
    619    */
    620   public function Hello($host = '') {
    621     $this->error = null; // so no confusion is caused
    622 
    623     if(!$this->connected()) {
    624       $this->error = array(
    625             "error" => "Called Hello() without being connected");
    626       return false;
    627     }
    628 
    629     // if hostname for HELO was not specified send default
    630     if(empty($host)) {
    631       // determine appropriate default to send to server
    632       $host = "localhost";
    633     }
    634 
    635     // Send extended hello first (RFC 2821)
    636     if(!$this->SendHello("EHLO", $host)) {
    637       if(!$this->SendHello("HELO", $host)) {
    638         return false;
    639       }
    640     }
    641 
    642     return true;
    643   }
    644 
    645   /**
    646    * Sends a HELO/EHLO command.
    647    * @access private
    648    * @param string $hello
    649    * @param string $host
    650    * @return bool
    651    */
    652   private function SendHello($hello, $host) {
    653     fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
    654 
    655     $rply = $this->get_lines();
    656     $code = substr($rply,0,3);
    657 
    658     if($this->do_debug >= 2) {
    659       $this->edebug("SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />');
    660     }
    661 
    662     if($code != 250) {
    663       $this->error =
    664         array("error" => $hello . " not accepted from server",
    665               "smtp_code" => $code,
    666               "smtp_msg" => substr($rply,4));
    667       if($this->do_debug >= 1) {
    668         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    669       }
    670       return false;
    671     }
    672 
    673     $this->helo_rply = $rply;
    674 
    675     return true;
    676   }
    677 
    678   /**
    679    * Starts a mail transaction from the email address specified in
    680    * $from. Returns true if successful or false otherwise. If True
    681    * the mail transaction is started and then one or more Recipient
    682    * commands may be called followed by a Data command.
    683    *
    684    * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
    685    *
    686    * SMTP CODE SUCCESS: 250
    687    * SMTP CODE SUCCESS: 552,451,452
    688    * SMTP CODE SUCCESS: 500,501,421
    689    * @access public
    690    * @param string $from
    691    * @return bool
    692    */
    693   public function Mail($from) {
    694     $this->error = null; // so no confusion is caused
    695 
    696     if(!$this->connected()) {
    697       $this->error = array(
    698               "error" => "Called Mail() without being connected");
    699       return false;
    700     }
    701 
    702     $useVerp = ($this->do_verp ? " XVERP" : "");
    703     fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
    704 
    705     $rply = $this->get_lines();
    706     $code = substr($rply,0,3);
    707 
    708     if($this->do_debug >= 2) {
    709       $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
    710     }
    711 
    712     if($code != 250) {
    713       $this->error =
    714         array("error" => "MAIL not accepted from server",
    715               "smtp_code" => $code,
    716               "smtp_msg" => substr($rply,4));
    717       if($this->do_debug >= 1) {
    718         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    719       }
    720       return false;
    721     }
    722     return true;
    723   }
    724 
    725   /**
    726    * Sends the quit command to the server and then closes the socket
    727    * if there is no error or the $close_on_error argument is true.
    728    *
    729    * Implements from rfc 821: QUIT <CRLF>
    730    *
    731    * SMTP CODE SUCCESS: 221
    732    * SMTP CODE ERROR  : 500
    733    * @access public
    734    * @param bool $close_on_error
    735    * @return bool
    736    */
    737   public function Quit($close_on_error = true) {
    738     $this->error = null; // so there is no confusion
    739 
    740     if(!$this->connected()) {
    741       $this->error = array(
    742               "error" => "Called Quit() without being connected");
    743       return false;
    744     }
    745 
    746     // send the quit command to the server
    747     fputs($this->smtp_conn,"quit" . $this->CRLF);
    748 
    749     // get any good-bye messages
    750     $byemsg = $this->get_lines();
    751 
    752     if($this->do_debug >= 2) {
    753       $this->edebug("SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />');
    754     }
    755 
    756     $rval = true;
    757     $e = null;
    758 
    759     $code = substr($byemsg,0,3);
    760     if($code != 221) {
    761       // use e as a tmp var cause Close will overwrite $this->error
    762       $e = array("error" => "SMTP server rejected quit command",
    763                  "smtp_code" => $code,
    764                  "smtp_rply" => substr($byemsg,4));
    765       $rval = false;
    766       if($this->do_debug >= 1) {
    767         $this->edebug("SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />');
    768       }
    769     }
    770 
    771     if(empty($e) || $close_on_error) {
    772       $this->Close();
    773     }
    774 
    775     return $rval;
    776   }
    777 
    778   /**
    779    * Sends the command RCPT to the SMTP server with the TO: argument of $to.
    780    * Returns true if the recipient was accepted false if it was rejected.
    781    *
    782    * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
    783    *
    784    * SMTP CODE SUCCESS: 250,251
    785    * SMTP CODE FAILURE: 550,551,552,553,450,451,452
    786    * SMTP CODE ERROR  : 500,501,503,421
    787    * @access public
    788    * @param string $to
    789    * @return bool
    790    */
    791   public function Recipient($to) {
    792     $this->error = null; // so no confusion is caused
    793 
    794     if(!$this->connected()) {
    795       $this->error = array(
    796               "error" => "Called Recipient() without being connected");
    797       return false;
    798     }
    799 
    800     fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
    801 
    802     $rply = $this->get_lines();
    803     $code = substr($rply,0,3);
    804 
    805     if($this->do_debug >= 2) {
    806       $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
    807     }
    808 
    809     if($code != 250 && $code != 251) {
    810       $this->error =
    811         array("error" => "RCPT not accepted from server",
    812               "smtp_code" => $code,
    813               "smtp_msg" => substr($rply,4));
    814       if($this->do_debug >= 1) {
    815         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    816       }
    817       return false;
    818     }
    819     return true;
    820   }
    821 
    822   /**
    823    * Sends the RSET command to abort and transaction that is
    824    * currently in progress. Returns true if successful false
    825    * otherwise.
    826    *
    827    * Implements rfc 821: RSET <CRLF>
    828    *
    829    * SMTP CODE SUCCESS: 250
    830    * SMTP CODE ERROR  : 500,501,504,421
    831    * @access public
    832    * @return bool
    833    */
    834   public function Reset() {
    835     $this->error = null; // so no confusion is caused
    836 
    837     if(!$this->connected()) {
    838       $this->error = array(
    839               "error" => "Called Reset() without being connected");
    840       return false;
    841     }
    842 
    843     fputs($this->smtp_conn,"RSET" . $this->CRLF);
    844 
    845     $rply = $this->get_lines();
    846     $code = substr($rply,0,3);
    847 
    848     if($this->do_debug >= 2) {
    849       $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
    850     }
    851 
    852     if($code != 250) {
    853       $this->error =
    854         array("error" => "RSET failed",
    855               "smtp_code" => $code,
    856               "smtp_msg" => substr($rply,4));
    857       if($this->do_debug >= 1) {
    858         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    859       }
    860       return false;
    861     }
    862 
    863     return true;
    864   }
    865 
    866   /**
    867    * Starts a mail transaction from the email address specified in
    868    * $from. Returns true if successful or false otherwise. If True
    869    * the mail transaction is started and then one or more Recipient
    870    * commands may be called followed by a Data command. This command
    871    * will send the message to the users terminal if they are logged
    872    * in and send them an email.
    873    *
    874    * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
    875    *
    876    * SMTP CODE SUCCESS: 250
    877    * SMTP CODE SUCCESS: 552,451,452
    878    * SMTP CODE SUCCESS: 500,501,502,421
    879    * @access public
    880    * @param string $from
    881    * @return bool
    882    */
    883   public function SendAndMail($from) {
    884     $this->error = null; // so no confusion is caused
    885 
    886     if(!$this->connected()) {
    887       $this->error = array(
    888           "error" => "Called SendAndMail() without being connected");
    889       return false;
    890     }
    891 
    892     fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
    893 
    894     $rply = $this->get_lines();
    895     $code = substr($rply,0,3);
    896 
    897     if($this->do_debug >= 2) {
    898       $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
    899     }
    900 
    901     if($code != 250) {
    902       $this->error =
    903         array("error" => "SAML not accepted from server",
    904               "smtp_code" => $code,
    905               "smtp_msg" => substr($rply,4));
    906       if($this->do_debug >= 1) {
    907         $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
    908       }
    909       return false;
    910     }
    911     return true;
    912   }
    913 
    914   /**
    915    * This is an optional command for SMTP that this class does not
    916    * support. This method is here to make the RFC821 Definition
    917    * complete for this class and __may__ be implimented in the future
    918    *
    919    * Implements from rfc 821: TURN <CRLF>
    920    *
    921    * SMTP CODE SUCCESS: 250
    922    * SMTP CODE FAILURE: 502
    923    * SMTP CODE ERROR  : 500, 503
    924    * @access public
    925    * @return bool
    926    */
    927   public function Turn() {
    928     $this->error = array("error" => "This method, TURN, of the SMTP ".
    929                                     "is not implemented");
    930     if($this->do_debug >= 1) {
    931       $this->edebug("SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />');
    932     }
    933     return false;
    934   }
    935 
    936   /**
    937   * Get the current error
    938   * @access public
    939   * @return array
    940   */
    941   public function getError() {
    942     return $this->error;
    943   }
    944 
    945   /////////////////////////////////////////////////
    946   // INTERNAL FUNCTIONS
    947   /////////////////////////////////////////////////
    948 
    949   /**
    950    * Read in as many lines as possible
    951    * either before eof or socket timeout occurs on the operation.
    952    * With SMTP we can tell if we have more lines to read if the
    953    * 4th character is '-' symbol. If it is a space then we don't
    954    * need to read anything else.
    955    * @access private
    956    * @return string
    957    */
    958   private function get_lines() {
    959     $data = "";
    960     $endtime = 0;
    961     /* If for some reason the fp is bad, don't inf loop */
    962     if (!is_resource($this->smtp_conn)) {
    963       return $data;
    964     }
    965     stream_set_timeout($this->smtp_conn, $this->Timeout);
    966     if ($this->Timelimit > 0) {
    967       $endtime = time() + $this->Timelimit;
    968     }
    969     while(is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
    970       $str = @fgets($this->smtp_conn,515);
    971       if($this->do_debug >= 4) {
    972         $this->edebug("SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />');
    973         $this->edebug("SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />');
    974       }
    975       $data .= $str;
    976       if($this->do_debug >= 4) {
    977         $this->edebug("SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />');
    978       }
    979       // if 4th character is a space, we are done reading, break the loop
    980       if(substr($str,3,1) == " ") { break; }
    981       // Timed-out? Log and break
    982       $info = stream_get_meta_data($this->smtp_conn);
    983       if ($info['timed_out']) {
    984         if($this->do_debug >= 4) {
    985           $this->edebug("SMTP -> get_lines(): timed-out (" . $this->Timeout . " seconds) <br />");
    986         }
    987         break;
    988       }
    989       // Now check if reads took too long
    990       if ($endtime) {
    991         if (time() > $endtime) {
    992           if($this->do_debug >= 4) {
    993             $this->edebug("SMTP -> get_lines(): timelimit reached (" . $this->Timelimit . " seconds) <br />");
    994           }
    995           break;
    996         }
    997       }
    998     }
    999     return $data;
    1000   }
    1001 
    1002 }
    1003 ?>
     8require_once( 'PHPMailer/PHPMailerAutoload.php' );
  • src/wp-includes/pluggable.php

    diff --git src/wp-includes/pluggable.php src/wp-includes/pluggable.php
    index 794565f..a575c6f 100644
    function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() 
    222222
    223223        // (Re)create it, if it's gone missing
    224224        if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) {
    225                 require_once ABSPATH . WPINC . '/class-phpmailer.php';
    226                 require_once ABSPATH . WPINC . '/class-smtp.php';
     225                require_once ABSPATH . WPINC . '/PHPMailer/class.phpmailer.php';
     226                require_once ABSPATH . WPINC . '/PHPMailer/class.smtp.php';
    227227                $phpmailer = new PHPMailer( true );
    228228        }
    229229
  • tests/phpunit/includes/mock-mailer.php

    diff --git tests/phpunit/includes/mock-mailer.php tests/phpunit/includes/mock-mailer.php
    index f52a95a..06d7976 100644
     
    11<?php
    2 require_once( ABSPATH . '/wp-includes/class-phpmailer.php' );
     2require_once( ABSPATH . '/wp-includes/PHPMailer/PHPMailerAutoload.php' );
    33
    44class MockPHPMailer extends PHPMailer {
    55        var $mock_sent = array();
    66
    7         // override the Send function so it doesn't actually send anything
    8         function Send() {
     7        /**
     8         * Override send() so mail isn't actually sent.
     9         */
     10        function send() {
    911                try {
    10                         if ( ! $this->PreSend() )
     12                        if ( ! $this->preSend() )
    1113                                return false;
    1214
    1315                        $this->mock_sent[] = array(