WP Live Chat Support - Version 7.0.01

Version Description

  • 2017-01-03 =
  • Fixed a bug that caused the chat to disappear after being opened for some users
  • Changes made to the German language files
  • PHPMailer has been updated to the latest version
Download this release

Release Info

Developer WP-LiveChat
Plugin Icon 128x128 WP Live Chat Support
Version 7.0.01
Comparing to
See all releases

Code changes from version 7.0.00 to 7.0.01

Files changed (64) hide show
  1. images/Thumbs.db +0 -0
  2. js/wplc_u.js +4 -1
  3. languages/wplivechat-de_DE.mo +0 -0
  4. languages/wplivechat-de_DE.po +4 -8
  5. phpmailer/PHPMailerAutoload.php +4 -4
  6. phpmailer/VERSION +1 -0
  7. phpmailer/class.phpmailer.php +1452 -728
  8. phpmailer/class.phpmaileroauth.php +197 -0
  9. phpmailer/class.phpmaileroauthgoogle.php +77 -0
  10. phpmailer/class.pop3.php +95 -107
  11. phpmailer/class.smtp.php +600 -309
  12. phpmailer/extras/EasyPeasyICS.php +136 -78
  13. phpmailer/extras/README.md +17 -0
  14. phpmailer/extras/htmlfilter.php +1038 -740
  15. phpmailer/extras/ntlm_sasl_client.php +166 -166
  16. phpmailer/get_oauth_token.php +162 -0
  17. phpmailer/language/phpmailer.lang-am.php +26 -0
  18. phpmailer/language/phpmailer.lang-ar.php +21 -20
  19. phpmailer/language/phpmailer.lang-az.php +26 -0
  20. phpmailer/language/phpmailer.lang-be.php +5 -3
  21. phpmailer/language/phpmailer.lang-bg.php +26 -0
  22. phpmailer/language/phpmailer.lang-ca.php +16 -15
  23. phpmailer/language/phpmailer.lang-ch.php +17 -16
  24. phpmailer/language/phpmailer.lang-cs.php +25 -0
  25. phpmailer/language/phpmailer.lang-da.php +26 -0
  26. phpmailer/language/phpmailer.lang-de.php +16 -15
  27. phpmailer/language/phpmailer.lang-el.php +25 -0
  28. phpmailer/language/phpmailer.lang-eo.php +4 -3
  29. phpmailer/language/phpmailer.lang-es.php +16 -16
  30. phpmailer/language/phpmailer.lang-et.php +7 -6
  31. phpmailer/language/phpmailer.lang-fa.php +14 -12
  32. phpmailer/language/phpmailer.lang-fi.php +6 -5
  33. phpmailer/language/phpmailer.lang-fo.php +6 -6
  34. phpmailer/language/phpmailer.lang-fr.php +7 -7
  35. phpmailer/language/phpmailer.lang-gl.php +5 -5
  36. phpmailer/language/phpmailer.lang-he.php +6 -5
  37. phpmailer/language/phpmailer.lang-hr.php +26 -0
  38. phpmailer/language/phpmailer.lang-hu.php +5 -3
  39. phpmailer/language/phpmailer.lang-id.php +26 -0
  40. phpmailer/language/phpmailer.lang-it.php +7 -6
  41. phpmailer/language/phpmailer.lang-ja.php +18 -17
  42. phpmailer/language/phpmailer.lang-ka.php +26 -0
  43. phpmailer/language/phpmailer.lang-ko.php +26 -0
  44. phpmailer/language/phpmailer.lang-lt.php +6 -4
  45. phpmailer/language/phpmailer.lang-lv.php +6 -4
  46. phpmailer/language/phpmailer.lang-ms.php +26 -0
  47. phpmailer/language/phpmailer.lang-nb.php +25 -0
  48. phpmailer/language/phpmailer.lang-nl.php +22 -20
  49. phpmailer/language/phpmailer.lang-pl.php +8 -6
  50. phpmailer/language/phpmailer.lang-pt.php +5 -5
  51. phpmailer/language/phpmailer.lang-pt_br.php +28 -0
  52. phpmailer/language/phpmailer.lang-ro.php +22 -22
  53. phpmailer/language/phpmailer.lang-ru.php +10 -7
  54. phpmailer/language/phpmailer.lang-sk.php +6 -5
  55. phpmailer/language/phpmailer.lang-sl.php +26 -0
  56. phpmailer/language/phpmailer.lang-sr.php +26 -0
  57. phpmailer/language/phpmailer.lang-sv.php +26 -0
  58. phpmailer/language/phpmailer.lang-tr.php +23 -20
  59. phpmailer/language/phpmailer.lang-uk.php +10 -7
  60. phpmailer/language/phpmailer.lang-vi.php +26 -0
  61. phpmailer/language/phpmailer.lang-zh.php +25 -22
  62. phpmailer/language/phpmailer.lang-zh_cn.php +18 -17
  63. readme.txt +5 -1
  64. wp-live-chat-support.php +7 -2
images/Thumbs.db ADDED
Binary file
js/wplc_u.js CHANGED
@@ -1153,7 +1153,10 @@ jQuery(document).ready(function() {
1153
 
1154
  jQuery(document).on("wplc_open_chat", function (event) {
1155
  /* what is the current status? */
1156
- wplc_chat_status = Cookies.get('wplc_chat_status');
 
 
 
1157
  var wplc_tmp_checker = wplc_pre_open_check_status(status, function() {
1158
  open_chat();
1159
  });
1153
 
1154
  jQuery(document).on("wplc_open_chat", function (event) {
1155
  /* what is the current status? */
1156
+ wplc_chat_status = Cookies.get('wplc_chat_status');
1157
+ if( typeof wplc_chat_status == 'undefined' ){
1158
+ Cookies.set('wplc_chat_status', 5, { expires: 1, path: '/' });
1159
+ }
1160
  var wplc_tmp_checker = wplc_pre_open_check_status(status, function() {
1161
  open_chat();
1162
  });
languages/wplivechat-de_DE.mo CHANGED
Binary file
languages/wplivechat-de_DE.po CHANGED
@@ -3,7 +3,7 @@ msgstr ""
3
  "Project-Id-Version: WP Live Chat Support v4.2.10\n"
4
  "Report-Msgid-Bugs-To: \n"
5
  "POT-Creation-Date: 2016-10-18 14:14+0200\n"
6
- "PO-Revision-Date: 2016-10-18 14:14+0200\n"
7
  "Last-Translator: Zoran Horvat <zoran.horvat@outlook.com>\n"
8
  "Language-Team: \n"
9
  "Language: de_DE\n"
@@ -11,7 +11,7 @@ msgstr ""
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
- "X-Generator: Poedit 1.8.10\n"
15
  "X-Poedit-SourceCharset: UTF-8\n"
16
  "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
  "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
@@ -2790,9 +2790,7 @@ msgstr "mit Ihren Besuchern über einen Knopfdruck starten"
2790
  #: wp-live-chat-support/wp-live-chat-support.php:2240
2791
  #: wp-live-chat-support/wp-live-chat-support.php:2242
2792
  msgid "Buy the Pro add-on now."
2793
- msgstr ""
2794
- "Kaufen Sie das Pro add-on jetzt für nur $19,95. Kostenlose Updates für "
2795
- "IMMER. "
2796
 
2797
  # @ wplivechat
2798
  #: wp-live-chat-support/wp-live-chat-support.php:2296
@@ -3223,9 +3221,7 @@ msgstr "Live-Chat"
3223
  #: wp-live-chat-support/wp-live-chat-support.php:3676
3224
  #: wp-live-chat-support/wp-live-chat-support.php:3677
3225
  msgid "Buy the Pro add-on now (once off payment)."
3226
- msgstr ""
3227
- "Kaufen Sie das Pro add-on jetzt für nur $19,95. Kostenlose Updates für "
3228
- "IMMER. "
3229
 
3230
  # @ wplivechat
3231
  #: wp-live-chat-support/wp-live-chat-support.php:3677
3
  "Project-Id-Version: WP Live Chat Support v4.2.10\n"
4
  "Report-Msgid-Bugs-To: \n"
5
  "POT-Creation-Date: 2016-10-18 14:14+0200\n"
6
+ "PO-Revision-Date: 2017-01-03 09:43+0200\n"
7
  "Last-Translator: Zoran Horvat <zoran.horvat@outlook.com>\n"
8
  "Language-Team: \n"
9
  "Language: de_DE\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
+ "X-Generator: Poedit 1.8.7\n"
15
  "X-Poedit-SourceCharset: UTF-8\n"
16
  "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
17
  "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
2790
  #: wp-live-chat-support/wp-live-chat-support.php:2240
2791
  #: wp-live-chat-support/wp-live-chat-support.php:2242
2792
  msgid "Buy the Pro add-on now."
2793
+ msgstr "Kaufen Sie das Pro Add-on jetzt."
 
 
2794
 
2795
  # @ wplivechat
2796
  #: wp-live-chat-support/wp-live-chat-support.php:2296
3221
  #: wp-live-chat-support/wp-live-chat-support.php:3676
3222
  #: wp-live-chat-support/wp-live-chat-support.php:3677
3223
  msgid "Buy the Pro add-on now (once off payment)."
3224
+ msgstr "Kaufen Sie das Pro Add-on jetzt."
 
 
3225
 
3226
  # @ wplivechat
3227
  #: wp-live-chat-support/wp-live-chat-support.php:3677
phpmailer/PHPMailerAutoload.php CHANGED
@@ -1,14 +1,14 @@
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
1
  <?php
2
  /**
3
  * PHPMailer SPL autoloader.
4
+ * PHP Version 5
5
  * @package PHPMailer
6
+ * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
7
+ * @author Marcus Bointon (Synchro/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 2012 - 2014 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
phpmailer/VERSION ADDED
@@ -0,0 +1 @@
 
1
+ 5.2.21
phpmailer/class.phpmailer.php CHANGED
@@ -1,15 +1,14 @@
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
@@ -18,98 +17,94 @@
18
  * FITNESS FOR A PARTICULAR PURPOSE.
19
  */
20
 
21
- if (version_compare(PHP_VERSION, '5.0.0', '<')) {
22
- exit("Sorry, PHPMailer will only run on PHP version 5 or greater!\n");
23
- }
24
-
25
  /**
26
  * PHPMailer - PHP email creation and transport class.
27
- * PHP Version 5.0.0
28
  * @package PHPMailer
29
- * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
30
  * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
31
  * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
32
  * @author Brent R. Matzelle (original founder)
33
- * @copyright 2013 Marcus Bointon
34
- * @copyright 2010 - 2012 Jim Jagielski
35
- * @copyright 2004 - 2009 Andy Prevost
36
  */
37
  class PHPMailer
38
  {
39
  /**
40
  * The PHPMailer Version number.
41
- * @type string
42
  */
43
- public $Version = '5.2.7';
44
 
45
  /**
46
  * Email priority.
47
- * Options: 1 = High, 3 = Normal, 5 = low.
48
- * @type int
 
49
  */
50
- public $Priority = 3;
51
 
52
  /**
53
  * The character set of the message.
54
- * @type string
55
  */
56
  public $CharSet = 'iso-8859-1';
57
 
58
  /**
59
  * The MIME Content-type of the message.
60
- * @type string
61
  */
62
  public $ContentType = 'text/plain';
63
 
64
  /**
65
  * The message encoding.
66
  * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
67
- * @type string
68
  */
69
  public $Encoding = '8bit';
70
 
71
  /**
72
  * Holds the most recent mailer error message.
73
- * @type string
74
  */
75
  public $ErrorInfo = '';
76
 
77
  /**
78
  * The From email address for the message.
79
- * @type string
80
  */
81
  public $From = 'root@localhost';
82
 
83
  /**
84
  * The From name of the message.
85
- * @type string
86
  */
87
  public $FromName = 'Root User';
88
 
89
  /**
90
  * The Sender email (Return-Path) of the message.
91
  * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
92
- * @type string
93
  */
94
  public $Sender = '';
95
 
96
  /**
97
  * The Return-Path of the message.
98
  * If empty, it will be set to either From or Sender.
99
- * @type string
 
 
 
100
  */
101
  public $ReturnPath = '';
102
 
103
  /**
104
  * The Subject of the message.
105
- * @type string
106
  */
107
  public $Subject = '';
108
 
109
  /**
110
  * An HTML or plain text message body.
111
  * If HTML then call isHTML(true).
112
- * @type string
113
  */
114
  public $Body = '';
115
 
@@ -118,7 +113,7 @@ class PHPMailer
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
 
@@ -128,91 +123,95 @@ class PHPMailer
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
 
@@ -222,130 +221,164 @@ class PHPMailer
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
 
@@ -353,43 +386,50 @@ class PHPMailer
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
  *
@@ -399,176 +439,225 @@ class PHPMailer
399
  * Value can be any php callable: http://www.php.net/is_callable
400
  *
401
  * Parameters:
402
- * bool $result result of the send action
403
  * string $to email address of the recipient
404
  * string $cc cc email addresses
405
  * string $bcc bcc email addresses
406
  * string $subject the subject
407
  * string $body the email body
408
  * string $from email address of sender
409
- * @type string
410
  */
411
  public $action_function = '';
412
 
413
  /**
414
- * What to use in the X-Mailer header.
415
- * Options: null for default, whitespace for none, or a string to use
416
- * @type string
417
  */
418
  public $XMailer = '';
419
 
 
 
 
 
 
 
 
 
 
420
  /**
421
  * An instance of the SMTP sender class.
422
- * @type SMTP
423
  * @access protected
424
  */
425
  protected $smtp = null;
426
 
427
  /**
428
- * The array of 'to' addresses.
429
- * @type array
430
  * @access protected
431
  */
432
  protected $to = array();
433
 
434
  /**
435
- * The array of 'cc' addresses.
436
- * @type array
437
  * @access protected
438
  */
439
  protected $cc = array();
440
 
441
  /**
442
- * The array of 'bcc' addresses.
443
- * @type array
444
  * @access protected
445
  */
446
  protected $bcc = array();
447
 
448
  /**
449
  * The array of reply-to names and addresses.
450
- * @type array
451
  * @access protected
452
  */
453
  protected $ReplyTo = array();
454
 
455
  /**
456
  * An array of all kinds of addresses.
457
- * Includes all of $to, $cc, $bcc, $replyto
458
- * @type array
459
  * @access protected
 
460
  */
461
  protected $all_recipients = array();
462
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  /**
464
  * The array of attachments.
465
- * @type array
466
  * @access protected
467
  */
468
  protected $attachment = array();
469
 
470
  /**
471
  * The array of custom headers.
472
- * @type array
473
  * @access protected
474
  */
475
  protected $CustomHeader = array();
476
 
477
  /**
478
  * The most recent Message-ID (including angular brackets).
479
- * @type string
480
  * @access protected
481
  */
482
  protected $lastMessageID = '';
483
 
484
  /**
485
  * The message's MIME type.
486
- * @type string
487
  * @access protected
488
  */
489
  protected $message_type = '';
490
 
491
  /**
492
  * The array of MIME boundary strings.
493
- * @type array
494
  * @access protected
495
  */
496
  protected $boundary = array();
497
 
498
  /**
499
  * The array of available languages.
500
- * @type array
501
  * @access protected
502
  */
503
  protected $language = array();
504
 
505
  /**
506
  * The number of errors encountered.
507
- * @type integer
508
  * @access protected
509
  */
510
  protected $error_count = 0;
511
 
512
  /**
513
  * The S/MIME certificate file path.
514
- * @type string
515
  * @access protected
516
  */
517
  protected $sign_cert_file = '';
518
 
519
  /**
520
  * The S/MIME key file path.
521
- * @type string
522
  * @access protected
523
  */
524
  protected $sign_key_file = '';
525
 
 
 
 
 
 
 
 
526
  /**
527
  * The S/MIME password for the key.
528
  * Used only if the key is encrypted.
529
- * @type string
530
  * @access protected
531
  */
532
  protected $sign_key_pass = '';
533
 
534
  /**
535
  * Whether to throw exceptions for errors.
536
- * @type bool
537
  * @access protected
538
  */
539
  protected $exceptions = false;
540
 
541
  /**
542
- * Error severity: message only, continue processing
 
 
 
 
 
 
 
543
  */
544
  const STOP_MESSAGE = 0;
545
 
546
  /**
547
- * Error severity: message, likely ok to continue processing
548
  */
549
  const STOP_CONTINUE = 1;
550
 
551
  /**
552
- * Error severity: message, plus full stop, critical error reached
553
  */
554
  const STOP_CRITICAL = 2;
555
 
556
  /**
557
- * SMTP RFC standard line ending
558
  */
559
  const CRLF = "\r\n";
560
 
561
  /**
562
- * Constructor
563
- * @param bool $exceptions Should we throw external exceptions?
564
  */
565
- public function __construct($exceptions = false)
 
 
 
 
 
 
566
  {
567
- $this->exceptions = ($exceptions == true);
568
- //Make sure our autoloader is loaded
569
- if (version_compare(PHP_VERSION, '5.1.2', '>=') and
570
- !spl_autoload_functions() || !in_array('PHPMailerAutoload', spl_autoload_functions())) {
571
- require 'PHPMailerAutoload.php';
572
  }
573
  }
574
 
@@ -577,9 +666,8 @@ class PHPMailer
577
  */
578
  public function __destruct()
579
  {
580
- if ($this->Mailer == 'smtp') { //close any open SMTP connection nicely
581
- $this->smtpClose();
582
- }
583
  }
584
 
585
  /**
@@ -593,7 +681,7 @@ class PHPMailer
593
  * @param string $header Additional Header(s)
594
  * @param string $params Params
595
  * @access private
596
- * @return bool
597
  */
598
  private function mailPassthru($to, $subject, $body, $header, $params)
599
  {
@@ -603,48 +691,67 @@ class PHPMailer
603
  } else {
604
  $subject = $this->encodeHeader($this->secureHeader($subject));
605
  }
606
- if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
607
- $rt = @mail($to, $subject, $body, $header);
 
 
 
608
  } else {
609
- $rt = @mail($to, $subject, $body, $header, $params);
610
  }
611
- return $rt;
612
  }
613
-
614
  /**
615
  * Output debugging info via user-defined method.
616
- * Only if debug output is enabled.
617
  * @see PHPMailer::$Debugoutput
618
  * @see PHPMailer::$SMTPDebug
619
  * @param string $str
620
  */
621
  protected function edebug($str)
622
  {
623
- if (!$this->SMTPDebug) {
 
 
 
 
 
624
  return;
625
  }
626
  switch ($this->Debugoutput) {
627
  case 'error_log':
 
628
  error_log($str);
629
  break;
630
  case 'html':
631
- //Cleans up output a bit for a better looking display that's HTML-safe
632
- echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, $this->CharSet) . "<br>\n";
 
 
 
 
 
633
  break;
634
  case 'echo':
635
  default:
636
- echo $str."\n";
 
 
 
 
 
 
637
  }
638
  }
639
 
640
  /**
641
  * Sets message type to HTML or plain.
642
- * @param bool $ishtml True for HTML mode.
643
  * @return void
644
  */
645
- public function isHTML($ishtml = true)
646
  {
647
- if ($ishtml) {
648
  $this->ContentType = 'text/html';
649
  } else {
650
  $this->ContentType = 'text/plain';
@@ -675,8 +782,12 @@ class PHPMailer
675
  */
676
  public function isSendmail()
677
  {
678
- if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
 
 
679
  $this->Sendmail = '/usr/sbin/sendmail';
 
 
680
  }
681
  $this->Mailer = 'sendmail';
682
  }
@@ -687,90 +798,140 @@ class PHPMailer
687
  */
688
  public function isQmail()
689
  {
690
- if (!stristr(ini_get('sendmail_path'), 'qmail')) {
 
 
691
  $this->Sendmail = '/var/qmail/bin/qmail-inject';
 
 
692
  }
693
  $this->Mailer = 'qmail';
694
  }
695
 
696
  /**
697
  * Add a "To" address.
698
- * @param string $address
699
  * @param string $name
700
- * @return bool true on success, false if address already used
701
  */
702
  public function addAddress($address, $name = '')
703
  {
704
- return $this->addAnAddress('to', $address, $name);
705
  }
706
 
707
  /**
708
  * Add a "CC" address.
709
  * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
710
- * @param string $address
711
  * @param string $name
712
- * @return bool true on success, false if address already used
713
  */
714
  public function addCC($address, $name = '')
715
  {
716
- return $this->addAnAddress('cc', $address, $name);
717
  }
718
 
719
  /**
720
  * Add a "BCC" address.
721
  * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
722
- * @param string $address
723
  * @param string $name
724
- * @return bool true on success, false if address already used
725
  */
726
  public function addBCC($address, $name = '')
727
  {
728
- return $this->addAnAddress('bcc', $address, $name);
729
  }
730
 
731
  /**
732
- * Add a "Reply-to" address.
733
- * @param string $address
734
  * @param string $name
735
- * @return bool
736
  */
737
  public function addReplyTo($address, $name = '')
738
  {
739
- return $this->addAnAddress('Reply-To', $address, $name);
740
  }
741
 
742
  /**
743
- * Add an address to one of the recipient arrays.
744
- * Addresses that have been added already return false, but do not throw exceptions
745
- * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
746
- * @param string $address The email address to send to
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747
  * @param string $name
748
  * @throws phpmailerException
749
- * @return bool true on success, false if address already used or invalid in some way
750
  * @access protected
751
  */
752
  protected function addAnAddress($kind, $address, $name = '')
753
  {
754
- if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
755
- $this->setError($this->lang('Invalid recipient array') . ': ' . $kind);
756
- $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind);
 
757
  if ($this->exceptions) {
758
- throw new phpmailerException('Invalid recipient array: ' . $kind);
759
  }
760
  return false;
761
  }
762
- $address = trim($address);
763
- $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
764
  if (!$this->validateAddress($address)) {
765
- $this->setError($this->lang('invalid_address') . ': ' . $address);
766
- $this->edebug($this->lang('invalid_address') . ': ' . $address);
 
767
  if ($this->exceptions) {
768
- throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
769
  }
770
  return false;
771
  }
772
  if ($kind != 'Reply-To') {
773
- if (!isset($this->all_recipients[strtolower($address)])) {
774
  array_push($this->$kind, array($address, $name));
775
  $this->all_recipients[strtolower($address)] = true;
776
  return true;
@@ -784,23 +945,82 @@ class PHPMailer
784
  return false;
785
  }
786
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
787
  /**
788
  * Set the From and FromName properties.
789
  * @param string $address
790
  * @param string $name
791
- * @param bool $auto Whether to also set the Sender address, defaults to true
792
  * @throws phpmailerException
793
- * @return bool
794
  */
795
  public function setFrom($address, $name = '', $auto = true)
796
  {
797
  $address = trim($address);
798
  $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
799
- if (!$this->validateAddress($address)) {
800
- $this->setError($this->lang('invalid_address') . ': ' . $address);
801
- $this->edebug($this->lang('invalid_address') . ': ' . $address);
 
 
 
 
802
  if ($this->exceptions) {
803
- throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
804
  }
805
  return false;
806
  }
@@ -829,28 +1049,47 @@ class PHPMailer
829
  /**
830
  * Check that a string looks like an email address.
831
  * @param string $address The email address to check
832
- * @param string $patternselect A selector for the validation pattern to use :
833
- * 'auto' - pick best one automatically;
834
- * 'pcre8' - use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
835
- * 'pcre' - use old PCRE implementation;
836
- * 'php' - use PHP built-in FILTER_VALIDATE_EMAIL; faster, less thorough;
837
- * 'noregex' - super fast, really dumb.
838
- * @return bool
 
 
 
 
 
 
839
  * @static
840
  * @access public
841
  */
842
- public static function validateAddress($address, $patternselect = 'auto')
843
  {
844
- if ($patternselect == 'auto') {
845
- if (defined(
846
- 'PCRE_VERSION'
847
- )
848
- ) { //Check this instead of extension_loaded so it works when that function is disabled
849
- if (version_compare(PCRE_VERSION, '8.0') >= 0) {
 
 
 
 
 
 
 
 
 
 
850
  $patternselect = 'pcre8';
851
  } else {
852
  $patternselect = 'pcre';
853
  }
 
 
 
854
  } else {
855
  //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension
856
  if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
@@ -863,14 +1102,12 @@ class PHPMailer
863
  switch ($patternselect) {
864
  case 'pcre8':
865
  /**
866
- * Conforms to RFC5322: Uses *correct* regex on which FILTER_VALIDATE_EMAIL is
867
- * based; So why not use FILTER_VALIDATE_EMAIL? Because it was broken to
868
- * not allow a@b type valid addresses :(
869
  * @link http://squiloople.com/2009/12/20/email-address-validation/
870
  * @copyright 2009-2010 Michael Rushton
871
  * Feel free to use and redistribute this code. But please keep this copyright notice.
872
  */
873
- return (bool)preg_match(
874
  '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
875
  '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
876
  '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
@@ -882,10 +1119,9 @@ class PHPMailer
882
  '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
883
  $address
884
  );
885
- break;
886
  case 'pcre':
887
  //An older regex that doesn't need a recent PCRE
888
- return (bool)preg_match(
889
  '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
890
  '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
891
  '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
@@ -898,26 +1134,75 @@ class PHPMailer
898
  '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
899
  $address
900
  );
901
- break;
902
- case 'php':
903
- default:
904
- return (bool)filter_var($address, FILTER_VALIDATE_EMAIL);
905
- break;
 
 
 
 
 
906
  case 'noregex':
907
  //No PCRE! Do something _very_ approximate!
908
  //Check the address is 3 chars or longer and contains an @ that's not the first or last char
909
  return (strlen($address) >= 3
910
  and strpos($address, '@') >= 1
911
  and strpos($address, '@') != strlen($address) - 1);
912
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
913
  }
 
914
  }
915
 
916
  /**
917
  * Create a message and send it.
918
  * Uses the sending method specified by $Mailer.
919
  * @throws phpmailerException
920
- * @return bool false on error - See the ErrorInfo property for details of the error.
921
  */
922
  public function send()
923
  {
@@ -926,11 +1211,11 @@ class PHPMailer
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
  }
@@ -939,38 +1224,67 @@ class PHPMailer
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',
@@ -980,10 +1294,11 @@ class PHPMailer
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)),
@@ -993,11 +1308,10 @@ class PHPMailer
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
  }
@@ -1007,7 +1321,7 @@ class PHPMailer
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
  {
@@ -1022,18 +1336,18 @@ class PHPMailer
1022
  case 'mail':
1023
  return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
1024
  default:
1025
- if (method_exists($this, $this->Mailer.'Send')) {
1026
- $sendMethod = $this->Mailer.'Send';
1027
  return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
1028
- } else {
1029
- return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
1030
  }
 
 
1031
  }
1032
- } catch (phpmailerException $e) {
1033
- $this->setError($e->getMessage());
1034
- $this->edebug($e->getMessage());
1035
  if ($this->exceptions) {
1036
- throw $e;
1037
  }
1038
  }
1039
  return false;
@@ -1046,35 +1360,46 @@ class PHPMailer
1046
  * @see PHPMailer::$Sendmail
1047
  * @throws phpmailerException
1048
  * @access protected
1049
- * @return bool
1050
  */
1051
  protected function sendmailSend($header, $body)
1052
  {
1053
- if ($this->Sender != '') {
 
1054
  if ($this->Mailer == 'qmail') {
1055
- $sendmail = sprintf("%s -f%s", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
1056
  } else {
1057
- $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
1058
  }
1059
  } else {
1060
  if ($this->Mailer == 'qmail') {
1061
- $sendmail = sprintf("%s", escapeshellcmd($this->Sendmail));
1062
  } else {
1063
- $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
1064
  }
1065
  }
1066
- if ($this->SingleTo === true) {
1067
- foreach ($this->SingleToArray as $val) {
 
 
 
 
1068
  if (!@$mail = popen($sendmail, 'w')) {
1069
  throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1070
  }
1071
- fputs($mail, "To: " . $val . "\n");
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, $val, $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
  }
@@ -1086,9 +1411,15 @@ class PHPMailer
1086
  fputs($mail, $header);
1087
  fputs($mail, $body);
1088
  $result = pclose($mail);
1089
- // implement call back function if it exists
1090
- $isSent = ($result == 0) ? 1 : 0;
1091
- $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
 
 
 
 
 
 
1092
  if ($result != 0) {
1093
  throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1094
  }
@@ -1096,6 +1427,40 @@ class PHPMailer
1096
  return true;
1097
  }
1098
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1099
  /**
1100
  * Send mail using the PHP mail() function.
1101
  * @param string $header The message headers
@@ -1103,43 +1468,42 @@ class PHPMailer
1103
  * @link http://www.php.net/manual/en/book.mail.php
1104
  * @throws phpmailerException
1105
  * @access protected
1106
- * @return bool
1107
  */
1108
  protected function mailSend($header, $body)
1109
  {
1110
  $toArr = array();
1111
- foreach ($this->to as $t) {
1112
- $toArr[] = $this->addrFormat($t);
1113
  }
1114
  $to = implode(', ', $toArr);
1115
 
1116
- if (empty($this->Sender)) {
1117
- $params = " ";
1118
- } else {
1119
- $params = sprintf("-f%s", $this->Sender);
 
 
 
1120
  }
1121
- if ($this->Sender != '' and !ini_get('safe_mode')) {
1122
  $old_from = ini_get('sendmail_from');
1123
  ini_set('sendmail_from', $this->Sender);
1124
  }
1125
- $rt = false;
1126
- if ($this->SingleTo === true && count($toArr) > 1) {
1127
- foreach ($toArr as $val) {
1128
- $rt = $this->mailPassthru($val, $this->Subject, $body, $header, $params);
1129
- // implement call back function if it exists
1130
- $isSent = ($rt == 1) ? 1 : 0;
1131
- $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1132
  }
1133
  } else {
1134
- $rt = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
1135
- // implement call back function if it exists
1136
- $isSent = ($rt == 1) ? 1 : 0;
1137
- $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1138
  }
1139
  if (isset($old_from)) {
1140
  ini_set('sendmail_from', $old_from);
1141
  }
1142
- if (!$rt) {
1143
  throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
1144
  }
1145
  return true;
@@ -1168,62 +1532,56 @@ class PHPMailer
1168
  * @throws phpmailerException
1169
  * @uses SMTP
1170
  * @access protected
1171
- * @return bool
1172
  */
1173
  protected function smtpSend($header, $body)
1174
  {
1175
  $bad_rcpt = array();
1176
-
1177
- if (!$this->smtpConnect()) {
1178
  throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
1179
  }
1180
- $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
 
 
 
 
1181
  if (!$this->smtp->mail($smtp_from)) {
1182
  $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
1183
  throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
1184
  }
1185
 
1186
- // Attempt to send attach all recipients
1187
- foreach ($this->to as $to) {
1188
- if (!$this->smtp->recipient($to[0])) {
1189
- $bad_rcpt[] = $to[0];
1190
- $isSent = 0;
1191
- } else {
1192
- $isSent = 1;
1193
- }
1194
- $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body, $this->From);
1195
- }
1196
- foreach ($this->cc as $cc) {
1197
- if (!$this->smtp->recipient($cc[0])) {
1198
- $bad_rcpt[] = $cc[0];
1199
- $isSent = 0;
1200
- } else {
1201
- $isSent = 1;
1202
- }
1203
- $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body, $this->From);
1204
- }
1205
- foreach ($this->bcc as $bcc) {
1206
- if (!$this->smtp->recipient($bcc[0])) {
1207
- $bad_rcpt[] = $bcc[0];
1208
- $isSent = 0;
1209
- } else {
1210
- $isSent = 1;
1211
  }
1212
- $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body, $this->From);
1213
  }
1214
 
1215
- if (!$this->smtp->data($header . $body)) {
 
1216
  throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
1217
  }
1218
- if ($this->SMTPKeepAlive == true) {
1219
  $this->smtp->reset();
1220
  } else {
1221
  $this->smtp->quit();
1222
  $this->smtp->close();
1223
  }
1224
- if (count($bad_rcpt) > 0) { //Create error message for any bad addresses
 
 
 
 
 
1225
  throw new phpmailerException(
1226
- $this->lang('recipients_failed') . implode(', ', $bad_rcpt),
1227
  self::STOP_CONTINUE
1228
  );
1229
  }
@@ -1237,15 +1595,20 @@ class PHPMailer
1237
  * @uses SMTP
1238
  * @access public
1239
  * @throws phpmailerException
1240
- * @return bool
1241
  */
1242
- public function smtpConnect($options = array())
1243
  {
1244
  if (is_null($this->smtp)) {
1245
  $this->smtp = $this->getSMTPInstance();
1246
  }
1247
 
1248
- //Already connected?
 
 
 
 
 
1249
  if ($this->smtp->connected()) {
1250
  return true;
1251
  }
@@ -1260,22 +1623,33 @@ class PHPMailer
1260
  foreach ($hosts as $hostentry) {
1261
  $hostinfo = array();
1262
  if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
1263
- //Not a valid host entry
1264
  continue;
1265
  }
1266
- //$hostinfo[2]: optional ssl or tls prefix
1267
- //$hostinfo[3]: the hostname
1268
- //$hostinfo[4]: optional port number
1269
- //The host string prefix can temporarily override the current setting for SMTPSecure
1270
- //If it's not specified, the default value is used
1271
  $prefix = '';
 
1272
  $tls = ($this->SMTPSecure == 'tls');
1273
- if ($hostinfo[2] == 'ssl' or ($hostinfo[2] == '' and $this->SMTPSecure == 'ssl')) {
1274
  $prefix = 'ssl://';
1275
- $tls = false; //Can't have SSL and TLS at once
 
1276
  } elseif ($hostinfo[2] == 'tls') {
1277
  $tls = true;
1278
- //tls doesn't use a prefix
 
 
 
 
 
 
 
 
 
1279
  }
1280
  $host = $hostinfo[3];
1281
  $port = $this->Port;
@@ -1291,12 +1665,19 @@ class PHPMailer
1291
  $hello = $this->serverHostname();
1292
  }
1293
  $this->smtp->hello($hello);
1294
-
 
 
 
 
 
 
 
1295
  if ($tls) {
1296
  if (!$this->smtp->startTLS()) {
1297
  throw new phpmailerException($this->lang('connect_host'));
1298
  }
1299
- //We must resend HELO after tls negotiation
1300
  $this->smtp->hello($hello);
1301
  }
1302
  if ($this->SMTPAuth) {
@@ -1312,16 +1693,17 @@ class PHPMailer
1312
  }
1313
  }
1314
  return true;
1315
- } catch (phpmailerException $e) {
1316
- $lastexception = $e;
1317
- //We must have connected, but then failed TLS or Auth, so close connection nicely
 
1318
  $this->smtp->quit();
1319
  }
1320
  }
1321
  }
1322
- //If we get here, all connection attempts have failed, so close connection hard
1323
  $this->smtp->close();
1324
- //As we've caught all exceptions, just report whatever the last one was
1325
  if ($this->exceptions and !is_null($lastexception)) {
1326
  throw $lastexception;
1327
  }
@@ -1334,7 +1716,7 @@ class PHPMailer
1334
  */
1335
  public function smtpClose()
1336
  {
1337
- if ($this->smtp !== null) {
1338
  if ($this->smtp->connected()) {
1339
  $this->smtp->quit();
1340
  $this->smtp->close();
@@ -1348,12 +1730,25 @@ class PHPMailer
1348
  * The default language is English.
1349
  * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr")
1350
  * @param string $lang_path Path to the language file directory, with trailing separator (slash)
1351
- * @return bool
1352
  * @access public
1353
  */
1354
- public function setLanguage($langcode = 'en', $lang_path = 'language/')
1355
  {
1356
- //Define full set of translatable strings
 
 
 
 
 
 
 
 
 
 
 
 
 
1357
  $PHPMAILER_LANG = array(
1358
  'authenticate' => 'SMTP Error: Could not authenticate.',
1359
  'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
@@ -1365,23 +1760,39 @@ class PHPMailer
1365
  'file_open' => 'File Error: Could not open file: ',
1366
  'from_failed' => 'The following From address failed: ',
1367
  'instantiate' => 'Could not instantiate mail function.',
1368
- 'invalid_address' => 'Invalid address',
1369
  'mailer_not_supported' => ' mailer is not supported.',
1370
  'provide_address' => 'You must provide at least one recipient email address.',
1371
  'recipients_failed' => 'SMTP Error: The following recipients failed: ',
1372
  'signing' => 'Signing Error: ',
1373
  'smtp_connect_failed' => 'SMTP connect() failed.',
1374
  'smtp_error' => 'SMTP server error: ',
1375
- 'variable_set' => 'Cannot set or reset variable: '
 
1376
  );
1377
- //Overwrite language-specific strings.
1378
- //This way we'll never have missing translations - no more "language string failed to load"!
1379
- $l = true;
1380
- if ($langcode != 'en') { //There is no English translation file
1381
- $l = @include $lang_path . 'phpmailer.lang-' . $langcode . '.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1382
  }
1383
  $this->language = $PHPMAILER_LANG;
1384
- return ($l == true); //Returns false if language not found
1385
  }
1386
 
1387
  /**
@@ -1406,8 +1817,8 @@ class PHPMailer
1406
  public function addrAppend($type, $addr)
1407
  {
1408
  $addresses = array();
1409
- foreach ($addr as $a) {
1410
- $addresses[] = $this->addrFormat($a);
1411
  }
1412
  return $type . ': ' . implode(', ', $addresses) . $this->LE;
1413
  }
@@ -1424,9 +1835,9 @@ class PHPMailer
1424
  if (empty($addr[1])) { // No name provided
1425
  return $this->secureHeader($addr[0]);
1426
  } else {
1427
- return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . " <" . $this->secureHeader(
1428
  $addr[0]
1429
- ) . ">";
1430
  }
1431
  }
1432
 
@@ -1437,47 +1848,54 @@ class PHPMailer
1437
  * Original written by philippe.
1438
  * @param string $message The message to wrap
1439
  * @param integer $length The line length to wrap to
1440
- * @param bool $qp_mode Whether to run in Quoted-Printable mode
1441
  * @access public
1442
  * @return string
1443
  */
1444
  public function wrapText($message, $length, $qp_mode = false)
1445
  {
1446
- $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
 
 
 
 
1447
  // If utf-8 encoding is used, we will need to make sure we don't
1448
  // split multibyte characters when we wrap
1449
- $is_utf8 = (strtolower($this->CharSet) == "utf-8");
1450
  $lelen = strlen($this->LE);
1451
  $crlflen = strlen(self::CRLF);
1452
 
1453
  $message = $this->fixEOL($message);
 
1454
  if (substr($message, -$lelen) == $this->LE) {
1455
  $message = substr($message, 0, -$lelen);
1456
  }
1457
 
1458
- $line = explode($this->LE, $message); // Magic. We know fixEOL uses $LE
 
 
1459
  $message = '';
1460
- for ($i = 0; $i < count($line); $i++) {
1461
- $line_part = explode(' ', $line[$i]);
1462
  $buf = '';
1463
- for ($e = 0; $e < count($line_part); $e++) {
1464
- $word = $line_part[$e];
1465
  if ($qp_mode and (strlen($word) > $length)) {
1466
  $space_left = $length - strlen($buf) - $crlflen;
1467
- if ($e != 0) {
1468
  if ($space_left > 20) {
1469
  $len = $space_left;
1470
  if ($is_utf8) {
1471
  $len = $this->utf8CharBoundary($word, $len);
1472
- } elseif (substr($word, $len - 1, 1) == "=") {
1473
  $len--;
1474
- } elseif (substr($word, $len - 2, 1) == "=") {
1475
  $len -= 2;
1476
  }
1477
  $part = substr($word, 0, $len);
1478
  $word = substr($word, $len);
1479
  $buf .= ' ' . $part;
1480
- $message .= $buf . sprintf("=%s", self::CRLF);
1481
  } else {
1482
  $message .= $buf . $soft_break;
1483
  }
@@ -1490,29 +1908,33 @@ class PHPMailer
1490
  $len = $length;
1491
  if ($is_utf8) {
1492
  $len = $this->utf8CharBoundary($word, $len);
1493
- } elseif (substr($word, $len - 1, 1) == "=") {
1494
  $len--;
1495
- } elseif (substr($word, $len - 2, 1) == "=") {
1496
  $len -= 2;
1497
  }
1498
  $part = substr($word, 0, $len);
1499
  $word = substr($word, $len);
1500
 
1501
  if (strlen($word) > 0) {
1502
- $message .= $part . sprintf("=%s", self::CRLF);
1503
  } else {
1504
  $buf = $part;
1505
  }
1506
  }
1507
  } else {
1508
  $buf_o = $buf;
1509
- $buf .= ($e == 0) ? $word : (' ' . $word);
 
 
 
1510
 
1511
  if (strlen($buf) > $length and $buf_o != '') {
1512
  $message .= $buf_o . $soft_break;
1513
  $buf = $word;
1514
  }
1515
  }
 
1516
  }
1517
  $message .= $buf . self::CRLF;
1518
  }
@@ -1522,12 +1944,12 @@ class PHPMailer
1522
 
1523
  /**
1524
  * Find the last character boundary prior to $maxLength in a utf-8
1525
- * quoted (printable) encoded string.
1526
  * Original written by Colin Brown.
1527
  * @access public
1528
  * @param string $encodedText utf-8 QP text
1529
- * @param int $maxLength find last character boundary prior to this length
1530
- * @return int
1531
  */
1532
  public function utf8CharBoundary($encodedText, $maxLength)
1533
  {
@@ -1535,23 +1957,27 @@ class PHPMailer
1535
  $lookBack = 3;
1536
  while (!$foundSplitPos) {
1537
  $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
1538
- $encodedCharPos = strpos($lastChunk, "=");
1539
- if ($encodedCharPos !== false) {
1540
  // Found start of encoded character byte within $lookBack block.
1541
  // Check the encoded byte value (the 2 chars after the '=')
1542
  $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
1543
  $dec = hexdec($hex);
1544
- if ($dec < 128) { // Single byte character.
 
1545
  // If the encoded char was found at pos 0, it will fit
1546
  // otherwise reduce maxLength to start of the encoded char
1547
- $maxLength = ($encodedCharPos == 0) ? $maxLength :
1548
- $maxLength - ($lookBack - $encodedCharPos);
 
1549
  $foundSplitPos = true;
1550
- } elseif ($dec >= 192) { // First byte of a multi byte character
 
1551
  // Reduce maxLength to split at start of character
1552
  $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1553
  $foundSplitPos = true;
1554
- } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
 
1555
  $lookBack += 3;
1556
  }
1557
  } else {
@@ -1562,9 +1988,11 @@ class PHPMailer
1562
  return $maxLength;
1563
  }
1564
 
1565
-
1566
  /**
1567
- * Set the body wrapping.
 
 
 
1568
  * @access public
1569
  * @return void
1570
  */
@@ -1596,38 +2024,25 @@ class PHPMailer
1596
  {
1597
  $result = '';
1598
 
1599
- // Set the boundaries
1600
- $uniq_id = md5(uniqid(time()));
1601
- $this->boundary[1] = 'b1_' . $uniq_id;
1602
- $this->boundary[2] = 'b2_' . $uniq_id;
1603
- $this->boundary[3] = 'b3_' . $uniq_id;
1604
-
1605
  if ($this->MessageDate == '') {
1606
- $result .= $this->headerLine('Date', self::rfcDate());
1607
- } else {
1608
- $result .= $this->headerLine('Date', $this->MessageDate);
1609
- }
1610
-
1611
- if ($this->ReturnPath) {
1612
- $result .= $this->headerLine('Return-Path', '<' . trim($this->ReturnPath) . '>');
1613
- } elseif ($this->Sender == '') {
1614
- $result .= $this->headerLine('Return-Path', '<' . trim($this->From) . '>');
1615
- } else {
1616
- $result .= $this->headerLine('Return-Path', '<' . trim($this->Sender) . '>');
1617
  }
 
1618
 
1619
  // To be created automatically by mail()
1620
- if ($this->Mailer != 'mail') {
1621
- if ($this->SingleTo === true) {
1622
- foreach ($this->to as $t) {
1623
- $this->SingleToArray[] = $this->addrFormat($t);
1624
  }
1625
- } else {
1626
- if (count($this->to) > 0) {
 
 
1627
  $result .= $this->addrAppend('To', $this->to);
1628
- } elseif (count($this->cc) == 0) {
1629
- $result .= $this->headerLine('To', 'undisclosed-recipients:;');
1630
  }
 
 
1631
  }
1632
  }
1633
 
@@ -1656,17 +2071,21 @@ class PHPMailer
1656
  $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
1657
  }
1658
 
1659
- if ($this->MessageID != '') {
 
 
1660
  $this->lastMessageID = $this->MessageID;
1661
  } else {
1662
- $this->lastMessageID = sprintf("<%s@%s>", $uniq_id, $this->ServerHostname());
 
 
 
 
1663
  }
1664
- $result .= $this->HeaderLine('Message-ID', $this->lastMessageID);
1665
- $result .= $this->headerLine('X-Priority', $this->Priority);
1666
  if ($this->XMailer == '') {
1667
  $result .= $this->headerLine(
1668
  'X-Mailer',
1669
- 'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer/)'
1670
  );
1671
  } else {
1672
  $myXmailer = trim($this->XMailer);
@@ -1676,14 +2095,14 @@ class PHPMailer
1676
  }
1677
 
1678
  if ($this->ConfirmReadingTo != '') {
1679
- $result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
1680
  }
1681
 
1682
  // Add custom headers
1683
- for ($index = 0; $index < count($this->CustomHeader); $index++) {
1684
  $result .= $this->headerLine(
1685
- trim($this->CustomHeader[$index][0]),
1686
- $this->encodeHeader(trim($this->CustomHeader[$index][1]))
1687
  );
1688
  }
1689
  if (!$this->sign_key_file) {
@@ -1702,6 +2121,7 @@ class PHPMailer
1702
  public function getMailMIME()
1703
  {
1704
  $result = '';
 
1705
  switch ($this->message_type) {
1706
  case 'inline':
1707
  $result .= $this->headerLine('Content-Type', 'multipart/related;');
@@ -1722,11 +2142,20 @@ class PHPMailer
1722
  default:
1723
  // Catches case 'plain': and case '':
1724
  $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
 
1725
  break;
1726
  }
1727
- //RFC1341 part 5 says 7bit is assumed if not specified
1728
  if ($this->Encoding != '7bit') {
1729
- $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
 
 
 
 
 
 
 
 
1730
  }
1731
 
1732
  if ($this->Mailer != 'mail') {
@@ -1739,16 +2168,23 @@ class PHPMailer
1739
  /**
1740
  * Returns the whole MIME message.
1741
  * Includes complete headers and body.
1742
- * Only valid post PreSend().
1743
- * @see PHPMailer::PreSend()
1744
  * @access public
1745
  * @return string
1746
  */
1747
  public function getSentMIMEMessage()
1748
  {
1749
- return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
1750
  }
1751
 
 
 
 
 
 
 
 
1752
 
1753
  /**
1754
  * Assemble the message body.
@@ -1760,6 +2196,11 @@ class PHPMailer
1760
  public function createBody()
1761
  {
1762
  $body = '';
 
 
 
 
 
1763
 
1764
  if ($this->sign_key_file) {
1765
  $body .= $this->getMailMIME() . $this->LE;
@@ -1767,37 +2208,70 @@ class PHPMailer
1767
 
1768
  $this->setWordWrap();
1769
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1770
  switch ($this->message_type) {
1771
  case 'inline':
1772
- $body .= $this->getBoundary($this->boundary[1], '', '', '');
1773
- $body .= $this->encodeString($this->Body, $this->Encoding);
 
1774
  $body .= $this->LE . $this->LE;
1775
  $body .= $this->attachAll('inline', $this->boundary[1]);
1776
  break;
1777
  case 'attach':
1778
- $body .= $this->getBoundary($this->boundary[1], '', '', '');
1779
- $body .= $this->encodeString($this->Body, $this->Encoding);
 
1780
  $body .= $this->LE . $this->LE;
1781
  $body .= $this->attachAll('attachment', $this->boundary[1]);
1782
  break;
1783
  case 'inline_attach':
 
1784
  $body .= $this->textLine('--' . $this->boundary[1]);
1785
  $body .= $this->headerLine('Content-Type', 'multipart/related;');
1786
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
1787
  $body .= $this->LE;
1788
- $body .= $this->getBoundary($this->boundary[2], '', '', '');
1789
- $body .= $this->encodeString($this->Body, $this->Encoding);
1790
  $body .= $this->LE . $this->LE;
1791
  $body .= $this->attachAll('inline', $this->boundary[2]);
1792
  $body .= $this->LE;
1793
  $body .= $this->attachAll('attachment', $this->boundary[1]);
1794
  break;
1795
  case 'alt':
1796
- $body .= $this->getBoundary($this->boundary[1], '', 'text/plain', '');
1797
- $body .= $this->encodeString($this->AltBody, $this->Encoding);
 
1798
  $body .= $this->LE . $this->LE;
1799
- $body .= $this->getBoundary($this->boundary[1], '', 'text/html', '');
1800
- $body .= $this->encodeString($this->Body, $this->Encoding);
1801
  $body .= $this->LE . $this->LE;
1802
  if (!empty($this->Ical)) {
1803
  $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
@@ -1807,49 +2281,52 @@ class PHPMailer
1807
  $body .= $this->endBoundary($this->boundary[1]);
1808
  break;
1809
  case 'alt_inline':
1810
- $body .= $this->getBoundary($this->boundary[1], '', 'text/plain', '');
1811
- $body .= $this->encodeString($this->AltBody, $this->Encoding);
 
1812
  $body .= $this->LE . $this->LE;
1813
  $body .= $this->textLine('--' . $this->boundary[1]);
1814
  $body .= $this->headerLine('Content-Type', 'multipart/related;');
1815
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
1816
  $body .= $this->LE;
1817
- $body .= $this->getBoundary($this->boundary[2], '', 'text/html', '');
1818
- $body .= $this->encodeString($this->Body, $this->Encoding);
1819
  $body .= $this->LE . $this->LE;
1820
  $body .= $this->attachAll('inline', $this->boundary[2]);
1821
  $body .= $this->LE;
1822
  $body .= $this->endBoundary($this->boundary[1]);
1823
  break;
1824
  case 'alt_attach':
 
1825
  $body .= $this->textLine('--' . $this->boundary[1]);
1826
  $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
1827
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
1828
  $body .= $this->LE;
1829
- $body .= $this->getBoundary($this->boundary[2], '', 'text/plain', '');
1830
- $body .= $this->encodeString($this->AltBody, $this->Encoding);
1831
  $body .= $this->LE . $this->LE;
1832
- $body .= $this->getBoundary($this->boundary[2], '', 'text/html', '');
1833
- $body .= $this->encodeString($this->Body, $this->Encoding);
1834
  $body .= $this->LE . $this->LE;
1835
  $body .= $this->endBoundary($this->boundary[2]);
1836
  $body .= $this->LE;
1837
  $body .= $this->attachAll('attachment', $this->boundary[1]);
1838
  break;
1839
  case 'alt_inline_attach':
 
1840
  $body .= $this->textLine('--' . $this->boundary[1]);
1841
  $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
1842
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
1843
  $body .= $this->LE;
1844
- $body .= $this->getBoundary($this->boundary[2], '', 'text/plain', '');
1845
- $body .= $this->encodeString($this->AltBody, $this->Encoding);
1846
  $body .= $this->LE . $this->LE;
1847
  $body .= $this->textLine('--' . $this->boundary[2]);
1848
  $body .= $this->headerLine('Content-Type', 'multipart/related;');
1849
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"');
1850
  $body .= $this->LE;
1851
- $body .= $this->getBoundary($this->boundary[3], '', 'text/html', '');
1852
- $body .= $this->encodeString($this->Body, $this->Encoding);
1853
  $body .= $this->LE . $this->LE;
1854
  $body .= $this->attachAll('inline', $this->boundary[3]);
1855
  $body .= $this->LE;
@@ -1858,7 +2335,9 @@ class PHPMailer
1858
  $body .= $this->attachAll('attachment', $this->boundary[1]);
1859
  break;
1860
  default:
1861
- // catch case 'plain' and case ''
 
 
1862
  $body .= $this->encodeString($this->Body, $this->Encoding);
1863
  break;
1864
  }
@@ -1868,32 +2347,51 @@ class PHPMailer
1868
  } elseif ($this->sign_key_file) {
1869
  try {
1870
  if (!defined('PKCS7_TEXT')) {
1871
- throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
1872
  }
1873
- //TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1
1874
  $file = tempnam(sys_get_temp_dir(), 'mail');
1875
- file_put_contents($file, $body); //TODO check this worked
 
 
1876
  $signed = tempnam(sys_get_temp_dir(), 'signed');
1877
- if (@openssl_pkcs7_sign(
1878
- $file,
1879
- $signed,
1880
- 'file://' . realpath($this->sign_cert_file),
1881
- array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
1882
- null
1883
- )
1884
- ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
1885
  @unlink($file);
1886
  $body = file_get_contents($signed);
1887
  @unlink($signed);
 
 
 
 
1888
  } else {
1889
  @unlink($file);
1890
  @unlink($signed);
1891
  throw new phpmailerException($this->lang('signing') . openssl_error_string());
1892
  }
1893
- } catch (phpmailerException $e) {
1894
  $body = '';
1895
  if ($this->exceptions) {
1896
- throw $e;
1897
  }
1898
  }
1899
  }
@@ -1922,9 +2420,12 @@ class PHPMailer
1922
  $encoding = $this->Encoding;
1923
  }
1924
  $result .= $this->textLine('--' . $boundary);
1925
- $result .= sprintf("Content-Type: %s; charset=%s", $contentType, $charSet);
1926
  $result .= $this->LE;
1927
- $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
 
 
 
1928
  $result .= $this->LE;
1929
 
1930
  return $result;
@@ -1943,26 +2444,26 @@ class PHPMailer
1943
 
1944
  /**
1945
  * Set the message type.
1946
- * PHPMailer only supports some preset message types,
1947
- * not arbitrary MIME structures.
1948
  * @access protected
1949
  * @return void
1950
  */
1951
  protected function setMessageType()
1952
  {
1953
- $this->message_type = array();
1954
  if ($this->alternativeExists()) {
1955
- $this->message_type[] = "alt";
1956
  }
1957
  if ($this->inlineImageExists()) {
1958
- $this->message_type[] = "inline";
1959
  }
1960
  if ($this->attachmentExists()) {
1961
- $this->message_type[] = "attach";
1962
  }
1963
- $this->message_type = implode("_", $this->message_type);
1964
- if ($this->message_type == "") {
1965
- $this->message_type = "plain";
 
1966
  }
1967
  }
1968
 
@@ -1998,7 +2499,7 @@ class PHPMailer
1998
  * @param string $type File extension (MIME) type.
1999
  * @param string $disposition Disposition to use
2000
  * @throws phpmailerException
2001
- * @return bool
2002
  */
2003
  public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')
2004
  {
@@ -2007,7 +2508,7 @@ class PHPMailer
2007
  throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
2008
  }
2009
 
2010
- //If a MIME type is not specified, try to work it out from the file name
2011
  if ($type == '') {
2012
  $type = self::filenameToType($path);
2013
  }
@@ -2028,11 +2529,11 @@ class PHPMailer
2028
  7 => 0
2029
  );
2030
 
2031
- } catch (phpmailerException $e) {
2032
- $this->setError($e->getMessage());
2033
- $this->edebug($e->getMessage());
2034
  if ($this->exceptions) {
2035
- throw $e;
2036
  }
2037
  return false;
2038
  }
@@ -2087,22 +2588,34 @@ class PHPMailer
2087
  $type = $attachment[4];
2088
  $disposition = $attachment[6];
2089
  $cid = $attachment[7];
2090
- if ($disposition == 'inline' && isset($cidUniq[$cid])) {
2091
  continue;
2092
  }
2093
  $cidUniq[$cid] = true;
2094
 
2095
- $mime[] = sprintf("--%s%s", $boundary, $this->LE);
2096
- $mime[] = sprintf(
2097
- "Content-Type: %s; name=\"%s\"%s",
2098
- $type,
2099
- $this->encodeHeader($this->secureHeader($name)),
2100
- $this->LE
2101
- );
2102
- $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
 
 
 
 
 
 
 
 
 
 
 
 
2103
 
2104
  if ($disposition == 'inline') {
2105
- $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
2106
  }
2107
 
2108
  // If a filename contains any of these chars, it should be quoted,
@@ -2110,20 +2623,29 @@ class PHPMailer
2110
  // Fixes a warning in IETF's msglint MIME checker
2111
  // Allow for bypassing the Content-Disposition header totally
2112
  if (!(empty($disposition))) {
2113
- if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $name)) {
 
2114
  $mime[] = sprintf(
2115
- "Content-Disposition: %s; filename=\"%s\"%s",
2116
  $disposition,
2117
- $this->encodeHeader($this->secureHeader($name)),
2118
  $this->LE . $this->LE
2119
  );
2120
  } else {
2121
- $mime[] = sprintf(
2122
- "Content-Disposition: %s; filename=%s%s",
2123
- $disposition,
2124
- $this->encodeHeader($this->secureHeader($name)),
2125
- $this->LE . $this->LE
2126
- );
 
 
 
 
 
 
 
 
2127
  }
2128
  } else {
2129
  $mime[] = $this->LE;
@@ -2146,9 +2668,9 @@ class PHPMailer
2146
  }
2147
  }
2148
 
2149
- $mime[] = sprintf("--%s--%s", $boundary, $this->LE);
2150
 
2151
- return implode("", $mime);
2152
  }
2153
 
2154
  /**
@@ -2157,7 +2679,6 @@ class PHPMailer
2157
  * @param string $path The full path to the file
2158
  * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
2159
  * @throws phpmailerException
2160
- * @see EncodeFile(encodeFile
2161
  * @access protected
2162
  * @return string
2163
  */
@@ -2170,9 +2691,12 @@ class PHPMailer
2170
  $magic_quotes = get_magic_quotes_runtime();
2171
  if ($magic_quotes) {
2172
  if (version_compare(PHP_VERSION, '5.3.0', '<')) {
2173
- set_magic_quotes_runtime(0);
2174
  } else {
2175
- ini_set('magic_quotes_runtime', 0);
 
 
 
2176
  }
2177
  }
2178
  $file_buffer = file_get_contents($path);
@@ -2185,8 +2709,8 @@ class PHPMailer
2185
  }
2186
  }
2187
  return $file_buffer;
2188
- } catch (Exception $e) {
2189
- $this->setError($e->getMessage());
2190
  return '';
2191
  }
2192
  }
@@ -2209,7 +2733,7 @@ class PHPMailer
2209
  case '7bit':
2210
  case '8bit':
2211
  $encoded = $this->fixEOL($str);
2212
- //Make sure it ends with a line break
2213
  if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
2214
  $encoded .= $this->LE;
2215
  }
@@ -2237,11 +2761,11 @@ class PHPMailer
2237
  */
2238
  public function encodeHeader($str, $position = 'text')
2239
  {
2240
- $x = 0;
2241
  switch (strtolower($position)) {
2242
  case 'phrase':
2243
  if (!preg_match('/[\200-\377]/', $str)) {
2244
- // Can't use addslashes as we don't know what value has magic_quotes_sybase
2245
  $encoded = addcslashes($str, "\0..\37\177\\\"");
2246
  if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
2247
  return ($encoded);
@@ -2249,26 +2773,27 @@ class PHPMailer
2249
  return ("\"$encoded\"");
2250
  }
2251
  }
2252
- $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
2253
  break;
2254
  /** @noinspection PhpMissingBreakStatementInspection */
2255
  case 'comment':
2256
- $x = preg_match_all('/[()"]/', $str, $matches);
2257
  // Intentional fall-through
2258
  case 'text':
2259
  default:
2260
- $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
2261
  break;
2262
  }
2263
 
2264
- if ($x == 0) { //There are no chars that need encoding
 
2265
  return ($str);
2266
  }
2267
 
2268
  $maxlen = 75 - 7 - strlen($this->CharSet);
2269
  // Try to select the encoding which should produce the shortest output
2270
- if ($x > strlen($str) / 3) {
2271
- //More than a third of the content will need encoding, so B encoding will be most efficient
2272
  $encoding = 'B';
2273
  if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
2274
  // Use a custom function which correctly encodes and wraps long
@@ -2286,7 +2811,7 @@ class PHPMailer
2286
  $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded));
2287
  }
2288
 
2289
- $encoded = preg_replace('/^(.*)$/m', " =?" . $this->CharSet . "?$encoding?\\1?=", $encoded);
2290
  $encoded = trim(str_replace("\n", $this->LE, $encoded));
2291
 
2292
  return $encoded;
@@ -2296,7 +2821,7 @@ class PHPMailer
2296
  * Check if a string contains multi-byte characters.
2297
  * @access public
2298
  * @param string $str multi-byte text to wrap encode
2299
- * @return bool
2300
  */
2301
  public function hasMultiBytes($str)
2302
  {
@@ -2307,22 +2832,33 @@ class PHPMailer
2307
  }
2308
  }
2309
 
 
 
 
 
 
 
 
 
 
 
2310
  /**
2311
  * Encode and wrap long multibyte strings for mail headers
2312
  * without breaking lines within a character.
2313
- * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
 
2314
  * @access public
2315
  * @param string $str multi-byte text to wrap encode
2316
- * @param string $lf string to use as linefeed/end-of-line
2317
  * @return string
2318
  */
2319
- public function base64EncodeWrapMB($str, $lf = null)
2320
  {
2321
- $start = "=?" . $this->CharSet . "?B?";
2322
- $end = "?=";
2323
- $encoded = "";
2324
- if ($lf === null) {
2325
- $lf = $this->LE;
2326
  }
2327
 
2328
  $mb_length = mb_strlen($str, $this->CharSet);
@@ -2341,11 +2877,11 @@ class PHPMailer
2341
  $chunk = base64_encode($chunk);
2342
  $lookBack++;
2343
  } while (strlen($chunk) > $length);
2344
- $encoded .= $chunk . $lf;
2345
  }
2346
 
2347
  // Chomp the last linefeed
2348
- $encoded = substr($encoded, 0, -strlen($lf));
2349
  return $encoded;
2350
  }
2351
 
@@ -2356,21 +2892,21 @@ class PHPMailer
2356
  * @param string $string The text to encode
2357
  * @param integer $line_max Number of chars allowed on a line before wrapping
2358
  * @return string
2359
- * @link PHP version adapted from http://www.php.net/manual/en/function.quoted-printable-decode.php#89417
2360
  */
2361
  public function encodeQP($string, $line_max = 76)
2362
  {
2363
- if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3)
 
2364
  return quoted_printable_encode($string);
2365
  }
2366
- //Fall back to a pure PHP implementation
2367
  $string = str_replace(
2368
  array('%20', '%0D%0A.', '%0D%0A', '%'),
2369
  array(' ', "\r\n=2E", "\r\n", '='),
2370
  rawurlencode($string)
2371
  );
2372
- $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
2373
- return $string;
2374
  }
2375
 
2376
  /**
@@ -2379,7 +2915,7 @@ class PHPMailer
2379
  * @access public
2380
  * @param string $string
2381
  * @param integer $line_max
2382
- * @param bool $space_conv
2383
  * @return string
2384
  * @deprecated Use encodeQP instead.
2385
  */
@@ -2401,45 +2937,44 @@ class PHPMailer
2401
  */
2402
  public function encodeQ($str, $position = 'text')
2403
  {
2404
- //There should not be any EOL in the string
2405
  $pattern = '';
2406
  $encoded = str_replace(array("\r", "\n"), '', $str);
2407
  switch (strtolower($position)) {
2408
  case 'phrase':
2409
- //RFC 2047 section 5.3
2410
  $pattern = '^A-Za-z0-9!*+\/ -';
2411
  break;
2412
  /** @noinspection PhpMissingBreakStatementInspection */
2413
  case 'comment':
2414
- //RFC 2047 section 5.2
2415
  $pattern = '\(\)"';
2416
- //intentional fall-through
2417
- //for this reason we build the $pattern without including delimiters and []
2418
  case 'text':
2419
  default:
2420
- //RFC 2047 section 5.1
2421
- //Replace every high ascii, control, =, ? and _ characters
2422
  $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
2423
  break;
2424
  }
2425
  $matches = array();
2426
  if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
2427
- //If the string contains an '=', make sure it's the first thing we replace
2428
- //so as to avoid double-encoding
2429
- $s = array_search('=', $matches[0]);
2430
- if ($s !== false) {
2431
- unset($matches[0][$s]);
2432
  array_unshift($matches[0], '=');
2433
  }
2434
  foreach (array_unique($matches[0]) as $char) {
2435
  $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
2436
  }
2437
  }
2438
- //Replace every spaces to _ (more readable than =20)
2439
  return str_replace(' ', '_', $encoded);
2440
  }
2441
 
2442
-
2443
  /**
2444
  * Add a string or binary attachment (non-filesystem).
2445
  * This method can be used to attach ascii or binary data,
@@ -2458,7 +2993,7 @@ class PHPMailer
2458
  $type = '',
2459
  $disposition = 'attachment'
2460
  ) {
2461
- //If a MIME type is not specified, try to work it out from the file name
2462
  if ($type == '') {
2463
  $type = self::filenameToType($filename);
2464
  }
@@ -2478,7 +3013,7 @@ class PHPMailer
2478
  /**
2479
  * Add an embedded (inline) attachment from a file.
2480
  * This can include images, sounds, and just about any other document type.
2481
- * These differ from 'regular' attachmants in that they are intended to be
2482
  * displayed inline with the message, not just attached for download.
2483
  * This is used in HTML messages that embed the images
2484
  * the HTML refers to using the $cid value.
@@ -2489,7 +3024,7 @@ class PHPMailer
2489
  * @param string $encoding File encoding (see $Encoding).
2490
  * @param string $type File MIME type.
2491
  * @param string $disposition Disposition to use
2492
- * @return bool True on successfully adding an attachment
2493
  */
2494
  public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
2495
  {
@@ -2498,7 +3033,7 @@ class PHPMailer
2498
  return false;
2499
  }
2500
 
2501
- //If a MIME type is not specified, try to work it out from the file name
2502
  if ($type == '') {
2503
  $type = self::filenameToType($path);
2504
  }
@@ -2534,7 +3069,7 @@ class PHPMailer
2534
  * @param string $encoding File encoding (see $Encoding).
2535
  * @param string $type MIME type.
2536
  * @param string $disposition Disposition to use
2537
- * @return bool True on successfully adding an attachment
2538
  */
2539
  public function addStringEmbeddedImage(
2540
  $string,
@@ -2544,8 +3079,8 @@ class PHPMailer
2544
  $type = '',
2545
  $disposition = 'inline'
2546
  ) {
2547
- //If a MIME type is not specified, try to work it out from the name
2548
- if ($type == '') {
2549
  $type = self::filenameToType($name);
2550
  }
2551
 
@@ -2566,7 +3101,7 @@ class PHPMailer
2566
  /**
2567
  * Check if an inline attachment is present.
2568
  * @access public
2569
- * @return bool
2570
  */
2571
  public function inlineImageExists()
2572
  {
@@ -2580,7 +3115,7 @@ class PHPMailer
2580
 
2581
  /**
2582
  * Check if an attachment (non-inline) is present.
2583
- * @return bool
2584
  */
2585
  public function attachmentExists()
2586
  {
@@ -2594,13 +3129,29 @@ class PHPMailer
2594
 
2595
  /**
2596
  * Check if this message has an alternative body set.
2597
- * @return bool
2598
  */
2599
  public function alternativeExists()
2600
  {
2601
  return !empty($this->AltBody);
2602
  }
2603
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2604
  /**
2605
  * Clear all To recipients.
2606
  * @return void
@@ -2611,6 +3162,7 @@ class PHPMailer
2611
  unset($this->all_recipients[strtolower($to[0])]);
2612
  }
2613
  $this->to = array();
 
2614
  }
2615
 
2616
  /**
@@ -2623,6 +3175,7 @@ class PHPMailer
2623
  unset($this->all_recipients[strtolower($cc[0])]);
2624
  }
2625
  $this->cc = array();
 
2626
  }
2627
 
2628
  /**
@@ -2635,6 +3188,7 @@ class PHPMailer
2635
  unset($this->all_recipients[strtolower($bcc[0])]);
2636
  }
2637
  $this->bcc = array();
 
2638
  }
2639
 
2640
  /**
@@ -2644,6 +3198,7 @@ class PHPMailer
2644
  public function clearReplyTos()
2645
  {
2646
  $this->ReplyTo = array();
 
2647
  }
2648
 
2649
  /**
@@ -2656,6 +3211,7 @@ class PHPMailer
2656
  $this->cc = array();
2657
  $this->bcc = array();
2658
  $this->all_recipients = array();
 
2659
  }
2660
 
2661
  /**
@@ -2687,8 +3243,17 @@ class PHPMailer
2687
  $this->error_count++;
2688
  if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
2689
  $lasterror = $this->smtp->getError();
2690
- if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
2691
- $msg .= '<p>' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
 
 
 
 
 
 
 
 
 
2692
  }
2693
  }
2694
  $this->ErrorInfo = $msg;
@@ -2702,8 +3267,8 @@ class PHPMailer
2702
  */
2703
  public static function rfcDate()
2704
  {
2705
- //Set the time zone to whatever the default is to avoid 500 errors
2706
- //Will default to UTC if it's not set properly in php.ini
2707
  date_default_timezone_set(@date_default_timezone_get());
2708
  return date('D, j M Y H:i:s O');
2709
  }
@@ -2716,14 +3281,16 @@ class PHPMailer
2716
  */
2717
  protected function serverHostname()
2718
  {
 
2719
  if (!empty($this->Hostname)) {
2720
  $result = $this->Hostname;
2721
- } elseif (isset($_SERVER['SERVER_NAME'])) {
2722
  $result = $_SERVER['SERVER_NAME'];
2723
- } else {
2724
- $result = 'localhost.localdomain';
 
 
2725
  }
2726
-
2727
  return $result;
2728
  }
2729
 
@@ -2739,17 +3306,24 @@ class PHPMailer
2739
  $this->setLanguage('en'); // set the default language
2740
  }
2741
 
2742
- if (isset($this->language[$key])) {
 
 
 
 
 
 
2743
  return $this->language[$key];
2744
  } else {
2745
- return 'Language string failed to load: ' . $key;
 
2746
  }
2747
  }
2748
 
2749
  /**
2750
  * Check if an error occurred.
2751
  * @access public
2752
- * @return bool True if an error did occur.
2753
  */
2754
  public function isError()
2755
  {
@@ -2794,29 +3368,58 @@ class PHPMailer
2794
  }
2795
 
2796
  /**
2797
- * Create a message from an HTML string.
2798
- * Automatically makes modifications for inline images and backgrounds
2799
- * and creates a plain-text version by converting the HTML.
2800
- * Overwrites any existing values in $this->Body and $this->AltBody
 
 
 
 
 
 
 
 
 
 
 
2801
  * @access public
2802
  * @param string $message HTML message string
2803
- * @param string $basedir baseline directory for path
2804
- * @param bool $advanced Whether to use the advanced HTML to text converter
2805
- * @return string $message
 
2806
  */
2807
  public function msgHTML($message, $basedir = '', $advanced = false)
2808
  {
2809
- preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images);
2810
- if (isset($images[2])) {
2811
- foreach ($images[2] as $i => $url) {
2812
- // do not change urls for absolute images (thanks to corvuscorax)
2813
- if (!preg_match('#^[A-z]+://#', $url)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2814
  $filename = basename($url);
2815
  $directory = dirname($url);
2816
  if ($directory == '.') {
2817
  $directory = '';
2818
  }
2819
- $cid = md5($url) . '@phpmailer.0'; //RFC2392 S 2
2820
  if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
2821
  $basedir .= '/';
2822
  }
@@ -2828,12 +3431,12 @@ class PHPMailer
2828
  $cid,
2829
  $filename,
2830
  'base64',
2831
- self::_mime_types(self::mb_pathinfo($filename, PATHINFO_EXTENSION))
2832
  )
2833
  ) {
2834
  $message = preg_replace(
2835
- "/" . $images[1][$i] . "=[\"']" . preg_quote($url, '/') . "[\"']/Ui",
2836
- $images[1][$i] . "=\"cid:" . $cid . "\"",
2837
  $message
2838
  );
2839
  }
@@ -2841,27 +3444,40 @@ class PHPMailer
2841
  }
2842
  }
2843
  $this->isHTML(true);
2844
- if (empty($this->AltBody)) {
2845
- $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
2846
- }
2847
- //Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
2848
  $this->Body = $this->normalizeBreaks($message);
2849
  $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
 
 
 
 
2850
  return $this->Body;
2851
  }
2852
 
2853
  /**
2854
  * Convert an HTML string into plain text.
 
 
 
 
 
 
 
 
 
 
 
 
 
2855
  * @param string $html The HTML text to convert
2856
- * @param bool $advanced Should this use the more complex html2text converter or just a simple one?
 
2857
  * @return string
2858
  */
2859
  public function html2text($html, $advanced = false)
2860
  {
2861
- if ($advanced) {
2862
- require_once 'extras/class.html2text.php';
2863
- $h = new html2text($html);
2864
- return $h->get_text();
2865
  }
2866
  return html_entity_decode(
2867
  trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))),
@@ -2880,94 +3496,109 @@ class PHPMailer
2880
  public static function _mime_types($ext = '')
2881
  {
2882
  $mimes = array(
2883
- 'xl' => 'application/excel',
2884
- 'hqx' => 'application/mac-binhex40',
2885
- 'cpt' => 'application/mac-compactpro',
2886
- 'bin' => 'application/macbinary',
2887
- 'doc' => 'application/msword',
2888
- 'word' => 'application/msword',
 
 
 
 
 
 
 
 
 
 
 
2889
  'class' => 'application/octet-stream',
2890
- 'dll' => 'application/octet-stream',
2891
- 'dms' => 'application/octet-stream',
2892
- 'exe' => 'application/octet-stream',
2893
- 'lha' => 'application/octet-stream',
2894
- 'lzh' => 'application/octet-stream',
2895
- 'psd' => 'application/octet-stream',
2896
- 'sea' => 'application/octet-stream',
2897
- 'so' => 'application/octet-stream',
2898
- 'oda' => 'application/oda',
2899
- 'pdf' => 'application/pdf',
2900
- 'ai' => 'application/postscript',
2901
- 'eps' => 'application/postscript',
2902
- 'ps' => 'application/postscript',
2903
- 'smi' => 'application/smil',
2904
- 'smil' => 'application/smil',
2905
- 'mif' => 'application/vnd.mif',
2906
- 'xls' => 'application/vnd.ms-excel',
2907
- 'ppt' => 'application/vnd.ms-powerpoint',
2908
  'wbxml' => 'application/vnd.wap.wbxml',
2909
- 'wmlc' => 'application/vnd.wap.wmlc',
2910
- 'dcr' => 'application/x-director',
2911
- 'dir' => 'application/x-director',
2912
- 'dxr' => 'application/x-director',
2913
- 'dvi' => 'application/x-dvi',
2914
- 'gtar' => 'application/x-gtar',
2915
- 'php3' => 'application/x-httpd-php',
2916
- 'php4' => 'application/x-httpd-php',
2917
- 'php' => 'application/x-httpd-php',
2918
  'phtml' => 'application/x-httpd-php',
2919
- 'phps' => 'application/x-httpd-php-source',
2920
- 'js' => 'application/x-javascript',
2921
- 'swf' => 'application/x-shockwave-flash',
2922
- 'sit' => 'application/x-stuffit',
2923
- 'tar' => 'application/x-tar',
2924
- 'tgz' => 'application/x-tar',
2925
- 'xht' => 'application/xhtml+xml',
2926
  'xhtml' => 'application/xhtml+xml',
2927
- 'zip' => 'application/zip',
2928
- 'mid' => 'audio/midi',
2929
- 'midi' => 'audio/midi',
2930
- 'mp2' => 'audio/mpeg',
2931
- 'mp3' => 'audio/mpeg',
2932
- 'mpga' => 'audio/mpeg',
2933
- 'aif' => 'audio/x-aiff',
2934
- 'aifc' => 'audio/x-aiff',
2935
- 'aiff' => 'audio/x-aiff',
2936
- 'ram' => 'audio/x-pn-realaudio',
2937
- 'rm' => 'audio/x-pn-realaudio',
2938
- 'rpm' => 'audio/x-pn-realaudio-plugin',
2939
- 'ra' => 'audio/x-realaudio',
2940
- 'wav' => 'audio/x-wav',
2941
- 'bmp' => 'image/bmp',
2942
- 'gif' => 'image/gif',
2943
- 'jpeg' => 'image/jpeg',
2944
- 'jpe' => 'image/jpeg',
2945
- 'jpg' => 'image/jpeg',
2946
- 'png' => 'image/png',
2947
- 'tiff' => 'image/tiff',
2948
- 'tif' => 'image/tiff',
2949
- 'eml' => 'message/rfc822',
2950
- 'css' => 'text/css',
2951
- 'html' => 'text/html',
2952
- 'htm' => 'text/html',
2953
  'shtml' => 'text/html',
2954
- 'log' => 'text/plain',
2955
- 'text' => 'text/plain',
2956
- 'txt' => 'text/plain',
2957
- 'rtx' => 'text/richtext',
2958
- 'rtf' => 'text/rtf',
2959
- 'xml' => 'text/xml',
2960
- 'xsl' => 'text/xml',
2961
- 'mpeg' => 'video/mpeg',
2962
- 'mpe' => 'video/mpeg',
2963
- 'mpg' => 'video/mpeg',
2964
- 'mov' => 'video/quicktime',
2965
- 'qt' => 'video/quicktime',
2966
- 'rv' => 'video/vnd.rn-realvideo',
2967
- 'avi' => 'video/x-msvideo',
 
 
2968
  'movie' => 'video/x-sgi-movie'
2969
  );
2970
- return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]: 'application/octet-stream');
 
 
 
2971
  }
2972
 
2973
  /**
@@ -2979,9 +3610,9 @@ class PHPMailer
2979
  */
2980
  public static function filenameToType($filename)
2981
  {
2982
- //In case the path is a URL, strip any query string before getting extension
2983
  $qpos = strpos($filename, '?');
2984
- if ($qpos !== false) {
2985
  $filename = substr($filename, 0, $qpos);
2986
  }
2987
  $pathinfo = self::mb_pathinfo($filename);
@@ -3002,37 +3633,34 @@ class PHPMailer
3002
  public static function mb_pathinfo($path, $options = null)
3003
  {
3004
  $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
3005
- $m = array();
3006
- preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $m);
3007
- if (array_key_exists(1, $m)) {
3008
- $ret['dirname'] = $m[1];
3009
- }
3010
- if (array_key_exists(2, $m)) {
3011
- $ret['basename'] = $m[2];
3012
- }
3013
- if (array_key_exists(5, $m)) {
3014
- $ret['extension'] = $m[5];
3015
- }
3016
- if (array_key_exists(3, $m)) {
3017
- $ret['filename'] = $m[3];
 
3018
  }
3019
  switch ($options) {
3020
  case PATHINFO_DIRNAME:
3021
  case 'dirname':
3022
  return $ret['dirname'];
3023
- break;
3024
  case PATHINFO_BASENAME:
3025
  case 'basename':
3026
  return $ret['basename'];
3027
- break;
3028
  case PATHINFO_EXTENSION:
3029
  case 'extension':
3030
  return $ret['extension'];
3031
- break;
3032
  case PATHINFO_FILENAME:
3033
  case 'filename':
3034
  return $ret['filename'];
3035
- break;
3036
  default:
3037
  return $ret;
3038
  }
@@ -3040,33 +3668,27 @@ class PHPMailer
3040
 
3041
  /**
3042
  * Set or reset instance properties.
3043
- *
 
3044
  * Usage Example:
3045
- * $page->set('X-Priority', '3');
3046
- *
 
3047
  * @access public
3048
- * @param string $name
3049
- * @param mixed $value
3050
- * NOTE: will not work with arrays, there are no arrays to set/reset
3051
- * @throws phpmailerException
3052
- * @return bool
3053
- * @todo Should this not be using __set() magic function?
3054
  */
3055
  public function set($name, $value = '')
3056
  {
3057
- try {
3058
- if (isset($this->$name)) {
3059
- $this->$name = $value;
3060
- } else {
3061
- throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL);
3062
- }
3063
- } catch (Exception $e) {
3064
- $this->setError($e->getMessage());
3065
- if ($e->getCode() == self::STOP_CRITICAL) {
3066
- return false;
3067
- }
3068
  }
3069
- return true;
3070
  }
3071
 
3072
  /**
@@ -3095,19 +3717,20 @@ class PHPMailer
3095
  return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text);
3096
  }
3097
 
3098
-
3099
  /**
3100
  * Set the public and private key files and password for S/MIME signing.
3101
  * @access public
3102
  * @param string $cert_filename
3103
  * @param string $key_filename
3104
  * @param string $key_pass Password for private key
 
3105
  */
3106
- public function sign($cert_filename, $key_filename, $key_pass)
3107
  {
3108
  $this->sign_cert_file = $cert_filename;
3109
  $this->sign_key_file = $key_filename;
3110
  $this->sign_key_pass = $key_pass;
 
3111
  }
3112
 
3113
  /**
@@ -3124,7 +3747,7 @@ class PHPMailer
3124
  if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
3125
  $line .= $txt[$i];
3126
  } else {
3127
- $line .= "=" . sprintf("%02X", $ord);
3128
  }
3129
  }
3130
  return $line;
@@ -3133,48 +3756,68 @@ class PHPMailer
3133
  /**
3134
  * Generate a DKIM signature.
3135
  * @access public
3136
- * @param string $s Header
3137
  * @throws phpmailerException
3138
- * @return string
3139
  */
3140
- public function DKIM_Sign($s)
3141
  {
3142
  if (!defined('PKCS7_TEXT')) {
3143
  if ($this->exceptions) {
3144
- throw new phpmailerException($this->lang("signing") . ' OpenSSL extension missing.');
3145
  }
3146
  return '';
3147
  }
3148
- $privKeyStr = file_get_contents($this->DKIM_private);
3149
- if ($this->DKIM_passphrase != '') {
3150
  $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
3151
  } else {
3152
- $privKey = $privKeyStr;
3153
- }
3154
- if (openssl_sign($s, $signature, $privKey)) {
3155
- return base64_encode($signature);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3156
  }
 
3157
  return '';
3158
  }
3159
 
3160
  /**
3161
  * Generate a DKIM canonicalization header.
3162
  * @access public
3163
- * @param string $s Header
3164
  * @return string
3165
  */
3166
- public function DKIM_HeaderC($s)
3167
  {
3168
- $s = preg_replace("/\r\n\s+/", " ", $s);
3169
- $lines = explode("\r\n", $s);
3170
  foreach ($lines as $key => $line) {
3171
- list($heading, $value) = explode(":", $line, 2);
3172
  $heading = strtolower($heading);
3173
- $value = preg_replace("/\s+/", " ", $value); // Compress useless spaces
3174
- $lines[$key] = $heading . ":" . trim($value); // Don't forget to remove WSP around the value
3175
  }
3176
- $s = implode("\r\n", $lines);
3177
- return $s;
3178
  }
3179
 
3180
  /**
@@ -3208,7 +3851,7 @@ class PHPMailer
3208
  */
3209
  public function DKIM_Add($headers_line, $subject, $body)
3210
  {
3211
- $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
3212
  $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
3213
  $DKIMquery = 'dns/txt'; // Query method
3214
  $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
@@ -3216,6 +3859,7 @@ class PHPMailer
3216
  $headers = explode($this->LE, $headers_line);
3217
  $from_header = '';
3218
  $to_header = '';
 
3219
  $current = '';
3220
  foreach ($headers as $header) {
3221
  if (strpos($header, 'From:') === 0) {
@@ -3224,9 +3868,12 @@ class PHPMailer
3224
  } elseif (strpos($header, 'To:') === 0) {
3225
  $to_header = $header;
3226
  $current = 'to_header';
 
 
 
3227
  } else {
3228
- if ($current && strpos($header, ' =?') === 0) {
3229
- $current .= $header;
3230
  } else {
3231
  $current = '';
3232
  }
@@ -3234,6 +3881,7 @@ class PHPMailer
3234
  }
3235
  $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
3236
  $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
 
3237
  $subject = str_replace(
3238
  '|',
3239
  '=7C',
@@ -3241,40 +3889,116 @@ class PHPMailer
3241
  ); // Copied header fields (dkim-quoted-printable)
3242
  $body = $this->DKIM_BodyC($body);
3243
  $DKIMlen = strlen($body); // Length of body
3244
- $DKIMb64 = base64_encode(pack("H*", sha1($body))); // Base64 of packed binary SHA-1 hash of body
3245
- $ident = ($this->DKIM_identity == '') ? '' : " i=" . $this->DKIM_identity . ";";
3246
- $dkimhdrs = "DKIM-Signature: v=1; a=" .
3247
- $DKIMsignatureType . "; q=" .
3248
- $DKIMquery . "; l=" .
3249
- $DKIMlen . "; s=" .
 
 
 
 
3250
  $this->DKIM_selector .
3251
  ";\r\n" .
3252
- "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n" .
3253
- "\th=From:To:Subject;\r\n" .
3254
- "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n" .
3255
  "\tz=$from\r\n" .
3256
  "\t|$to\r\n" .
 
3257
  "\t|$subject;\r\n" .
3258
  "\tbh=" . $DKIMb64 . ";\r\n" .
3259
  "\tb=";
3260
  $toSign = $this->DKIM_HeaderC(
3261
- $from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs
 
 
 
 
3262
  );
3263
  $signed = $this->DKIM_Sign($toSign);
3264
  return $dkimhdrs . $signed . "\r\n";
3265
  }
3266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3267
  /**
3268
  * Perform a callback.
3269
- * @param bool $isSent
3270
- * @param string $to
3271
- * @param string $cc
3272
- * @param string $bcc
3273
  * @param string $subject
3274
  * @param string $body
3275
  * @param string $from
3276
  */
3277
- protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from = null)
3278
  {
3279
  if (!empty($this->action_function) && is_callable($this->action_function)) {
3280
  $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
1
  <?php
2
  /**
3
  * PHPMailer - PHP email creation and transport class.
4
+ * PHP Version 5
 
5
  * @package PHPMailer
6
+ * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
7
+ * @author Marcus Bointon (Synchro/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 2012 - 2014 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
17
  * FITNESS FOR A PARTICULAR PURPOSE.
18
  */
19
 
 
 
 
 
20
  /**
21
  * PHPMailer - PHP email creation and transport class.
 
22
  * @package PHPMailer
23
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
24
  * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
25
  * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
26
  * @author Brent R. Matzelle (original founder)
 
 
 
27
  */
28
  class PHPMailer
29
  {
30
  /**
31
  * The PHPMailer Version number.
32
+ * @var string
33
  */
34
+ public $Version = '5.2.21';
35
 
36
  /**
37
  * Email priority.
38
+ * Options: null (default), 1 = High, 3 = Normal, 5 = low.
39
+ * When null, the header is not set at all.
40
+ * @var integer
41
  */
42
+ public $Priority = null;
43
 
44
  /**
45
  * The character set of the message.
46
+ * @var string
47
  */
48
  public $CharSet = 'iso-8859-1';
49
 
50
  /**
51
  * The MIME Content-type of the message.
52
+ * @var string
53
  */
54
  public $ContentType = 'text/plain';
55
 
56
  /**
57
  * The message encoding.
58
  * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
59
+ * @var string
60
  */
61
  public $Encoding = '8bit';
62
 
63
  /**
64
  * Holds the most recent mailer error message.
65
+ * @var string
66
  */
67
  public $ErrorInfo = '';
68
 
69
  /**
70
  * The From email address for the message.
71
+ * @var string
72
  */
73
  public $From = 'root@localhost';
74
 
75
  /**
76
  * The From name of the message.
77
+ * @var string
78
  */
79
  public $FromName = 'Root User';
80
 
81
  /**
82
  * The Sender email (Return-Path) of the message.
83
  * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
84
+ * @var string
85
  */
86
  public $Sender = '';
87
 
88
  /**
89
  * The Return-Path of the message.
90
  * If empty, it will be set to either From or Sender.
91
+ * @var string
92
+ * @deprecated Email senders should never set a return-path header;
93
+ * it's the receiver's job (RFC5321 section 4.4), so this no longer does anything.
94
+ * @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference
95
  */
96
  public $ReturnPath = '';
97
 
98
  /**
99
  * The Subject of the message.
100
+ * @var string
101
  */
102
  public $Subject = '';
103
 
104
  /**
105
  * An HTML or plain text message body.
106
  * If HTML then call isHTML(true).
107
+ * @var string
108
  */
109
  public $Body = '';
110
 
113
  * This body can be read by mail clients that do not have HTML email
114
  * capability such as mutt & Eudora.
115
  * Clients that can read HTML will view the normal Body.
116
+ * @var string
117
  */
118
  public $AltBody = '';
119
 
123
  * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator
124
  * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/
125
  * @link http://kigkonsult.se/iCalcreator/
126
+ * @var string
127
  */
128
  public $Ical = '';
129
 
130
  /**
131
  * The complete compiled MIME message body.
132
  * @access protected
133
+ * @var string
134
  */
135
  protected $MIMEBody = '';
136
 
137
  /**
138
  * The complete compiled MIME message headers.
139
+ * @var string
140
  * @access protected
141
  */
142
  protected $MIMEHeader = '';
143
 
144
  /**
145
  * Extra headers that createHeader() doesn't fold in.
146
+ * @var string
147
  * @access protected
148
  */
149
  protected $mailHeader = '';
150
 
151
  /**
152
  * Word-wrap the message body to this number of chars.
153
+ * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance.
154
+ * @var integer
155
  */
156
  public $WordWrap = 0;
157
 
158
  /**
159
  * Which method to use to send mail.
160
  * Options: "mail", "sendmail", or "smtp".
161
+ * @var string
162
  */
163
  public $Mailer = 'mail';
164
 
165
  /**
166
  * The path to the sendmail program.
167
+ * @var string
168
  */
169
  public $Sendmail = '/usr/sbin/sendmail';
170
 
171
  /**
172
  * Whether mail() uses a fully sendmail-compatible MTA.
173
  * One which supports sendmail's "-oi -f" options.
174
+ * @var boolean
175
  */
176
  public $UseSendmailOptions = true;
177
 
178
  /**
179
  * Path to PHPMailer plugins.
180
  * Useful if the SMTP class is not in the PHP include path.
181
+ * @var string
182
  * @deprecated Should not be needed now there is an autoloader.
183
  */
184
  public $PluginDir = '';
185
 
186
  /**
187
+ * The email address that a reading confirmation should be sent to, also known as read receipt.
188
+ * @var string
189
  */
190
  public $ConfirmReadingTo = '';
191
 
192
  /**
193
+ * The hostname to use in the Message-ID header and as default HELO string.
194
+ * If empty, PHPMailer attempts to find one with, in order,
195
+ * $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value
196
+ * 'localhost.localdomain'.
197
+ * @var string
198
  */
199
  public $Hostname = '';
200
 
201
  /**
202
+ * An ID to be used in the Message-ID header.
203
  * If empty, a unique id will be generated.
204
+ * You can set your own, but it must be in the format "<id@domain>",
205
+ * as defined in RFC5322 section 3.6.4 or it will be ignored.
206
+ * @see https://tools.ietf.org/html/rfc5322#section-3.6.4
207
+ * @var string
208
  */
209
  public $MessageID = '';
210
 
211
  /**
212
  * The message Date to be used in the Date header.
213
  * If empty, the current date will be added.
214
+ * @var string
215
  */
216
  public $MessageDate = '';
217
 
221
  * You can also specify a different port
222
  * for each host by using this format: [hostname:port]
223
  * (e.g. "smtp1.example.com:25;smtp2.example.com").
224
+ * You can also specify encryption type, for example:
225
+ * (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465").
226
  * Hosts will be tried in order.
227
+ * @var string
228
  */
229
  public $Host = 'localhost';
230
 
231
  /**
232
  * The default SMTP server port.
233
+ * @var integer
234
+ * @TODO Why is this needed when the SMTP class takes care of it?
235
  */
236
  public $Port = 25;
237
 
238
  /**
239
  * The SMTP HELO of the message.
240
+ * Default is $Hostname. If $Hostname is empty, PHPMailer attempts to find
241
+ * one with the same method described above for $Hostname.
242
+ * @var string
243
  * @see PHPMailer::$Hostname
244
  */
245
  public $Helo = '';
246
 
247
  /**
248
+ * What kind of encryption to use on the SMTP connection.
249
+ * Options: '', 'ssl' or 'tls'
250
+ * @var string
251
  */
252
  public $SMTPSecure = '';
253
 
254
+ /**
255
+ * Whether to enable TLS encryption automatically if a server supports it,
256
+ * even if `SMTPSecure` is not set to 'tls'.
257
+ * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid.
258
+ * @var boolean
259
+ */
260
+ public $SMTPAutoTLS = true;
261
+
262
  /**
263
  * Whether to use SMTP authentication.
264
  * Uses the Username and Password properties.
265
+ * @var boolean
266
  * @see PHPMailer::$Username
267
  * @see PHPMailer::$Password
268
  */
269
  public $SMTPAuth = false;
270
 
271
+ /**
272
+ * Options array passed to stream_context_create when connecting via SMTP.
273
+ * @var array
274
+ */
275
+ public $SMTPOptions = array();
276
+
277
  /**
278
  * SMTP username.
279
+ * @var string
280
  */
281
  public $Username = '';
282
 
283
  /**
284
  * SMTP password.
285
+ * @var string
286
  */
287
  public $Password = '';
288
 
289
  /**
290
  * SMTP auth type.
291
+ * Options are CRAM-MD5, LOGIN, PLAIN, NTLM, XOAUTH2, attempted in that order if not specified
292
+ * @var string
293
  */
294
  public $AuthType = '';
295
 
296
  /**
297
  * SMTP realm.
298
  * Used for NTLM auth
299
+ * @var string
300
  */
301
  public $Realm = '';
302
 
303
  /**
304
  * SMTP workstation.
305
  * Used for NTLM auth
306
+ * @var string
307
  */
308
  public $Workstation = '';
309
 
310
  /**
311
  * The SMTP server timeout in seconds.
312
+ * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
313
+ * @var integer
314
  */
315
+ public $Timeout = 300;
316
 
317
  /**
318
  * SMTP class debug output mode.
319
+ * Debug output level.
320
+ * Options:
321
+ * * `0` No output
322
+ * * `1` Commands
323
+ * * `2` Data and commands
324
+ * * `3` As 2 plus connection status
325
+ * * `4` Low-level data output
326
+ * @var integer
327
  * @see SMTP::$do_debug
328
  */
329
  public $SMTPDebug = 0;
330
 
331
  /**
332
+ * How to handle debug output.
333
+ * Options:
334
+ * * `echo` Output plain-text as-is, appropriate for CLI
335
+ * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
336
+ * * `error_log` Output to error log as configured in php.ini
337
+ *
338
+ * Alternatively, you can provide a callable expecting two params: a message string and the debug level:
339
+ * <code>
340
+ * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
341
+ * </code>
342
+ * @var string|callable
343
  * @see SMTP::$Debugoutput
344
  */
345
+ public $Debugoutput = 'echo';
346
 
347
  /**
348
  * Whether to keep SMTP connection open after each message.
349
  * If this is set to true then to close the connection
350
  * requires an explicit call to smtpClose().
351
+ * @var boolean
352
  */
353
  public $SMTPKeepAlive = false;
354
 
355
  /**
356
  * Whether to split multiple to addresses into multiple messages
357
  * or send them all in one message.
358
+ * Only supported in `mail` and `sendmail` transports, not in SMTP.
359
+ * @var boolean
360
  */
361
  public $SingleTo = false;
362
 
363
  /**
364
  * Storage for addresses when SingleTo is enabled.
365
+ * @var array
366
+ * @TODO This should really not be public
367
  */
368
  public $SingleToArray = array();
369
 
370
  /**
371
  * Whether to generate VERP addresses on send.
372
  * Only applicable when sending via SMTP.
373
+ * @link https://en.wikipedia.org/wiki/Variable_envelope_return_path
374
+ * @link http://www.postfix.org/VERP_README.html Postfix VERP info
375
+ * @var boolean
376
  */
377
  public $do_verp = false;
378
 
379
  /**
380
  * Whether to allow sending messages with an empty body.
381
+ * @var boolean
382
  */
383
  public $AllowEmpty = false;
384
 
386
  * The default line ending.
387
  * @note The default remains "\n". We force CRLF where we know
388
  * it must be used via self::CRLF.
389
+ * @var string
390
  */
391
  public $LE = "\n";
392
 
393
  /**
394
  * DKIM selector.
395
+ * @var string
396
  */
397
  public $DKIM_selector = '';
398
 
399
  /**
400
  * DKIM Identity.
401
+ * Usually the email address used as the source of the email.
402
+ * @var string
403
  */
404
  public $DKIM_identity = '';
405
 
406
  /**
407
  * DKIM passphrase.
408
  * Used if your key is encrypted.
409
+ * @var string
410
  */
411
  public $DKIM_passphrase = '';
412
 
413
  /**
414
  * DKIM signing domain name.
415
  * @example 'example.com'
416
+ * @var string
417
  */
418
  public $DKIM_domain = '';
419
 
420
  /**
421
  * DKIM private key file path.
422
+ * @var string
423
  */
424
  public $DKIM_private = '';
425
 
426
+ /**
427
+ * DKIM private key string.
428
+ * If set, takes precedence over `$DKIM_private`.
429
+ * @var string
430
+ */
431
+ public $DKIM_private_string = '';
432
+
433
  /**
434
  * Callback Action function name.
435
  *
439
  * Value can be any php callable: http://www.php.net/is_callable
440
  *
441
  * Parameters:
442
+ * boolean $result result of the send action
443
  * string $to email address of the recipient
444
  * string $cc cc email addresses
445
  * string $bcc bcc email addresses
446
  * string $subject the subject
447
  * string $body the email body
448
  * string $from email address of sender
449
+ * @var string
450
  */
451
  public $action_function = '';
452
 
453
  /**
454
+ * What to put in the X-Mailer header.
455
+ * Options: An empty string for PHPMailer default, whitespace for none, or a string to use
456
+ * @var string
457
  */
458
  public $XMailer = '';
459
 
460
+ /**
461
+ * Which validator to use by default when validating email addresses.
462
+ * May be a callable to inject your own validator, but there are several built-in validators.
463
+ * @see PHPMailer::validateAddress()
464
+ * @var string|callable
465
+ * @static
466
+ */
467
+ public static $validator = 'auto';
468
+
469
  /**
470
  * An instance of the SMTP sender class.
471
+ * @var SMTP
472
  * @access protected
473
  */
474
  protected $smtp = null;
475
 
476
  /**
477
+ * The array of 'to' names and addresses.
478
+ * @var array
479
  * @access protected
480
  */
481
  protected $to = array();
482
 
483
  /**
484
+ * The array of 'cc' names and addresses.
485
+ * @var array
486
  * @access protected
487
  */
488
  protected $cc = array();
489
 
490
  /**
491
+ * The array of 'bcc' names and addresses.
492
+ * @var array
493
  * @access protected
494
  */
495
  protected $bcc = array();
496
 
497
  /**
498
  * The array of reply-to names and addresses.
499
+ * @var array
500
  * @access protected
501
  */
502
  protected $ReplyTo = array();
503
 
504
  /**
505
  * An array of all kinds of addresses.
506
+ * Includes all of $to, $cc, $bcc
507
+ * @var array
508
  * @access protected
509
+ * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc
510
  */
511
  protected $all_recipients = array();
512
 
513
+ /**
514
+ * An array of names and addresses queued for validation.
515
+ * In send(), valid and non duplicate entries are moved to $all_recipients
516
+ * and one of $to, $cc, or $bcc.
517
+ * This array is used only for addresses with IDN.
518
+ * @var array
519
+ * @access protected
520
+ * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc
521
+ * @see PHPMailer::$all_recipients
522
+ */
523
+ protected $RecipientsQueue = array();
524
+
525
+ /**
526
+ * An array of reply-to names and addresses queued for validation.
527
+ * In send(), valid and non duplicate entries are moved to $ReplyTo.
528
+ * This array is used only for addresses with IDN.
529
+ * @var array
530
+ * @access protected
531
+ * @see PHPMailer::$ReplyTo
532
+ */
533
+ protected $ReplyToQueue = array();
534
+
535
  /**
536
  * The array of attachments.
537
+ * @var array
538
  * @access protected
539
  */
540
  protected $attachment = array();
541
 
542
  /**
543
  * The array of custom headers.
544
+ * @var array
545
  * @access protected
546
  */
547
  protected $CustomHeader = array();
548
 
549
  /**
550
  * The most recent Message-ID (including angular brackets).
551
+ * @var string
552
  * @access protected
553
  */
554
  protected $lastMessageID = '';
555
 
556
  /**
557
  * The message's MIME type.
558
+ * @var string
559
  * @access protected
560
  */
561
  protected $message_type = '';
562
 
563
  /**
564
  * The array of MIME boundary strings.
565
+ * @var array
566
  * @access protected
567
  */
568
  protected $boundary = array();
569
 
570
  /**
571
  * The array of available languages.
572
+ * @var array
573
  * @access protected
574
  */
575
  protected $language = array();
576
 
577
  /**
578
  * The number of errors encountered.
579
+ * @var integer
580
  * @access protected
581
  */
582
  protected $error_count = 0;
583
 
584
  /**
585
  * The S/MIME certificate file path.
586
+ * @var string
587
  * @access protected
588
  */
589
  protected $sign_cert_file = '';
590
 
591
  /**
592
  * The S/MIME key file path.
593
+ * @var string
594
  * @access protected
595
  */
596
  protected $sign_key_file = '';
597
 
598
+ /**
599
+ * The optional S/MIME extra certificates ("CA Chain") file path.
600
+ * @var string
601
+ * @access protected
602
+ */
603
+ protected $sign_extracerts_file = '';
604
+
605
  /**
606
  * The S/MIME password for the key.
607
  * Used only if the key is encrypted.
608
+ * @var string
609
  * @access protected
610
  */
611
  protected $sign_key_pass = '';
612
 
613
  /**
614
  * Whether to throw exceptions for errors.
615
+ * @var boolean
616
  * @access protected
617
  */
618
  protected $exceptions = false;
619
 
620
  /**
621
+ * Unique ID used for message ID and boundaries.
622
+ * @var string
623
+ * @access protected
624
+ */
625
+ protected $uniqueid = '';
626
+
627
+ /**
628
+ * Error severity: message only, continue processing.
629
  */
630
  const STOP_MESSAGE = 0;
631
 
632
  /**
633
+ * Error severity: message, likely ok to continue processing.
634
  */
635
  const STOP_CONTINUE = 1;
636
 
637
  /**
638
+ * Error severity: message, plus full stop, critical error reached.
639
  */
640
  const STOP_CRITICAL = 2;
641
 
642
  /**
643
+ * SMTP RFC standard line ending.
644
  */
645
  const CRLF = "\r\n";
646
 
647
  /**
648
+ * The maximum line length allowed by RFC 2822 section 2.1.1
649
+ * @var integer
650
  */
651
+ const MAX_LINE_LENGTH = 998;
652
+
653
+ /**
654
+ * Constructor.
655
+ * @param boolean $exceptions Should we throw external exceptions?
656
+ */
657
+ public function __construct($exceptions = null)
658
  {
659
+ if ($exceptions !== null) {
660
+ $this->exceptions = (boolean)$exceptions;
 
 
 
661
  }
662
  }
663
 
666
  */
667
  public function __destruct()
668
  {
669
+ //Close any open SMTP connection nicely
670
+ $this->smtpClose();
 
671
  }
672
 
673
  /**
681
  * @param string $header Additional Header(s)
682
  * @param string $params Params
683
  * @access private
684
+ * @return boolean
685
  */
686
  private function mailPassthru($to, $subject, $body, $header, $params)
687
  {
691
  } else {
692
  $subject = $this->encodeHeader($this->secureHeader($subject));
693
  }
694
+
695
+ //Can't use additional_parameters in safe_mode, calling mail() with null params breaks
696
+ //@link http://php.net/manual/en/function.mail.php
697
+ if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) {
698
+ $result = @mail($to, $subject, $body, $header);
699
  } else {
700
+ $result = @mail($to, $subject, $body, $header, $params);
701
  }
702
+ return $result;
703
  }
 
704
  /**
705
  * Output debugging info via user-defined method.
706
+ * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug).
707
  * @see PHPMailer::$Debugoutput
708
  * @see PHPMailer::$SMTPDebug
709
  * @param string $str
710
  */
711
  protected function edebug($str)
712
  {
713
+ if ($this->SMTPDebug <= 0) {
714
+ return;
715
+ }
716
+ //Avoid clash with built-in function names
717
+ if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
718
+ call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
719
  return;
720
  }
721
  switch ($this->Debugoutput) {
722
  case 'error_log':
723
+ //Don't output, just log
724
  error_log($str);
725
  break;
726
  case 'html':
727
+ //Cleans up output a bit for a better looking, HTML-safe output
728
+ echo htmlentities(
729
+ preg_replace('/[\r\n]+/', '', $str),
730
+ ENT_QUOTES,
731
+ 'UTF-8'
732
+ )
733
+ . "<br>\n";
734
  break;
735
  case 'echo':
736
  default:
737
+ //Normalize line breaks
738
+ $str = preg_replace('/\r\n?/ms', "\n", $str);
739
+ echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
740
+ "\n",
741
+ "\n \t ",
742
+ trim($str)
743
+ ) . "\n";
744
  }
745
  }
746
 
747
  /**
748
  * Sets message type to HTML or plain.
749
+ * @param boolean $isHtml True for HTML mode.
750
  * @return void
751
  */
752
+ public function isHTML($isHtml = true)
753
  {
754
+ if ($isHtml) {
755
  $this->ContentType = 'text/html';
756
  } else {
757
  $this->ContentType = 'text/plain';
782
  */
783
  public function isSendmail()
784
  {
785
+ $ini_sendmail_path = ini_get('sendmail_path');
786
+
787
+ if (!stristr($ini_sendmail_path, 'sendmail')) {
788
  $this->Sendmail = '/usr/sbin/sendmail';
789
+ } else {
790
+ $this->Sendmail = $ini_sendmail_path;
791
  }
792
  $this->Mailer = 'sendmail';
793
  }
798
  */
799
  public function isQmail()
800
  {
801
+ $ini_sendmail_path = ini_get('sendmail_path');
802
+
803
+ if (!stristr($ini_sendmail_path, 'qmail')) {
804
  $this->Sendmail = '/var/qmail/bin/qmail-inject';
805
+ } else {
806
+ $this->Sendmail = $ini_sendmail_path;
807
  }
808
  $this->Mailer = 'qmail';
809
  }
810
 
811
  /**
812
  * Add a "To" address.
813
+ * @param string $address The email address to send to
814
  * @param string $name
815
+ * @return boolean true on success, false if address already used or invalid in some way
816
  */
817
  public function addAddress($address, $name = '')
818
  {
819
+ return $this->addOrEnqueueAnAddress('to', $address, $name);
820
  }
821
 
822
  /**
823
  * Add a "CC" address.
824
  * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
825
+ * @param string $address The email address to send to
826
  * @param string $name
827
+ * @return boolean true on success, false if address already used or invalid in some way
828
  */
829
  public function addCC($address, $name = '')
830
  {
831
+ return $this->addOrEnqueueAnAddress('cc', $address, $name);
832
  }
833
 
834
  /**
835
  * Add a "BCC" address.
836
  * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
837
+ * @param string $address The email address to send to
838
  * @param string $name
839
+ * @return boolean true on success, false if address already used or invalid in some way
840
  */
841
  public function addBCC($address, $name = '')
842
  {
843
+ return $this->addOrEnqueueAnAddress('bcc', $address, $name);
844
  }
845
 
846
  /**
847
+ * Add a "Reply-To" address.
848
+ * @param string $address The email address to reply to
849
  * @param string $name
850
+ * @return boolean true on success, false if address already used or invalid in some way
851
  */
852
  public function addReplyTo($address, $name = '')
853
  {
854
+ return $this->addOrEnqueueAnAddress('Reply-To', $address, $name);
855
  }
856
 
857
  /**
858
+ * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer
859
+ * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still
860
+ * be modified after calling this function), addition of such addresses is delayed until send().
861
+ * Addresses that have been added already return false, but do not throw exceptions.
862
+ * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
863
+ * @param string $address The email address to send, resp. to reply to
864
+ * @param string $name
865
+ * @throws phpmailerException
866
+ * @return boolean true on success, false if address already used or invalid in some way
867
+ * @access protected
868
+ */
869
+ protected function addOrEnqueueAnAddress($kind, $address, $name)
870
+ {
871
+ $address = trim($address);
872
+ $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
873
+ if (($pos = strrpos($address, '@')) === false) {
874
+ // At-sign is misssing.
875
+ $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
876
+ $this->setError($error_message);
877
+ $this->edebug($error_message);
878
+ if ($this->exceptions) {
879
+ throw new phpmailerException($error_message);
880
+ }
881
+ return false;
882
+ }
883
+ $params = array($kind, $address, $name);
884
+ // Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
885
+ if ($this->has8bitChars(substr($address, ++$pos)) and $this->idnSupported()) {
886
+ if ($kind != 'Reply-To') {
887
+ if (!array_key_exists($address, $this->RecipientsQueue)) {
888
+ $this->RecipientsQueue[$address] = $params;
889
+ return true;
890
+ }
891
+ } else {
892
+ if (!array_key_exists($address, $this->ReplyToQueue)) {
893
+ $this->ReplyToQueue[$address] = $params;
894
+ return true;
895
+ }
896
+ }
897
+ return false;
898
+ }
899
+ // Immediately add standard addresses without IDN.
900
+ return call_user_func_array(array($this, 'addAnAddress'), $params);
901
+ }
902
+
903
+ /**
904
+ * Add an address to one of the recipient arrays or to the ReplyTo array.
905
+ * Addresses that have been added already return false, but do not throw exceptions.
906
+ * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
907
+ * @param string $address The email address to send, resp. to reply to
908
  * @param string $name
909
  * @throws phpmailerException
910
+ * @return boolean true on success, false if address already used or invalid in some way
911
  * @access protected
912
  */
913
  protected function addAnAddress($kind, $address, $name = '')
914
  {
915
+ if (!in_array($kind, array('to', 'cc', 'bcc', 'Reply-To'))) {
916
+ $error_message = $this->lang('Invalid recipient kind: ') . $kind;
917
+ $this->setError($error_message);
918
+ $this->edebug($error_message);
919
  if ($this->exceptions) {
920
+ throw new phpmailerException($error_message);
921
  }
922
  return false;
923
  }
 
 
924
  if (!$this->validateAddress($address)) {
925
+ $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
926
+ $this->setError($error_message);
927
+ $this->edebug($error_message);
928
  if ($this->exceptions) {
929
+ throw new phpmailerException($error_message);
930
  }
931
  return false;
932
  }
933
  if ($kind != 'Reply-To') {
934
+ if (!array_key_exists(strtolower($address), $this->all_recipients)) {
935
  array_push($this->$kind, array($address, $name));
936
  $this->all_recipients[strtolower($address)] = true;
937
  return true;
945
  return false;
946
  }
947
 
948
+ /**
949
+ * Parse and validate a string containing one or more RFC822-style comma-separated email addresses
950
+ * of the form "display name <address>" into an array of name/address pairs.
951
+ * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
952
+ * Note that quotes in the name part are removed.
953
+ * @param string $addrstr The address list string
954
+ * @param bool $useimap Whether to use the IMAP extension to parse the list
955
+ * @return array
956
+ * @link http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
957
+ */
958
+ public function parseAddresses($addrstr, $useimap = true)
959
+ {
960
+ $addresses = array();
961
+ if ($useimap and function_exists('imap_rfc822_parse_adrlist')) {
962
+ //Use this built-in parser if it's available
963
+ $list = imap_rfc822_parse_adrlist($addrstr, '');
964
+ foreach ($list as $address) {
965
+ if ($address->host != '.SYNTAX-ERROR.') {
966
+ if ($this->validateAddress($address->mailbox . '@' . $address->host)) {
967
+ $addresses[] = array(
968
+ 'name' => (property_exists($address, 'personal') ? $address->personal : ''),
969
+ 'address' => $address->mailbox . '@' . $address->host
970
+ );
971
+ }
972
+ }
973
+ }
974
+ } else {
975
+ //Use this simpler parser
976
+ $list = explode(',', $addrstr);
977
+ foreach ($list as $address) {
978
+ $address = trim($address);
979
+ //Is there a separate name part?
980
+ if (strpos($address, '<') === false) {
981
+ //No separate name, just use the whole thing
982
+ if ($this->validateAddress($address)) {
983
+ $addresses[] = array(
984
+ 'name' => '',
985
+ 'address' => $address
986
+ );
987
+ }
988
+ } else {
989
+ list($name, $email) = explode('<', $address);
990
+ $email = trim(str_replace('>', '', $email));
991
+ if ($this->validateAddress($email)) {
992
+ $addresses[] = array(
993
+ 'name' => trim(str_replace(array('"', "'"), '', $name)),
994
+ 'address' => $email
995
+ );
996
+ }
997
+ }
998
+ }
999
+ }
1000
+ return $addresses;
1001
+ }
1002
+
1003
  /**
1004
  * Set the From and FromName properties.
1005
  * @param string $address
1006
  * @param string $name
1007
+ * @param boolean $auto Whether to also set the Sender address, defaults to true
1008
  * @throws phpmailerException
1009
+ * @return boolean
1010
  */
1011
  public function setFrom($address, $name = '', $auto = true)
1012
  {
1013
  $address = trim($address);
1014
  $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
1015
+ // Don't validate now addresses with IDN. Will be done in send().
1016
+ if (($pos = strrpos($address, '@')) === false or
1017
+ (!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and
1018
+ !$this->validateAddress($address)) {
1019
+ $error_message = $this->lang('invalid_address') . " (setFrom) $address";
1020
+ $this->setError($error_message);
1021
+ $this->edebug($error_message);
1022
  if ($this->exceptions) {
1023
+ throw new phpmailerException($error_message);
1024
  }
1025
  return false;
1026
  }
1049
  /**
1050
  * Check that a string looks like an email address.
1051
  * @param string $address The email address to check
1052
+ * @param string|callable $patternselect A selector for the validation pattern to use :
1053
+ * * `auto` Pick best pattern automatically;
1054
+ * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
1055
+ * * `pcre` Use old PCRE implementation;
1056
+ * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
1057
+ * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
1058
+ * * `noregex` Don't use a regex: super fast, really dumb.
1059
+ * Alternatively you may pass in a callable to inject your own validator, for example:
1060
+ * PHPMailer::validateAddress('user@example.com', function($address) {
1061
+ * return (strpos($address, '@') !== false);
1062
+ * });
1063
+ * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
1064
+ * @return boolean
1065
  * @static
1066
  * @access public
1067
  */
1068
+ public static function validateAddress($address, $patternselect = null)
1069
  {
1070
+ if (is_null($patternselect)) {
1071
+ $patternselect = self::$validator;
1072
+ }
1073
+ if (is_callable($patternselect)) {
1074
+ return call_user_func($patternselect, $address);
1075
+ }
1076
+ //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
1077
+ if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) {
1078
+ return false;
1079
+ }
1080
+ if (!$patternselect or $patternselect == 'auto') {
1081
+ //Check this constant first so it works when extension_loaded() is disabled by safe mode
1082
+ //Constant was added in PHP 5.2.4
1083
+ if (defined('PCRE_VERSION')) {
1084
+ //This pattern can get stuck in a recursive loop in PCRE <= 8.0.2
1085
+ if (version_compare(PCRE_VERSION, '8.0.3') >= 0) {
1086
  $patternselect = 'pcre8';
1087
  } else {
1088
  $patternselect = 'pcre';
1089
  }
1090
+ } elseif (function_exists('extension_loaded') and extension_loaded('pcre')) {
1091
+ //Fall back to older PCRE
1092
+ $patternselect = 'pcre';
1093
  } else {
1094
  //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension
1095
  if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
1102
  switch ($patternselect) {
1103
  case 'pcre8':
1104
  /**
1105
+ * Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains.
 
 
1106
  * @link http://squiloople.com/2009/12/20/email-address-validation/
1107
  * @copyright 2009-2010 Michael Rushton
1108
  * Feel free to use and redistribute this code. But please keep this copyright notice.
1109
  */
1110
+ return (boolean)preg_match(
1111
  '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
1112
  '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
1113
  '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
1119
  '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
1120
  $address
1121
  );
 
1122
  case 'pcre':
1123
  //An older regex that doesn't need a recent PCRE
1124
+ return (boolean)preg_match(
1125
  '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
1126
  '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
1127
  '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
1134
  '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
1135
  $address
1136
  );
1137
+ case 'html5':
1138
+ /**
1139
+ * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.
1140
+ * @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email)
1141
+ */
1142
+ return (boolean)preg_match(
1143
+ '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
1144
+ '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
1145
+ $address
1146
+ );
1147
  case 'noregex':
1148
  //No PCRE! Do something _very_ approximate!
1149
  //Check the address is 3 chars or longer and contains an @ that's not the first or last char
1150
  return (strlen($address) >= 3
1151
  and strpos($address, '@') >= 1
1152
  and strpos($address, '@') != strlen($address) - 1);
1153
+ case 'php':
1154
+ default:
1155
+ return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL);
1156
+ }
1157
+ }
1158
+
1159
+ /**
1160
+ * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the
1161
+ * "intl" and "mbstring" PHP extensions.
1162
+ * @return bool "true" if required functions for IDN support are present
1163
+ */
1164
+ public function idnSupported()
1165
+ {
1166
+ // @TODO: Write our own "idn_to_ascii" function for PHP <= 5.2.
1167
+ return function_exists('idn_to_ascii') and function_exists('mb_convert_encoding');
1168
+ }
1169
+
1170
+ /**
1171
+ * Converts IDN in given email address to its ASCII form, also known as punycode, if possible.
1172
+ * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet.
1173
+ * This function silently returns unmodified address if:
1174
+ * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form)
1175
+ * - Conversion to punycode is impossible (e.g. required PHP functions are not available)
1176
+ * or fails for any reason (e.g. domain has characters not allowed in an IDN)
1177
+ * @see PHPMailer::$CharSet
1178
+ * @param string $address The email address to convert
1179
+ * @return string The encoded address in ASCII form
1180
+ */
1181
+ public function punyencodeAddress($address)
1182
+ {
1183
+ // Verify we have required functions, CharSet, and at-sign.
1184
+ if ($this->idnSupported() and
1185
+ !empty($this->CharSet) and
1186
+ ($pos = strrpos($address, '@')) !== false) {
1187
+ $domain = substr($address, ++$pos);
1188
+ // Verify CharSet string is a valid one, and domain properly encoded in this CharSet.
1189
+ if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) {
1190
+ $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet);
1191
+ if (($punycode = defined('INTL_IDNA_VARIANT_UTS46') ?
1192
+ idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) :
1193
+ idn_to_ascii($domain)) !== false) {
1194
+ return substr($address, 0, $pos) . $punycode;
1195
+ }
1196
+ }
1197
  }
1198
+ return $address;
1199
  }
1200
 
1201
  /**
1202
  * Create a message and send it.
1203
  * Uses the sending method specified by $Mailer.
1204
  * @throws phpmailerException
1205
+ * @return boolean false on error - See the ErrorInfo property for details of the error.
1206
  */
1207
  public function send()
1208
  {
1211
  return false;
1212
  }
1213
  return $this->postSend();
1214
+ } catch (phpmailerException $exc) {
1215
  $this->mailHeader = '';
1216
+ $this->setError($exc->getMessage());
1217
  if ($this->exceptions) {
1218
+ throw $exc;
1219
  }
1220
  return false;
1221
  }
1224
  /**
1225
  * Prepare a message for sending.
1226
  * @throws phpmailerException
1227
+ * @return boolean
1228
  */
1229
  public function preSend()
1230
  {
1231
  try {
1232
+ $this->error_count = 0; // Reset errors
1233
+ $this->mailHeader = '';
1234
+
1235
+ // Dequeue recipient and Reply-To addresses with IDN
1236
+ foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
1237
+ $params[1] = $this->punyencodeAddress($params[1]);
1238
+ call_user_func_array(array($this, 'addAnAddress'), $params);
1239
+ }
1240
  if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
1241
  throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
1242
  }
1243
 
1244
+ // Validate From, Sender, and ConfirmReadingTo addresses
1245
+ foreach (array('From', 'Sender', 'ConfirmReadingTo') as $address_kind) {
1246
+ $this->$address_kind = trim($this->$address_kind);
1247
+ if (empty($this->$address_kind)) {
1248
+ continue;
1249
+ }
1250
+ $this->$address_kind = $this->punyencodeAddress($this->$address_kind);
1251
+ if (!$this->validateAddress($this->$address_kind)) {
1252
+ $error_message = $this->lang('invalid_address') . ' (punyEncode) ' . $this->$address_kind;
1253
+ $this->setError($error_message);
1254
+ $this->edebug($error_message);
1255
+ if ($this->exceptions) {
1256
+ throw new phpmailerException($error_message);
1257
+ }
1258
+ return false;
1259
+ }
1260
+ }
1261
+
1262
  // Set whether the message is multipart/alternative
1263
+ if ($this->alternativeExists()) {
1264
  $this->ContentType = 'multipart/alternative';
1265
  }
1266
 
 
1267
  $this->setMessageType();
1268
  // Refuse to send an empty message unless we are specifically allowing it
1269
  if (!$this->AllowEmpty and empty($this->Body)) {
1270
  throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL);
1271
  }
1272
 
1273
+ // Create body before headers in case body makes changes to headers (e.g. altering transfer encoding)
1274
+ $this->MIMEHeader = '';
1275
  $this->MIMEBody = $this->createBody();
1276
+ // createBody may have added some headers, so retain them
1277
+ $tempheaders = $this->MIMEHeader;
1278
+ $this->MIMEHeader = $this->createHeader();
1279
+ $this->MIMEHeader .= $tempheaders;
1280
 
1281
  // To capture the complete message when using mail(), create
1282
  // an extra header list which createHeader() doesn't fold in
1283
  if ($this->Mailer == 'mail') {
1284
  if (count($this->to) > 0) {
1285
+ $this->mailHeader .= $this->addrAppend('To', $this->to);
1286
  } else {
1287
+ $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;');
1288
  }
1289
  $this->mailHeader .= $this->headerLine(
1290
  'Subject',
1294
 
1295
  // Sign with DKIM if enabled
1296
  if (!empty($this->DKIM_domain)
 
1297
  && !empty($this->DKIM_selector)
1298
+ && (!empty($this->DKIM_private_string)
1299
+ || (!empty($this->DKIM_private) && file_exists($this->DKIM_private))
1300
+ )
1301
+ ) {
1302
  $header_dkim = $this->DKIM_Add(
1303
  $this->MIMEHeader . $this->mailHeader,
1304
  $this->encodeHeader($this->secureHeader($this->Subject)),
1308
  str_replace("\r\n", "\n", $header_dkim) . self::CRLF;
1309
  }
1310
  return true;
1311
+ } catch (phpmailerException $exc) {
1312
+ $this->setError($exc->getMessage());
 
1313
  if ($this->exceptions) {
1314
+ throw $exc;
1315
  }
1316
  return false;
1317
  }
1321
  * Actually send a message.
1322
  * Send the email via the selected mechanism
1323
  * @throws phpmailerException
1324
+ * @return boolean
1325
  */
1326
  public function postSend()
1327
  {
1336
  case 'mail':
1337
  return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
1338
  default:
1339
+ $sendMethod = $this->Mailer.'Send';
1340
+ if (method_exists($this, $sendMethod)) {
1341
  return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
 
 
1342
  }
1343
+
1344
+ return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
1345
  }
1346
+ } catch (phpmailerException $exc) {
1347
+ $this->setError($exc->getMessage());
1348
+ $this->edebug($exc->getMessage());
1349
  if ($this->exceptions) {
1350
+ throw $exc;
1351
  }
1352
  }
1353
  return false;
1360
  * @see PHPMailer::$Sendmail
1361
  * @throws phpmailerException
1362
  * @access protected
1363
+ * @return boolean
1364
  */
1365
  protected function sendmailSend($header, $body)
1366
  {
1367
+ // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
1368
+ if (!empty($this->Sender) and self::isShellSafe($this->Sender)) {
1369
  if ($this->Mailer == 'qmail') {
1370
+ $sendmailFmt = '%s -f%s';
1371
  } else {
1372
+ $sendmailFmt = '%s -oi -f%s -t';
1373
  }
1374
  } else {
1375
  if ($this->Mailer == 'qmail') {
1376
+ $sendmailFmt = '%s';
1377
  } else {
1378
+ $sendmailFmt = '%s -oi -t';
1379
  }
1380
  }
1381
+
1382
+ // TODO: If possible, this should be changed to escapeshellarg. Needs thorough testing.
1383
+ $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender);
1384
+
1385
+ if ($this->SingleTo) {
1386
+ foreach ($this->SingleToArray as $toAddr) {
1387
  if (!@$mail = popen($sendmail, 'w')) {
1388
  throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1389
  }
1390
+ fputs($mail, 'To: ' . $toAddr . "\n");
1391
  fputs($mail, $header);
1392
  fputs($mail, $body);
1393
  $result = pclose($mail);
1394
+ $this->doCallback(
1395
+ ($result == 0),
1396
+ array($toAddr),
1397
+ $this->cc,
1398
+ $this->bcc,
1399
+ $this->Subject,
1400
+ $body,
1401
+ $this->From
1402
+ );
1403
  if ($result != 0) {
1404
  throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1405
  }
1411
  fputs($mail, $header);
1412
  fputs($mail, $body);
1413
  $result = pclose($mail);
1414
+ $this->doCallback(
1415
+ ($result == 0),
1416
+ $this->to,
1417
+ $this->cc,
1418
+ $this->bcc,
1419
+ $this->Subject,
1420
+ $body,
1421
+ $this->From
1422
+ );
1423
  if ($result != 0) {
1424
  throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1425
  }
1427
  return true;
1428
  }
1429
 
1430
+ /**
1431
+ * Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters.
1432
+ *
1433
+ * Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows.
1434
+ * @param string $string The string to be validated
1435
+ * @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report
1436
+ * @access protected
1437
+ * @return boolean
1438
+ */
1439
+ protected static function isShellSafe($string)
1440
+ {
1441
+ // Future-proof
1442
+ if (escapeshellcmd($string) !== $string
1443
+ or !in_array(escapeshellarg($string), array("'$string'", "\"$string\""))
1444
+ ) {
1445
+ return false;
1446
+ }
1447
+
1448
+ $length = strlen($string);
1449
+
1450
+ for ($i = 0; $i < $length; $i++) {
1451
+ $c = $string[$i];
1452
+
1453
+ // All other characters have a special meaning in at least one common shell, including = and +.
1454
+ // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
1455
+ // Note that this does permit non-Latin alphanumeric characters based on the current locale.
1456
+ if (!ctype_alnum($c) && strpos('@_-.', $c) === false) {
1457
+ return false;
1458
+ }
1459
+ }
1460
+
1461
+ return true;
1462
+ }
1463
+
1464
  /**
1465
  * Send mail using the PHP mail() function.
1466
  * @param string $header The message headers
1468
  * @link http://www.php.net/manual/en/book.mail.php
1469
  * @throws phpmailerException
1470
  * @access protected
1471
+ * @return boolean
1472
  */
1473
  protected function mailSend($header, $body)
1474
  {
1475
  $toArr = array();
1476
+ foreach ($this->to as $toaddr) {
1477
+ $toArr[] = $this->addrFormat($toaddr);
1478
  }
1479
  $to = implode(', ', $toArr);
1480
 
1481
+ $params = null;
1482
+ //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
1483
+ if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {
1484
+ // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
1485
+ if (self::isShellSafe($this->Sender)) {
1486
+ $params = sprintf('-f%s', $this->Sender);
1487
+ }
1488
  }
1489
+ if (!empty($this->Sender) and !ini_get('safe_mode') and $this->validateAddress($this->Sender)) {
1490
  $old_from = ini_get('sendmail_from');
1491
  ini_set('sendmail_from', $this->Sender);
1492
  }
1493
+ $result = false;
1494
+ if ($this->SingleTo and count($toArr) > 1) {
1495
+ foreach ($toArr as $toAddr) {
1496
+ $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
1497
+ $this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
 
 
1498
  }
1499
  } else {
1500
+ $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
1501
+ $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
 
 
1502
  }
1503
  if (isset($old_from)) {
1504
  ini_set('sendmail_from', $old_from);
1505
  }
1506
+ if (!$result) {
1507
  throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
1508
  }
1509
  return true;
1532
  * @throws phpmailerException
1533
  * @uses SMTP
1534
  * @access protected
1535
+ * @return boolean
1536
  */
1537
  protected function smtpSend($header, $body)
1538
  {
1539
  $bad_rcpt = array();
1540
+ if (!$this->smtpConnect($this->SMTPOptions)) {
 
1541
  throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
1542
  }
1543
+ if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {
1544
+ $smtp_from = $this->Sender;
1545
+ } else {
1546
+ $smtp_from = $this->From;
1547
+ }
1548
  if (!$this->smtp->mail($smtp_from)) {
1549
  $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
1550
  throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
1551
  }
1552
 
1553
+ // Attempt to send to all recipients
1554
+ foreach (array($this->to, $this->cc, $this->bcc) as $togroup) {
1555
+ foreach ($togroup as $to) {
1556
+ if (!$this->smtp->recipient($to[0])) {
1557
+ $error = $this->smtp->getError();
1558
+ $bad_rcpt[] = array('to' => $to[0], 'error' => $error['detail']);
1559
+ $isSent = false;
1560
+ } else {
1561
+ $isSent = true;
1562
+ }
1563
+ $this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1564
  }
 
1565
  }
1566
 
1567
+ // Only send the DATA command if we have viable recipients
1568
+ if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {
1569
  throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
1570
  }
1571
+ if ($this->SMTPKeepAlive) {
1572
  $this->smtp->reset();
1573
  } else {
1574
  $this->smtp->quit();
1575
  $this->smtp->close();
1576
  }
1577
+ //Create error message for any bad addresses
1578
+ if (count($bad_rcpt) > 0) {
1579
+ $errstr = '';
1580
+ foreach ($bad_rcpt as $bad) {
1581
+ $errstr .= $bad['to'] . ': ' . $bad['error'];
1582
+ }
1583
  throw new phpmailerException(
1584
+ $this->lang('recipients_failed') . $errstr,
1585
  self::STOP_CONTINUE
1586
  );
1587
  }
1595
  * @uses SMTP
1596
  * @access public
1597
  * @throws phpmailerException
1598
+ * @return boolean
1599
  */
1600
+ public function smtpConnect($options = null)
1601
  {
1602
  if (is_null($this->smtp)) {
1603
  $this->smtp = $this->getSMTPInstance();
1604
  }
1605
 
1606
+ //If no options are provided, use whatever is set in the instance
1607
+ if (is_null($options)) {
1608
+ $options = $this->SMTPOptions;
1609
+ }
1610
+
1611
+ // Already connected?
1612
  if ($this->smtp->connected()) {
1613
  return true;
1614
  }
1623
  foreach ($hosts as $hostentry) {
1624
  $hostinfo = array();
1625
  if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
1626
+ // Not a valid host entry
1627
  continue;
1628
  }
1629
+ // $hostinfo[2]: optional ssl or tls prefix
1630
+ // $hostinfo[3]: the hostname
1631
+ // $hostinfo[4]: optional port number
1632
+ // The host string prefix can temporarily override the current setting for SMTPSecure
1633
+ // If it's not specified, the default value is used
1634
  $prefix = '';
1635
+ $secure = $this->SMTPSecure;
1636
  $tls = ($this->SMTPSecure == 'tls');
1637
+ if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
1638
  $prefix = 'ssl://';
1639
+ $tls = false; // Can't have SSL and TLS at the same time
1640
+ $secure = 'ssl';
1641
  } elseif ($hostinfo[2] == 'tls') {
1642
  $tls = true;
1643
+ // tls doesn't use a prefix
1644
+ $secure = 'tls';
1645
+ }
1646
+ //Do we need the OpenSSL extension?
1647
+ $sslext = defined('OPENSSL_ALGO_SHA1');
1648
+ if ('tls' === $secure or 'ssl' === $secure) {
1649
+ //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
1650
+ if (!$sslext) {
1651
+ throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
1652
+ }
1653
  }
1654
  $host = $hostinfo[3];
1655
  $port = $this->Port;
1665
  $hello = $this->serverHostname();
1666
  }
1667
  $this->smtp->hello($hello);
1668
+ //Automatically enable TLS encryption if:
1669
+ // * it's not disabled
1670
+ // * we have openssl extension
1671
+ // * we are not already using SSL
1672
+ // * the server offers STARTTLS
1673
+ if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
1674
+ $tls = true;
1675
+ }
1676
  if ($tls) {
1677
  if (!$this->smtp->startTLS()) {
1678
  throw new phpmailerException($this->lang('connect_host'));
1679
  }
1680
+ // We must resend EHLO after TLS negotiation
1681
  $this->smtp->hello($hello);
1682
  }
1683
  if ($this->SMTPAuth) {
1693
  }
1694
  }
1695
  return true;
1696
+ } catch (phpmailerException $exc) {
1697
+ $lastexception = $exc;
1698
+ $this->edebug($exc->getMessage());
1699
+ // We must have connected, but then failed TLS or Auth, so close connection nicely
1700
  $this->smtp->quit();
1701
  }
1702
  }
1703
  }
1704
+ // If we get here, all connection attempts have failed, so close connection hard
1705
  $this->smtp->close();
1706
+ // As we've caught all exceptions, just report whatever the last one was
1707
  if ($this->exceptions and !is_null($lastexception)) {
1708
  throw $lastexception;
1709
  }
1716
  */
1717
  public function smtpClose()
1718
  {
1719
+ if (is_a($this->smtp, 'SMTP')) {
1720
  if ($this->smtp->connected()) {
1721
  $this->smtp->quit();
1722
  $this->smtp->close();
1730
  * The default language is English.
1731
  * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr")
1732
  * @param string $lang_path Path to the language file directory, with trailing separator (slash)
1733
+ * @return boolean
1734
  * @access public
1735
  */
1736
+ public function setLanguage($langcode = 'en', $lang_path = '')
1737
  {
1738
+ // Backwards compatibility for renamed language codes
1739
+ $renamed_langcodes = array(
1740
+ 'br' => 'pt_br',
1741
+ 'cz' => 'cs',
1742
+ 'dk' => 'da',
1743
+ 'no' => 'nb',
1744
+ 'se' => 'sv',
1745
+ );
1746
+
1747
+ if (isset($renamed_langcodes[$langcode])) {
1748
+ $langcode = $renamed_langcodes[$langcode];
1749
+ }
1750
+
1751
+ // Define full set of translatable strings in English
1752
  $PHPMAILER_LANG = array(
1753
  'authenticate' => 'SMTP Error: Could not authenticate.',
1754
  'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
1760
  'file_open' => 'File Error: Could not open file: ',
1761
  'from_failed' => 'The following From address failed: ',
1762
  'instantiate' => 'Could not instantiate mail function.',
1763
+ 'invalid_address' => 'Invalid address: ',
1764
  'mailer_not_supported' => ' mailer is not supported.',
1765
  'provide_address' => 'You must provide at least one recipient email address.',
1766
  'recipients_failed' => 'SMTP Error: The following recipients failed: ',
1767
  'signing' => 'Signing Error: ',
1768
  'smtp_connect_failed' => 'SMTP connect() failed.',
1769
  'smtp_error' => 'SMTP server error: ',
1770
+ 'variable_set' => 'Cannot set or reset variable: ',
1771
+ 'extension_missing' => 'Extension missing: '
1772
  );
1773
+ if (empty($lang_path)) {
1774
+ // Calculate an absolute path so it can work if CWD is not here
1775
+ $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR;
1776
+ }
1777
+ //Validate $langcode
1778
+ if (!preg_match('/^[a-z]{2}(?:_[a-zA-Z]{2})?$/', $langcode)) {
1779
+ $langcode = 'en';
1780
+ }
1781
+ $foundlang = true;
1782
+ $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
1783
+ // There is no English translation file
1784
+ if ($langcode != 'en') {
1785
+ // Make sure language file path is readable
1786
+ if (!is_readable($lang_file)) {
1787
+ $foundlang = false;
1788
+ } else {
1789
+ // Overwrite language-specific strings.
1790
+ // This way we'll never have missing translation keys.
1791
+ $foundlang = include $lang_file;
1792
+ }
1793
  }
1794
  $this->language = $PHPMAILER_LANG;
1795
+ return (boolean)$foundlang; // Returns false if language not found
1796
  }
1797
 
1798
  /**
1817
  public function addrAppend($type, $addr)
1818
  {
1819
  $addresses = array();
1820
+ foreach ($addr as $address) {
1821
+ $addresses[] = $this->addrFormat($address);
1822
  }
1823
  return $type . ': ' . implode(', ', $addresses) . $this->LE;
1824
  }
1835
  if (empty($addr[1])) { // No name provided
1836
  return $this->secureHeader($addr[0]);
1837
  } else {
1838
+ return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader(
1839
  $addr[0]
1840
+ ) . '>';
1841
  }
1842
  }
1843
 
1848
  * Original written by philippe.
1849
  * @param string $message The message to wrap
1850
  * @param integer $length The line length to wrap to
1851
+ * @param boolean $qp_mode Whether to run in Quoted-Printable mode
1852
  * @access public
1853
  * @return string
1854
  */
1855
  public function wrapText($message, $length, $qp_mode = false)
1856
  {
1857
+ if ($qp_mode) {
1858
+ $soft_break = sprintf(' =%s', $this->LE);
1859
+ } else {
1860
+ $soft_break = $this->LE;
1861
+ }
1862
  // If utf-8 encoding is used, we will need to make sure we don't
1863
  // split multibyte characters when we wrap
1864
+ $is_utf8 = (strtolower($this->CharSet) == 'utf-8');
1865
  $lelen = strlen($this->LE);
1866
  $crlflen = strlen(self::CRLF);
1867
 
1868
  $message = $this->fixEOL($message);
1869
+ //Remove a trailing line break
1870
  if (substr($message, -$lelen) == $this->LE) {
1871
  $message = substr($message, 0, -$lelen);
1872
  }
1873
 
1874
+ //Split message into lines
1875
+ $lines = explode($this->LE, $message);
1876
+ //Message will be rebuilt in here
1877
  $message = '';
1878
+ foreach ($lines as $line) {
1879
+ $words = explode(' ', $line);
1880
  $buf = '';
1881
+ $firstword = true;
1882
+ foreach ($words as $word) {
1883
  if ($qp_mode and (strlen($word) > $length)) {
1884
  $space_left = $length - strlen($buf) - $crlflen;
1885
+ if (!$firstword) {
1886
  if ($space_left > 20) {
1887
  $len = $space_left;
1888
  if ($is_utf8) {
1889
  $len = $this->utf8CharBoundary($word, $len);
1890
+ } elseif (substr($word, $len - 1, 1) == '=') {
1891
  $len--;
1892
+ } elseif (substr($word, $len - 2, 1) == '=') {
1893
  $len -= 2;
1894
  }
1895
  $part = substr($word, 0, $len);
1896
  $word = substr($word, $len);
1897
  $buf .= ' ' . $part;
1898
+ $message .= $buf . sprintf('=%s', self::CRLF);
1899
  } else {
1900
  $message .= $buf . $soft_break;
1901
  }
1908
  $len = $length;
1909
  if ($is_utf8) {
1910
  $len = $this->utf8CharBoundary($word, $len);
1911
+ } elseif (substr($word, $len - 1, 1) == '=') {
1912
  $len--;
1913
+ } elseif (substr($word, $len - 2, 1) == '=') {
1914
  $len -= 2;
1915
  }
1916
  $part = substr($word, 0, $len);
1917
  $word = substr($word, $len);
1918
 
1919
  if (strlen($word) > 0) {
1920
+ $message .= $part . sprintf('=%s', self::CRLF);
1921
  } else {
1922
  $buf = $part;
1923
  }
1924
  }
1925
  } else {
1926
  $buf_o = $buf;
1927
+ if (!$firstword) {
1928
+ $buf .= ' ';
1929
+ }
1930
+ $buf .= $word;
1931
 
1932
  if (strlen($buf) > $length and $buf_o != '') {
1933
  $message .= $buf_o . $soft_break;
1934
  $buf = $word;
1935
  }
1936
  }
1937
+ $firstword = false;
1938
  }
1939
  $message .= $buf . self::CRLF;
1940
  }
1944
 
1945
  /**
1946
  * Find the last character boundary prior to $maxLength in a utf-8
1947
+ * quoted-printable encoded string.
1948
  * Original written by Colin Brown.
1949
  * @access public
1950
  * @param string $encodedText utf-8 QP text
1951
+ * @param integer $maxLength Find the last character boundary prior to this length
1952
+ * @return integer
1953
  */
1954
  public function utf8CharBoundary($encodedText, $maxLength)
1955
  {
1957
  $lookBack = 3;
1958
  while (!$foundSplitPos) {
1959
  $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
1960
+ $encodedCharPos = strpos($lastChunk, '=');
1961
+ if (false !== $encodedCharPos) {
1962
  // Found start of encoded character byte within $lookBack block.
1963
  // Check the encoded byte value (the 2 chars after the '=')
1964
  $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
1965
  $dec = hexdec($hex);
1966
+ if ($dec < 128) {
1967
+ // Single byte character.
1968
  // If the encoded char was found at pos 0, it will fit
1969
  // otherwise reduce maxLength to start of the encoded char
1970
+ if ($encodedCharPos > 0) {
1971
+ $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1972
+ }
1973
  $foundSplitPos = true;
1974
+ } elseif ($dec >= 192) {
1975
+ // First byte of a multi byte character
1976
  // Reduce maxLength to split at start of character
1977
  $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1978
  $foundSplitPos = true;
1979
+ } elseif ($dec < 192) {
1980
+ // Middle byte of a multi byte character, look further back
1981
  $lookBack += 3;
1982
  }
1983
  } else {
1988
  return $maxLength;
1989
  }
1990
 
 
1991
  /**
1992
+ * Apply word wrapping to the message body.
1993
+ * Wraps the message body to the number of chars set in the WordWrap property.
1994
+ * You should only do this to plain-text bodies as wrapping HTML tags may break them.
1995
+ * This is called automatically by createBody(), so you don't need to call it yourself.
1996
  * @access public
1997
  * @return void
1998
  */
2024
  {
2025
  $result = '';
2026
 
 
 
 
 
 
 
2027
  if ($this->MessageDate == '') {
2028
+ $this->MessageDate = self::rfcDate();
 
 
 
 
 
 
 
 
 
 
2029
  }
2030
+ $result .= $this->headerLine('Date', $this->MessageDate);
2031
 
2032
  // To be created automatically by mail()
2033
+ if ($this->SingleTo) {
2034
+ if ($this->Mailer != 'mail') {
2035
+ foreach ($this->to as $toaddr) {
2036
+ $this->SingleToArray[] = $this->addrFormat($toaddr);
2037
  }
2038
+ }
2039
+ } else {
2040
+ if (count($this->to) > 0) {
2041
+ if ($this->Mailer != 'mail') {
2042
  $result .= $this->addrAppend('To', $this->to);
 
 
2043
  }
2044
+ } elseif (count($this->cc) == 0) {
2045
+ $result .= $this->headerLine('To', 'undisclosed-recipients:;');
2046
  }
2047
  }
2048
 
2071
  $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
2072
  }
2073
 
2074
+ // Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
2075
+ // https://tools.ietf.org/html/rfc5322#section-3.6.4
2076
+ if ('' != $this->MessageID and preg_match('/^<.*@.*>$/', $this->MessageID)) {
2077
  $this->lastMessageID = $this->MessageID;
2078
  } else {
2079
+ $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname());
2080
+ }
2081
+ $result .= $this->headerLine('Message-ID', $this->lastMessageID);
2082
+ if (!is_null($this->Priority)) {
2083
+ $result .= $this->headerLine('X-Priority', $this->Priority);
2084
  }
 
 
2085
  if ($this->XMailer == '') {
2086
  $result .= $this->headerLine(
2087
  'X-Mailer',
2088
+ 'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer)'
2089
  );
2090
  } else {
2091
  $myXmailer = trim($this->XMailer);
2095
  }
2096
 
2097
  if ($this->ConfirmReadingTo != '') {
2098
+ $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>');
2099
  }
2100
 
2101
  // Add custom headers
2102
+ foreach ($this->CustomHeader as $header) {
2103
  $result .= $this->headerLine(
2104
+ trim($header[0]),
2105
+ $this->encodeHeader(trim($header[1]))
2106
  );
2107
  }
2108
  if (!$this->sign_key_file) {
2121
  public function getMailMIME()
2122
  {
2123
  $result = '';
2124
+ $ismultipart = true;
2125
  switch ($this->message_type) {
2126
  case 'inline':
2127
  $result .= $this->headerLine('Content-Type', 'multipart/related;');
2142
  default:
2143
  // Catches case 'plain': and case '':
2144
  $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
2145
+ $ismultipart = false;
2146
  break;
2147
  }
2148
+ // RFC1341 part 5 says 7bit is assumed if not specified
2149
  if ($this->Encoding != '7bit') {
2150
+ // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
2151
+ if ($ismultipart) {
2152
+ if ($this->Encoding == '8bit') {
2153
+ $result .= $this->headerLine('Content-Transfer-Encoding', '8bit');
2154
+ }
2155
+ // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
2156
+ } else {
2157
+ $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
2158
+ }
2159
  }
2160
 
2161
  if ($this->Mailer != 'mail') {
2168
  /**
2169
  * Returns the whole MIME message.
2170
  * Includes complete headers and body.
2171
+ * Only valid post preSend().
2172
+ * @see PHPMailer::preSend()
2173
  * @access public
2174
  * @return string
2175
  */
2176
  public function getSentMIMEMessage()
2177
  {
2178
+ return rtrim($this->MIMEHeader . $this->mailHeader, "\n\r") . self::CRLF . self::CRLF . $this->MIMEBody;
2179
  }
2180
 
2181
+ /**
2182
+ * Create unique ID
2183
+ * @return string
2184
+ */
2185
+ protected function generateId() {
2186
+ return md5(uniqid(time()));
2187
+ }
2188
 
2189
  /**
2190
  * Assemble the message body.
2196
  public function createBody()
2197
  {
2198
  $body = '';
2199
+ //Create unique IDs and preset boundaries
2200
+ $this->uniqueid = $this->generateId();
2201
+ $this->boundary[1] = 'b1_' . $this->uniqueid;
2202
+ $this->boundary[2] = 'b2_' . $this->uniqueid;
2203
+ $this->boundary[3] = 'b3_' . $this->uniqueid;
2204
 
2205
  if ($this->sign_key_file) {
2206
  $body .= $this->getMailMIME() . $this->LE;
2208
 
2209
  $this->setWordWrap();
2210
 
2211
+ $bodyEncoding = $this->Encoding;
2212
+ $bodyCharSet = $this->CharSet;
2213
+ //Can we do a 7-bit downgrade?
2214
+ if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
2215
+ $bodyEncoding = '7bit';
2216
+ //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
2217
+ $bodyCharSet = 'us-ascii';
2218
+ }
2219
+ //If lines are too long, and we're not already using an encoding that will shorten them,
2220
+ //change to quoted-printable transfer encoding for the body part only
2221
+ if ('base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) {
2222
+ $bodyEncoding = 'quoted-printable';
2223
+ }
2224
+
2225
+ $altBodyEncoding = $this->Encoding;
2226
+ $altBodyCharSet = $this->CharSet;
2227
+ //Can we do a 7-bit downgrade?
2228
+ if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
2229
+ $altBodyEncoding = '7bit';
2230
+ //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
2231
+ $altBodyCharSet = 'us-ascii';
2232
+ }
2233
+ //If lines are too long, and we're not already using an encoding that will shorten them,
2234
+ //change to quoted-printable transfer encoding for the alt body part only
2235
+ if ('base64' != $altBodyEncoding and self::hasLineLongerThanMax($this->AltBody)) {
2236
+ $altBodyEncoding = 'quoted-printable';
2237
+ }
2238
+ //Use this as a preamble in all multipart message types
2239
+ $mimepre = "This is a multi-part message in MIME format." . $this->LE . $this->LE;
2240
  switch ($this->message_type) {
2241
  case 'inline':
2242
+ $body .= $mimepre;
2243
+ $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
2244
+ $body .= $this->encodeString($this->Body, $bodyEncoding);
2245
  $body .= $this->LE . $this->LE;
2246
  $body .= $this->attachAll('inline', $this->boundary[1]);
2247
  break;
2248
  case 'attach':
2249
+ $body .= $mimepre;
2250
+ $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
2251
+ $body .= $this->encodeString($this->Body, $bodyEncoding);
2252
  $body .= $this->LE . $this->LE;
2253
  $body .= $this->attachAll('attachment', $this->boundary[1]);
2254
  break;
2255
  case 'inline_attach':
2256
+ $body .= $mimepre;
2257
  $body .= $this->textLine('--' . $this->boundary[1]);
2258
  $body .= $this->headerLine('Content-Type', 'multipart/related;');
2259
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
2260
  $body .= $this->LE;
2261
+ $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);
2262
+ $body .= $this->encodeString($this->Body, $bodyEncoding);
2263
  $body .= $this->LE . $this->LE;
2264
  $body .= $this->attachAll('inline', $this->boundary[2]);
2265
  $body .= $this->LE;
2266
  $body .= $this->attachAll('attachment', $this->boundary[1]);
2267
  break;
2268
  case 'alt':
2269
+ $body .= $mimepre;
2270
+ $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
2271
+ $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
2272
  $body .= $this->LE . $this->LE;
2273
+ $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding);
2274
+ $body .= $this->encodeString($this->Body, $bodyEncoding);
2275
  $body .= $this->LE . $this->LE;
2276
  if (!empty($this->Ical)) {
2277
  $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
2281
  $body .= $this->endBoundary($this->boundary[1]);
2282
  break;
2283
  case 'alt_inline':
2284
+ $body .= $mimepre;
2285
+ $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
2286
+ $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
2287
  $body .= $this->LE . $this->LE;
2288
  $body .= $this->textLine('--' . $this->boundary[1]);
2289
  $body .= $this->headerLine('Content-Type', 'multipart/related;');
2290
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
2291
  $body .= $this->LE;
2292
+ $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
2293
+ $body .= $this->encodeString($this->Body, $bodyEncoding);
2294
  $body .= $this->LE . $this->LE;
2295
  $body .= $this->attachAll('inline', $this->boundary[2]);
2296
  $body .= $this->LE;
2297
  $body .= $this->endBoundary($this->boundary[1]);
2298
  break;
2299
  case 'alt_attach':
2300
+ $body .= $mimepre;
2301
  $body .= $this->textLine('--' . $this->boundary[1]);
2302
  $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
2303
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
2304
  $body .= $this->LE;
2305
+ $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
2306
+ $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
2307
  $body .= $this->LE . $this->LE;
2308
+ $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
2309
+ $body .= $this->encodeString($this->Body, $bodyEncoding);
2310
  $body .= $this->LE . $this->LE;
2311
  $body .= $this->endBoundary($this->boundary[2]);
2312
  $body .= $this->LE;
2313
  $body .= $this->attachAll('attachment', $this->boundary[1]);
2314
  break;
2315
  case 'alt_inline_attach':
2316
+ $body .= $mimepre;
2317
  $body .= $this->textLine('--' . $this->boundary[1]);
2318
  $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
2319
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
2320
  $body .= $this->LE;
2321
+ $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
2322
+ $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
2323
  $body .= $this->LE . $this->LE;
2324
  $body .= $this->textLine('--' . $this->boundary[2]);
2325
  $body .= $this->headerLine('Content-Type', 'multipart/related;');
2326
  $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"');
2327
  $body .= $this->LE;
2328
+ $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding);
2329
+ $body .= $this->encodeString($this->Body, $bodyEncoding);
2330
  $body .= $this->LE . $this->LE;
2331
  $body .= $this->attachAll('inline', $this->boundary[3]);
2332
  $body .= $this->LE;
2335
  $body .= $this->attachAll('attachment', $this->boundary[1]);
2336
  break;
2337
  default:
2338
+ // Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types
2339
+ //Reset the `Encoding` property in case we changed it for line length reasons
2340
+ $this->Encoding = $bodyEncoding;
2341
  $body .= $this->encodeString($this->Body, $this->Encoding);
2342
  break;
2343
  }
2347
  } elseif ($this->sign_key_file) {
2348
  try {
2349
  if (!defined('PKCS7_TEXT')) {
2350
+ throw new phpmailerException($this->lang('extension_missing') . 'openssl');
2351
  }
2352
+ // @TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1
2353
  $file = tempnam(sys_get_temp_dir(), 'mail');
2354
+ if (false === file_put_contents($file, $body)) {
2355
+ throw new phpmailerException($this->lang('signing') . ' Could not write temp file');
2356
+ }
2357
  $signed = tempnam(sys_get_temp_dir(), 'signed');
2358
+ //Workaround for PHP bug https://bugs.php.net/bug.php?id=69197
2359
+ if (empty($this->sign_extracerts_file)) {
2360
+ $sign = @openssl_pkcs7_sign(
2361
+ $file,
2362
+ $signed,
2363
+ 'file://' . realpath($this->sign_cert_file),
2364
+ array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
2365
+ null
2366
+ );
2367
+ } else {
2368
+ $sign = @openssl_pkcs7_sign(
2369
+ $file,
2370
+ $signed,
2371
+ 'file://' . realpath($this->sign_cert_file),
2372
+ array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
2373
+ null,
2374
+ PKCS7_DETACHED,
2375
+ $this->sign_extracerts_file
2376
+ );
2377
+ }
2378
+ if ($sign) {
2379
  @unlink($file);
2380
  $body = file_get_contents($signed);
2381
  @unlink($signed);
2382
+ //The message returned by openssl contains both headers and body, so need to split them up
2383
+ $parts = explode("\n\n", $body, 2);
2384
+ $this->MIMEHeader .= $parts[0] . $this->LE . $this->LE;
2385
+ $body = $parts[1];
2386
  } else {
2387
  @unlink($file);
2388
  @unlink($signed);
2389
  throw new phpmailerException($this->lang('signing') . openssl_error_string());
2390
  }
2391
+ } catch (phpmailerException $exc) {
2392
  $body = '';
2393
  if ($this->exceptions) {
2394
+ throw $exc;
2395
  }
2396
  }
2397
  }
2420
  $encoding = $this->Encoding;
2421
  }
2422
  $result .= $this->textLine('--' . $boundary);
2423
+ $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet);
2424
  $result .= $this->LE;
2425
+ // RFC1341 part 5 says 7bit is assumed if not specified
2426
+ if ($encoding != '7bit') {
2427
+ $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
2428
+ }
2429
  $result .= $this->LE;
2430
 
2431
  return $result;
2444
 
2445
  /**
2446
  * Set the message type.
2447
+ * PHPMailer only supports some preset message types, not arbitrary MIME structures.
 
2448
  * @access protected
2449
  * @return void
2450
  */
2451
  protected function setMessageType()
2452
  {
2453
+ $type = array();
2454
  if ($this->alternativeExists()) {
2455
+ $type[] = 'alt';
2456
  }
2457
  if ($this->inlineImageExists()) {
2458
+ $type[] = 'inline';
2459
  }
2460
  if ($this->attachmentExists()) {
2461
+ $type[] = 'attach';
2462
  }
2463
+ $this->message_type = implode('_', $type);
2464
+ if ($this->message_type == '') {
2465
+ //The 'plain' message_type refers to the message having a single body element, not that it is plain-text
2466
+ $this->message_type = 'plain';
2467
  }
2468
  }
2469
 
2499
  * @param string $type File extension (MIME) type.
2500
  * @param string $disposition Disposition to use
2501
  * @throws phpmailerException
2502
+ * @return boolean
2503
  */
2504
  public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')
2505
  {
2508
  throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
2509
  }
2510
 
2511
+ // If a MIME type is not specified, try to work it out from the file name
2512
  if ($type == '') {
2513
  $type = self::filenameToType($path);
2514
  }
2529
  7 => 0
2530
  );
2531
 
2532
+ } catch (phpmailerException $exc) {
2533
+ $this->setError($exc->getMessage());
2534
+ $this->edebug($exc->getMessage());
2535
  if ($this->exceptions) {
2536
+ throw $exc;
2537
  }
2538
  return false;
2539
  }
2588
  $type = $attachment[4];
2589
  $disposition = $attachment[6];
2590
  $cid = $attachment[7];
2591
+ if ($disposition == 'inline' && array_key_exists($cid, $cidUniq)) {
2592
  continue;
2593
  }
2594
  $cidUniq[$cid] = true;
2595
 
2596
+ $mime[] = sprintf('--%s%s', $boundary, $this->LE);
2597
+ //Only include a filename property if we have one
2598
+ if (!empty($name)) {
2599
+ $mime[] = sprintf(
2600
+ 'Content-Type: %s; name="%s"%s',
2601
+ $type,
2602
+ $this->encodeHeader($this->secureHeader($name)),
2603
+ $this->LE
2604
+ );
2605
+ } else {
2606
+ $mime[] = sprintf(
2607
+ 'Content-Type: %s%s',
2608
+ $type,
2609
+ $this->LE
2610
+ );
2611
+ }
2612
+ // RFC1341 part 5 says 7bit is assumed if not specified
2613
+ if ($encoding != '7bit') {
2614
+ $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
2615
+ }
2616
 
2617
  if ($disposition == 'inline') {
2618
+ $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE);
2619
  }
2620
 
2621
  // If a filename contains any of these chars, it should be quoted,
2623
  // Fixes a warning in IETF's msglint MIME checker
2624
  // Allow for bypassing the Content-Disposition header totally
2625
  if (!(empty($disposition))) {
2626
+ $encoded_name = $this->encodeHeader($this->secureHeader($name));
2627
+ if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $encoded_name)) {
2628
  $mime[] = sprintf(
2629
+ 'Content-Disposition: %s; filename="%s"%s',
2630
  $disposition,
2631
+ $encoded_name,
2632
  $this->LE . $this->LE
2633
  );
2634
  } else {
2635
+ if (!empty($encoded_name)) {
2636
+ $mime[] = sprintf(
2637
+ 'Content-Disposition: %s; filename=%s%s',
2638
+ $disposition,
2639
+ $encoded_name,
2640
+ $this->LE . $this->LE
2641
+ );
2642
+ } else {
2643
+ $mime[] = sprintf(
2644
+ 'Content-Disposition: %s%s',
2645
+ $disposition,
2646
+ $this->LE . $this->LE
2647
+ );
2648
+ }
2649
  }
2650
  } else {
2651
  $mime[] = $this->LE;
2668
  }
2669
  }
2670
 
2671
+ $mime[] = sprintf('--%s--%s', $boundary, $this->LE);
2672
 
2673
+ return implode('', $mime);
2674
  }
2675
 
2676
  /**
2679
  * @param string $path The full path to the file
2680
  * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
2681
  * @throws phpmailerException
 
2682
  * @access protected
2683
  * @return string
2684
  */
2691
  $magic_quotes = get_magic_quotes_runtime();
2692
  if ($magic_quotes) {
2693
  if (version_compare(PHP_VERSION, '5.3.0', '<')) {
2694
+ set_magic_quotes_runtime(false);
2695
  } else {
2696
+ //Doesn't exist in PHP 5.4, but we don't need to check because
2697
+ //get_magic_quotes_runtime always returns false in 5.4+
2698
+ //so it will never get here
2699
+ ini_set('magic_quotes_runtime', false);
2700
  }
2701
  }
2702
  $file_buffer = file_get_contents($path);
2709
  }
2710
  }
2711
  return $file_buffer;
2712
+ } catch (Exception $exc) {
2713
+ $this->setError($exc->getMessage());
2714
  return '';
2715
  }
2716
  }
2733
  case '7bit':
2734
  case '8bit':
2735
  $encoded = $this->fixEOL($str);
2736
+ // Make sure it ends with a line break
2737
  if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
2738
  $encoded .= $this->LE;
2739
  }
2761
  */
2762
  public function encodeHeader($str, $position = 'text')
2763
  {
2764
+ $matchcount = 0;
2765
  switch (strtolower($position)) {
2766
  case 'phrase':
2767
  if (!preg_match('/[\200-\377]/', $str)) {
2768
+ // Can't use addslashes as we don't know the value of magic_quotes_sybase
2769
  $encoded = addcslashes($str, "\0..\37\177\\\"");
2770
  if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
2771
  return ($encoded);
2773
  return ("\"$encoded\"");
2774
  }
2775
  }
2776
+ $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
2777
  break;
2778
  /** @noinspection PhpMissingBreakStatementInspection */
2779
  case 'comment':
2780
+ $matchcount = preg_match_all('/[()"]/', $str, $matches);
2781
  // Intentional fall-through
2782
  case 'text':
2783
  default:
2784
+ $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
2785
  break;
2786
  }
2787
 
2788
+ //There are no chars that need encoding
2789
+ if ($matchcount == 0) {
2790
  return ($str);
2791
  }
2792
 
2793
  $maxlen = 75 - 7 - strlen($this->CharSet);
2794
  // Try to select the encoding which should produce the shortest output
2795
+ if ($matchcount > strlen($str) / 3) {
2796
+ // More than a third of the content will need encoding, so B encoding will be most efficient
2797
  $encoding = 'B';
2798
  if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
2799
  // Use a custom function which correctly encodes and wraps long
2811
  $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded));
2812
  }
2813
 
2814
+ $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded);
2815
  $encoded = trim(str_replace("\n", $this->LE, $encoded));
2816
 
2817
  return $encoded;
2821
  * Check if a string contains multi-byte characters.
2822
  * @access public
2823
  * @param string $str multi-byte text to wrap encode
2824
+ * @return boolean
2825
  */
2826
  public function hasMultiBytes($str)
2827
  {
2832
  }
2833
  }
2834
 
2835
+ /**
2836
+ * Does a string contain any 8-bit chars (in any charset)?
2837
+ * @param string $text
2838
+ * @return boolean
2839
+ */
2840
+ public function has8bitChars($text)
2841
+ {
2842
+ return (boolean)preg_match('/[\x80-\xFF]/', $text);
2843
+ }
2844
+
2845
  /**
2846
  * Encode and wrap long multibyte strings for mail headers
2847
  * without breaking lines within a character.
2848
+ * Adapted from a function by paravoid
2849
+ * @link http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
2850
  * @access public
2851
  * @param string $str multi-byte text to wrap encode
2852
+ * @param string $linebreak string to use as linefeed/end-of-line
2853
  * @return string
2854
  */
2855
+ public function base64EncodeWrapMB($str, $linebreak = null)
2856
  {
2857
+ $start = '=?' . $this->CharSet . '?B?';
2858
+ $end = '?=';
2859
+ $encoded = '';
2860
+ if ($linebreak === null) {
2861
+ $linebreak = $this->LE;
2862
  }
2863
 
2864
  $mb_length = mb_strlen($str, $this->CharSet);
2877
  $chunk = base64_encode($chunk);
2878
  $lookBack++;
2879
  } while (strlen($chunk) > $length);
2880
+ $encoded .= $chunk . $linebreak;
2881
  }
2882
 
2883
  // Chomp the last linefeed
2884
+ $encoded = substr($encoded, 0, -strlen($linebreak));
2885
  return $encoded;
2886
  }
2887
 
2892
  * @param string $string The text to encode
2893
  * @param integer $line_max Number of chars allowed on a line before wrapping
2894
  * @return string
2895
+ * @link http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 Adapted from this comment
2896
  */
2897
  public function encodeQP($string, $line_max = 76)
2898
  {
2899
+ // Use native function if it's available (>= PHP5.3)
2900
+ if (function_exists('quoted_printable_encode')) {
2901
  return quoted_printable_encode($string);
2902
  }
2903
+ // Fall back to a pure PHP implementation
2904
  $string = str_replace(
2905
  array('%20', '%0D%0A.', '%0D%0A', '%'),
2906
  array(' ', "\r\n=2E", "\r\n", '='),
2907
  rawurlencode($string)
2908
  );
2909
+ return preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
 
2910
  }
2911
 
2912
  /**
2915
  * @access public
2916
  * @param string $string
2917
  * @param integer $line_max
2918
+ * @param boolean $space_conv
2919
  * @return string
2920
  * @deprecated Use encodeQP instead.
2921
  */
2937
  */
2938
  public function encodeQ($str, $position = 'text')
2939
  {
2940
+ // There should not be any EOL in the string
2941
  $pattern = '';
2942
  $encoded = str_replace(array("\r", "\n"), '', $str);
2943
  switch (strtolower($position)) {
2944
  case 'phrase':
2945
+ // RFC 2047 section 5.3
2946
  $pattern = '^A-Za-z0-9!*+\/ -';
2947
  break;
2948
  /** @noinspection PhpMissingBreakStatementInspection */
2949
  case 'comment':
2950
+ // RFC 2047 section 5.2
2951
  $pattern = '\(\)"';
2952
+ // intentional fall-through
2953
+ // for this reason we build the $pattern without including delimiters and []
2954
  case 'text':
2955
  default:
2956
+ // RFC 2047 section 5.1
2957
+ // Replace every high ascii, control, =, ? and _ characters
2958
  $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
2959
  break;
2960
  }
2961
  $matches = array();
2962
  if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
2963
+ // If the string contains an '=', make sure it's the first thing we replace
2964
+ // so as to avoid double-encoding
2965
+ $eqkey = array_search('=', $matches[0]);
2966
+ if (false !== $eqkey) {
2967
+ unset($matches[0][$eqkey]);
2968
  array_unshift($matches[0], '=');
2969
  }
2970
  foreach (array_unique($matches[0]) as $char) {
2971
  $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
2972
  }
2973
  }
2974
+ // Replace every spaces to _ (more readable than =20)
2975
  return str_replace(' ', '_', $encoded);
2976
  }
2977
 
 
2978
  /**
2979
  * Add a string or binary attachment (non-filesystem).
2980
  * This method can be used to attach ascii or binary data,
2993
  $type = '',
2994
  $disposition = 'attachment'
2995
  ) {
2996
+ // If a MIME type is not specified, try to work it out from the file name
2997
  if ($type == '') {
2998
  $type = self::filenameToType($filename);
2999
  }
3013
  /**
3014
  * Add an embedded (inline) attachment from a file.
3015
  * This can include images, sounds, and just about any other document type.
3016
+ * These differ from 'regular' attachments in that they are intended to be
3017
  * displayed inline with the message, not just attached for download.
3018
  * This is used in HTML messages that embed the images
3019
  * the HTML refers to using the $cid value.
3024
  * @param string $encoding File encoding (see $Encoding).
3025
  * @param string $type File MIME type.
3026
  * @param string $disposition Disposition to use
3027
+ * @return boolean True on successfully adding an attachment
3028
  */
3029
  public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
3030
  {
3033
  return false;
3034
  }
3035
 
3036
+ // If a MIME type is not specified, try to work it out from the file name
3037
  if ($type == '') {
3038
  $type = self::filenameToType($path);
3039
  }
3069
  * @param string $encoding File encoding (see $Encoding).
3070
  * @param string $type MIME type.
3071
  * @param string $disposition Disposition to use
3072
+ * @return boolean True on successfully adding an attachment
3073
  */
3074
  public function addStringEmbeddedImage(
3075
  $string,
3079
  $type = '',
3080
  $disposition = 'inline'
3081
  ) {
3082
+ // If a MIME type is not specified, try to work it out from the name
3083
+ if ($type == '' and !empty($name)) {
3084
  $type = self::filenameToType($name);
3085
  }
3086
 
3101
  /**
3102
  * Check if an inline attachment is present.
3103
  * @access public
3104
+ * @return boolean
3105
  */
3106
  public function inlineImageExists()
3107
  {
3115
 
3116
  /**
3117
  * Check if an attachment (non-inline) is present.
3118
+ * @return boolean
3119
  */
3120
  public function attachmentExists()
3121
  {
3129
 
3130
  /**
3131
  * Check if this message has an alternative body set.
3132
+ * @return boolean
3133
  */
3134
  public function alternativeExists()
3135
  {
3136
  return !empty($this->AltBody);
3137
  }
3138
 
3139
+ /**
3140
+ * Clear queued addresses of given kind.
3141
+ * @access protected
3142
+ * @param string $kind 'to', 'cc', or 'bcc'
3143
+ * @return void
3144
+ */
3145
+ public function clearQueuedAddresses($kind)
3146
+ {
3147
+ $RecipientsQueue = $this->RecipientsQueue;
3148
+ foreach ($RecipientsQueue as $address => $params) {
3149
+ if ($params[0] == $kind) {
3150
+ unset($this->RecipientsQueue[$address]);
3151
+ }
3152
+ }
3153
+ }
3154
+
3155
  /**
3156
  * Clear all To recipients.
3157
  * @return void
3162
  unset($this->all_recipients[strtolower($to[0])]);
3163
  }
3164
  $this->to = array();
3165
+ $this->clearQueuedAddresses('to');
3166
  }
3167
 
3168
  /**
3175
  unset($this->all_recipients[strtolower($cc[0])]);
3176
  }
3177
  $this->cc = array();
3178
+ $this->clearQueuedAddresses('cc');
3179
  }
3180
 
3181
  /**
3188
  unset($this->all_recipients[strtolower($bcc[0])]);
3189
  }
3190
  $this->bcc = array();
3191
+ $this->clearQueuedAddresses('bcc');
3192
  }
3193
 
3194
  /**
3198
  public function clearReplyTos()
3199
  {
3200
  $this->ReplyTo = array();
3201
+ $this->ReplyToQueue = array();
3202
  }
3203
 
3204
  /**
3211
  $this->cc = array();
3212
  $this->bcc = array();
3213
  $this->all_recipients = array();
3214
+ $this->RecipientsQueue = array();
3215
  }
3216
 
3217
  /**
3243
  $this->error_count++;
3244
  if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
3245
  $lasterror = $this->smtp->getError();
3246
+ if (!empty($lasterror['error'])) {
3247
+ $msg .= $this->lang('smtp_error') . $lasterror['error'];
3248
+ if (!empty($lasterror['detail'])) {
3249
+ $msg .= ' Detail: '. $lasterror['detail'];
3250
+ }
3251
+ if (!empty($lasterror['smtp_code'])) {
3252
+ $msg .= ' SMTP code: ' . $lasterror['smtp_code'];
3253
+ }
3254
+ if (!empty($lasterror['smtp_code_ex'])) {
3255
+ $msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex'];
3256
+ }
3257
  }
3258
  }
3259
  $this->ErrorInfo = $msg;
3267
  */
3268
  public static function rfcDate()
3269
  {
3270
+ // Set the time zone to whatever the default is to avoid 500 errors
3271
+ // Will default to UTC if it's not set properly in php.ini
3272
  date_default_timezone_set(@date_default_timezone_get());
3273
  return date('D, j M Y H:i:s O');
3274
  }
3281
  */
3282
  protected function serverHostname()
3283
  {
3284
+ $result = 'localhost.localdomain';
3285
  if (!empty($this->Hostname)) {
3286
  $result = $this->Hostname;
3287
+ } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) {
3288
  $result = $_SERVER['SERVER_NAME'];
3289
+ } elseif (function_exists('gethostname') && gethostname() !== false) {
3290
+ $result = gethostname();
3291
+ } elseif (php_uname('n') !== false) {
3292
+ $result = php_uname('n');
3293
  }
 
3294
  return $result;
3295
  }
3296
 
3306
  $this->setLanguage('en'); // set the default language
3307
  }
3308
 
3309
+ if (array_key_exists($key, $this->language)) {
3310
+ if ($key == 'smtp_connect_failed') {
3311
+ //Include a link to troubleshooting docs on SMTP connection failure
3312
+ //this is by far the biggest cause of support questions
3313
+ //but it's usually not PHPMailer's fault.
3314
+ return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
3315
+ }
3316
  return $this->language[$key];
3317
  } else {
3318
+ //Return the key as a fallback
3319
+ return $key;
3320
  }
3321
  }
3322
 
3323
  /**
3324
  * Check if an error occurred.
3325
  * @access public
3326
+ * @return boolean True if an error did occur.
3327
  */
3328
  public function isError()
3329
  {
3368
  }
3369
 
3370
  /**
3371
+ * Returns all custom headers.
3372
+ * @return array
3373
+ */
3374
+ public function getCustomHeaders()
3375
+ {
3376
+ return $this->CustomHeader;
3377
+ }
3378
+
3379
+ /**
3380
+ * Create a message body from an HTML string.
3381
+ * Automatically inlines images and creates a plain-text version by converting the HTML,
3382
+ * overwriting any existing values in Body and AltBody.
3383
+ * $basedir is used when handling relative image paths, e.g. <img src="images/a.png">
3384
+ * will look for an image file in $basedir/images/a.png and convert it to inline.
3385
+ * If you don't want to apply these transformations to your HTML, just set Body and AltBody yourself.
3386
  * @access public
3387
  * @param string $message HTML message string
3388
+ * @param string $basedir base directory for relative paths to images
3389
+ * @param boolean|callable $advanced Whether to use the internal HTML to text converter
3390
+ * or your own custom converter @see PHPMailer::html2text()
3391
+ * @return string $message The transformed message Body
3392
  */
3393
  public function msgHTML($message, $basedir = '', $advanced = false)
3394
  {
3395
+ preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images);
3396
+ if (array_key_exists(2, $images)) {
3397
+ foreach ($images[2] as $imgindex => $url) {
3398
+ // Convert data URIs into embedded images
3399
+ if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) {
3400
+ $data = substr($url, strpos($url, ','));
3401
+ if ($match[2]) {
3402
+ $data = base64_decode($data);
3403
+ } else {
3404
+ $data = rawurldecode($data);
3405
+ }
3406
+ $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
3407
+ if ($this->addStringEmbeddedImage($data, $cid, 'embed' . $imgindex, 'base64', $match[1])) {
3408
+ $message = str_replace(
3409
+ $images[0][$imgindex],
3410
+ $images[1][$imgindex] . '="cid:' . $cid . '"',
3411
+ $message
3412
+ );
3413
+ }
3414
+ } elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[a-z][a-z0-9+.-]*://#i', $url)) {
3415
+ // Do not change urls for absolute images (thanks to corvuscorax)
3416
+ // Do not change urls that are already inline images
3417
  $filename = basename($url);
3418
  $directory = dirname($url);
3419
  if ($directory == '.') {
3420
  $directory = '';
3421
  }
3422
+ $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
3423
  if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
3424
  $basedir .= '/';
3425
  }
3431
  $cid,
3432
  $filename,
3433
  'base64',
3434
+ self::_mime_types((string)self::mb_pathinfo($filename, PATHINFO_EXTENSION))
3435
  )
3436
  ) {
3437
  $message = preg_replace(
3438
+ '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui',
3439
+ $images[1][$imgindex] . '="cid:' . $cid . '"',
3440
  $message
3441
  );
3442
  }
3444
  }
3445
  }
3446
  $this->isHTML(true);
3447
+ // Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
 
 
 
3448
  $this->Body = $this->normalizeBreaks($message);
3449
  $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
3450
+ if (!$this->alternativeExists()) {
3451
+ $this->AltBody = 'To view this email message, open it in a program that understands HTML!' .
3452
+ self::CRLF . self::CRLF;
3453
+ }
3454
  return $this->Body;
3455
  }
3456
 
3457
  /**
3458
  * Convert an HTML string into plain text.
3459
+ * This is used by msgHTML().
3460
+ * Note - older versions of this function used a bundled advanced converter
3461
+ * which was been removed for license reasons in #232.
3462
+ * Example usage:
3463
+ * <code>
3464
+ * // Use default conversion
3465
+ * $plain = $mail->html2text($html);
3466
+ * // Use your own custom converter
3467
+ * $plain = $mail->html2text($html, function($html) {
3468
+ * $converter = new MyHtml2text($html);
3469
+ * return $converter->get_text();
3470
+ * });
3471
+ * </code>
3472
  * @param string $html The HTML text to convert
3473
+ * @param boolean|callable $advanced Any boolean value to use the internal converter,
3474
+ * or provide your own callable for custom conversion.
3475
  * @return string
3476
  */
3477
  public function html2text($html, $advanced = false)
3478
  {
3479
+ if (is_callable($advanced)) {
3480
+ return call_user_func($advanced, $html);
 
 
3481
  }
3482
  return html_entity_decode(
3483
  trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))),
3496
  public static function _mime_types($ext = '')
3497
  {
3498
  $mimes = array(
3499
+ 'xl' => 'application/excel',
3500
+ 'js' => 'application/javascript',
3501
+ 'hqx' => 'application/mac-binhex40',
3502
+ 'cpt' => 'application/mac-compactpro',
3503
+ 'bin' => 'application/macbinary',
3504
+ 'doc' => 'application/msword',
3505
+ 'word' => 'application/msword',
3506
+ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
3507
+ 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
3508
+ 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
3509
+ 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
3510
+ 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
3511
+ 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
3512
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
3513
+ 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
3514
+ 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
3515
+ 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
3516
  'class' => 'application/octet-stream',
3517
+ 'dll' => 'application/octet-stream',
3518
+ 'dms' => 'application/octet-stream',
3519
+ 'exe' => 'application/octet-stream',
3520
+ 'lha' => 'application/octet-stream',
3521
+ 'lzh' => 'application/octet-stream',
3522
+ 'psd' => 'application/octet-stream',
3523
+ 'sea' => 'application/octet-stream',
3524
+ 'so' => 'application/octet-stream',
3525
+ 'oda' => 'application/oda',
3526
+ 'pdf' => 'application/pdf',
3527
+ 'ai' => 'application/postscript',
3528
+ 'eps' => 'application/postscript',
3529
+ 'ps' => 'application/postscript',
3530
+ 'smi' => 'application/smil',
3531
+ 'smil' => 'application/smil',
3532
+ 'mif' => 'application/vnd.mif',
3533
+ 'xls' => 'application/vnd.ms-excel',
3534
+ 'ppt' => 'application/vnd.ms-powerpoint',
3535
  'wbxml' => 'application/vnd.wap.wbxml',
3536
+ 'wmlc' => 'application/vnd.wap.wmlc',
3537
+ 'dcr' => 'application/x-director',
3538
+ 'dir' => 'application/x-director',
3539
+ 'dxr' => 'application/x-director',
3540
+ 'dvi' => 'application/x-dvi',
3541
+ 'gtar' => 'application/x-gtar',
3542
+ 'php3' => 'application/x-httpd-php',
3543
+ 'php4' => 'application/x-httpd-php',
3544
+ 'php' => 'application/x-httpd-php',
3545
  'phtml' => 'application/x-httpd-php',
3546
+ 'phps' => 'application/x-httpd-php-source',
3547
+ 'swf' => 'application/x-shockwave-flash',
3548
+ 'sit' => 'application/x-stuffit',
3549
+ 'tar' => 'application/x-tar',
3550
+ 'tgz' => 'application/x-tar',
3551
+ 'xht' => 'application/xhtml+xml',
 
3552
  'xhtml' => 'application/xhtml+xml',
3553
+ 'zip' => 'application/zip',
3554
+ 'mid' => 'audio/midi',
3555
+ 'midi' => 'audio/midi',
3556
+ 'mp2' => 'audio/mpeg',
3557
+ 'mp3' => 'audio/mpeg',
3558
+ 'mpga' => 'audio/mpeg',
3559
+ 'aif' => 'audio/x-aiff',
3560
+ 'aifc' => 'audio/x-aiff',
3561
+ 'aiff' => 'audio/x-aiff',
3562
+ 'ram' => 'audio/x-pn-realaudio',
3563
+ 'rm' => 'audio/x-pn-realaudio',
3564
+ 'rpm' => 'audio/x-pn-realaudio-plugin',
3565
+ 'ra' => 'audio/x-realaudio',
3566
+ 'wav' => 'audio/x-wav',
3567
+ 'bmp' => 'image/bmp',
3568
+ 'gif' => 'image/gif',
3569
+ 'jpeg' => 'image/jpeg',
3570
+ 'jpe' => 'image/jpeg',
3571
+ 'jpg' => 'image/jpeg',
3572
+ 'png' => 'image/png',
3573
+ 'tiff' => 'image/tiff',
3574
+ 'tif' => 'image/tiff',
3575
+ 'eml' => 'message/rfc822',
3576
+ 'css' => 'text/css',
3577
+ 'html' => 'text/html',
3578
+ 'htm' => 'text/html',
3579
  'shtml' => 'text/html',
3580
+ 'log' => 'text/plain',
3581
+ 'text' => 'text/plain',
3582
+ 'txt' => 'text/plain',
3583
+ 'rtx' => 'text/richtext',
3584
+ 'rtf' => 'text/rtf',
3585
+ 'vcf' => 'text/vcard',
3586
+ 'vcard' => 'text/vcard',
3587
+ 'xml' => 'text/xml',
3588
+ 'xsl' => 'text/xml',
3589
+ 'mpeg' => 'video/mpeg',
3590
+ 'mpe' => 'video/mpeg',
3591
+ 'mpg' => 'video/mpeg',
3592
+ 'mov' => 'video/quicktime',
3593
+ 'qt' => 'video/quicktime',
3594
+ 'rv' => 'video/vnd.rn-realvideo',
3595
+ 'avi' => 'video/x-msvideo',
3596
  'movie' => 'video/x-sgi-movie'
3597
  );
3598
+ if (array_key_exists(strtolower($ext), $mimes)) {
3599
+ return $mimes[strtolower($ext)];
3600
+ }
3601
+ return 'application/octet-stream';
3602
  }
3603
 
3604
  /**
3610
  */
3611
  public static function filenameToType($filename)
3612
  {
3613
+ // In case the path is a URL, strip any query string before getting extension
3614
  $qpos = strpos($filename, '?');
3615
+ if (false !== $qpos) {
3616
  $filename = substr($filename, 0, $qpos);
3617
  }
3618
  $pathinfo = self::mb_pathinfo($filename);
3633
  public static function mb_pathinfo($path, $options = null)
3634
  {
3635
  $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
3636
+ $pathinfo = array();
3637
+ if (preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo)) {
3638
+ if (array_key_exists(1, $pathinfo)) {
3639
+ $ret['dirname'] = $pathinfo[1];
3640
+ }
3641
+ if (array_key_exists(2, $pathinfo)) {
3642
+ $ret['basename'] = $pathinfo[2];
3643
+ }
3644
+ if (array_key_exists(5, $pathinfo)) {
3645
+ $ret['extension'] = $pathinfo[5];
3646
+ }
3647
+ if (array_key_exists(3, $pathinfo)) {
3648
+ $ret['filename'] = $pathinfo[3];
3649
+ }
3650
  }
3651
  switch ($options) {
3652
  case PATHINFO_DIRNAME:
3653
  case 'dirname':
3654
  return $ret['dirname'];
 
3655
  case PATHINFO_BASENAME:
3656
  case 'basename':
3657
  return $ret['basename'];
 
3658
  case PATHINFO_EXTENSION:
3659
  case 'extension':
3660
  return $ret['extension'];
 
3661
  case PATHINFO_FILENAME:
3662
  case 'filename':
3663
  return $ret['filename'];
 
3664
  default:
3665
  return $ret;
3666
  }
3668
 
3669
  /**
3670
  * Set or reset instance properties.
3671
+ * You should avoid this function - it's more verbose, less efficient, more error-prone and
3672
+ * harder to debug than setting properties directly.
3673
  * Usage Example:
3674
+ * `$mail->set('SMTPSecure', 'tls');`
3675
+ * is the same as:
3676
+ * `$mail->SMTPSecure = 'tls';`
3677
  * @access public
3678
+ * @param string $name The property name to set
3679
+ * @param mixed $value The value to set the property to
3680
+ * @return boolean
3681
+ * @TODO Should this not be using the __set() magic function?
 
 
3682
  */
3683
  public function set($name, $value = '')
3684
  {
3685
+ if (property_exists($this, $name)) {
3686
+ $this->$name = $value;
3687
+ return true;
3688
+ } else {
3689
+ $this->setError($this->lang('variable_set') . $name);
3690
+ return false;
 
 
 
 
 
3691
  }
 
3692
  }
3693
 
3694
  /**
3717
  return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text);
3718
  }
3719
 
 
3720
  /**
3721
  * Set the public and private key files and password for S/MIME signing.
3722
  * @access public
3723
  * @param string $cert_filename
3724
  * @param string $key_filename
3725
  * @param string $key_pass Password for private key
3726
+ * @param string $extracerts_filename Optional path to chain certificate
3727
  */
3728
+ public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '')
3729
  {
3730
  $this->sign_cert_file = $cert_filename;
3731
  $this->sign_key_file = $key_filename;
3732
  $this->sign_key_pass = $key_pass;
3733
+ $this->sign_extracerts_file = $extracerts_filename;
3734
  }
3735
 
3736
  /**
3747
  if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
3748
  $line .= $txt[$i];
3749
  } else {
3750
+ $line .= '=' . sprintf('%02X', $ord);
3751
  }
3752
  }
3753
  return $line;
3756
  /**
3757
  * Generate a DKIM signature.
3758
  * @access public
3759
+ * @param string $signHeader
3760
  * @throws phpmailerException
3761
+ * @return string The DKIM signature value
3762
  */
3763
+ public function DKIM_Sign($signHeader)
3764
  {
3765
  if (!defined('PKCS7_TEXT')) {
3766
  if ($this->exceptions) {
3767
+ throw new phpmailerException($this->lang('extension_missing') . 'openssl');
3768
  }
3769
  return '';
3770
  }
3771
+ $privKeyStr = !empty($this->DKIM_private_string) ? $this->DKIM_private_string : file_get_contents($this->DKIM_private);
3772
+ if ('' != $this->DKIM_passphrase) {
3773
  $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
3774
  } else {
3775
+ $privKey = openssl_pkey_get_private($privKeyStr);
3776
+ }
3777
+ //Workaround for missing digest algorithms in old PHP & OpenSSL versions
3778
+ //@link http://stackoverflow.com/a/11117338/333340
3779
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0 and
3780
+ in_array('sha256WithRSAEncryption', openssl_get_md_methods(true))) {
3781
+ if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) {
3782
+ openssl_pkey_free($privKey);
3783
+ return base64_encode($signature);
3784
+ }
3785
+ } else {
3786
+ $pinfo = openssl_pkey_get_details($privKey);
3787
+ $hash = hash('sha256', $signHeader);
3788
+ //'Magic' constant for SHA256 from RFC3447
3789
+ //@link https://tools.ietf.org/html/rfc3447#page-43
3790
+ $t = '3031300d060960864801650304020105000420' . $hash;
3791
+ $pslen = $pinfo['bits'] / 8 - (strlen($t) / 2 + 3);
3792
+ $eb = pack('H*', '0001' . str_repeat('FF', $pslen) . '00' . $t);
3793
+
3794
+ if (openssl_private_encrypt($eb, $signature, $privKey, OPENSSL_NO_PADDING)) {
3795
+ openssl_pkey_free($privKey);
3796
+ return base64_encode($signature);
3797
+ }
3798
  }
3799
+ openssl_pkey_free($privKey);
3800
  return '';
3801
  }
3802
 
3803
  /**
3804
  * Generate a DKIM canonicalization header.
3805
  * @access public
3806
+ * @param string $signHeader Header
3807
  * @return string
3808
  */
3809
+ public function DKIM_HeaderC($signHeader)
3810
  {
3811
+ $signHeader = preg_replace('/\r\n\s+/', ' ', $signHeader);
3812
+ $lines = explode("\r\n", $signHeader);
3813
  foreach ($lines as $key => $line) {
3814
+ list($heading, $value) = explode(':', $line, 2);
3815
  $heading = strtolower($heading);
3816
+ $value = preg_replace('/\s{2,}/', ' ', $value); // Compress useless spaces
3817
+ $lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value
3818
  }
3819
+ $signHeader = implode("\r\n", $lines);
3820
+ return $signHeader;
3821
  }
3822
 
3823
  /**
3851
  */
3852
  public function DKIM_Add($headers_line, $subject, $body)
3853
  {
3854
+ $DKIMsignatureType = 'rsa-sha256'; // Signature & hash algorithms
3855
  $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
3856
  $DKIMquery = 'dns/txt'; // Query method
3857
  $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
3859
  $headers = explode($this->LE, $headers_line);
3860
  $from_header = '';
3861
  $to_header = '';
3862
+ $date_header = '';
3863
  $current = '';
3864
  foreach ($headers as $header) {
3865
  if (strpos($header, 'From:') === 0) {
3868
  } elseif (strpos($header, 'To:') === 0) {
3869
  $to_header = $header;
3870
  $current = 'to_header';
3871
+ } elseif (strpos($header, 'Date:') === 0) {
3872
+ $date_header = $header;
3873
+ $current = 'date_header';
3874
  } else {
3875
+ if (!empty($$current) && strpos($header, ' =?') === 0) {
3876
+ $$current .= $header;
3877
  } else {
3878
  $current = '';
3879
  }
3881
  }
3882
  $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
3883
  $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
3884
+ $date = str_replace('|', '=7C', $this->DKIM_QP($date_header));
3885
  $subject = str_replace(
3886
  '|',
3887
  '=7C',
3889
  ); // Copied header fields (dkim-quoted-printable)
3890
  $body = $this->DKIM_BodyC($body);
3891
  $DKIMlen = strlen($body); // Length of body
3892
+ $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body
3893
+ if ('' == $this->DKIM_identity) {
3894
+ $ident = '';
3895
+ } else {
3896
+ $ident = ' i=' . $this->DKIM_identity . ';';
3897
+ }
3898
+ $dkimhdrs = 'DKIM-Signature: v=1; a=' .
3899
+ $DKIMsignatureType . '; q=' .
3900
+ $DKIMquery . '; l=' .
3901
+ $DKIMlen . '; s=' .
3902
  $this->DKIM_selector .
3903
  ";\r\n" .
3904
+ "\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" .
3905
+ "\th=From:To:Date:Subject;\r\n" .
3906
+ "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" .
3907
  "\tz=$from\r\n" .
3908
  "\t|$to\r\n" .
3909
+ "\t|$date\r\n" .
3910
  "\t|$subject;\r\n" .
3911
  "\tbh=" . $DKIMb64 . ";\r\n" .
3912
  "\tb=";
3913
  $toSign = $this->DKIM_HeaderC(
3914
+ $from_header . "\r\n" .
3915
+ $to_header . "\r\n" .
3916
+ $date_header . "\r\n" .
3917
+ $subject_header . "\r\n" .
3918
+ $dkimhdrs
3919
  );
3920
  $signed = $this->DKIM_Sign($toSign);
3921
  return $dkimhdrs . $signed . "\r\n";
3922
  }
3923
 
3924
+ /**
3925
+ * Detect if a string contains a line longer than the maximum line length allowed.
3926
+ * @param string $str
3927
+ * @return boolean
3928
+ * @static
3929
+ */
3930
+ public static function hasLineLongerThanMax($str)
3931
+ {
3932
+ //+2 to include CRLF line break for a 1000 total
3933
+ return (boolean)preg_match('/^(.{'.(self::MAX_LINE_LENGTH + 2).',})/m', $str);
3934
+ }
3935
+
3936
+ /**
3937
+ * Allows for public read access to 'to' property.
3938
+ * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
3939
+ * @access public
3940
+ * @return array
3941
+ */
3942
+ public function getToAddresses()
3943
+ {
3944
+ return $this->to;
3945
+ }
3946
+
3947
+ /**
3948
+ * Allows for public read access to 'cc' property.
3949
+ * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
3950
+ * @access public
3951
+ * @return array
3952
+ */
3953
+ public function getCcAddresses()
3954
+ {
3955
+ return $this->cc;
3956
+ }
3957
+
3958
+ /**
3959
+ * Allows for public read access to 'bcc' property.
3960
+ * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
3961
+ * @access public
3962
+ * @return array
3963
+ */
3964
+ public function getBccAddresses()
3965
+ {
3966
+ return $this->bcc;
3967
+ }
3968
+
3969
+ /**
3970
+ * Allows for public read access to 'ReplyTo' property.
3971
+ * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
3972
+ * @access public
3973
+ * @return array
3974
+ */
3975
+ public function getReplyToAddresses()
3976
+ {
3977
+ return $this->ReplyTo;
3978
+ }
3979
+
3980
+ /**
3981
+ * Allows for public read access to 'all_recipients' property.
3982
+ * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.
3983
+ * @access public
3984
+ * @return array
3985
+ */
3986
+ public function getAllRecipientAddresses()
3987
+ {
3988
+ return $this->all_recipients;
3989
+ }
3990
+
3991
  /**
3992
  * Perform a callback.
3993
+ * @param boolean $isSent
3994
+ * @param array $to
3995
+ * @param array $cc
3996
+ * @param array $bcc
3997
  * @param string $subject
3998
  * @param string $body
3999
  * @param string $from
4000
  */
4001
+ protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from)
4002
  {
4003
  if (!empty($this->action_function) && is_callable($this->action_function)) {
4004
  $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
phpmailer/class.phpmaileroauth.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer - PHP email creation and transport class.
4
+ * PHP Version 5.4
5
+ * @package PHPMailer
6
+ * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
7
+ * @author Marcus Bointon (Synchro/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 2012 - 2014 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
+ * PHPMailerOAuth - PHPMailer subclass adding OAuth support.
22
+ * @package PHPMailer
23
+ * @author @sherryl4george
24
+ * @author Marcus Bointon (@Synchro) <phpmailer@synchromedia.co.uk>
25
+ */
26
+ class PHPMailerOAuth extends PHPMailer
27
+ {
28
+ /**
29
+ * The OAuth user's email address
30
+ * @var string
31
+ */
32
+ public $oauthUserEmail = '';
33
+
34
+ /**
35
+ * The OAuth refresh token
36
+ * @var string
37
+ */
38
+ public $oauthRefreshToken = '';
39
+
40
+ /**
41
+ * The OAuth client ID
42
+ * @var string
43
+ */
44
+ public $oauthClientId = '';
45
+
46
+ /**
47
+ * The OAuth client secret
48
+ * @var string
49
+ */
50
+ public $oauthClientSecret = '';
51
+
52
+ /**
53
+ * An instance of the PHPMailerOAuthGoogle class.
54
+ * @var PHPMailerOAuthGoogle
55
+ * @access protected
56
+ */
57
+ protected $oauth = null;
58
+
59
+ /**
60
+ * Get a PHPMailerOAuthGoogle instance to use.
61
+ * @return PHPMailerOAuthGoogle
62
+ */
63
+ public function getOAUTHInstance()
64
+ {
65
+ if (!is_object($this->oauth)) {
66
+ $this->oauth = new PHPMailerOAuthGoogle(
67
+ $this->oauthUserEmail,
68
+ $this->oauthClientSecret,
69
+ $this->oauthClientId,
70
+ $this->oauthRefreshToken
71
+ );
72
+ }
73
+ return $this->oauth;
74
+ }
75
+
76
+ /**
77
+ * Initiate a connection to an SMTP server.
78
+ * Overrides the original smtpConnect method to add support for OAuth.
79
+ * @param array $options An array of options compatible with stream_context_create()
80
+ * @uses SMTP
81
+ * @access public
82
+ * @return bool
83
+ * @throws phpmailerException
84
+ */
85
+ public function smtpConnect($options = array())
86
+ {
87
+ if (is_null($this->smtp)) {
88
+ $this->smtp = $this->getSMTPInstance();
89
+ }
90
+
91
+ if (is_null($this->oauth)) {
92
+ $this->oauth = $this->getOAUTHInstance();
93
+ }
94
+
95
+ // Already connected?
96
+ if ($this->smtp->connected()) {
97
+ return true;
98
+ }
99
+
100
+ $this->smtp->setTimeout($this->Timeout);
101
+ $this->smtp->setDebugLevel($this->SMTPDebug);
102
+ $this->smtp->setDebugOutput($this->Debugoutput);
103
+ $this->smtp->setVerp($this->do_verp);
104
+ $hosts = explode(';', $this->Host);
105
+ $lastexception = null;
106
+
107
+ foreach ($hosts as $hostentry) {
108
+ $hostinfo = array();
109
+ if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
110
+ // Not a valid host entry
111
+ continue;
112
+ }
113
+ // $hostinfo[2]: optional ssl or tls prefix
114
+ // $hostinfo[3]: the hostname
115
+ // $hostinfo[4]: optional port number
116
+ // The host string prefix can temporarily override the current setting for SMTPSecure
117
+ // If it's not specified, the default value is used
118
+ $prefix = '';
119
+ $secure = $this->SMTPSecure;
120
+ $tls = ($this->SMTPSecure == 'tls');
121
+ if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
122
+ $prefix = 'ssl://';
123
+ $tls = false; // Can't have SSL and TLS at the same time
124
+ $secure = 'ssl';
125
+ } elseif ($hostinfo[2] == 'tls') {
126
+ $tls = true;
127
+ // tls doesn't use a prefix
128
+ $secure = 'tls';
129
+ }
130
+ //Do we need the OpenSSL extension?
131
+ $sslext = defined('OPENSSL_ALGO_SHA1');
132
+ if ('tls' === $secure or 'ssl' === $secure) {
133
+ //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
134
+ if (!$sslext) {
135
+ throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
136
+ }
137
+ }
138
+ $host = $hostinfo[3];
139
+ $port = $this->Port;
140
+ $tport = (integer)$hostinfo[4];
141
+ if ($tport > 0 and $tport < 65536) {
142
+ $port = $tport;
143
+ }
144
+ if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
145
+ try {
146
+ if ($this->Helo) {
147
+ $hello = $this->Helo;
148
+ } else {
149
+ $hello = $this->serverHostname();
150
+ }
151
+ $this->smtp->hello($hello);
152
+ //Automatically enable TLS encryption if:
153
+ // * it's not disabled
154
+ // * we have openssl extension
155
+ // * we are not already using SSL
156
+ // * the server offers STARTTLS
157
+ if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
158
+ $tls = true;
159
+ }
160
+ if ($tls) {
161
+ if (!$this->smtp->startTLS()) {
162
+ throw new phpmailerException($this->lang('connect_host'));
163
+ }
164
+ // We must resend HELO after tls negotiation
165
+ $this->smtp->hello($hello);
166
+ }
167
+ if ($this->SMTPAuth) {
168
+ if (!$this->smtp->authenticate(
169
+ $this->Username,
170
+ $this->Password,
171
+ $this->AuthType,
172
+ $this->Realm,
173
+ $this->Workstation,
174
+ $this->oauth
175
+ )
176
+ ) {
177
+ throw new phpmailerException($this->lang('authenticate'));
178
+ }
179
+ }
180
+ return true;
181
+ } catch (phpmailerException $exc) {
182
+ $lastexception = $exc;
183
+ $this->edebug($exc->getMessage());
184
+ // We must have connected, but then failed TLS or Auth, so close connection nicely
185
+ $this->smtp->quit();
186
+ }
187
+ }
188
+ }
189
+ // If we get here, all connection attempts have failed, so close connection hard
190
+ $this->smtp->close();
191
+ // As we've caught all exceptions, just report whatever the last one was
192
+ if ($this->exceptions and !is_null($lastexception)) {
193
+ throw $lastexception;
194
+ }
195
+ return false;
196
+ }
197
+ }
phpmailer/class.phpmaileroauthgoogle.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPMailer - PHP email creation and transport class.
4
+ * PHP Version 5.4
5
+ * @package PHPMailer
6
+ * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
7
+ * @author Marcus Bointon (Synchro/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 2012 - 2014 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
+ * PHPMailerOAuthGoogle - Wrapper for League OAuth2 Google provider.
22
+ * @package PHPMailer
23
+ * @author @sherryl4george
24
+ * @author Marcus Bointon (@Synchro) <phpmailer@synchromedia.co.uk>
25
+ * @link https://github.com/thephpleague/oauth2-client
26
+ */
27
+ class PHPMailerOAuthGoogle
28
+ {
29
+ private $oauthUserEmail = '';
30
+ private $oauthRefreshToken = '';
31
+ private $oauthClientId = '';
32
+ private $oauthClientSecret = '';
33
+
34
+ /**
35
+ * @param string $UserEmail
36
+ * @param string $ClientSecret
37
+ * @param string $ClientId
38
+ * @param string $RefreshToken
39
+ */
40
+ public function __construct(
41
+ $UserEmail,
42
+ $ClientSecret,
43
+ $ClientId,
44
+ $RefreshToken
45
+ ) {
46
+ $this->oauthClientId = $ClientId;
47
+ $this->oauthClientSecret = $ClientSecret;
48
+ $this->oauthRefreshToken = $RefreshToken;
49
+ $this->oauthUserEmail = $UserEmail;
50
+ }
51
+
52
+ private function getProvider()
53
+ {
54
+ return new League\OAuth2\Client\Provider\Google([
55
+ 'clientId' => $this->oauthClientId,
56
+ 'clientSecret' => $this->oauthClientSecret
57
+ ]);
58
+ }
59
+
60
+ private function getGrant()
61
+ {
62
+ return new \League\OAuth2\Client\Grant\RefreshToken();
63
+ }
64
+
65
+ private function getToken()
66
+ {
67
+ $provider = $this->getProvider();
68
+ $grant = $this->getGrant();
69
+ return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]);
70
+ }
71
+
72
+ public function getOauth64()
73
+ {
74
+ $token = $this->getToken();
75
+ return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001");
76
+ }
77
+ }
phpmailer/class.pop3.php CHANGED
@@ -1,15 +1,14 @@
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
@@ -24,37 +23,36 @@
24
  * Does not support APOP.
25
  * @package PHPMailer
26
  * @author Richard Davey (original author) <rich@corephp.co.uk>
27
- * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
28
  * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
29
  * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
30
  */
31
-
32
  class POP3
33
  {
34
  /**
35
  * The POP3 PHPMailer Version number.
36
- * @type string
37
  * @access public
38
  */
39
- public $Version = '5.2.7';
40
 
41
  /**
42
  * Default POP3 port number.
43
- * @type int
44
  * @access public
45
  */
46
  public $POP3_PORT = 110;
47
 
48
  /**
49
  * Default timeout in seconds.
50
- * @type int
51
  * @access public
52
  */
53
  public $POP3_TIMEOUT = 30;
54
 
55
  /**
56
  * POP3 Carriage Return + Line Feed.
57
- * @type string
58
  * @access public
59
  * @deprecated Use the constant instead
60
  */
@@ -63,103 +61,92 @@ class POP3
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
  /**
@@ -167,34 +154,34 @@ class POP3
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) {
@@ -213,7 +200,7 @@ class POP3
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
  */
@@ -228,6 +215,10 @@ class POP3
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
@@ -238,34 +229,20 @@ class POP3
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();
@@ -288,12 +265,8 @@ class POP3
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;
@@ -325,7 +298,11 @@ class POP3
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
  /**
@@ -333,24 +310,24 @@ class POP3
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
@@ -366,19 +343,16 @@ class POP3
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;
@@ -386,16 +360,30 @@ class POP3
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
  /**
@@ -404,16 +392,16 @@ class POP3
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
  }
1
  <?php
2
  /**
3
  * PHPMailer POP-Before-SMTP Authentication Class.
4
+ * PHP Version 5
 
5
  * @package PHPMailer
6
  * @link https://github.com/PHPMailer/PHPMailer/
7
+ * @author Marcus Bointon (Synchro/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 2012 - 2014 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
23
  * Does not support APOP.
24
  * @package PHPMailer
25
  * @author Richard Davey (original author) <rich@corephp.co.uk>
26
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
27
  * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
28
  * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
29
  */
 
30
  class POP3
31
  {
32
  /**
33
  * The POP3 PHPMailer Version number.
34
+ * @var string
35
  * @access public
36
  */
37
+ public $Version = '5.2.21';
38
 
39
  /**
40
  * Default POP3 port number.
41
+ * @var integer
42
  * @access public
43
  */
44
  public $POP3_PORT = 110;
45
 
46
  /**
47
  * Default timeout in seconds.
48
+ * @var integer
49
  * @access public
50
  */
51
  public $POP3_TIMEOUT = 30;
52
 
53
  /**
54
  * POP3 Carriage Return + Line Feed.
55
+ * @var string
56
  * @access public
57
  * @deprecated Use the constant instead
58
  */
61
  /**
62
  * Debug display level.
63
  * Options: 0 = no, 1+ = yes
64
+ * @var integer
65
  * @access public
66
  */
67
  public $do_debug = 0;
68
 
69
  /**
70
  * POP3 mail server hostname.
71
+ * @var string
72
  * @access public
73
  */
74
  public $host;
75
 
76
  /**
77
  * POP3 port number.
78
+ * @var integer
79
  * @access public
80
  */
81
  public $port;
82
 
83
  /**
84
  * POP3 Timeout Value in seconds.
85
+ * @var integer
86
  * @access public
87
  */
88
  public $tval;
89
 
90
  /**
91
  * POP3 username
92
+ * @var string
93
  * @access public
94
  */
95
  public $username;
96
 
97
  /**
98
  * POP3 password.
99
+ * @var string
100
  * @access public
101
  */
102
  public $password;
103
 
104
  /**
105
  * Resource handle for the POP3 connection socket.
106
+ * @var resource
107
+ * @access protected
108
  */
109
+ protected $pop_conn;
110
 
111
  /**
112
  * Are we connected?
113
+ * @var boolean
114
+ * @access protected
115
  */
116
+ protected $connected = false;
117
 
118
  /**
119
  * Error container.
120
+ * @var array
121
+ * @access protected
122
  */
123
+ protected $errors = array();
124
 
125
  /**
126
  * Line break constant
127
  */
128
  const CRLF = "\r\n";
129
 
 
 
 
 
 
 
 
 
 
 
 
130
  /**
131
  * Simple static wrapper for all-in-one POP before SMTP
132
  * @param $host
133
+ * @param integer|boolean $port The port number to connect to
134
+ * @param integer|boolean $timeout The timeout value
135
  * @param string $username
136
  * @param string $password
137
+ * @param integer $debug_level
138
+ * @return boolean
139
  */
140
  public static function popBeforeSmtp(
141
  $host,
142
  $port = false,
143
+ $timeout = false,
144
  $username = '',
145
  $password = '',
146
  $debug_level = 0
147
  ) {
148
  $pop = new POP3;
149
+ return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
150
  }
151
 
152
  /**
154
  * A connect, login, disconnect sequence
155
  * appropriate for POP-before SMTP authorisation.
156
  * @access public
157
+ * @param string $host The hostname to connect to
158
+ * @param integer|boolean $port The port number to connect to
159
+ * @param integer|boolean $timeout The timeout value
160
  * @param string $username
161
  * @param string $password
162
+ * @param integer $debug_level
163
+ * @return boolean
164
  */
165
+ public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
166
  {
167
  $this->host = $host;
168
  // If no port value provided, use default
169
+ if (false === $port) {
170
  $this->port = $this->POP3_PORT;
171
  } else {
172
+ $this->port = (integer)$port;
173
  }
174
  // If no timeout value provided, use default
175
+ if (false === $timeout) {
176
  $this->tval = $this->POP3_TIMEOUT;
177
  } else {
178
+ $this->tval = (integer)$timeout;
179
  }
180
  $this->do_debug = $debug_level;
181
  $this->username = $username;
182
  $this->password = $password;
183
+ // Reset the error log
184
+ $this->errors = array();
185
  // connect
186
  $result = $this->connect($this->host, $this->port, $this->tval);
187
  if ($result) {
200
  * Connect to a POP3 server.
201
  * @access public
202
  * @param string $host
203
+ * @param integer|boolean $port
204
  * @param integer $tval
205
  * @return boolean
206
  */
215
  //Rather than suppress it with @fsockopen, capture it cleanly instead
216
  set_error_handler(array($this, 'catchWarning'));
217
 
218
+ if (false === $port) {
219
+ $port = $this->POP3_PORT;
220
+ }
221
+
222
  // connect to the POP3 server
223
  $this->pop_conn = fsockopen(
224
  $host, // POP3 Host
229
  ); // Timeout (seconds)
230
  // Restore the error handler
231
  restore_error_handler();
232
+
 
 
 
233
  // Did we connect?
234
+ if (false === $this->pop_conn) {
235
  // It would appear not...
236
+ $this->setError(array(
237
  'error' => "Failed to connect to server $host on port $port",
238
  'errno' => $errno,
239
  'errstr' => $errstr
240
+ ));
 
 
 
241
  return false;
242
  }
243
 
244
  // Increase the stream time-out
245
+ stream_set_timeout($this->pop_conn, $tval, 0);
 
 
 
 
 
 
 
 
246
 
247
  // Get the POP3 server response
248
  $pop3_response = $this->getResponse();
265
  */
266
  public function login($username = '', $password = '')
267
  {
268
+ if (!$this->connected) {
269
+ $this->setError('Not connected to POP3 server');
 
 
 
 
270
  }
271
  if (empty($username)) {
272
  $username = $this->username;
298
  $this->sendString('QUIT');
299
  //The QUIT command may cause the daemon to exit, which will kill our connection
300
  //So ignore errors here
301
+ try {
302
+ @fclose($this->pop_conn);
303
+ } catch (Exception $e) {
304
+ //Do nothing
305
+ };
306
  }
307
 
308
  /**
310
  * $size is the maximum number of bytes to retrieve
311
  * @param integer $size
312
  * @return string
313
+ * @access protected
314
  */
315
+ protected function getResponse($size = 128)
316
  {
317
+ $response = fgets($this->pop_conn, $size);
318
  if ($this->do_debug >= 1) {
319
+ echo "Server -> Client: $response";
320
  }
321
+ return $response;
322
  }
323
 
324
  /**
325
  * Send raw data to the POP3 server.
326
  * @param string $string
327
  * @return integer
328
+ * @access protected
329
  */
330
+ protected function sendString($string)
331
  {
332
  if ($this->pop_conn) {
333
  if ($this->do_debug >= 2) { //Show client messages when debug >= 2
343
  * Looks for for +OK or -ERR.
344
  * @param string $string
345
  * @return boolean
346
+ * @access protected
347
  */
348
+ protected function checkResponse($string)
349
  {
350
  if (substr($string, 0, 3) !== '+OK') {
351
+ $this->setError(array(
352
  'error' => "Server reported an error: $string",
353
  'errno' => 0,
354
  'errstr' => ''
355
+ ));
 
 
 
356
  return false;
357
  } else {
358
  return true;
360
  }
361
 
362
  /**
363
+ * Add an error to the internal error store.
364
+ * Also display debug output if it's enabled.
365
+ * @param $error
366
+ * @access protected
367
  */
368
+ protected function setError($error)
369
  {
370
+ $this->errors[] = $error;
371
+ if ($this->do_debug >= 1) {
372
+ echo '<pre>';
373
+ foreach ($this->errors as $error) {
374
+ print_r($error);
375
+ }
376
+ echo '</pre>';
377
  }
378
+ }
379
+
380
+ /**
381
+ * Get an array of error messages, if any.
382
+ * @return array
383
+ */
384
+ public function getErrors()
385
+ {
386
+ return $this->errors;
387
  }
388
 
389
  /**
392
  * @param string $errstr
393
  * @param string $errfile
394
  * @param integer $errline
395
+ * @access protected
396
  */
397
+ protected function catchWarning($errno, $errstr, $errfile, $errline)
398
  {
399
+ $this->setError(array(
400
  'error' => "Connecting to the POP3 server raised a PHP warning: ",
401
  'errno' => $errno,
402
  'errstr' => $errstr,
403
  'errfile' => $errfile,
404
  'errline' => $errline
405
+ ));
406
  }
407
  }
phpmailer/class.smtp.php CHANGED
@@ -1,73 +1,100 @@
1
  <?php
2
  /**
3
  * PHPMailer RFC821 SMTP email transport class.
4
- * Version 5.2.7
5
- * PHP version 5.0.0
6
- * @category PHP
7
- * @package PHPMailer
8
- * @link https://github.com/PHPMailer/PHPMailer/
9
- * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
10
  * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
11
  * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
12
- * @copyright 2013 Marcus Bointon
13
- * @copyright 2004 - 2008 Andy Prevost
14
  * @copyright 2010 - 2012 Jim Jagielski
15
- * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
 
 
 
 
16
  */
17
 
18
  /**
19
  * PHPMailer RFC821 SMTP email transport class.
20
- *
21
- * Implements RFC 821 SMTP commands
22
- * and provides some utility methods for sending mail to an SMTP server.
23
- *
24
- * PHP Version 5.0.0
25
- *
26
- * @category PHP
27
- * @package PHPMailer
28
- * @link https://github.com/PHPMailer/PHPMailer/blob/master/class.smtp.php
29
- * @author Chris Ryan <unknown@example.com>
30
- * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
31
- * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
32
  */
33
-
34
  class SMTP
35
  {
36
  /**
37
- * The PHPMailer SMTP Version number.
 
38
  */
39
- const VERSION = '5.2.7';
40
 
41
  /**
42
  * SMTP line break constant.
 
43
  */
44
  const CRLF = "\r\n";
45
 
46
  /**
47
  * The SMTP port to use if one is not specified.
 
48
  */
49
  const DEFAULT_SMTP_PORT = 25;
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * The PHPMailer SMTP Version number.
53
- * @type string
54
- * @deprecated This should be a constant
55
  * @see SMTP::VERSION
56
  */
57
- public $Version = '5.2.7';
58
 
59
  /**
60
  * SMTP server port number.
61
- * @type int
62
- * @deprecated This is only ever ued as default value, so should be a constant
63
  * @see SMTP::DEFAULT_SMTP_PORT
64
  */
65
  public $SMTP_PORT = 25;
66
 
67
  /**
68
- * SMTP reply line ending
69
- * @type string
70
- * @deprecated Use the class constant instead
71
  * @see SMTP::CRLF
72
  */
73
  public $CRLF = "\r\n";
@@ -75,85 +102,124 @@ class SMTP
75
  /**
76
  * Debug output level.
77
  * Options:
78
- * 0: no output
79
- * 1: commands
80
- * 2: data and commands
81
- * 3: as 2 plus connection status
82
- * 4: low level data output
83
- * @type int
84
  */
85
- public $do_debug = 0;
86
 
87
  /**
88
- * The function/method to use for debugging output.
89
- * Options: 'echo', 'html' or 'error_log'
90
- * @type string
 
 
 
 
 
 
 
 
91
  */
92
  public $Debugoutput = 'echo';
93
 
94
  /**
95
  * Whether to use VERP.
96
- * @type bool
 
 
97
  */
98
  public $do_verp = false;
99
 
100
  /**
101
  * The timeout value for connection, in seconds.
102
  * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
103
- * @type int
 
 
104
  */
105
  public $Timeout = 300;
106
 
107
  /**
108
- * The SMTP timelimit value for reads, in seconds.
109
- * @type int
 
110
  */
111
- public $Timelimit = 30;
 
 
 
 
 
 
 
 
 
 
 
112
 
113
  /**
114
  * The socket for the server connection.
115
- * @type resource
116
  */
117
  protected $smtp_conn;
118
 
119
  /**
120
- * Error message, if any, for the last call.
121
- * @type string
122
  */
123
- protected $error = '';
 
 
 
 
 
124
 
125
  /**
126
  * The reply the server sent to us for HELO.
127
- * @type string
 
128
  */
129
- protected $helo_rply = '';
130
 
131
  /**
132
- * The most recent reply received from the server.
133
- * @type string
 
 
 
 
 
134
  */
135
- protected $last_reply = '';
136
 
137
  /**
138
- * Constructor.
139
- * @access public
140
  */
141
- public function __construct()
142
- {
143
- $this->smtp_conn = 0;
144
- $this->error = null;
145
- $this->helo_rply = null;
146
-
147
- $this->do_debug = 0;
148
- }
149
 
150
  /**
151
  * Output debugging info via a user-selected method.
 
 
152
  * @param string $str Debug string to output
 
153
  * @return void
154
  */
155
- protected function edebug($str)
156
  {
 
 
 
 
 
 
 
 
157
  switch ($this->Debugoutput) {
158
  case 'error_log':
159
  //Don't output, just log
@@ -170,109 +236,137 @@ class SMTP
170
  break;
171
  case 'echo':
172
  default:
173
- echo gmdate('Y-m-d H:i:s')."\t".trim($str)."\n";
 
 
 
 
 
 
174
  }
175
  }
176
 
177
  /**
178
  * Connect to an SMTP server.
179
- * @param string $host SMTP server IP or host name
180
- * @param int $port The port number to connect to
181
- * @param int $timeout How long to wait for the connection to open
182
  * @param array $options An array of options for stream_context_create()
183
  * @access public
184
- * @return bool
185
  */
186
  public function connect($host, $port = null, $timeout = 30, $options = array())
187
  {
 
 
 
 
 
 
188
  // Clear errors to avoid confusion
189
- $this->error = null;
190
-
191
  // Make sure we are __not__ connected
192
  if ($this->connected()) {
193
  // Already connected, generate error
194
- $this->error = array('error' => 'Already connected to a server');
195
  return false;
196
  }
197
-
198
  if (empty($port)) {
199
  $port = self::DEFAULT_SMTP_PORT;
200
  }
201
-
202
  // Connect to the SMTP server
203
- if ($this->do_debug >= 3) {
204
- $this->edebug('Connection: opening');
205
- }
206
-
207
  $errno = 0;
208
  $errstr = '';
209
- $socket_context = stream_context_create($options);
210
- //Suppress errors; connection failures are handled at a higher level
211
- $this->smtp_conn = @stream_socket_client(
212
- $host . ":" . $port,
213
- $errno,
214
- $errstr,
215
- $timeout,
216
- STREAM_CLIENT_CONNECT,
217
- $socket_context
218
- );
219
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  // Verify we connected properly
221
- if (empty($this->smtp_conn)) {
222
- $this->error = array(
223
- 'error' => 'Failed to connect to server',
224
- 'errno' => $errno,
225
- 'errstr' => $errstr
 
 
 
 
 
226
  );
227
- if ($this->do_debug >= 1) {
228
- $this->edebug(
229
- 'SMTP ERROR: ' . $this->error['error']
230
- . ": $errstr ($errno)"
231
- );
232
- }
233
  return false;
234
  }
235
- if ($this->do_debug >= 3) {
236
- $this->edebug('Connection: opened');
237
- }
238
-
239
  // SMTP server can take longer to respond, give longer timeout for first read
240
  // Windows does not have support for this timeout function
241
  if (substr(PHP_OS, 0, 3) != 'WIN') {
242
  $max = ini_get('max_execution_time');
243
- if ($max != 0 && $timeout > $max) { // Don't bother if unlimited
 
244
  @set_time_limit($timeout);
245
  }
246
  stream_set_timeout($this->smtp_conn, $timeout, 0);
247
  }
248
-
249
  // Get any announcement
250
  $announce = $this->get_lines();
251
-
252
- if ($this->do_debug >= 2) {
253
- $this->edebug('SERVER -> CLIENT: ' . $announce);
254
- }
255
-
256
  return true;
257
  }
258
 
259
  /**
260
  * Initiate a TLS (encrypted) session.
261
  * @access public
262
- * @return bool
263
  */
264
  public function startTLS()
265
  {
266
- if (!$this->sendCommand("STARTTLS", "STARTTLS", 220)) {
267
  return false;
268
  }
 
 
 
 
 
 
 
 
 
 
 
269
  // Begin encrypted connection
270
  if (!stream_socket_enable_crypto(
271
  $this->smtp_conn,
272
  true,
273
- STREAM_CRYPTO_METHOD_TLS_CLIENT
274
- )
275
- ) {
276
  return false;
277
  }
278
  return true;
@@ -282,25 +376,64 @@ class SMTP
282
  * Perform SMTP authentication.
283
  * Must be run after hello().
284
  * @see hello()
285
- * @param string $username The user name
286
- * @param string $password The password
287
- * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5)
288
- * @param string $realm The auth realm for NTLM
289
  * @param string $workstation The auth workstation for NTLM
290
- * @access public
291
- * @return bool True if successfully authenticated.
292
  */
293
  public function authenticate(
294
  $username,
295
  $password,
296
- $authtype = 'LOGIN',
297
  $realm = '',
298
- $workstation = ''
 
299
  ) {
300
- if (empty($authtype)) {
301
- $authtype = 'LOGIN';
 
302
  }
303
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  switch ($authtype) {
305
  case 'PLAIN':
306
  // Start authentication
@@ -329,6 +462,19 @@ class SMTP
329
  return false;
330
  }
331
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  case 'NTLM':
333
  /*
334
  * ntlm_sasl_client.php
@@ -339,21 +485,20 @@ class SMTP
339
  * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
340
  */
341
  require_once 'extras/ntlm_sasl_client.php';
342
- $temp = new stdClass();
343
  $ntlm_client = new ntlm_sasl_client_class;
344
  //Check that functions are available
345
- if (!$ntlm_client->Initialize($temp)) {
346
- $this->error = array('error' => $temp->error);
347
- if ($this->do_debug >= 1) {
348
- $this->edebug(
349
- 'You need to enable some modules in your php.ini file: '
350
- . $this->error['error']
351
- );
352
- }
353
  return false;
354
  }
355
  //msg1
356
- $msg1 = $ntlm_client->TypeMsg1($realm, $workstation); //msg1
357
 
358
  if (!$this->sendCommand(
359
  'AUTH NTLM',
@@ -363,7 +508,6 @@ class SMTP
363
  ) {
364
  return false;
365
  }
366
-
367
  //Though 0 based, there is a white space after the 3 digit number
368
  //msg2
369
  $challenge = substr($this->last_reply, 3);
@@ -373,7 +517,7 @@ class SMTP
373
  $password
374
  );
375
  //msg3
376
- $msg3 = $ntlm_client->TypeMsg3(
377
  $ntlm_res,
378
  $username,
379
  $realm,
@@ -381,7 +525,6 @@ class SMTP
381
  );
382
  // send encoded username
383
  return $this->sendCommand('Username', base64_encode($msg3), 235);
384
- break;
385
  case 'CRAM-MD5':
386
  // Start authentication
387
  if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
@@ -395,7 +538,9 @@ class SMTP
395
 
396
  // send encoded credentials
397
  return $this->sendCommand('Username', base64_encode($response), 235);
398
- break;
 
 
399
  }
400
  return true;
401
  }
@@ -421,15 +566,15 @@ class SMTP
421
  // RFC 2104 HMAC implementation for php.
422
  // Creates an md5 HMAC.
423
  // Eliminates the need to install mhash to compute a HMAC
424
- // Hacked by Lance Rushing
425
 
426
- $b = 64; // byte length for md5
427
- if (strlen($key) > $b) {
428
  $key = pack('H*', md5($key));
429
  }
430
- $key = str_pad($key, $b, chr(0x00));
431
- $ipad = str_pad('', $b, chr(0x36));
432
- $opad = str_pad('', $b, chr(0x5c));
433
  $k_ipad = $key ^ $ipad;
434
  $k_opad = $key ^ $opad;
435
 
@@ -439,19 +584,18 @@ class SMTP
439
  /**
440
  * Check connection state.
441
  * @access public
442
- * @return bool True if connected.
443
  */
444
  public function connected()
445
  {
446
- if (!empty($this->smtp_conn)) {
447
  $sock_status = stream_get_meta_data($this->smtp_conn);
448
  if ($sock_status['eof']) {
449
- // the socket is valid but we are not connected
450
- if ($this->do_debug >= 1) {
451
- $this->edebug(
452
- 'SMTP NOTICE: EOF caught while checking if connected'
453
- );
454
- }
455
  $this->close();
456
  return false;
457
  }
@@ -469,15 +613,14 @@ class SMTP
469
  */
470
  public function close()
471
  {
472
- $this->error = null; // so there is no confusion
 
473
  $this->helo_rply = null;
474
- if (!empty($this->smtp_conn)) {
475
  // close the connection and cleanup
476
  fclose($this->smtp_conn);
477
- if ($this->do_debug >= 3) {
478
- $this->edebug('Connection: closed');
479
- }
480
- $this->smtp_conn = 0;
481
  }
482
  }
483
 
@@ -491,111 +634,101 @@ class SMTP
491
  * Implements rfc 821: DATA <CRLF>
492
  * @param string $msg_data Message data to send
493
  * @access public
494
- * @return bool
495
  */
496
  public function data($msg_data)
497
  {
 
498
  if (!$this->sendCommand('DATA', 'DATA', 354)) {
499
  return false;
500
  }
501
 
502
  /* The server is ready to accept data!
503
- * according to rfc821 we should not send more than 1000
504
- * including the CRLF
505
- * characters on a single line so we will break the data up
506
- * into lines by \r and/or \n then if needed we will break
507
- * each of those into smaller lines to fit within the limit.
508
- * in addition we will be looking for lines that start with
509
- * a period '.' and append and additional period '.' to that
510
- * line. NOTE: this does not count towards limit.
511
  */
512
 
513
- // Normalize the line breaks before exploding
514
- $msg_data = str_replace("\r\n", "\n", $msg_data);
515
- $msg_data = str_replace("\r", "\n", $msg_data);
516
- $lines = explode("\n", $msg_data);
517
-
518
- /* We need to find a good way to determine if headers are
519
- * in the msg_data or if it is a straight msg body
520
- * currently I am assuming rfc822 definitions of msg headers
521
- * and if the first field of the first line (':' separated)
522
- * does not contain a space then it _should_ be a header
523
- * and we can process all lines before a blank "" line as
524
- * headers.
525
  */
526
 
527
  $field = substr($lines[0], 0, strpos($lines[0], ':'));
528
  $in_headers = false;
529
- if (!empty($field) && !strstr($field, ' ')) {
530
  $in_headers = true;
531
  }
532
 
533
- //RFC 2822 section 2.1.1 limit
534
- $max_line_length = 998;
535
-
536
  foreach ($lines as $line) {
537
- $lines_out = null;
538
- if ($line == '' && $in_headers) {
539
  $in_headers = false;
540
  }
541
- // ok we need to break this line up into several smaller lines
542
- while (strlen($line) > $max_line_length) {
543
- $pos = strrpos(substr($line, 0, $max_line_length), ' ');
544
-
545
- // Patch to fix DOS attack
 
 
546
  if (!$pos) {
547
- $pos = $max_line_length - 1;
 
548
  $lines_out[] = substr($line, 0, $pos);
549
  $line = substr($line, $pos);
550
  } else {
 
551
  $lines_out[] = substr($line, 0, $pos);
 
552
  $line = substr($line, $pos + 1);
553
  }
554
-
555
- /* If processing headers add a LWSP-char to the front of new line
556
- * rfc822 on long msg headers
557
- */
558
  if ($in_headers) {
559
  $line = "\t" . $line;
560
  }
561
  }
562
  $lines_out[] = $line;
563
 
564
- // send the lines to the server
565
- while (list(, $line_out) = @each($lines_out)) {
566
- if (strlen($line_out) > 0) {
567
- if (substr($line_out, 0, 1) == '.') {
568
- $line_out = '.' . $line_out;
569
- }
570
  }
571
  $this->client_send($line_out . self::CRLF);
572
  }
573
  }
574
 
575
- // Message data has been sent, complete the command
576
- return $this->sendCommand('DATA END', '.', 250);
 
 
 
 
 
 
577
  }
578
 
579
  /**
580
  * Send an SMTP HELO or EHLO command.
581
  * Used to identify the sending server to the receiving server.
582
  * This makes sure that client and server are in a known state.
583
- * Implements from RFC 821: HELO <SP> <domain> <CRLF>
584
  * and RFC 2821 EHLO.
585
  * @param string $host The host name or IP to connect to
586
  * @access public
587
- * @return bool
588
  */
589
  public function hello($host = '')
590
  {
591
- // Try extended hello first (RFC 2821)
592
- if (!$this->sendHello('EHLO', $host)) {
593
- if (!$this->sendHello('HELO', $host)) {
594
- return false;
595
- }
596
- }
597
-
598
- return true;
599
  }
600
 
601
  /**
@@ -603,17 +736,64 @@ class SMTP
603
  * Low-level implementation used by hello()
604
  * @see hello()
605
  * @param string $hello The HELO string
606
- * @param string $host The hostname to say we are
607
  * @access protected
608
- * @return bool
609
  */
610
  protected function sendHello($hello, $host)
611
  {
612
  $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
613
  $this->helo_rply = $this->last_reply;
 
 
 
 
 
614
  return $noerror;
615
  }
616
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
617
  /**
618
  * Send an SMTP MAIL command.
619
  * Starts a mail transaction from the email address specified in
@@ -623,7 +803,7 @@ class SMTP
623
  * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
624
  * @param string $from Source address of this message
625
  * @access public
626
- * @return bool
627
  */
628
  public function mail($from)
629
  {
@@ -639,35 +819,35 @@ class SMTP
639
  * Send an SMTP QUIT command.
640
  * Closes the socket if there is no error or the $close_on_error argument is true.
641
  * Implements from rfc 821: QUIT <CRLF>
642
- * @param bool $close_on_error Should the connection close if an error occurs?
643
  * @access public
644
- * @return bool
645
  */
646
  public function quit($close_on_error = true)
647
  {
648
  $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
649
- $e = $this->error; //Save any error
650
  if ($noerror or $close_on_error) {
651
  $this->close();
652
- $this->error = $e; //Restore any error from the quit command
653
  }
654
  return $noerror;
655
  }
656
 
657
  /**
658
  * Send an SMTP RCPT command.
659
- * Sets the TO argument to $to.
660
  * Returns true if the recipient was accepted false if it was rejected.
661
  * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
662
- * @param string $to The address the message is being sent to
663
  * @access public
664
- * @return bool
665
  */
666
- public function recipient($to)
667
  {
668
  return $this->sendCommand(
669
- 'RCPT TO ',
670
- 'RCPT TO:<' . $to . '>',
671
  array(250, 251)
672
  );
673
  }
@@ -677,7 +857,7 @@ class SMTP
677
  * Abort any transaction that is currently in progress.
678
  * Implements rfc 821: RSET <CRLF>
679
  * @access public
680
- * @return bool True on success.
681
  */
682
  public function reset()
683
  {
@@ -686,46 +866,61 @@ class SMTP
686
 
687
  /**
688
  * Send a command to an SMTP server and check its return code.
689
- * @param string $command The command name - not sent to the server
690
  * @param string $commandstring The actual command to send
691
- * @param int|array $expect One or more expected integer success codes
692
  * @access protected
693
- * @return bool True on success.
694
  */
695
  protected function sendCommand($command, $commandstring, $expect)
696
  {
697
  if (!$this->connected()) {
698
- $this->error = array(
699
- "error" => "Called $command without being connected"
700
- );
 
 
 
701
  return false;
702
  }
703
  $this->client_send($commandstring . self::CRLF);
704
 
705
- $reply = $this->get_lines();
706
- $code = substr($reply, 0, 3);
707
-
708
- if ($this->do_debug >= 2) {
709
- $this->edebug('SERVER -> CLIENT: ' . $reply);
 
 
 
 
 
 
 
 
 
 
 
 
710
  }
711
 
 
 
712
  if (!in_array($code, (array)$expect)) {
713
- $this->last_reply = null;
714
- $this->error = array(
715
- "error" => "$command command failed",
716
- "smtp_code" => $code,
717
- "detail" => substr($reply, 4)
 
 
 
 
718
  );
719
- if ($this->do_debug >= 1) {
720
- $this->edebug(
721
- 'SMTP ERROR: ' . $this->error['error'] . ': ' . $reply
722
- );
723
- }
724
  return false;
725
  }
726
 
727
- $this->last_reply = $reply;
728
- $this->error = null;
729
  return true;
730
  }
731
 
@@ -740,52 +935,48 @@ class SMTP
740
  * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
741
  * @param string $from The address the message is from
742
  * @access public
743
- * @return bool
744
  */
745
  public function sendAndMail($from)
746
  {
747
- return $this->sendCommand("SAML", "SAML FROM:$from", 250);
748
  }
749
 
750
  /**
751
  * Send an SMTP VRFY command.
752
  * @param string $name The name to verify
753
  * @access public
754
- * @return bool
755
  */
756
  public function verify($name)
757
  {
758
- return $this->sendCommand("VRFY", "VRFY $name", array(250, 251));
759
  }
760
 
761
  /**
762
  * Send an SMTP NOOP command.
763
  * Used to keep keep-alives alive, doesn't actually do anything
764
  * @access public
765
- * @return bool
766
  */
767
  public function noop()
768
  {
769
- return $this->sendCommand("NOOP", "NOOP", 250);
770
  }
771
 
772
  /**
773
  * Send an SMTP TURN command.
774
  * This is an optional command for SMTP that this class does not support.
775
- * This method is here to make the RFC821 Definition
776
- * complete for this class and __may__ be implemented in future
777
  * Implements from rfc 821: TURN <CRLF>
778
  * @access public
779
- * @return bool
780
  */
781
  public function turn()
782
  {
783
- $this->error = array(
784
- 'error' => 'The SMTP TURN command is not implemented'
785
- );
786
- if ($this->do_debug >= 1) {
787
- $this->edebug('SMTP NOTICE: ' . $this->error['error']);
788
- }
789
  return false;
790
  }
791
 
@@ -793,13 +984,11 @@ class SMTP
793
  * Send raw data to the server.
794
  * @param string $data The data to send
795
  * @access public
796
- * @return int|bool The number of bytes sent to the server or FALSE on error
797
  */
798
  public function client_send($data)
799
  {
800
- if ($this->do_debug >= 1) {
801
- $this->edebug("CLIENT -> SERVER: $data");
802
- }
803
  return fwrite($this->smtp_conn, $data);
804
  }
805
 
@@ -813,6 +1002,57 @@ class SMTP
813
  return $this->error;
814
  }
815
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
816
  /**
817
  * Get the last reply from the server.
818
  * @access public
@@ -834,51 +1074,42 @@ class SMTP
834
  */
835
  protected function get_lines()
836
  {
837
- $data = '';
838
- $endtime = 0;
839
- // If the connection is bad, give up now
840
  if (!is_resource($this->smtp_conn)) {
841
- return $data;
842
  }
 
 
843
  stream_set_timeout($this->smtp_conn, $this->Timeout);
844
  if ($this->Timelimit > 0) {
845
  $endtime = time() + $this->Timelimit;
846
  }
847
  while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
848
  $str = @fgets($this->smtp_conn, 515);
849
- if ($this->do_debug >= 4) {
850
- $this->edebug("SMTP -> get_lines(): \$data was \"$data\"");
851
- $this->edebug("SMTP -> get_lines(): \$str is \"$str\"");
852
- }
853
  $data .= $str;
854
- if ($this->do_debug >= 4) {
855
- $this->edebug("SMTP -> get_lines(): \$data is \"$data\"");
856
- }
857
- // if 4th character is a space, we are done reading, break the loop
858
- if (substr($str, 3, 1) == ' ') {
859
  break;
860
  }
861
  // Timed-out? Log and break
862
  $info = stream_get_meta_data($this->smtp_conn);
863
  if ($info['timed_out']) {
864
- if ($this->do_debug >= 4) {
865
- $this->edebug(
866
- 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)'
867
- );
868
- }
869
  break;
870
  }
871
  // Now check if reads took too long
872
- if ($endtime) {
873
- if (time() > $endtime) {
874
- if ($this->do_debug >= 4) {
875
- $this->edebug(
876
- 'SMTP -> get_lines(): timelimit reached ('
877
- . $this->Timelimit . ' sec)'
878
- );
879
- }
880
- break;
881
- }
882
  }
883
  }
884
  return $data;
@@ -886,7 +1117,7 @@ class SMTP
886
 
887
  /**
888
  * Enable or disable VERP address generation.
889
- * @param bool $enabled
890
  */
891
  public function setVerp($enabled = false)
892
  {
@@ -895,16 +1126,33 @@ class SMTP
895
 
896
  /**
897
  * Get VERP address generation mode.
898
- * @return bool
899
  */
900
  public function getVerp()
901
  {
902
  return $this->do_verp;
903
  }
904
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
905
  /**
906
  * Set debug output method.
907
- * @param string $method The function/method to use for debugging output.
908
  */
909
  public function setDebugOutput($method = 'echo')
910
  {
@@ -922,7 +1170,7 @@ class SMTP
922
 
923
  /**
924
  * Set debug output level.
925
- * @param int $level
926
  */
927
  public function setDebugLevel($level = 0)
928
  {
@@ -931,7 +1179,7 @@ class SMTP
931
 
932
  /**
933
  * Get debug output level.
934
- * @return int
935
  */
936
  public function getDebugLevel()
937
  {
@@ -940,7 +1188,7 @@ class SMTP
940
 
941
  /**
942
  * Set SMTP timeout.
943
- * @param int $timeout
944
  */
945
  public function setTimeout($timeout = 0)
946
  {
@@ -949,10 +1197,53 @@ class SMTP
949
 
950
  /**
951
  * Get SMTP timeout.
952
- * @return int
953
  */
954
  public function getTimeout()
955
  {
956
  return $this->Timeout;
957
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
958
  }
1
  <?php
2
  /**
3
  * PHPMailer RFC821 SMTP email transport class.
4
+ * PHP Version 5
5
+ * @package PHPMailer
6
+ * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
7
+ * @author Marcus Bointon (Synchro/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 2014 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 RFC821 SMTP email transport class.
22
+ * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server.
23
+ * @package PHPMailer
24
+ * @author Chris Ryan
25
+ * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
 
 
 
 
 
 
 
 
26
  */
 
27
  class SMTP
28
  {
29
  /**
30
+ * The PHPMailer SMTP version number.
31
+ * @var string
32
  */
33
+ const VERSION = '5.2.21';
34
 
35
  /**
36
  * SMTP line break constant.
37
+ * @var string
38
  */
39
  const CRLF = "\r\n";
40
 
41
  /**
42
  * The SMTP port to use if one is not specified.
43
+ * @var integer
44
  */
45
  const DEFAULT_SMTP_PORT = 25;
46
 
47
+ /**
48
+ * The maximum line length allowed by RFC 2822 section 2.1.1
49
+ * @var integer
50
+ */
51
+ const MAX_LINE_LENGTH = 998;
52
+
53
+ /**
54
+ * Debug level for no output
55
+ */
56
+ const DEBUG_OFF = 0;
57
+
58
+ /**
59
+ * Debug level to show client -> server messages
60
+ */
61
+ const DEBUG_CLIENT = 1;
62
+
63
+ /**
64
+ * Debug level to show client -> server and server -> client messages
65
+ */
66
+ const DEBUG_SERVER = 2;
67
+
68
+ /**
69
+ * Debug level to show connection status, client -> server and server -> client messages
70
+ */
71
+ const DEBUG_CONNECTION = 3;
72
+
73
+ /**
74
+ * Debug level to show all messages
75
+ */
76
+ const DEBUG_LOWLEVEL = 4;
77
+
78
  /**
79
  * The PHPMailer SMTP Version number.
80
+ * @var string
81
+ * @deprecated Use the `VERSION` constant instead
82
  * @see SMTP::VERSION
83
  */
84
+ public $Version = '5.2.21';
85
 
86
  /**
87
  * SMTP server port number.
88
+ * @var integer
89
+ * @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead
90
  * @see SMTP::DEFAULT_SMTP_PORT
91
  */
92
  public $SMTP_PORT = 25;
93
 
94
  /**
95
+ * SMTP reply line ending.
96
+ * @var string
97
+ * @deprecated Use the `CRLF` constant instead
98
  * @see SMTP::CRLF
99
  */
100
  public $CRLF = "\r\n";
102
  /**
103
  * Debug output level.
104
  * Options:
105
+ * * self::DEBUG_OFF (`0`) No debug output, default
106
+ * * self::DEBUG_CLIENT (`1`) Client commands
107
+ * * self::DEBUG_SERVER (`2`) Client commands and server responses
108
+ * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status
109
+ * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages
110
+ * @var integer
111
  */
112
+ public $do_debug = self::DEBUG_OFF;
113
 
114
  /**
115
+ * How to handle debug output.
116
+ * Options:
117
+ * * `echo` Output plain-text as-is, appropriate for CLI
118
+ * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
119
+ * * `error_log` Output to error log as configured in php.ini
120
+ *
121
+ * Alternatively, you can provide a callable expecting two params: a message string and the debug level:
122
+ * <code>
123
+ * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
124
+ * </code>
125
+ * @var string|callable
126
  */
127
  public $Debugoutput = 'echo';
128
 
129
  /**
130
  * Whether to use VERP.
131
+ * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
132
+ * @link http://www.postfix.org/VERP_README.html Info on VERP
133
+ * @var boolean
134
  */
135
  public $do_verp = false;
136
 
137
  /**
138
  * The timeout value for connection, in seconds.
139
  * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
140
+ * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
141
+ * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2
142
+ * @var integer
143
  */
144
  public $Timeout = 300;
145
 
146
  /**
147
+ * How long to wait for commands to complete, in seconds.
148
+ * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
149
+ * @var integer
150
  */
151
+ public $Timelimit = 300;
152
+
153
+ /**
154
+ * @var array patterns to extract smtp transaction id from smtp reply
155
+ * Only first capture group will be use, use non-capturing group to deal with it
156
+ * Extend this class to override this property to fulfil your needs.
157
+ */
158
+ protected $smtp_transaction_id_patterns = array(
159
+ 'exim' => '/[0-9]{3} OK id=(.*)/',
160
+ 'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/',
161
+ 'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/'
162
+ );
163
 
164
  /**
165
  * The socket for the server connection.
166
+ * @var resource
167
  */
168
  protected $smtp_conn;
169
 
170
  /**
171
+ * Error information, if any, for the last SMTP command.
172
+ * @var array
173
  */
174
+ protected $error = array(
175
+ 'error' => '',
176
+ 'detail' => '',
177
+ 'smtp_code' => '',
178
+ 'smtp_code_ex' => ''
179
+ );
180
 
181
  /**
182
  * The reply the server sent to us for HELO.
183
+ * If null, no HELO string has yet been received.
184
+ * @var string|null
185
  */
186
+ protected $helo_rply = null;
187
 
188
  /**
189
+ * The set of SMTP extensions sent in reply to EHLO command.
190
+ * Indexes of the array are extension names.
191
+ * Value at index 'HELO' or 'EHLO' (according to command that was sent)
192
+ * represents the server name. In case of HELO it is the only element of the array.
193
+ * Other values can be boolean TRUE or an array containing extension options.
194
+ * If null, no HELO/EHLO string has yet been received.
195
+ * @var array|null
196
  */
197
+ protected $server_caps = null;
198
 
199
  /**
200
+ * The most recent reply received from the server.
201
+ * @var string
202
  */
203
+ protected $last_reply = '';
 
 
 
 
 
 
 
204
 
205
  /**
206
  * Output debugging info via a user-selected method.
207
+ * @see SMTP::$Debugoutput
208
+ * @see SMTP::$do_debug
209
  * @param string $str Debug string to output
210
+ * @param integer $level The debug level of this message; see DEBUG_* constants
211
  * @return void
212
  */
213
+ protected function edebug($str, $level = 0)
214
  {
215
+ if ($level > $this->do_debug) {
216
+ return;
217
+ }
218
+ //Avoid clash with built-in function names
219
+ if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
220
+ call_user_func($this->Debugoutput, $str, $level);
221
+ return;
222
+ }
223
  switch ($this->Debugoutput) {
224
  case 'error_log':
225
  //Don't output, just log
236
  break;
237
  case 'echo':
238
  default:
239
+ //Normalize line breaks
240
+ $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
241
+ echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
242
+ "\n",
243
+ "\n \t ",
244
+ trim($str)
245
+ )."\n";
246
  }
247
  }
248
 
249
  /**
250
  * Connect to an SMTP server.
251
+ * @param string $host SMTP server IP or host name
252
+ * @param integer $port The port number to connect to
253
+ * @param integer $timeout How long to wait for the connection to open
254
  * @param array $options An array of options for stream_context_create()
255
  * @access public
256
+ * @return boolean
257
  */
258
  public function connect($host, $port = null, $timeout = 30, $options = array())
259
  {
260
+ static $streamok;
261
+ //This is enabled by default since 5.0.0 but some providers disable it
262
+ //Check this once and cache the result
263
+ if (is_null($streamok)) {
264
+ $streamok = function_exists('stream_socket_client');
265
+ }
266
  // Clear errors to avoid confusion
267
+ $this->setError('');
 
268
  // Make sure we are __not__ connected
269
  if ($this->connected()) {
270
  // Already connected, generate error
271
+ $this->setError('Already connected to a server');
272
  return false;
273
  }
 
274
  if (empty($port)) {
275
  $port = self::DEFAULT_SMTP_PORT;
276
  }
 
277
  // Connect to the SMTP server
278
+ $this->edebug(
279
+ "Connection: opening to $host:$port, timeout=$timeout, options=".var_export($options, true),
280
+ self::DEBUG_CONNECTION
281
+ );
282
  $errno = 0;
283
  $errstr = '';
284
+ if ($streamok) {
285
+ $socket_context = stream_context_create($options);
286
+ set_error_handler(array($this, 'errorHandler'));
287
+ $this->smtp_conn = stream_socket_client(
288
+ $host . ":" . $port,
289
+ $errno,
290
+ $errstr,
291
+ $timeout,
292
+ STREAM_CLIENT_CONNECT,
293
+ $socket_context
294
+ );
295
+ restore_error_handler();
296
+ } else {
297
+ //Fall back to fsockopen which should work in more places, but is missing some features
298
+ $this->edebug(
299
+ "Connection: stream_socket_client not available, falling back to fsockopen",
300
+ self::DEBUG_CONNECTION
301
+ );
302
+ set_error_handler(array($this, 'errorHandler'));
303
+ $this->smtp_conn = fsockopen(
304
+ $host,
305
+ $port,
306
+ $errno,
307
+ $errstr,
308
+ $timeout
309
+ );
310
+ restore_error_handler();
311
+ }
312
  // Verify we connected properly
313
+ if (!is_resource($this->smtp_conn)) {
314
+ $this->setError(
315
+ 'Failed to connect to server',
316
+ $errno,
317
+ $errstr
318
+ );
319
+ $this->edebug(
320
+ 'SMTP ERROR: ' . $this->error['error']
321
+ . ": $errstr ($errno)",
322
+ self::DEBUG_CLIENT
323
  );
 
 
 
 
 
 
324
  return false;
325
  }
326
+ $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
 
 
 
327
  // SMTP server can take longer to respond, give longer timeout for first read
328
  // Windows does not have support for this timeout function
329
  if (substr(PHP_OS, 0, 3) != 'WIN') {
330
  $max = ini_get('max_execution_time');
331
+ // Don't bother if unlimited
332
+ if ($max != 0 && $timeout > $max) {
333
  @set_time_limit($timeout);
334
  }
335
  stream_set_timeout($this->smtp_conn, $timeout, 0);
336
  }
 
337
  // Get any announcement
338
  $announce = $this->get_lines();
339
+ $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
 
 
 
 
340
  return true;
341
  }
342
 
343
  /**
344
  * Initiate a TLS (encrypted) session.
345
  * @access public
346
+ * @return boolean
347
  */
348
  public function startTLS()
349
  {
350
+ if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
351
  return false;
352
  }
353
+
354
+ //Allow the best TLS version(s) we can
355
+ $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
356
+
357
+ //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
358
+ //so add them back in manually if we can
359
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
360
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
361
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
362
+ }
363
+
364
  // Begin encrypted connection
365
  if (!stream_socket_enable_crypto(
366
  $this->smtp_conn,
367
  true,
368
+ $crypto_method
369
+ )) {
 
370
  return false;
371
  }
372
  return true;
376
  * Perform SMTP authentication.
377
  * Must be run after hello().
378
  * @see hello()
379
+ * @param string $username The user name
380
+ * @param string $password The password
381
+ * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2)
382
+ * @param string $realm The auth realm for NTLM
383
  * @param string $workstation The auth workstation for NTLM
384
+ * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth)
385
+ * @return bool True if successfully authenticated.* @access public
386
  */
387
  public function authenticate(
388
  $username,
389
  $password,
390
+ $authtype = null,
391
  $realm = '',
392
+ $workstation = '',
393
+ $OAuth = null
394
  ) {
395
+ if (!$this->server_caps) {
396
+ $this->setError('Authentication is not allowed before HELO/EHLO');
397
+ return false;
398
  }
399
 
400
+ if (array_key_exists('EHLO', $this->server_caps)) {
401
+ // SMTP extensions are available. Let's try to find a proper authentication method
402
+
403
+ if (!array_key_exists('AUTH', $this->server_caps)) {
404
+ $this->setError('Authentication is not allowed at this stage');
405
+ // 'at this stage' means that auth may be allowed after the stage changes
406
+ // e.g. after STARTTLS
407
+ return false;
408
+ }
409
+
410
+ self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL);
411
+ self::edebug(
412
+ 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']),
413
+ self::DEBUG_LOWLEVEL
414
+ );
415
+
416
+ if (empty($authtype)) {
417
+ foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN', 'NTLM', 'XOAUTH2') as $method) {
418
+ if (in_array($method, $this->server_caps['AUTH'])) {
419
+ $authtype = $method;
420
+ break;
421
+ }
422
+ }
423
+ if (empty($authtype)) {
424
+ $this->setError('No supported authentication methods found');
425
+ return false;
426
+ }
427
+ self::edebug('Auth method selected: '.$authtype, self::DEBUG_LOWLEVEL);
428
+ }
429
+
430
+ if (!in_array($authtype, $this->server_caps['AUTH'])) {
431
+ $this->setError("The requested authentication method \"$authtype\" is not supported by the server");
432
+ return false;
433
+ }
434
+ } elseif (empty($authtype)) {
435
+ $authtype = 'LOGIN';
436
+ }
437
  switch ($authtype) {
438
  case 'PLAIN':
439
  // Start authentication
462
  return false;
463
  }
464
  break;
465
+ case 'XOAUTH2':
466
+ //If the OAuth Instance is not set. Can be a case when PHPMailer is used
467
+ //instead of PHPMailerOAuth
468
+ if (is_null($OAuth)) {
469
+ return false;
470
+ }
471
+ $oauth = $OAuth->getOauth64();
472
+
473
+ // Start authentication
474
+ if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
475
+ return false;
476
+ }
477
+ break;
478
  case 'NTLM':
479
  /*
480
  * ntlm_sasl_client.php
485
  * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
486
  */
487
  require_once 'extras/ntlm_sasl_client.php';
488
+ $temp = new stdClass;
489
  $ntlm_client = new ntlm_sasl_client_class;
490
  //Check that functions are available
491
+ if (!$ntlm_client->initialize($temp)) {
492
+ $this->setError($temp->error);
493
+ $this->edebug(
494
+ 'You need to enable some modules in your php.ini file: '
495
+ . $this->error['error'],
496
+ self::DEBUG_CLIENT
497
+ );
 
498
  return false;
499
  }
500
  //msg1
501
+ $msg1 = $ntlm_client->typeMsg1($realm, $workstation); //msg1
502
 
503
  if (!$this->sendCommand(
504
  'AUTH NTLM',
508
  ) {
509
  return false;
510
  }
 
511
  //Though 0 based, there is a white space after the 3 digit number
512
  //msg2
513
  $challenge = substr($this->last_reply, 3);
517
  $password
518
  );
519
  //msg3
520
+ $msg3 = $ntlm_client->typeMsg3(
521
  $ntlm_res,
522
  $username,
523
  $realm,
525
  );
526
  // send encoded username
527
  return $this->sendCommand('Username', base64_encode($msg3), 235);
 
528
  case 'CRAM-MD5':
529
  // Start authentication
530
  if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
538
 
539
  // send encoded credentials
540
  return $this->sendCommand('Username', base64_encode($response), 235);
541
+ default:
542
+ $this->setError("Authentication method \"$authtype\" is not supported");
543
+ return false;
544
  }
545
  return true;
546
  }
566
  // RFC 2104 HMAC implementation for php.
567
  // Creates an md5 HMAC.
568
  // Eliminates the need to install mhash to compute a HMAC
569
+ // by Lance Rushing
570
 
571
+ $bytelen = 64; // byte length for md5
572
+ if (strlen($key) > $bytelen) {
573
  $key = pack('H*', md5($key));
574
  }
575
+ $key = str_pad($key, $bytelen, chr(0x00));
576
+ $ipad = str_pad('', $bytelen, chr(0x36));
577
+ $opad = str_pad('', $bytelen, chr(0x5c));
578
  $k_ipad = $key ^ $ipad;
579
  $k_opad = $key ^ $opad;
580
 
584
  /**
585
  * Check connection state.
586
  * @access public
587
+ * @return boolean True if connected.
588
  */
589
  public function connected()
590
  {
591
+ if (is_resource($this->smtp_conn)) {
592
  $sock_status = stream_get_meta_data($this->smtp_conn);
593
  if ($sock_status['eof']) {
594
+ // The socket is valid but we are not connected
595
+ $this->edebug(
596
+ 'SMTP NOTICE: EOF caught while checking if connected',
597
+ self::DEBUG_CLIENT
598
+ );
 
599
  $this->close();
600
  return false;
601
  }
613
  */
614
  public function close()
615
  {
616
+ $this->setError('');
617
+ $this->server_caps = null;
618
  $this->helo_rply = null;
619
+ if (is_resource($this->smtp_conn)) {
620
  // close the connection and cleanup
621
  fclose($this->smtp_conn);
622
+ $this->smtp_conn = null; //Makes for cleaner serialization
623
+ $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
 
 
624
  }
625
  }
626
 
634
  * Implements rfc 821: DATA <CRLF>
635
  * @param string $msg_data Message data to send
636
  * @access public
637
+ * @return boolean
638
  */
639
  public function data($msg_data)
640
  {
641
+ //This will use the standard timelimit
642
  if (!$this->sendCommand('DATA', 'DATA', 354)) {
643
  return false;
644
  }
645
 
646
  /* The server is ready to accept data!
647
+ * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF)
648
+ * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into
649
+ * smaller lines to fit within the limit.
650
+ * We will also look for lines that start with a '.' and prepend an additional '.'.
651
+ * NOTE: this does not count towards line-length limit.
 
 
 
652
  */
653
 
654
+ // Normalize line breaks before exploding
655
+ $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data));
656
+
657
+ /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
658
+ * of the first line (':' separated) does not contain a space then it _should_ be a header and we will
659
+ * process all lines before a blank line as headers.
 
 
 
 
 
 
660
  */
661
 
662
  $field = substr($lines[0], 0, strpos($lines[0], ':'));
663
  $in_headers = false;
664
+ if (!empty($field) && strpos($field, ' ') === false) {
665
  $in_headers = true;
666
  }
667
 
 
 
 
668
  foreach ($lines as $line) {
669
+ $lines_out = array();
670
+ if ($in_headers and $line == '') {
671
  $in_headers = false;
672
  }
673
+ //Break this line up into several smaller lines if it's too long
674
+ //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len),
675
+ while (isset($line[self::MAX_LINE_LENGTH])) {
676
+ //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on
677
+ //so as to avoid breaking in the middle of a word
678
+ $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
679
+ //Deliberately matches both false and 0
680
  if (!$pos) {
681
+ //No nice break found, add a hard break
682
+ $pos = self::MAX_LINE_LENGTH - 1;
683
  $lines_out[] = substr($line, 0, $pos);
684
  $line = substr($line, $pos);
685
  } else {
686
+ //Break at the found point
687
  $lines_out[] = substr($line, 0, $pos);
688
+ //Move along by the amount we dealt with
689
  $line = substr($line, $pos + 1);
690
  }
691
+ //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1
 
 
 
692
  if ($in_headers) {
693
  $line = "\t" . $line;
694
  }
695
  }
696
  $lines_out[] = $line;
697
 
698
+ //Send the lines to the server
699
+ foreach ($lines_out as $line_out) {
700
+ //RFC2821 section 4.5.2
701
+ if (!empty($line_out) and $line_out[0] == '.') {
702
+ $line_out = '.' . $line_out;
 
703
  }
704
  $this->client_send($line_out . self::CRLF);
705
  }
706
  }
707
 
708
+ //Message data has been sent, complete the command
709
+ //Increase timelimit for end of DATA command
710
+ $savetimelimit = $this->Timelimit;
711
+ $this->Timelimit = $this->Timelimit * 2;
712
+ $result = $this->sendCommand('DATA END', '.', 250);
713
+ //Restore timelimit
714
+ $this->Timelimit = $savetimelimit;
715
+ return $result;
716
  }
717
 
718
  /**
719
  * Send an SMTP HELO or EHLO command.
720
  * Used to identify the sending server to the receiving server.
721
  * This makes sure that client and server are in a known state.
722
+ * Implements RFC 821: HELO <SP> <domain> <CRLF>
723
  * and RFC 2821 EHLO.
724
  * @param string $host The host name or IP to connect to
725
  * @access public
726
+ * @return boolean
727
  */
728
  public function hello($host = '')
729
  {
730
+ //Try extended hello first (RFC 2821)
731
+ return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
 
 
 
 
 
 
732
  }
733
 
734
  /**
736
  * Low-level implementation used by hello()
737
  * @see hello()
738
  * @param string $hello The HELO string
739
+ * @param string $host The hostname to say we are
740
  * @access protected
741
+ * @return boolean
742
  */
743
  protected function sendHello($hello, $host)
744
  {
745
  $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
746
  $this->helo_rply = $this->last_reply;
747
+ if ($noerror) {
748
+ $this->parseHelloFields($hello);
749
+ } else {
750
+ $this->server_caps = null;
751
+ }
752
  return $noerror;
753
  }
754
 
755
+ /**
756
+ * Parse a reply to HELO/EHLO command to discover server extensions.
757
+ * In case of HELO, the only parameter that can be discovered is a server name.
758
+ * @access protected
759
+ * @param string $type - 'HELO' or 'EHLO'
760
+ */
761
+ protected function parseHelloFields($type)
762
+ {
763
+ $this->server_caps = array();
764
+ $lines = explode("\n", $this->helo_rply);
765
+
766
+ foreach ($lines as $n => $s) {
767
+ //First 4 chars contain response code followed by - or space
768
+ $s = trim(substr($s, 4));
769
+ if (empty($s)) {
770
+ continue;
771
+ }
772
+ $fields = explode(' ', $s);
773
+ if (!empty($fields)) {
774
+ if (!$n) {
775
+ $name = $type;
776
+ $fields = $fields[0];
777
+ } else {
778
+ $name = array_shift($fields);
779
+ switch ($name) {
780
+ case 'SIZE':
781
+ $fields = ($fields ? $fields[0] : 0);
782
+ break;
783
+ case 'AUTH':
784
+ if (!is_array($fields)) {
785
+ $fields = array();
786
+ }
787
+ break;
788
+ default:
789
+ $fields = true;
790
+ }
791
+ }
792
+ $this->server_caps[$name] = $fields;
793
+ }
794
+ }
795
+ }
796
+
797
  /**
798
  * Send an SMTP MAIL command.
799
  * Starts a mail transaction from the email address specified in
803
  * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
804
  * @param string $from Source address of this message
805
  * @access public
806
+ * @return boolean
807
  */
808
  public function mail($from)
809
  {
819
  * Send an SMTP QUIT command.
820
  * Closes the socket if there is no error or the $close_on_error argument is true.
821
  * Implements from rfc 821: QUIT <CRLF>
822
+ * @param boolean $close_on_error Should the connection close if an error occurs?
823
  * @access public
824
+ * @return boolean
825
  */
826
  public function quit($close_on_error = true)
827
  {
828
  $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
829
+ $err = $this->error; //Save any error
830
  if ($noerror or $close_on_error) {
831
  $this->close();
832
+ $this->error = $err; //Restore any error from the quit command
833
  }
834
  return $noerror;
835
  }
836
 
837
  /**
838
  * Send an SMTP RCPT command.
839
+ * Sets the TO argument to $toaddr.
840
  * Returns true if the recipient was accepted false if it was rejected.
841
  * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
842
+ * @param string $address The address the message is being sent to
843
  * @access public
844
+ * @return boolean
845
  */
846
+ public function recipient($address)
847
  {
848
  return $this->sendCommand(
849
+ 'RCPT TO',
850
+ 'RCPT TO:<' . $address . '>',
851
  array(250, 251)
852
  );
853
  }
857
  * Abort any transaction that is currently in progress.
858
  * Implements rfc 821: RSET <CRLF>
859
  * @access public
860
+ * @return boolean True on success.
861
  */
862
  public function reset()
863
  {
866
 
867
  /**
868
  * Send a command to an SMTP server and check its return code.
869
+ * @param string $command The command name - not sent to the server
870
  * @param string $commandstring The actual command to send
871
+ * @param integer|array $expect One or more expected integer success codes
872
  * @access protected
873
+ * @return boolean True on success.
874
  */
875
  protected function sendCommand($command, $commandstring, $expect)
876
  {
877
  if (!$this->connected()) {
878
+ $this->setError("Called $command without being connected");
879
+ return false;
880
+ }
881
+ //Reject line breaks in all commands
882
+ if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
883
+ $this->setError("Command '$command' contained line breaks");
884
  return false;
885
  }
886
  $this->client_send($commandstring . self::CRLF);
887
 
888
+ $this->last_reply = $this->get_lines();
889
+ // Fetch SMTP code and possible error code explanation
890
+ $matches = array();
891
+ if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) {
892
+ $code = $matches[1];
893
+ $code_ex = (count($matches) > 2 ? $matches[2] : null);
894
+ // Cut off error code from each response line
895
+ $detail = preg_replace(
896
+ "/{$code}[ -]".($code_ex ? str_replace('.', '\\.', $code_ex).' ' : '')."/m",
897
+ '',
898
+ $this->last_reply
899
+ );
900
+ } else {
901
+ // Fall back to simple parsing if regex fails
902
+ $code = substr($this->last_reply, 0, 3);
903
+ $code_ex = null;
904
+ $detail = substr($this->last_reply, 4);
905
  }
906
 
907
+ $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
908
+
909
  if (!in_array($code, (array)$expect)) {
910
+ $this->setError(
911
+ "$command command failed",
912
+ $detail,
913
+ $code,
914
+ $code_ex
915
+ );
916
+ $this->edebug(
917
+ 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
918
+ self::DEBUG_CLIENT
919
  );
 
 
 
 
 
920
  return false;
921
  }
922
 
923
+ $this->setError('');
 
924
  return true;
925
  }
926
 
935
  * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
936
  * @param string $from The address the message is from
937
  * @access public
938
+ * @return boolean
939
  */
940
  public function sendAndMail($from)
941
  {
942
+ return $this->sendCommand('SAML', "SAML FROM:$from", 250);
943
  }
944
 
945
  /**
946
  * Send an SMTP VRFY command.
947
  * @param string $name The name to verify
948
  * @access public
949
+ * @return boolean
950
  */
951
  public function verify($name)
952
  {
953
+ return $this->sendCommand('VRFY', "VRFY $name", array(250, 251));
954
  }
955
 
956
  /**
957
  * Send an SMTP NOOP command.
958
  * Used to keep keep-alives alive, doesn't actually do anything
959
  * @access public
960
+ * @return boolean
961
  */
962
  public function noop()
963
  {
964
+ return $this->sendCommand('NOOP', 'NOOP', 250);
965
  }
966
 
967
  /**
968
  * Send an SMTP TURN command.
969
  * This is an optional command for SMTP that this class does not support.
970
+ * This method is here to make the RFC821 Definition complete for this class
971
+ * and _may_ be implemented in future
972
  * Implements from rfc 821: TURN <CRLF>
973
  * @access public
974
+ * @return boolean
975
  */
976
  public function turn()
977
  {
978
+ $this->setError('The SMTP TURN command is not implemented');
979
+ $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);
 
 
 
 
980
  return false;
981
  }
982
 
984
  * Send raw data to the server.
985
  * @param string $data The data to send
986
  * @access public
987
+ * @return integer|boolean The number of bytes sent to the server or false on error
988
  */
989
  public function client_send($data)
990
  {
991
+ $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT);
 
 
992
  return fwrite($this->smtp_conn, $data);
993
  }
994
 
1002
  return $this->error;
1003
  }
1004
 
1005
+ /**
1006
+ * Get SMTP extensions available on the server
1007
+ * @access public
1008
+ * @return array|null
1009
+ */
1010
+ public function getServerExtList()
1011
+ {
1012
+ return $this->server_caps;
1013
+ }
1014
+
1015
+ /**
1016
+ * A multipurpose method
1017
+ * The method works in three ways, dependent on argument value and current state
1018
+ * 1. HELO/EHLO was not sent - returns null and set up $this->error
1019
+ * 2. HELO was sent
1020
+ * $name = 'HELO': returns server name
1021
+ * $name = 'EHLO': returns boolean false
1022
+ * $name = any string: returns null and set up $this->error
1023
+ * 3. EHLO was sent
1024
+ * $name = 'HELO'|'EHLO': returns server name
1025
+ * $name = any string: if extension $name exists, returns boolean True
1026
+ * or its options. Otherwise returns boolean False
1027
+ * In other words, one can use this method to detect 3 conditions:
1028
+ * - null returned: handshake was not or we don't know about ext (refer to $this->error)
1029
+ * - false returned: the requested feature exactly not exists
1030
+ * - positive value returned: the requested feature exists
1031
+ * @param string $name Name of SMTP extension or 'HELO'|'EHLO'
1032
+ * @return mixed
1033
+ */
1034
+ public function getServerExt($name)
1035
+ {
1036
+ if (!$this->server_caps) {
1037
+ $this->setError('No HELO/EHLO was sent');
1038
+ return null;
1039
+ }
1040
+
1041
+ // the tight logic knot ;)
1042
+ if (!array_key_exists($name, $this->server_caps)) {
1043
+ if ($name == 'HELO') {
1044
+ return $this->server_caps['EHLO'];
1045
+ }
1046
+ if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) {
1047
+ return false;
1048
+ }
1049
+ $this->setError('HELO handshake was used. Client knows nothing about server extensions');
1050
+ return null;
1051
+ }
1052
+
1053
+ return $this->server_caps[$name];
1054
+ }
1055
+
1056
  /**
1057
  * Get the last reply from the server.
1058
  * @access public
1074
  */
1075
  protected function get_lines()
1076
  {
1077
+ // If the connection is bad, give up straight away
 
 
1078
  if (!is_resource($this->smtp_conn)) {
1079
+ return '';
1080
  }
1081
+ $data = '';
1082
+ $endtime = 0;
1083
  stream_set_timeout($this->smtp_conn, $this->Timeout);
1084
  if ($this->Timelimit > 0) {
1085
  $endtime = time() + $this->Timelimit;
1086
  }
1087
  while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
1088
  $str = @fgets($this->smtp_conn, 515);
1089
+ $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
1090
+ $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL);
 
 
1091
  $data .= $str;
1092
+ // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
1093
+ if ((isset($str[3]) and $str[3] == ' ')) {
 
 
 
1094
  break;
1095
  }
1096
  // Timed-out? Log and break
1097
  $info = stream_get_meta_data($this->smtp_conn);
1098
  if ($info['timed_out']) {
1099
+ $this->edebug(
1100
+ 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)',
1101
+ self::DEBUG_LOWLEVEL
1102
+ );
 
1103
  break;
1104
  }
1105
  // Now check if reads took too long
1106
+ if ($endtime and time() > $endtime) {
1107
+ $this->edebug(
1108
+ 'SMTP -> get_lines(): timelimit reached ('.
1109
+ $this->Timelimit . ' sec)',
1110
+ self::DEBUG_LOWLEVEL
1111
+ );
1112
+ break;
 
 
 
1113
  }
1114
  }
1115
  return $data;
1117
 
1118
  /**
1119
  * Enable or disable VERP address generation.
1120
+ * @param boolean $enabled
1121
  */
1122
  public function setVerp($enabled = false)
1123
  {
1126
 
1127
  /**
1128
  * Get VERP address generation mode.
1129
+ * @return boolean
1130
  */
1131
  public function getVerp()
1132
  {
1133
  return $this->do_verp;
1134
  }
1135
 
1136
+ /**
1137
+ * Set error messages and codes.
1138
+ * @param string $message The error message
1139
+ * @param string $detail Further detail on the error
1140
+ * @param string $smtp_code An associated SMTP error code
1141
+ * @param string $smtp_code_ex Extended SMTP code
1142
+ */
1143
+ protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '')
1144
+ {
1145
+ $this->error = array(
1146
+ 'error' => $message,
1147
+ 'detail' => $detail,
1148
+ 'smtp_code' => $smtp_code,
1149
+ 'smtp_code_ex' => $smtp_code_ex
1150
+ );
1151
+ }
1152
+
1153
  /**
1154
  * Set debug output method.
1155
+ * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it.
1156
  */
1157
  public function setDebugOutput($method = 'echo')
1158
  {
1170
 
1171
  /**
1172
  * Set debug output level.
1173
+ * @param integer $level
1174
  */
1175
  public function setDebugLevel($level = 0)
1176
  {
1179
 
1180
  /**
1181
  * Get debug output level.
1182
+ * @return integer
1183
  */
1184
  public function getDebugLevel()
1185
  {
1188
 
1189
  /**
1190
  * Set SMTP timeout.
1191
+ * @param integer $timeout
1192
  */
1193
  public function setTimeout($timeout = 0)
1194
  {
1197
 
1198
  /**
1199
  * Get SMTP timeout.
1200
+ * @return integer
1201
  */
1202
  public function getTimeout()
1203
  {
1204
  return $this->Timeout;
1205
  }
1206
+
1207
+ /**
1208
+ * Reports an error number and string.
1209
+ * @param integer $errno The error number returned by PHP.
1210
+ * @param string $errmsg The error message returned by PHP.
1211
+ */
1212
+ protected function errorHandler($errno, $errmsg)
1213
+ {
1214
+ $notice = 'Connection: Failed to connect to server.';
1215
+ $this->setError(
1216
+ $notice,
1217
+ $errno,
1218
+ $errmsg
1219
+ );
1220
+ $this->edebug(
1221
+ $notice . ' Error number ' . $errno . '. "Error notice: ' . $errmsg,
1222
+ self::DEBUG_CONNECTION
1223
+ );
1224
+ }
1225
+
1226
+ /**
1227
+ * Will return the ID of the last smtp transaction based on a list of patterns provided
1228
+ * in SMTP::$smtp_transaction_id_patterns.
1229
+ * If no reply has been received yet, it will return null.
1230
+ * If no pattern has been matched, it will return false.
1231
+ * @return bool|null|string
1232
+ */
1233
+ public function getLastTransactionID()
1234
+ {
1235
+ $reply = $this->getLastReply();
1236
+
1237
+ if (empty($reply)) {
1238
+ return null;
1239
+ }
1240
+
1241
+ foreach($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) {
1242
+ if(preg_match($smtp_transaction_id_pattern, $reply, $matches)) {
1243
+ return $matches[1];
1244
+ }
1245
+ }
1246
+
1247
+ return false;
1248
+ }
1249
  }
phpmailer/extras/EasyPeasyICS.php CHANGED
@@ -1,90 +1,148 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
2
 
3
- /* ------------------------------------------------------------------------ */
4
- /* EasyPeasyICS
5
- /* ------------------------------------------------------------------------ */
6
- /* Manuel Reinhard, manu@sprain.ch
7
- /* Twitter: @sprain
8
- /* Web: www.sprain.ch
9
- /*
10
- /* Built with inspiration by
11
- /" http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355
12
- /* ------------------------------------------------------------------------ */
13
- /* History:
14
- /* 2010/12/17 - Manuel Reinhard - when it all started
15
- /* ------------------------------------------------------------------------ */
 
 
 
 
 
16
 
17
- class EasyPeasyICS {
 
 
 
 
 
 
 
18
 
19
- protected $calendarName;
20
- protected $events = array();
21
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
- /**
24
- * Constructor
25
- * @param string $calendarName
26
- */
27
- public function __construct($calendarName=""){
28
- $this->calendarName = $calendarName;
29
- }//function
30
 
 
 
 
 
 
 
 
31
 
32
- /**
33
- * Add event to calendar
34
- * @param string $calendarName
35
- */
36
- public function addEvent($start, $end, $summary="", $description="", $url=""){
37
- $this->events[] = array(
38
- "start" => $start,
39
- "end" => $end,
40
- "summary" => $summary,
41
- "description" => $description,
42
- "url" => $url
43
- );
44
- }//function
45
-
46
-
47
- public function render($output = true){
48
-
49
- //start Variable
50
- $ics = "";
51
-
52
- //Add header
53
- $ics .= "BEGIN:VCALENDAR
 
 
 
 
 
54
  METHOD:PUBLISH
55
  VERSION:2.0
56
- X-WR-CALNAME:".$this->calendarName."
57
- PRODID:-//hacksw/handcal//NONSGML v1.0//EN";
58
-
59
- //Add events
60
- foreach($this->events as $event){
61
- $ics .= "
62
- BEGIN:VEVENT
63
- UID:". md5(uniqid(mt_rand(), true)) ."@EasyPeasyICS.php
64
- DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
65
- DTSTART:".gmdate('Ymd', $event["start"])."T".gmdate('His', $event["start"])."Z
66
- DTEND:".gmdate('Ymd', $event["end"])."T".gmdate('His', $event["end"])."Z
67
- SUMMARY:".str_replace("\n", "\\n", $event['summary'])."
68
- DESCRIPTION:".str_replace("\n", "\\n", $event['description'])."
69
- URL;VALUE=URI:".$event['url']."
70
- END:VEVENT";
71
- }//foreach
72
-
73
-
74
- //Footer
75
- $ics .= "
76
- END:VCALENDAR";
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
- if ($output) {
80
- //Output
81
- header('Content-type: text/calendar; charset=utf-8');
82
- header('Content-Disposition: inline; filename='.$this->calendarName.'.ics');
83
- echo $ics;
84
- } else {
85
- return $ics;
86
- }
87
-
88
- }//function
89
 
90
- }//class
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ /**
3
+ * EasyPeasyICS Simple ICS/vCal data generator.
4
+ * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
5
+ * @author Manuel Reinhard <manu@sprain.ch>
6
+ *
7
+ * Built with inspiration from
8
+ * http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355
9
+ * History:
10
+ * 2010/12/17 - Manuel Reinhard - when it all started
11
+ * 2014 PHPMailer project becomes maintainer
12
+ */
13
 
14
+ /**
15
+ * Class EasyPeasyICS.
16
+ * Simple ICS data generator
17
+ * @package phpmailer
18
+ * @subpackage easypeasyics
19
+ */
20
+ class EasyPeasyICS
21
+ {
22
+ /**
23
+ * The name of the calendar
24
+ * @var string
25
+ */
26
+ protected $calendarName;
27
+ /**
28
+ * The array of events to add to this calendar
29
+ * @var array
30
+ */
31
+ protected $events = array();
32
 
33
+ /**
34
+ * Constructor
35
+ * @param string $calendarName
36
+ */
37
+ public function __construct($calendarName = "")
38
+ {
39
+ $this->calendarName = $calendarName;
40
+ }
41
 
42
+ /**
43
+ * Add an event to this calendar.
44
+ * @param string $start The start date and time as a unix timestamp
45
+ * @param string $end The end date and time as a unix timestamp
46
+ * @param string $summary A summary or title for the event
47
+ * @param string $description A description of the event
48
+ * @param string $url A URL for the event
49
+ * @param string $uid A unique identifier for the event - generated automatically if not provided
50
+ * @return array An array of event details, including any generated UID
51
+ */
52
+ public function addEvent($start, $end, $summary = '', $description = '', $url = '', $uid = '')
53
+ {
54
+ if (empty($uid)) {
55
+ $uid = md5(uniqid(mt_rand(), true)) . '@EasyPeasyICS';
56
+ }
57
+ $event = array(
58
+ 'start' => gmdate('Ymd', $start) . 'T' . gmdate('His', $start) . 'Z',
59
+ 'end' => gmdate('Ymd', $end) . 'T' . gmdate('His', $end) . 'Z',
60
+ 'summary' => $summary,
61
+ 'description' => $description,
62
+ 'url' => $url,
63
+ 'uid' => $uid
64
+ );
65
+ $this->events[] = $event;
66
+ return $event;
67
+ }
68
 
69
+ /**
70
+ * @return array Get the array of events.
71
+ */
72
+ public function getEvents()
73
+ {
74
+ return $this->events;
75
+ }
76
 
77
+ /**
78
+ * Clear all events.
79
+ */
80
+ public function clearEvents()
81
+ {
82
+ $this->events = array();
83
+ }
84
 
85
+ /**
86
+ * Get the name of the calendar.
87
+ * @return string
88
+ */
89
+ public function getName()
90
+ {
91
+ return $this->calendarName;
92
+ }
93
+
94
+ /**
95
+ * Set the name of the calendar.
96
+ * @param $name
97
+ */
98
+ public function setName($name)
99
+ {
100
+ $this->calendarName = $name;
101
+ }
102
+
103
+ /**
104
+ * Render and optionally output a vcal string.
105
+ * @param bool $output Whether to output the calendar data directly (the default).
106
+ * @return string The complete rendered vlal
107
+ */
108
+ public function render($output = true)
109
+ {
110
+ //Add header
111
+ $ics = 'BEGIN:VCALENDAR
112
  METHOD:PUBLISH
113
  VERSION:2.0
114
+ X-WR-CALNAME:' . $this->calendarName . '
115
+ PRODID:-//hacksw/handcal//NONSGML v1.0//EN';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
+ //Add events
118
+ foreach ($this->events as $event) {
119
+ $ics .= '
120
+ BEGIN:VEVENT
121
+ UID:' . $event['uid'] . '
122
+ DTSTAMP:' . gmdate('Ymd') . 'T' . gmdate('His') . 'Z
123
+ DTSTART:' . $event['start'] . '
124
+ DTEND:' . $event['end'] . '
125
+ SUMMARY:' . str_replace("\n", "\\n", $event['summary']) . '
126
+ DESCRIPTION:' . str_replace("\n", "\\n", $event['description']) . '
127
+ URL;VALUE=URI:' . $event['url'] . '
128
+ END:VEVENT';
129
+ }
130
 
131
+ //Add footer
132
+ $ics .= '
133
+ END:VCALENDAR';
 
 
 
 
 
 
 
134
 
135
+ if ($output) {
136
+ //Output
137
+ $filename = $this->calendarName;
138
+ //Filename needs quoting if it contains spaces
139
+ if (strpos($filename, ' ') !== false) {
140
+ $filename = '"'.$filename.'"';
141
+ }
142
+ header('Content-type: text/calendar; charset=utf-8');
143
+ header('Content-Disposition: inline; filename=' . $filename . '.ics');
144
+ echo $ics;
145
+ }
146
+ return $ics;
147
+ }
148
+ }
phpmailer/extras/README.md ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #PHPMailer Extras
2
+
3
+ These classes provide optional additional functions to PHPMailer.
4
+
5
+ These are not loaded by the PHPMailer autoloader, so in some cases you may need to `require` them yourself before using them.
6
+
7
+ ##EasyPeasyICS
8
+
9
+ This class was originally written by Manuel Reinhard and provides a simple means of generating ICS/vCal files that are used in sending calendar events. PHPMailer does not use it directly, but you can use it to generate content appropriate for placing in the `Ical` property of PHPMailer. The PHPMailer project is now its official home as Manuel has given permission for that and is no longer maintaining it himself.
10
+
11
+ ##htmlfilter
12
+
13
+ This class by Konstantin Riabitsev and Jim Jagielski implements HTML filtering to remove potentially malicious tags, such as `<script>` or `onclick=` attributes that can result in XSS attacks. This is a simple filter and is not as comprehensive as [HTMLawed](http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/) or [HTMLPurifier](http://htmlpurifier.org), but it's easier to use and considerably better than nothing! PHPMailer does not use it directly, but you may want to apply it to user-supplied HTML before using it as a message body.
14
+
15
+ ##NTLM_SASL_client
16
+
17
+ This class by Manuel Lemos (bundled with permission) adds the ability to authenticate with Microsoft Windows mail servers that use NTLM-based authentication. It is used by PHPMailer if you send via SMTP and set the `AuthType` property to `NTLM`; you will also need to use the `Realm` and `Workstation` properties. The original source is [here](http://www.phpclasses.org/browse/file/7495.html).
phpmailer/extras/htmlfilter.php CHANGED
@@ -20,77 +20,75 @@
20
  *
21
  * You should have received a copy of the GNU Lesser General Public
22
  * License along with this library; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24
  * 02110-1301 USA
25
  *
26
  * @Author Konstantin Riabitsev <icon@linux.duke.edu>
27
- * @Version 1.1 ($Date: 2011-07-04 14:02:23 -0400 (Mon, 04 Jul 2011) $)
28
- */
29
-
30
- /**
31
  * @Author Jim Jagielski <jim@jaguNET.com / jimjag@gmail.com>
 
32
  */
33
 
34
  /**
35
  * This function returns the final tag out of the tag name, an array
36
- * of attributes, and the type of the tag. This function is called by
37
  * tln_sanitize internally.
38
  *
39
- * @param $tagname the name of the tag.
40
- * @param $attary the array of attributes and their values
41
- * @param $tagtype The type of the tag (see in comments).
42
- * @return a string with the final tag representation.
43
  */
44
- function tln_tagprint($tagname, $attary, $tagtype){
45
- $me = 'tln_tagprint';
46
- if ($tagtype == 2){
47
- $fulltag = '</' . $tagname . '>';
48
- } else {
49
- $fulltag = '<' . $tagname;
50
- if (is_array($attary) && sizeof($attary)){
51
- $atts = Array();
52
- while (list($attname, $attvalue) = each($attary)){
53
- array_push($atts, "$attname=$attvalue");
54
- }
55
- $fulltag .= ' ' . join(' ', $atts);
56
- }
57
- if ($tagtype == 3){
58
- $fulltag .= ' /';
59
- }
60
- $fulltag .= '>';
61
- }
62
- return $fulltag;
63
  }
64
 
65
  /**
66
  * A small helper function to use with array_walk. Modifies a by-ref
67
  * value and makes it lowercase.
68
  *
69
- * @param $val a value passed by-ref.
70
  * @return void since it modifies a by-ref value.
71
  */
72
- function tln_casenormalize(&$val){
73
- $val = strtolower($val);
 
74
  }
75
 
76
  /**
77
  * This function skips any whitespace from the current position within
78
  * a string and to the next non-whitespace value.
79
- *
80
- * @param $body the string
81
- * @param $offset the offset within the string where we should start
82
  * looking for the next non-whitespace character.
83
- * @return the location within the $body where the next
84
  * non-whitespace char is located.
85
  */
86
- function tln_skipspace($body, $offset){
87
- $me = 'tln_skipspace';
88
- preg_match('/^(\s*)/s', substr($body, $offset), $matches);
89
- if (sizeof($matches[1])){
90
- $count = strlen($matches[1]);
91
- $offset += $count;
92
- }
93
- return $offset;
94
  }
95
 
96
  /**
@@ -98,56 +96,56 @@ function tln_skipspace($body, $offset){
98
  * really just a glorified "strpos", except it catches the failures
99
  * nicely.
100
  *
101
- * @param $body The string to look for needle in.
102
- * @param $offset Start looking from this position.
103
- * @param $needle The character/string to look for.
104
- * @return location of the next occurrence of the needle, or
105
  * strlen($body) if needle wasn't found.
106
  */
107
- function tln_findnxstr($body, $offset, $needle){
108
- $me = 'tln_findnxstr';
109
- $pos = strpos($body, $needle, $offset);
110
- if ($pos === FALSE){
111
- $pos = strlen($body);
112
- }
113
- return $pos;
114
  }
115
 
116
  /**
117
  * This function takes a PCRE-style regexp and tries to match it
118
  * within the string.
119
  *
120
- * @param $body The string to look for needle in.
121
- * @param $offset Start looking from here.
122
- * @param $reg A PCRE-style regex to match.
123
- * @return Returns a false if no matches found, or an array
124
  * with the following members:
125
  * - integer with the location of the match within $body
126
  * - string with whatever content between offset and the match
127
  * - string with whatever it is we matched
128
  */
129
- function tln_findnxreg($body, $offset, $reg){
130
- $me = 'tln_findnxreg';
131
- $matches = Array();
132
- $retarr = Array();
133
- $preg_rule = '%^(.*?)(' . $reg . ')%s';
134
- preg_match($preg_rule, substr($body, $offset), $matches);
135
- if (!isset($matches[0])){
136
- $retarr = false;
137
- } else {
138
- $retarr[0] = $offset + strlen($matches[1]);
139
- $retarr[1] = $matches[1];
140
- $retarr[2] = $matches[2];
141
- }
142
- return $retarr;
143
  }
144
 
145
  /**
146
  * This function looks for the next tag.
147
  *
148
- * @param $body String where to look for the next tag.
149
- * @param $offset Start looking from here.
150
- * @return false if no more tags exist in the body, or
151
  * an array with the following members:
152
  * - string with the name of the tag
153
  * - array with attributes and their values
@@ -156,309 +154,305 @@ function tln_findnxreg($body, $offset, $reg){
156
  * - integer where the tag ends (ending ">")
157
  * first three members will be false, if the tag is invalid.
158
  */
159
- function tln_getnxtag($body, $offset){
160
- $me = 'tln_getnxtag';
161
- if ($offset > strlen($body)){
162
- return false;
163
- }
164
- $lt = tln_findnxstr($body, $offset, '<');
165
- if ($lt == strlen($body)){
166
- return false;
167
- }
168
- /**
169
- * We are here:
170
- * blah blah <tag attribute="value">
171
- * \---------^
172
- */
173
- $pos = tln_skipspace($body, $lt + 1);
174
- if ($pos >= strlen($body)){
175
- return Array(false, false, false, $lt, strlen($body));
176
- }
177
- /**
178
- * There are 3 kinds of tags:
179
- * 1. Opening tag, e.g.:
180
- * <a href="blah">
181
- * 2. Closing tag, e.g.:
182
- * </a>
183
- * 3. XHTML-style content-less tag, e.g.:
184
- * <img src="blah"/>
185
- */
186
- $tagtype = false;
187
- switch (substr($body, $pos, 1)){
188
- case '/':
189
- $tagtype = 2;
190
- $pos++;
191
- break;
192
- case '!':
193
- /**
194
- * A comment or an SGML declaration.
195
- */
196
- if (substr($body, $pos+1, 2) == '--'){
197
- $gt = strpos($body, '-->', $pos);
198
- if ($gt === false){
199
- $gt = strlen($body);
200
- } else {
201
- $gt += 2;
202
- }
203
- return Array(false, false, false, $lt, $gt);
204
- } else {
205
- $gt = tln_findnxstr($body, $pos, '>');
206
- return Array(false, false, false, $lt, $gt);
207
- }
208
- break;
209
- default:
210
- /**
211
- * Assume tagtype 1 for now. If it's type 3, we'll switch values
212
- * later.
213
- */
214
- $tagtype = 1;
215
- break;
216
- }
217
-
218
- $tag_start = $pos;
219
- $tagname = '';
220
- /**
221
- * Look for next [\W-_], which will indicate the end of the tag name.
222
- */
223
- $regary = tln_findnxreg($body, $pos, '[^\w\-_]');
224
- if ($regary == false){
225
- return Array(false, false, false, $lt, strlen($body));
226
- }
227
- list($pos, $tagname, $match) = $regary;
228
- $tagname = strtolower($tagname);
229
-
230
- /**
231
- * $match can be either of these:
232
- * '>' indicating the end of the tag entirely.
233
- * '\s' indicating the end of the tag name.
234
- * '/' indicating that this is type-3 xhtml tag.
235
- *
236
- * Whatever else we find there indicates an invalid tag.
237
- */
238
- switch ($match){
239
- case '/':
240
- /**
241
- * This is an xhtml-style tag with a closing / at the
242
- * end, like so: <img src="blah"/>. Check if it's followed
243
- * by the closing bracket. If not, then this tag is invalid
244
- */
245
- if (substr($body, $pos, 2) == '/>'){
246
- $pos++;
247
- $tagtype = 3;
248
- } else {
249
- $gt = tln_findnxstr($body, $pos, '>');
250
- $retary = Array(false, false, false, $lt, $gt);
251
- return $retary;
252
- }
253
- case '>':
254
- return Array($tagname, false, $tagtype, $lt, $pos);
255
- break;
256
- default:
257
- /**
258
- * Check if it's whitespace
259
- */
260
- if (preg_match('/\s/', $match)){
261
- } else {
262
- /**
263
- * This is an invalid tag! Look for the next closing ">".
264
- */
265
- $gt = tln_findnxstr($body, $lt, '>');
266
- return Array(false, false, false, $lt, $gt);
267
- }
268
- }
269
-
270
- /**
271
- * At this point we're here:
272
- * <tagname attribute='blah'>
273
- * \-------^
274
- *
275
- * At this point we loop in order to find all attributes.
276
- */
277
- $attname = '';
278
- $atttype = false;
279
- $attary = Array();
280
-
281
- while ($pos <= strlen($body)){
282
- $pos = tln_skipspace($body, $pos);
283
- if ($pos == strlen($body)){
284
- /**
285
- * Non-closed tag.
286
- */
287
- return Array(false, false, false, $lt, $pos);
288
- }
289
- /**
290
- * See if we arrived at a ">" or "/>", which means that we reached
291
- * the end of the tag.
292
- */
293
- $matches = Array();
294
- preg_match('%^(\s*)(>|/>)%s', substr($body, $pos), $matches);
295
- if (isset($matches[0]) && $matches[0]){
296
- /**
297
- * Yep. So we did.
298
- */
299
- $pos += strlen($matches[1]);
300
- if ($matches[2] == '/>'){
301
- $tagtype = 3;
302
- $pos++;
303
- }
304
- return Array($tagname, $attary, $tagtype, $lt, $pos);
305
- }
306
-
307
- /**
308
- * There are several types of attributes, with optional
309
- * [:space:] between members.
310
- * Type 1:
311
- * attrname[:space:]=[:space:]'CDATA'
312
- * Type 2:
313
- * attrname[:space:]=[:space:]"CDATA"
314
- * Type 3:
315
- * attr[:space:]=[:space:]CDATA
316
- * Type 4:
317
- * attrname
318
- *
319
- * We leave types 1 and 2 the same, type 3 we check for
320
- * '"' and convert to "&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
  */
444
- function tln_deent(&$attvalue, $regex, $hex=false){
445
- $me = 'tln_deent';
446
- $ret_match = false;
447
- preg_match_all($regex, $attvalue, $matches);
448
- if (is_array($matches) && sizeof($matches[0]) > 0){
449
- $repl = Array();
450
- for ($i = 0; $i < sizeof($matches[0]); $i++){
451
- $numval = $matches[1][$i];
452
- if ($hex){
453
- $numval = hexdec($numval);
454
- }
455
- $repl{$matches[0][$i]} = chr($numval);
456
- }
457
- $attvalue = strtr($attvalue, $repl);
458
- return true;
459
- } else {
460
- return false;
461
- }
462
  }
463
 
464
  /**
@@ -466,396 +460,700 @@ function tln_deent(&$attvalue, $regex, $hex=false){
466
  * and returns them translated into 8-bit strings so we can run
467
  * checks on them.
468
  *
469
- * @param $attvalue A string to run entity check against.
470
- * @return Nothing, modifies a reference value.
471
  */
472
- function tln_defang(&$attvalue){
473
- $me = 'tln_defang';
474
- /**
475
- * Skip this if there aren't ampersands or backslashes.
476
- */
477
- if (strpos($attvalue, '&') === false
478
- && strpos($attvalue, '\\') === false){
479
- return;
480
- }
481
- $m = false;
482
- do {
483
- $m = false;
484
- $m = $m || tln_deent($attvalue, '/\&#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
  */
499
- function tln_unspace(&$attvalue){
500
- $me = 'tln_unspace';
501
- if (strcspn($attvalue, "\t\r\n\0 ") != strlen($attvalue)){
502
- $attvalue = str_replace(Array("\t", "\r", "\n", "\0", " "),
503
- Array('', '', '', '', ''), $attvalue);
504
- }
 
 
 
505
  }
506
 
507
  /**
508
  * This function runs various checks against the attributes.
509
  *
510
- * @param $tagname String with the name of the tag.
511
- * @param $attary Array with all tag attributes.
512
- * @param $rm_attnames See description for tln_sanitize
513
- * @param $bad_attvals See description for tln_sanitize
514
- * @param $add_attr_to_tag See description for tln_sanitize
515
- * @return Array with modified attributes.
 
 
516
  */
517
- function tln_fixatts($tagname,
518
- $attary,
519
- $rm_attnames,
520
- $bad_attvals,
521
- $add_attr_to_tag
522
- ){
523
- $me = 'tln_fixatts';
524
- while (list($attname, $attvalue) = each($attary)){
525
- /**
526
- * See if this attribute should be removed.
527
- */
528
- foreach ($rm_attnames as $matchtag=>$matchattrs){
529
- if (preg_match($matchtag, $tagname)){
530
- foreach ($matchattrs as $matchattr){
531
- if (preg_match($matchattr, $attname)){
532
- unset($attary{$attname});
533
- continue;
534
- }
535
- }
536
- }
537
- }
538
- /**
539
- * Remove any backslashes, entities, or extraneous whitespace.
540
- */
541
- tln_defang($attvalue);
542
- tln_unspace($attvalue);
543
-
544
- /**
545
- * Now let's run checks on the attvalues.
546
- * I don't expect anyone to comprehend this. If you do,
547
- * get in touch with me so I can drive to where you live and
548
- * shake your hand personally. :)
549
- */
550
- foreach ($bad_attvals as $matchtag=>$matchattrs){
551
- if (preg_match($matchtag, $tagname)){
552
- foreach ($matchattrs as $matchattr=>$valary){
553
- if (preg_match($matchattr, $attname)){
554
- /**
555
- * There are two arrays in valary.
556
- * First is matches.
557
- * Second one is replacements
558
- */
559
- list($valmatch, $valrepl) = $valary;
560
- $newvalue = preg_replace($valmatch,$valrepl,$attvalue);
561
- if ($newvalue != $attvalue){
562
- $attary{$attname} = $newvalue;
563
- }
564
- }
565
- }
566
- }
567
- }
568
- }
569
- /**
570
- * See if we need to append any attributes to this tag.
571
- */
572
- foreach ($add_attr_to_tag as $matchtag=>$addattary){
573
- if (preg_match($matchtag, $tagname)){
574
- $attary = array_merge($attary, $addattary);
575
- }
576
- }
577
- return $attary;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  }
579
 
580
  /**
581
  *
582
- * @param $body the string with HTML you wish to filter
583
- * @param $tag_list see description above
584
- * @param $rm_tags_with_content see description above
585
- * @param $self_closing_tags see description above
586
- * @param $force_tag_closing see description above
587
- * @param $rm_attnames see description above
588
- * @param $bad_attvals see description above
589
- * @param $add_attr_to_tag see description above
590
- * @return tln_sanitized html safe to show on your pages.
 
 
 
591
  */
592
- function tln_sanitize($body,
593
- $tag_list,
594
- $rm_tags_with_content,
595
- $self_closing_tags,
596
- $force_tag_closing,
597
- $rm_attnames,
598
- $bad_attvals,
599
- $add_attr_to_tag
600
- )
601
- {
602
- $me = 'tln_sanitize';
603
- /**
604
- * Normalize rm_tags and rm_tags_with_content.
605
- */
606
- $rm_tags = array_shift($tag_list);
607
- @array_walk($tag_list, 'tln_casenormalize');
608
- @array_walk($rm_tags_with_content, 'tln_casenormalize');
609
- @array_walk($self_closing_tags, 'tln_casenormalize');
610
- /**
611
- * See if tag_list is of tags to remove or tags to allow.
612
- * false means remove these tags
613
- * true means allow these tags
614
- */
615
- $curpos = 0;
616
- $open_tags = Array();
617
- $trusted = "<!-- begin tln_sanitized html -->\n";
618
- $skip_content = false;
619
- /**
620
- * Take care of netscape's stupid javascript entities like
621
- * &{alert('boo')};
622
- */
623
- $body = preg_replace('/&(\{.*?\};)/si', '&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
 
725
- function HTMLFilter($body, $trans_image_path, $block_external_images = false) {
726
-
727
- $tag_list = Array(
728
- false,
729
- "object",
730
- "meta",
731
- "html",
732
- "head",
733
- "base",
734
- "link",
735
- "frame",
736
- "iframe",
737
- "plaintext",
738
- "marquee"
739
- );
740
-
741
- $rm_tags_with_content = Array(
742
- "script",
743
- "applet",
744
- "embed",
745
- "title",
746
- "frameset",
747
- "xmp",
748
- "xml"
749
- );
750
-
751
- $self_closing_tags = Array(
752
- "img",
753
- "br",
754
- "hr",
755
- "input",
756
- "outbind"
757
- );
758
-
759
- $force_tag_closing = true;
760
-
761
- $rm_attnames = Array(
762
- "/.*/" =>
763
- Array(
764
- // "/target/i",
765
- "/^on.*/i",
766
- "/^dynsrc/i",
767
- "/^data.*/i",
768
- "/^lowsrc.*/i"
769
- )
770
- );
771
-
772
- $bad_attvals = Array(
773
- "/.*/" =>
774
- Array(
775
- "/^src|background/i" =>
776
- Array(
777
- Array(
778
- "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si",
779
- "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si",
780
- "/^([\'\"])\s*about\s*:.*([\'\"])/si"
781
- ),
782
- Array(
783
- "\\1$trans_image_path\\2",
784
- "\\1$trans_image_path\\2",
785
- "\\1$trans_image_path\\2",
786
- "\\1$trans_image_path\\2"
787
- )
788
- ),
789
- "/^href|action/i" =>
790
- Array(
791
- Array(
792
- "/^([\'\"])\s*\S+script\s*:.*([\'\"])/si",
793
- "/^([\'\"])\s*mocha\s*:*.*([\'\"])/si",
794
- "/^([\'\"])\s*about\s*:.*([\'\"])/si"
795
- ),
796
- Array(
797
- "\\1#\\1",
798
- "\\1#\\1",
799
- "\\1#\\1",
800
- "\\1#\\1"
801
- )
802
- ),
803
- "/^style/i" =>
804
- Array(
805
- Array(
806
- "/expression/i",
807
- "/binding/i",
808
- "/behaviou*r/i",
809
- "/include-source/i",
810
- "/position\s*:\s*absolute/i",
811
- "/url\s*\(\s*([\'\"])\s*\S+script\s*:.*([\'\"])\s*\)/si",
812
- "/url\s*\(\s*([\'\"])\s*mocha\s*:.*([\'\"])\s*\)/si",
813
- "/url\s*\(\s*([\'\"])\s*about\s*:.*([\'\"])\s*\)/si",
814
- "/(.*)\s*:\s*url\s*\(\s*([\'\"]*)\s*\S+script\s*:.*([\'\"]*)\s*\)/si"
815
- ),
816
- Array(
817
- "idiocy",
818
- "idiocy",
819
- "idiocy",
820
- "idiocy",
821
- "",
822
- "url(\\1#\\1)",
823
- "url(\\1#\\1)",
824
- "url(\\1#\\1)",
825
- "url(\\1#\\1)",
826
- "url(\\1#\\1)",
827
- "\\1:url(\\2#\\3)"
828
- )
829
- )
830
- )
831
- );
832
-
833
- if ($block_external_images){
834
- array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[0],
835
- '/^([\'\"])\s*https*:.*([\'\"])/si');
836
- array_push($bad_attvals{'/.*/'}{'/^src|background/i'}[1],
837
- "\\1$trans_image_path\\1");
838
- array_push($bad_attvals{'/.*/'}{'/^style/i'}[0],
839
- '/url\(([\'\"])\s*https*:.*([\'\"])\)/si');
840
- array_push($bad_attvals{'/.*/'}{'/^style/i'}[1],
841
- "url(\\1$trans_image_path\\1)");
842
- }
843
-
844
- $add_attr_to_tag = Array(
845
- "/^a$/i" =>
846
- Array('target'=>'"_blank"')
847
- );
848
-
849
- $trusted = tln_sanitize($body,
850
- $tag_list,
851
- $rm_tags_with_content,
852
- $self_closing_tags,
853
- $force_tag_closing,
854
- $rm_attnames,
855
- $bad_attvals,
856
- $add_attr_to_tag
857
- );
858
- return $trusted;
859
- }
860
 
861
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
  * @Author Jim Jagielski <jim@jaguNET.com / jimjag@gmail.com>
28
+ * @Version 1.1 ($Date$)
29
  */
30
 
31
  /**
32
  * This function returns the final tag out of the tag name, an array
33
+ * of attributes, and the type of the tag. This function is called by
34
  * tln_sanitize internally.
35
  *
36
+ * @param string $tagname the name of the tag.
37
+ * @param array $attary the array of attributes and their values
38
+ * @param integer $tagtype The type of the tag (see in comments).
39
+ * @return string A string with the final tag representation.
40
  */
41
+ function tln_tagprint($tagname, $attary, $tagtype)
42
+ {
43
+ if ($tagtype == 2) {
44
+ $fulltag = '</' . $tagname . '>';
45
+ } else {
46
+ $fulltag = '<' . $tagname;
47
+ if (is_array($attary) && sizeof($attary)) {
48
+ $atts = array();
49
+ while (list($attname, $attvalue) = each($attary)) {
50
+ array_push($atts, "$attname=$attvalue");
51
+ }
52
+ $fulltag .= ' ' . join(' ', $atts);
53
+ }
54
+ if ($tagtype == 3) {
55
+ $fulltag .= ' /';
56
+ }
57
+ $fulltag .= '>';
58
+ }
59
+ return $fulltag;
60
  }
61
 
62
  /**
63
  * A small helper function to use with array_walk. Modifies a by-ref
64
  * value and makes it lowercase.
65
  *
66
+ * @param string $val a value passed by-ref.
67
  * @return void since it modifies a by-ref value.
68
  */
69
+ function tln_casenormalize(&$val)
70
+ {
71
+ $val = strtolower($val);
72
  }
73
 
74
  /**
75
  * This function skips any whitespace from the current position within
76
  * a string and to the next non-whitespace value.
77
+ *
78
+ * @param string $body the string
79
+ * @param integer $offset the offset within the string where we should start
80
  * looking for the next non-whitespace character.
81
+ * @return integer the location within the $body where the next
82
  * non-whitespace char is located.
83
  */
84
+ function tln_skipspace($body, $offset)
85
+ {
86
+ preg_match('/^(\s*)/s', substr($body, $offset), $matches);
87
+ if (sizeof($matches[1])) {
88
+ $count = strlen($matches[1]);
89
+ $offset += $count;
90
+ }
91
+ return $offset;
92
  }
93
 
94
  /**
96
  * really just a glorified "strpos", except it catches the failures
97
  * nicely.
98
  *
99
+ * @param string $body The string to look for needle in.
100
+ * @param integer $offset Start looking from this position.
101
+ * @param string $needle The character/string to look for.
102
+ * @return integer location of the next occurrence of the needle, or
103
  * strlen($body) if needle wasn't found.
104
  */
105
+ function tln_findnxstr($body, $offset, $needle)
106
+ {
107
+ $pos = strpos($body, $needle, $offset);
108
+ if ($pos === false) {
109
+ $pos = strlen($body);
110
+ }
111
+ return $pos;
112
  }
113
 
114
  /**
115
  * This function takes a PCRE-style regexp and tries to match it
116
  * within the string.
117
  *
118
+ * @param string $body The string to look for needle in.
119
+ * @param integer $offset Start looking from here.
120
+ * @param string $reg A PCRE-style regex to match.
121
+ * @return array|boolean Returns a false if no matches found, or an array
122
  * with the following members:
123
  * - integer with the location of the match within $body
124
  * - string with whatever content between offset and the match
125
  * - string with whatever it is we matched
126
  */
127
+ function tln_findnxreg($body, $offset, $reg)
128
+ {
129
+ $matches = array();
130
+ $retarr = array();
131
+ $preg_rule = '%^(.*?)(' . $reg . ')%s';
132
+ preg_match($preg_rule, substr($body, $offset), $matches);
133
+ if (!isset($matches[0]) || !$matches[0]) {
134
+ $retarr = false;
135
+ } else {
136
+ $retarr[0] = $offset + strlen($matches[1]);
137
+ $retarr[1] = $matches[1];
138
+ $retarr[2] = $matches[2];
139
+ }
140
+ return $retarr;
141
  }
142
 
143
  /**
144
  * This function looks for the next tag.
145
  *
146
+ * @param string $body String where to look for the next tag.
147
+ * @param integer $offset Start looking from here.
148
+ * @return array|boolean false if no more tags exist in the body, or
149
  * an array with the following members:
150
  * - string with the name of the tag
151
  * - array with attributes and their values
154
  * - integer where the tag ends (ending ">")
155
  * first three members will be false, if the tag is invalid.
156
  */
157
+ function tln_getnxtag($body, $offset)
158
+ {
159
+ if ($offset > strlen($body)) {
160
+ return false;
161
+ }
162
+ $lt = tln_findnxstr($body, $offset, '<');
163
+ if ($lt == strlen($body)) {
164
+ return false;
165
+ }
166
+ /**
167
+ * We are here:
168
+ * blah blah <tag attribute="value">
169
+ * \---------^
170
+ */
171
+ $pos = tln_skipspace($body, $lt + 1);
172
+ if ($pos >= strlen($body)) {
173
+ return array(false, false, false, $lt, strlen($body));
174
+ }
175
+ /**
176
+ * There are 3 kinds of tags:
177
+ * 1. Opening tag, e.g.:
178
+ * <a href="blah">
179
+ * 2. Closing tag, e.g.:
180
+ * </a>
181
+ * 3. XHTML-style content-less tag, e.g.:
182
+ * <img src="blah"/>
183
+ */
184
+ switch (substr($body, $pos, 1)) {
185
+ case '/':
186
+ $tagtype = 2;
187
+ $pos++;
188
+ break;
189
+ case '!':
190
+ /**
191
+ * A comment or an SGML declaration.
192
+ */
193
+ if (substr($body, $pos + 1, 2) == '--') {
194
+ $gt = strpos($body, '-->', $pos);
195
+ if ($gt === false) {
196
+ $gt = strlen($body);
197
+ } else {
198
+ $gt += 2;
199
+ }
200
+ return array(false, false, false, $lt, $gt);
201
+ } else {
202
+ $gt = tln_findnxstr($body, $pos, '>');
203
+ return array(false, false, false, $lt, $gt);
204
+ }
205
+ break;
206
+ default:
207
+ /**
208
+ * Assume tagtype 1 for now. If it's type 3, we'll switch values
209
+ * later.
210
+ */
211
+ $tagtype = 1;
212
+ break;
213
+ }
214
+
215
+ /**
216
+ * Look for next [\W-_], which will indicate the end of the tag name.
217
+ */
218
+ $regary = tln_findnxreg($body, $pos, '[^\w\-_]');
219
+ if ($regary == false) {
220
+ return array(false, false, false, $lt, strlen($body));
221
+ }
222
+ list($pos, $tagname, $match) = $regary;
223
+ $tagname = strtolower($tagname);
224
+
225
+ /**
226
+ * $match can be either of these:
227
+ * '>' indicating the end of the tag entirely.
228
+ * '\s' indicating the end of the tag name.
229
+ * '/' indicating that this is type-3 xhtml tag.
230
+ *
231
+ * Whatever else we find there indicates an invalid tag.
232
+ */
233
+ switch ($match) {
234
+ case '/':
235
+ /**
236
+ * This is an xhtml-style tag with a closing / at the
237
+ * end, like so: <img src="blah"/>. Check if it's followed
238
+ * by the closing bracket. If not, then this tag is invalid
239
+ */
240
+ if (substr($body, $pos, 2) == '/>') {
241
+ $pos++;
242
+ $tagtype = 3;
243
+ } else {
244
+ $gt = tln_findnxstr($body, $pos, '>');
245
+ $retary = array(false, false, false, $lt, $gt);
246
+ return $retary;
247
+ }
248
+ //intentional fall-through
249
+ case '>':
250
+ return array($tagname, false, $tagtype, $lt, $pos);
251
+ break;
252
+ default:
253
+ /**
254
+ * Check if it's whitespace
255
+ */
256
+ if (!preg_match('/\s/', $match)) {
257
+ /**
258
+ * This is an invalid tag! Look for the next closing ">".
259
+ */
260
+ $gt = tln_findnxstr($body, $lt, '>');
261
+ return array(false, false, false, $lt, $gt);
262
+ }
263
+ break;
264
+ }
265
+
266
+ /**
267
+ * At this point we're here:
268
+ * <tagname attribute='blah'>
269
+ * \-------^
270
+ *
271
+ * At this point we loop in order to find all attributes.
272
+ */
273
+ $attary = array();
274
+
275
+ while ($pos <= strlen($body)) {
276
+ $pos = tln_skipspace($body, $pos);
277
+ if ($pos == strlen($body)) {
278
+ /**
279
+ * Non-closed tag.
280
+ */
281
+ return array(false, false, false, $lt, $pos);
282
+ }
283
+ /**
284
+ * See if we arrived at a ">" or "/>", which means that we reached
285
+ * the end of the tag.
286
+ */
287
+ $matches = array();
288
+ if (preg_match('%^(\s*)(>|/>)%s', substr($body, $pos), $matches)) {
289
+ /**
290
+ * Yep. So we did.
291
+ */
292
+ $pos += strlen($matches[1]);
293
+ if ($matches[2] == '/>') {
294
+ $tagtype = 3;
295
+ $pos++;
296
+ }
297
+ return array($tagname, $attary, $tagtype, $lt, $pos);
298
+ }
299
+
300
+ /**
301
+ * There are several types of attributes, with optional
302
+ * [:space:] between members.
303
+ * Type 1:
304
+ * attrname[:space:]=[:space:]'CDATA'
305
+ * Type 2:
306
+ * attrname[:space:]=[:space:]"CDATA"
307
+ * Type 3:
308
+ * attr[:space:]=[:space:]CDATA
309
+ * Type 4:
310
+ * attrname
311
+ *
312
+ * We leave types 1 and 2 the same, type 3 we check for
313
+ * '"' and convert to "&quot" if needed, then wrap in
314
+ * double quotes. Type 4 we convert into:
315
+ * attrname="yes".
316
+ */
317
+ $regary = tln_findnxreg($body, $pos, '[^\w\-_]');
318
+ if ($regary == false) {
319
+ /**
320
+ * Looks like body ended before the end of tag.
321
+ */
322
+ return array(false, false, false, $lt, strlen($body));
323
+ }
324
+ list($pos, $attname, $match) = $regary;
325
+ $attname = strtolower($attname);
326
+ /**
327
+ * We arrived at the end of attribute name. Several things possible
328
+ * here:
329
+ * '>' means the end of the tag and this is attribute type 4
330
+ * '/' if followed by '>' means the same thing as above
331
+ * '\s' means a lot of things -- look what it's followed by.
332
+ * anything else means the attribute is invalid.
333
+ */
334
+ switch ($match) {
335
+ case '/':
336
+ /**
337
+ * This is an xhtml-style tag with a closing / at the
338
+ * end, like so: <img src="blah"/>. Check if it's followed
339
+ * by the closing bracket. If not, then this tag is invalid
340
+ */
341
+ if (substr($body, $pos, 2) == '/>') {
342
+ $pos++;
343
+ $tagtype = 3;
344
+ } else {
345
+ $gt = tln_findnxstr($body, $pos, '>');
346
+ $retary = array(false, false, false, $lt, $gt);
347
+ return $retary;
348
+ }
349
+ //intentional fall-through
350
+ case '>':
351
+ $attary{$attname} = '"yes"';
352
+ return array($tagname, $attary, $tagtype, $lt, $pos);
353
+ break;
354
+ default:
355
+ /**
356
+ * Skip whitespace and see what we arrive at.
357
+ */
358
+ $pos = tln_skipspace($body, $pos);
359
+ $char = substr($body, $pos, 1);
360
+ /**
361
+ * Two things are valid here:
362
+ * '=' means this is attribute type 1 2 or 3.
363
+ * \w means this was attribute type 4.
364
+ * anything else we ignore and re-loop. End of tag and
365
+ * invalid stuff will be caught by our checks at the beginning
366
+ * of the loop.
367
+ */
368
+ if ($char == '=') {
369
+ $pos++;
370
+ $pos = tln_skipspace($body, $pos);
371
+ /**
372
+ * Here are 3 possibilities:
373
+ * "'" attribute type 1
374
+ * '"' attribute type 2
375
+ * everything else is the content of tag type 3
376
+ */
377
+ $quot = substr($body, $pos, 1);
378
+ if ($quot == '\'') {
379
+ $regary = tln_findnxreg($body, $pos + 1, '\'');
380
+ if ($regary == false) {
381
+ return array(false, false, false, $lt, strlen($body));
382
+ }
383
+ list($pos, $attval, $match) = $regary;
384
+ $pos++;
385
+ $attary{$attname} = '\'' . $attval . '\'';
386
+ } elseif ($quot == '"') {
387
+ $regary = tln_findnxreg($body, $pos + 1, '\"');
388
+ if ($regary == false) {
389
+ return array(false, false, false, $lt, strlen($body));
390
+ }
391
+ list($pos, $attval, $match) = $regary;
392
+ $pos++;
393
+ $attary{$attname} = '"' . $attval . '"';
394
+ } else {
395
+ /**
396
+ * These are hateful. Look for \s, or >.
397
+ */
398
+ $regary = tln_findnxreg($body, $pos, '[\s>]');
399
+ if ($regary == false) {
400
+ return array(false, false, false, $lt, strlen($body));
401
+ }
402
+ list($pos, $attval, $match) = $regary;
403
+ /**
404
+ * If it's ">" it will be caught at the top.
405
+ */
406
+ $attval = preg_replace('/\"/s', '&quot;', $attval);
407
+ $attary{$attname} = '"' . $attval . '"';
408
+ }
409
+ } elseif (preg_match('|[\w/>]|', $char)) {
410
+ /**
411
+ * That was attribute type 4.
412
+ */
413
+ $attary{$attname} = '"yes"';
414
+ } else {
415
+ /**
416
+ * An illegal character. Find next '>' and return.
417
+ */
418
+ $gt = tln_findnxstr($body, $pos, '>');
419
+ return array(false, false, false, $lt, $gt);
420
+ }
421
+ break;
422
+ }
423
+ }
424
+ /**
425
+ * The fact that we got here indicates that the tag end was never
426
+ * found. Return invalid tag indication so it gets stripped.
427
+ */
428
+ return array(false, false, false, $lt, strlen($body));
 
 
 
429
  }
430
 
431
  /**
432
  * Translates entities into literal values so they can be checked.
433
  *
434
+ * @param string $attvalue the by-ref value to check.
435
+ * @param string $regex the regular expression to check against.
436
+ * @param boolean $hex whether the entites are hexadecimal.
437
+ * @return boolean True or False depending on whether there were matches.
438
  */
439
+ function tln_deent(&$attvalue, $regex, $hex = false)
440
+ {
441
+ preg_match_all($regex, $attvalue, $matches);
442
+ if (is_array($matches) && sizeof($matches[0]) > 0) {
443
+ $repl = array();
444
+ for ($i = 0; $i < sizeof($matches[0]); $i++) {
445
+ $numval = $matches[1][$i];
446
+ if ($hex) {
447
+ $numval = hexdec($numval);
448
+ }
449
+ $repl{$matches[0][$i]} = chr($numval);
450
+ }
451
+ $attvalue = strtr($attvalue, $repl);
452
+ return true;
453
+ } else {
454
+ return false;
455
+ }
 
456
  }
457
 
458
  /**
460
  * and returns them translated into 8-bit strings so we can run
461
  * checks on them.
462
  *
463
+ * @param string $attvalue A string to run entity check against.
 
464
  */
465
+ function tln_defang(&$attvalue)
466
+ {
467
+ /**
468
+ * Skip this if there aren't ampersands or backslashes.
469
+ */
470
+ if (strpos($attvalue, '&') === false
471
+ && strpos($attvalue, '\\') === false
472
+ ) {
473
+ return;
474
+ }
475
+ do {
476
+ $m = false;
477
+ $m = $m || tln_deent($attvalue, '/\&#0*(\d+);*/s');
478
+ $m = $m || tln_deent($attvalue, '/\&#x0*((\d|[a-f])+);*/si', true);
479
+ $m = $m || tln_deent($attvalue, '/\\\\(\d+)/s', true);
480
+ } while ($m == true);
481
+ $attvalue = stripslashes($attvalue);
482
  }
483
 
484
  /**
485
  * Kill any tabs, newlines, or carriage returns. Our friends the
486
  * makers of the browser with 95% market value decided that it'd
487
  * be funny to make "java[tab]script" be just as good as "javascript".
488
+ *
489
+ * @param string $attvalue The attribute value before extraneous spaces removed.
 
490
  */
491
+ function tln_unspace(&$attvalue)
492
+ {
493
+ if (strcspn($attvalue, "\t\r\n\0 ") != strlen($attvalue)) {
494
+ $attvalue = str_replace(
495
+ array("\t", "\r", "\n", "\0", " "),
496
+ array('', '', '', '', ''),
497
+ $attvalue
498
+ );
499
+ }
500
  }
501
 
502
  /**
503
  * This function runs various checks against the attributes.
504
  *
505
+ * @param string $tagname String with the name of the tag.
506
+ * @param array $attary Array with all tag attributes.
507
+ * @param array $rm_attnames See description for tln_sanitize
508
+ * @param array $bad_attvals See description for tln_sanitize
509
+ * @param array $add_attr_to_tag See description for tln_sanitize
510
+ * @param string $trans_image_path
511
+ * @param boolean $block_external_images
512
+ * @return array with modified attributes.
513
  */
514
+ function tln_fixatts(
515
+ $tagname,
516
+ $attary,
517
+ $rm_attnames,
518
+ $bad_attvals,
519
+ $add_attr_to_tag,
520
+ $trans_image_path,
521
+ $block_external_images
522
+ ) {
523
+ while (list($attname, $attvalue) = each($attary)) {
524
+ /**
525
+ * See if this attribute should be removed.
526
+ */
527
+ foreach ($rm_attnames as $matchtag => $matchattrs) {
528
+ if (preg_match($matchtag, $tagname)) {
529
+ foreach ($matchattrs as $matchattr) {
530
+ if (preg_match($matchattr, $attname)) {
531
+ unset($attary{$attname});
532
+ continue;
533
+ }
534
+ }
535
+ }
536
+ }
537
+ /**
538
+ * Remove any backslashes, entities, or extraneous whitespace.
539
+ */
540
+ $oldattvalue = $attvalue;
541
+ tln_defang($attvalue);
542
+ if ($attname == 'style' && $attvalue !== $oldattvalue) {
543
+ $attvalue = "idiocy";
544
+ $attary{$attname} = $attvalue;
545
+ }
546
+ tln_unspace($attvalue);
547
+
548
+ /**
549
+ * Now let's run checks on the attvalues.
550
+ * I don't expect anyone to comprehend this. If you do,
551
+ * get in touch with me so I can drive to where you live and
552
+ * shake your hand personally. :)
553
+ */
554
+ foreach ($bad_attvals as $matchtag => $matchattrs) {
555
+ if (preg_match($matchtag, $tagname)) {
556
+ foreach ($matchattrs as $matchattr => $valary) {
557
+ if (preg_match($matchattr, $attname)) {
558
+ /**
559
+ * There are two arrays in valary.
560
+ * First is matches.
561
+ * Second one is replacements
562
+ */
563
+ list($valmatch, $valrepl) = $valary;
564
+ $newvalue = preg_replace($valmatch, $valrepl, $attvalue);
565
+ if ($newvalue != $attvalue) {
566
+ $attary{$attname} = $newvalue;
567
+ $attvalue = $newvalue;
568
+ }
569
+ }
570
+ }
571
+ }
572
+ }
573
+ if ($attname == 'style') {
574
+ if (preg_match('/[\0-\37\200-\377]+/', $attvalue)) {
575
+ $attary{$attname} = '"disallowed character"';
576
+ }
577
+ preg_match_all("/url\s*\((.+)\)/si", $attvalue, $aMatch);
578
+ if (count($aMatch)) {
579
+ foreach($aMatch[1] as $sMatch) {
580
+ $urlvalue = $sMatch;
581
+ tln_fixurl($attname, $urlvalue, $trans_image_path, $block_external_images);
582
+ $attary{$attname} = str_replace($sMatch, $urlvalue, $attvalue);
583
+ }
584
+ }
585
+ }
586
+ }
587
+ /**
588
+ * See if we need to append any attributes to this tag.
589
+ */
590
+ foreach ($add_attr_to_tag as $matchtag => $addattary) {
591
+ if (preg_match($matchtag, $tagname)) {
592
+ $attary = array_merge($attary, $addattary);
593
+ }
594
+ }
595
+ return $attary;
596
+ }
597
+
598
+ function tln_fixurl($attname, &$attvalue, $trans_image_path, $block_external_images)
599
+ {
600
+ $sQuote = '"';
601
+ $attvalue = trim($attvalue);
602
+ if ($attvalue && ($attvalue[0] =='"'|| $attvalue[0] == "'")) {
603
+ // remove the double quotes
604
+ $sQuote = $attvalue[0];
605
+ $attvalue = trim(substr($attvalue,1,-1));
606
+ }
607
+
608
+ /**
609
+ * Replace empty src tags with the blank image. src is only used
610
+ * for frames, images, and image inputs. Doing a replace should
611
+ * not affect them working as should be, however it will stop
612
+ * IE from being kicked off when src for img tags are not set
613
+ */
614
+ if ($attvalue == '') {
615
+ $attvalue = $sQuote . $trans_image_path . $sQuote;
616
+ } else {
617
+ // first, disallow 8 bit characters and control characters
618
+ if (preg_match('/[\0-\37\200-\377]+/',$attvalue)) {
619
+ switch ($attname) {
620
+ case 'href':
621
+ $attvalue = $sQuote . 'http://invalid-stuff-detected.example.com' . $sQuote;
622
+ break;
623
+ default:
624
+ $attvalue = $sQuote . $trans_image_path . $sQuote;
625
+ break;
626
+ }
627
+ } else {
628
+ $aUrl = parse_url($attvalue);
629
+ if (isset($aUrl['scheme'])) {
630
+ switch(strtolower($aUrl['scheme'])) {
631
+ case 'mailto':
632
+ case 'http':
633
+ case 'https':
634
+ case 'ftp':
635
+ if ($attname != 'href') {
636
+ if ($block_external_images == true) {
637
+ $attvalue = $sQuote . $trans_image_path . $sQuote;
638
+ } else {
639
+ if (!isset($aUrl['path'])) {
640
+ $attvalue = $sQuote . $trans_image_path . $sQuote;
641
+ }
642
+ }
643
+ } else {
644
+ $attvalue = $sQuote . $attvalue . $sQuote;
645
+ }
646
+ break;
647
+ case 'outbind':
648
+ $attvalue = $sQuote . $attvalue . $sQuote;
649
+ break;
650
+ case 'cid':
651
+ $attvalue = $sQuote . $attvalue . $sQuote;
652
+ break;
653
+ default:
654
+ $attvalue = $sQuote . $trans_image_path . $sQuote;
655
+ break;
656
+ }
657
+ } else {
658
+ if (!isset($aUrl['path']) || $aUrl['path'] != $trans_image_path) {
659
+ $$attvalue = $sQuote . $trans_image_path . $sQuote;
660
+ }
661
+ }
662
+ }
663
+ }
664
+ }
665
+
666
+ function tln_fixstyle($body, $pos, $trans_image_path, $block_external_images)
667
+ {
668
+ // workaround for </style> in between comments
669
+ $content = '';
670
+ $sToken = '';
671
+ $bSucces = false;
672
+ $bEndTag = false;
673
+ for ($i=$pos,$iCount=strlen($body);$i<$iCount;++$i) {
674
+ $char = $body{$i};
675
+ switch ($char) {
676
+ case '<':
677
+ $sToken = $char;
678
+ break;
679
+ case '/':
680
+ if ($sToken == '<') {
681
+ $sToken .= $char;
682
+ $bEndTag = true;
683
+ } else {
684
+ $content .= $char;
685
+ }
686
+ break;
687
+ case '>':
688
+ if ($bEndTag) {
689
+ $sToken .= $char;
690
+ if (preg_match('/\<\/\s*style\s*\>/i',$sToken,$aMatch)) {
691
+ $newpos = $i + 1;
692
+ $bSucces = true;
693
+ break 2;
694
+ } else {
695
+ $content .= $sToken;
696
+ }
697
+ $bEndTag = false;
698
+ } else {
699
+ $content .= $char;
700
+ }
701
+ break;
702
+ case '!':
703
+ if ($sToken == '<') {
704
+ // possible comment
705
+ if (isset($body{$i+2}) && substr($body,$i,3) == '!--') {
706
+ $i = strpos($body,'-->',$i+3);
707
+ if ($i === false) { // no end comment
708
+ $i = strlen($body);
709
+ }
710
+ $sToken = '';
711
+ }
712
+ } else {
713
+ $content .= $char;
714
+ }
715
+ break;
716
+ default:
717
+ if ($bEndTag) {
718
+ $sToken .= $char;
719
+ } else {
720
+ $content .= $char;
721
+ }
722
+ break;
723
+ }
724
+ }
725
+ if ($bSucces == FALSE){
726
+ return array(FALSE, strlen($body));
727
+ }
728
+
729
+
730
+
731
+ /**
732
+ * First look for general BODY style declaration, which would be
733
+ * like so:
734
+ * body {background: blah-blah}
735
+ * and change it to .bodyclass so we can just assign it to a <div>
736
+ */
737
+ $content = preg_replace("|body(\s*\{.*?\})|si", ".bodyclass\\1", $content);
738
+
739
+ /**
740
+ * Fix url('blah') declarations.
741
+ */
742
+ // $content = preg_replace("|url\s*\(\s*([\'\"])\s*\S+script\s*:.*?([\'\"])\s*\)|si",
743
+ // "url(\\1$trans_image_path\\2)", $content);
744
+
745
+ // first check for 8bit sequences and disallowed control characters
746
+ if (preg_match('/[\16-\37\200-\377]+/',$content)) {
747
+ $content = '<!-- style block removed by html filter due to presence of 8bit characters -->';
748
+ return array($content, $newpos);
749
+ }
750
+
751
+ // remove @import line
752
+ $content = preg_replace("/^\s*(@import.*)$/mi","\n<!-- @import rules forbidden -->\n",$content);
753
+
754
+ $content = preg_replace("/(\\\\)?u(\\\\)?r(\\\\)?l(\\\\)?/i", 'url', $content);
755
+ preg_match_all("/url\s*\((.+)\)/si",$content,$aMatch);
756
+ if (count($aMatch)) {
757
+ $aValue = $aReplace = array();
758
+ foreach($aMatch[1] as $sMatch) {
759
+ // url value
760
+ $urlvalue = $sMatch;
761
+ tln_fixurl('style',$urlvalue, $trans_image_path, $block_external_images);
762
+ $aValue[] = $sMatch;
763
+ $aReplace[] = $urlvalue;
764
+ }
765
+ $content = str_replace($aValue,$aReplace,$content);
766
+ }
767
+
768
+ /**
769
+ * Remove any backslashes, entities, and extraneous whitespace.
770
+ */
771
+ $contentTemp = $content;
772
+ tln_defang($contentTemp);
773
+ tln_unspace($contentTemp);
774
+
775
+ $match = array('/\/\*.*\*\//',
776
+ '/expression/i',
777
+ '/behaviou*r/i',
778
+ '/binding/i',
779
+ '/include-source/i',
780
+ '/javascript/i',
781
+ '/script/i',
782
+ '/position/i');
783
+ $replace = array('','idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', '');
784
+ $contentNew = preg_replace($match, $replace, $contentTemp);
785
+ if ($contentNew !== $contentTemp) {
786
+ $content = $contentNew;
787
+ }
788
+ return array($content, $newpos);
789
+ }
790
+
791
+ function tln_body2div($attary, $trans_image_path)
792
+ {
793
+ $divattary = array('class' => "'bodyclass'");
794
+ $text = '#000000';
795
+ $has_bgc_stl = $has_txt_stl = false;
796
+ $styledef = '';
797
+ if (is_array($attary) && sizeof($attary) > 0){
798
+ foreach ($attary as $attname=>$attvalue){
799
+ $quotchar = substr($attvalue, 0, 1);
800
+ $attvalue = str_replace($quotchar, "", $attvalue);
801
+ switch ($attname){
802
+ case 'background':
803
+ $styledef .= "background-image: url('$trans_image_path'); ";
804
+ break;
805
+ case 'bgcolor':
806
+ $has_bgc_stl = true;
807
+ $styledef .= "background-color: $attvalue; ";
808
+ break;
809
+ case 'text':
810
+ $has_txt_stl = true;
811
+ $styledef .= "color: $attvalue; ";
812
+ break;
813
+ }
814
+ }
815
+ // Outlook defines a white bgcolor and no text color. This can lead to
816
+ // white text on a white bg with certain themes.
817
+ if ($has_bgc_stl && !$has_txt_stl) {
818
+ $styledef .= "color: $text; ";
819
+ }
820
+ if (strlen($styledef) > 0){
821
+ $divattary{"style"} = "\"$styledef\"";
822
+ }
823
+ }
824
+ return $divattary;
825
  }
826
 
827
  /**
828
  *
829
+ * @param string $body The HTML you wish to filter
830
+ * @param array $tag_list see description above
831
+ * @param array $rm_tags_with_content see description above
832
+ * @param array $self_closing_tags see description above
833
+ * @param boolean $force_tag_closing see description above
834
+ * @param array $rm_attnames see description above
835
+ * @param array $bad_attvals see description above
836
+ * @param array $add_attr_to_tag see description above
837
+ * @param string $trans_image_path
838
+ * @param boolean $block_external_images
839
+
840
+ * @return string Sanitized html safe to show on your pages.
841
  */
842
+ function tln_sanitize(
843
+ $body,
844
+ $tag_list,
845
+ $rm_tags_with_content,
846
+ $self_closing_tags,
847
+ $force_tag_closing,
848
+ $rm_attnames,
849
+ $bad_attvals,
850
+ $add_attr_to_tag,
851
+ $trans_image_path,
852
+ $block_external_images
853
+ ) {
854
+ /**
855
+ * Normalize rm_tags and rm_tags_with_content.
856
+ */
857
+ $rm_tags = array_shift($tag_list);
858
+ @array_walk($tag_list, 'tln_casenormalize');
859
+ @array_walk($rm_tags_with_content, 'tln_casenormalize');
860
+ @array_walk($self_closing_tags, 'tln_casenormalize');
861
+ /**
862
+ * See if tag_list is of tags to remove or tags to allow.
863
+ * false means remove these tags
864
+ * true means allow these tags
865
+ */
866
+ $curpos = 0;
867
+ $open_tags = array();
868
+ $trusted = "<!-- begin tln_sanitized html -->\n";
869
+ $skip_content = false;
870
+ /**
871
+ * Take care of netscape's stupid javascript entities like
872
+ * &{alert('boo')};
873
+ */
874
+ $body = preg_replace('/&(\{.*?\};)/si', '&amp;\\1', $body);
875
+ while (($curtag = tln_getnxtag($body, $curpos)) != false) {
876
+ list($tagname, $attary, $tagtype, $lt, $gt) = $curtag;
877
+ $free_content = substr($body, $curpos, $lt-$curpos);
878
+ /**
879
+ * Take care of <style>
880
+ */
881
+ if ($tagname == "style" && $tagtype == 1){
882
+ list($free_content, $curpos) =
883
+ tln_fixstyle($body, $gt+1, $trans_image_path, $block_external_images);
884
+ if ($free_content != FALSE){
885
+ if ( !empty($attary) ) {
886
+ $attary = tln_fixatts($tagname,
887
+ $attary,
888
+ $rm_attnames,
889
+ $bad_attvals,
890
+ $add_attr_to_tag,
891
+ $trans_image_path,
892
+ $block_external_images
893
+ );
894
+ }
895
+ $trusted .= tln_tagprint($tagname, $attary, $tagtype);
896
+ $trusted .= $free_content;
897
+ $trusted .= tln_tagprint($tagname, null, 2);
898
+ }
899
+ continue;
900
+ }
901
+ if ($skip_content == false){
902
+ $trusted .= $free_content;
903
+ }
904
+ if ($tagname != false) {
905
+ if ($tagtype == 2) {
906
+ if ($skip_content == $tagname) {
907
+ /**
908
+ * Got to the end of tag we needed to remove.
909
+ */
910
+ $tagname = false;
911
+ $skip_content = false;
912
+ } else {
913
+ if ($skip_content == false) {
914
+ if ($tagname == "body") {
915
+ $tagname = "div";
916
+ }
917
+ if (isset($open_tags{$tagname}) &&
918
+ $open_tags{$tagname} > 0
919
+ ) {
920
+ $open_tags{$tagname}--;
921
+ } else {
922
+ $tagname = false;
923
+ }
924
+ }
925
+ }
926
+ } else {
927
+ /**
928
+ * $rm_tags_with_content
929
+ */
930
+ if ($skip_content == false) {
931
+ /**
932
+ * See if this is a self-closing type and change
933
+ * tagtype appropriately.
934
+ */
935
+ if ($tagtype == 1
936
+ && in_array($tagname, $self_closing_tags)
937
+ ) {
938
+ $tagtype = 3;
939
+ }
940
+ /**
941
+ * See if we should skip this tag and any content
942
+ * inside it.
943
+ */
944
+ if ($tagtype == 1
945
+ && in_array($tagname, $rm_tags_with_content)
946
+ ) {
947
+ $skip_content = $tagname;
948
+ } else {
949
+ if (($rm_tags == false
950
+ && in_array($tagname, $tag_list)) ||
951
+ ($rm_tags == true
952
+ && !in_array($tagname, $tag_list))
953
+ ) {
954
+ $tagname = false;
955
+ } else {
956
+ /**
957
+ * Convert body into div.
958
+ */
959
+ if ($tagname == "body"){
960
+ $tagname = "div";
961
+ $attary = tln_body2div($attary, $trans_image_path);
962
+ }
963
+ if ($tagtype == 1) {
964
+ if (isset($open_tags{$tagname})) {
965
+ $open_tags{$tagname}++;
966
+ } else {
967
+ $open_tags{$tagname} = 1;
968
+ }
969
+ }
970
+ /**
971
+ * This is where we run other checks.
972
+ */
973
+ if (is_array($attary) && sizeof($attary) > 0) {
974
+ $attary = tln_fixatts(
975
+ $tagname,
976
+ $attary,
977
+ $rm_attnames,
978
+ $bad_attvals,
979
+ $add_attr_to_tag,
980
+ $trans_image_path,
981
+ $block_external_images
982
+ );
983
+ }
984
+ }
985
+ }
986
+ }
987
+ }
988
+ if ($tagname != false && $skip_content == false) {
989
+ $trusted .= tln_tagprint($tagname, $attary, $tagtype);
990
+ }
991
+ }
992
+ $curpos = $gt + 1;
993
+ }
994
+ $trusted .= substr($body, $curpos, strlen($body) - $curpos);
995
+ if ($force_tag_closing == true) {
996
+ foreach ($open_tags as $tagname => $opentimes) {
997
+ while ($opentimes > 0) {
998
+ $trusted .= '</' . $tagname . '>';
999
+ $opentimes--;
1000
+ }
1001
+ }
1002
+ $trusted .= "\n";
1003
+ }
1004
+ $trusted .= "<!-- end tln_sanitized html -->\n";
1005
+ return $trusted;
1006
  }
1007
 
1008
+ //
1009
  // Use the nifty htmlfilter library
1010
  //
1011
 
1012
 
1013
+ function HTMLFilter($body, $trans_image_path, $block_external_images = false)
1014
+ {
1015
+
1016
+ $tag_list = array(
1017
+ false,
1018
+ "object",
1019
+ "meta",
1020
+ "html",
1021
+ "head",
1022
+ "base",
1023
+ "link",
1024
+ "frame",
1025
+ "iframe",
1026
+ "plaintext",
1027
+ "marquee"
1028
+ );
1029
+
1030
+ $rm_tags_with_content = array(
1031
+ "script",
1032
+ "applet",
1033
+ "embed",
1034
+ "title",
1035
+ "frameset",
1036
+ "xmp",
1037
+ "xml"
1038
+ );
1039
+
1040
+ $self_closing_tags = array(
1041
+ "img",
1042
+ "br",
1043
+ "hr",
1044
+ "input",
1045
+ "outbind"
1046
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1047
 
1048
+ $force_tag_closing = true;
1049
+
1050
+ $rm_attnames = array(
1051
+ "/.*/" =>
1052
+ array(
1053
+ // "/target/i",
1054
+ "/^on.*/i",
1055
+ "/^dynsrc/i",
1056
+ "/^data.*/i",
1057
+ "/^lowsrc.*/i"
1058
+ )
1059
+ );
1060
+
1061
+ $bad_attvals = array(
1062
+ "/.*/" =>
1063
+ array(
1064
+ "/^src|background/i" =>
1065
+ array(
1066
+ array(
1067
+ '/^([\'"])\s*\S+script\s*:.*([\'"])/si',
1068
+ '/^([\'"])\s*mocha\s*:*.*([\'"])/si',
1069
+ '/^([\'"])\s*about\s*:.*([\'"])/si'
1070
+ ),
1071
+ array(
1072
+ "\\1$trans_image_path\\2",
1073
+ "\\1$trans_image_path\\2",
1074
+ "\\1$trans_image_path\\2"
1075
+ )
1076
+ ),
1077
+ "/^href|action/i" =>
1078
+ array(
1079
+ array(
1080
+ '/^([\'"])\s*\S+script\s*:.*([\'"])/si',
1081
+ '/^([\'"])\s*mocha\s*:*.*([\'"])/si',
1082
+ '/^([\'"])\s*about\s*:.*([\'"])/si'
1083
+ ),
1084
+ array(
1085
+ "\\1#\\1",
1086
+ "\\1#\\1",
1087
+ "\\1#\\1"
1088
+ )
1089
+ ),
1090
+ "/^style/i" =>
1091
+ array(
1092
+ array(
1093
+ "/\/\*.*\*\//",
1094
+ "/expression/i",
1095
+ "/binding/i",
1096
+ "/behaviou*r/i",
1097
+ "/include-source/i",
1098
+ '/position\s*:/i',
1099
+ '/(\\\\)?u(\\\\)?r(\\\\)?l(\\\\)?/i',
1100
+ '/url\s*\(\s*([\'"])\s*\S+script\s*:.*([\'"])\s*\)/si',
1101
+ '/url\s*\(\s*([\'"])\s*mocha\s*:.*([\'"])\s*\)/si',
1102
+ '/url\s*\(\s*([\'"])\s*about\s*:.*([\'"])\s*\)/si',
1103
+ '/(.*)\s*:\s*url\s*\(\s*([\'"]*)\s*\S+script\s*:.*([\'"]*)\s*\)/si'
1104
+ ),
1105
+ array(
1106
+ "",
1107
+ "idiocy",
1108
+ "idiocy",
1109
+ "idiocy",
1110
+ "idiocy",
1111
+ "idiocy",
1112
+ "url",
1113
+ "url(\\1#\\1)",
1114
+ "url(\\1#\\1)",
1115
+ "url(\\1#\\1)",
1116
+ "\\1:url(\\2#\\3)"
1117
+ )
1118
+ )
1119
+ )
1120
+ );
1121
+
1122
+ if ($block_external_images) {
1123
+ array_push(
1124
+ $bad_attvals{'/.*/'}{'/^src|background/i'}[0],
1125
+ '/^([\'\"])\s*https*:.*([\'\"])/si'
1126
+ );
1127
+ array_push(
1128
+ $bad_attvals{'/.*/'}{'/^src|background/i'}[1],
1129
+ "\\1$trans_image_path\\1"
1130
+ );
1131
+ array_push(
1132
+ $bad_attvals{'/.*/'}{'/^style/i'}[0],
1133
+ '/url\(([\'\"])\s*https*:.*([\'\"])\)/si'
1134
+ );
1135
+ array_push(
1136
+ $bad_attvals{'/.*/'}{'/^style/i'}[1],
1137
+ "url(\\1$trans_image_path\\1)"
1138
+ );
1139
+ }
1140
+
1141
+ $add_attr_to_tag = array(
1142
+ "/^a$/i" =>
1143
+ array('target' => '"_blank"')
1144
+ );
1145
+
1146
+ $trusted = tln_sanitize(
1147
+ $body,
1148
+ $tag_list,
1149
+ $rm_tags_with_content,
1150
+ $self_closing_tags,
1151
+ $force_tag_closing,
1152
+ $rm_attnames,
1153
+ $bad_attvals,
1154
+ $add_attr_to_tag,
1155
+ $trans_image_path,
1156
+ $block_external_images
1157
+ );
1158
+ return $trusted;
1159
+ }
phpmailer/extras/ntlm_sasl_client.php CHANGED
@@ -4,182 +4,182 @@
4
  *
5
  * @(#) $Id: ntlm_sasl_client.php,v 1.3 2004/11/17 08:00:37 mlemos Exp $
6
  *
7
- **
8
- ** Source: http://www.phpclasses.org/browse/file/7495.html
9
- ** License: BSD (http://www.phpclasses.org/package/1888-PHP-Single-API-for-standard-authentication-mechanisms.html)
10
- ** Bundled with Permission
11
- **
12
  */
13
 
14
- define("SASL_NTLM_STATE_START", 0);
15
- define("SASL_NTLM_STATE_IDENTIFY_DOMAIN", 1);
16
  define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
17
- define("SASL_NTLM_STATE_DONE", 3);
 
 
18
 
19
  class ntlm_sasl_client_class
20
  {
21
- var $credentials=array();
22
- var $state=SASL_NTLM_STATE_START;
23
 
24
- Function Initialize(&$client)
25
- {
26
- if(!function_exists($function="mcrypt_encrypt")
27
- || !function_exists($function="mhash"))
28
- {
29
- $extensions=array(
30
- "mcrypt_encrypt"=>"mcrypt",
31
- "mhash"=>"mhash"
32
- );
33
- $client->error="the extension ".$extensions[$function]." required by the NTLM SASL client class is not available in this PHP configuration";
34
- return(0);
35
- }
36
- return(1);
37
- }
 
38
 
39
- Function ASCIIToUnicode($ascii)
40
- {
41
- for($unicode="",$a=0;$a<strlen($ascii);$a++)
42
- $unicode.=substr($ascii,$a,1).chr(0);
43
- return($unicode);
44
- }
 
45
 
46
- Function TypeMsg1($domain,$workstation)
47
- {
48
- $domain_length=strlen($domain);
49
- $workstation_length=strlen($workstation);
50
- $workstation_offset=32;
51
- $domain_offset=$workstation_offset+$workstation_length;
52
- return(
53
- "NTLMSSP\0".
54
- "\x01\x00\x00\x00".
55
- "\x07\x32\x00\x00".
56
- pack("v",$domain_length).
57
- pack("v",$domain_length).
58
- pack("V",$domain_offset).
59
- pack("v",$workstation_length).
60
- pack("v",$workstation_length).
61
- pack("V",$workstation_offset).
62
- $workstation.
63
- $domain
64
- );
65
- }
66
 
67
- Function NTLMResponse($challenge,$password)
68
- {
69
- $unicode=$this->ASCIIToUnicode($password);
70
- $md4=mhash(MHASH_MD4,$unicode);
71
- $padded=$md4.str_repeat(chr(0),21-strlen($md4));
72
- $iv_size=mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB);
73
- $iv=mcrypt_create_iv($iv_size,MCRYPT_RAND);
74
- for($response="",$third=0;$third<21;$third+=7)
75
- {
76
- for($packed="",$p=$third;$p<$third+7;$p++)
77
- $packed.=str_pad(decbin(ord(substr($padded,$p,1))),8,"0",STR_PAD_LEFT);
78
- for($key="",$p=0;$p<strlen($packed);$p+=7)
79
- {
80
- $s=substr($packed,$p,7);
81
- $b=$s.((substr_count($s,"1") % 2) ? "0" : "1");
82
- $key.=chr(bindec($b));
83
- }
84
- $ciphertext=mcrypt_encrypt(MCRYPT_DES,$key,$challenge,MCRYPT_MODE_ECB,$iv);
85
- $response.=$ciphertext;
86
- }
87
- return $response;
88
- }
89
 
90
- Function TypeMsg3($ntlm_response,$user,$domain,$workstation)
91
- {
92
- $domain_unicode=$this->ASCIIToUnicode($domain);
93
- $domain_length=strlen($domain_unicode);
94
- $domain_offset=64;
95
- $user_unicode=$this->ASCIIToUnicode($user);
96
- $user_length=strlen($user_unicode);
97
- $user_offset=$domain_offset+$domain_length;
98
- $workstation_unicode=$this->ASCIIToUnicode($workstation);
99
- $workstation_length=strlen($workstation_unicode);
100
- $workstation_offset=$user_offset+$user_length;
101
- $lm="";
102
- $lm_length=strlen($lm);
103
- $lm_offset=$workstation_offset+$workstation_length;
104
- $ntlm=$ntlm_response;
105
- $ntlm_length=strlen($ntlm);
106
- $ntlm_offset=$lm_offset+$lm_length;
107
- $session="";
108
- $session_length=strlen($session);
109
- $session_offset=$ntlm_offset+$ntlm_length;
110
- return(
111
- "NTLMSSP\0".
112
- "\x03\x00\x00\x00".
113
- pack("v",$lm_length).
114
- pack("v",$lm_length).
115
- pack("V",$lm_offset).
116
- pack("v",$ntlm_length).
117
- pack("v",$ntlm_length).
118
- pack("V",$ntlm_offset).
119
- pack("v",$domain_length).
120
- pack("v",$domain_length).
121
- pack("V",$domain_offset).
122
- pack("v",$user_length).
123
- pack("v",$user_length).
124
- pack("V",$user_offset).
125
- pack("v",$workstation_length).
126
- pack("v",$workstation_length).
127
- pack("V",$workstation_offset).
128
- pack("v",$session_length).
129
- pack("v",$session_length).
130
- pack("V",$session_offset).
131
- "\x01\x02\x00\x00".
132
- $domain_unicode.
133
- $user_unicode.
134
- $workstation_unicode.
135
- $lm.
136
- $ntlm
137
- );
138
- }
139
 
140
- Function Start(&$client, &$message, &$interactions)
141
- {
142
- if($this->state!=SASL_NTLM_STATE_START)
143
- {
144
- $client->error="NTLM authentication state is not at the start";
145
- return(SASL_FAIL);
146
- }
147
- $this->credentials=array(
148
- "user"=>"",
149
- "password"=>"",
150
- "realm"=>"",
151
- "workstation"=>""
152
- );
153
- $defaults=array();
154
- $status=$client->GetCredentials($this->credentials,$defaults,$interactions);
155
- if($status==SASL_CONTINUE)
156
- $this->state=SASL_NTLM_STATE_IDENTIFY_DOMAIN;
157
- Unset($message);
158
- return($status);
159
- }
160
 
161
- Function Step(&$client, $response, &$message, &$interactions)
162
- {
163
- switch($this->state)
164
- {
165
- case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
166
- $message=$this->TypeMsg1($this->credentials["realm"],$this->credentials["workstation"]);
167
- $this->state=SASL_NTLM_STATE_RESPOND_CHALLENGE;
168
- break;
169
- case SASL_NTLM_STATE_RESPOND_CHALLENGE:
170
- $ntlm_response=$this->NTLMResponse(substr($response,24,8),$this->credentials["password"]);
171
- $message=$this->TypeMsg3($ntlm_response,$this->credentials["user"],$this->credentials["realm"],$this->credentials["workstation"]);
172
- $this->state=SASL_NTLM_STATE_DONE;
173
- break;
174
- case SASL_NTLM_STATE_DONE:
175
- $client->error="NTLM authentication was finished without success";
176
- return(SASL_FAIL);
177
- default:
178
- $client->error="invalid NTLM authentication step state";
179
- return(SASL_FAIL);
180
- }
181
- return(SASL_CONTINUE);
182
- }
183
- };
184
-
185
- ?>
 
 
4
  *
5
  * @(#) $Id: ntlm_sasl_client.php,v 1.3 2004/11/17 08:00:37 mlemos Exp $
6
  *
 
 
 
 
 
7
  */
8
 
9
+ define("SASL_NTLM_STATE_START", 0);
10
+ define("SASL_NTLM_STATE_IDENTIFY_DOMAIN", 1);
11
  define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
12
+ define("SASL_NTLM_STATE_DONE", 3);
13
+ define("SASL_FAIL", -1);
14
+ define("SASL_CONTINUE", 1);
15
 
16
  class ntlm_sasl_client_class
17
  {
18
+ public $credentials = array();
19
+ public $state = SASL_NTLM_STATE_START;
20
 
21
+ public function initialize(&$client)
22
+ {
23
+ if (!function_exists($function = "mcrypt_encrypt")
24
+ || !function_exists($function = "mhash")
25
+ ) {
26
+ $extensions = array(
27
+ "mcrypt_encrypt" => "mcrypt",
28
+ "mhash" => "mhash"
29
+ );
30
+ $client->error = "the extension " . $extensions[$function] .
31
+ " required by the NTLM SASL client class is not available in this PHP configuration";
32
+ return (0);
33
+ }
34
+ return (1);
35
+ }
36
 
37
+ public function ASCIIToUnicode($ascii)
38
+ {
39
+ for ($unicode = "", $a = 0; $a < strlen($ascii); $a++) {
40
+ $unicode .= substr($ascii, $a, 1) . chr(0);
41
+ }
42
+ return ($unicode);
43
+ }
44
 
45
+ public function typeMsg1($domain, $workstation)
46
+ {
47
+ $domain_length = strlen($domain);
48
+ $workstation_length = strlen($workstation);
49
+ $workstation_offset = 32;
50
+ $domain_offset = $workstation_offset + $workstation_length;
51
+ return (
52
+ "NTLMSSP\0" .
53
+ "\x01\x00\x00\x00" .
54
+ "\x07\x32\x00\x00" .
55
+ pack("v", $domain_length) .
56
+ pack("v", $domain_length) .
57
+ pack("V", $domain_offset) .
58
+ pack("v", $workstation_length) .
59
+ pack("v", $workstation_length) .
60
+ pack("V", $workstation_offset) .
61
+ $workstation .
62
+ $domain
63
+ );
64
+ }
65
 
66
+ public function NTLMResponse($challenge, $password)
67
+ {
68
+ $unicode = $this->ASCIIToUnicode($password);
69
+ $md4 = mhash(MHASH_MD4, $unicode);
70
+ $padded = $md4 . str_repeat(chr(0), 21 - strlen($md4));
71
+ $iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
72
+ $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
73
+ for ($response = "", $third = 0; $third < 21; $third += 7) {
74
+ for ($packed = "", $p = $third; $p < $third + 7; $p++) {
75
+ $packed .= str_pad(decbin(ord(substr($padded, $p, 1))), 8, "0", STR_PAD_LEFT);
76
+ }
77
+ for ($key = "", $p = 0; $p < strlen($packed); $p += 7) {
78
+ $s = substr($packed, $p, 7);
79
+ $b = $s . ((substr_count($s, "1") % 2) ? "0" : "1");
80
+ $key .= chr(bindec($b));
81
+ }
82
+ $ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $challenge, MCRYPT_MODE_ECB, $iv);
83
+ $response .= $ciphertext;
84
+ }
85
+ return $response;
86
+ }
 
87
 
88
+ public function typeMsg3($ntlm_response, $user, $domain, $workstation)
89
+ {
90
+ $domain_unicode = $this->ASCIIToUnicode($domain);
91
+ $domain_length = strlen($domain_unicode);
92
+ $domain_offset = 64;
93
+ $user_unicode = $this->ASCIIToUnicode($user);
94
+ $user_length = strlen($user_unicode);
95
+ $user_offset = $domain_offset + $domain_length;
96
+ $workstation_unicode = $this->ASCIIToUnicode($workstation);
97
+ $workstation_length = strlen($workstation_unicode);
98
+ $workstation_offset = $user_offset + $user_length;
99
+ $lm = "";
100
+ $lm_length = strlen($lm);
101
+ $lm_offset = $workstation_offset + $workstation_length;
102
+ $ntlm = $ntlm_response;
103
+ $ntlm_length = strlen($ntlm);
104
+ $ntlm_offset = $lm_offset + $lm_length;
105
+ $session = "";
106
+ $session_length = strlen($session);
107
+ $session_offset = $ntlm_offset + $ntlm_length;
108
+ return (
109
+ "NTLMSSP\0" .
110
+ "\x03\x00\x00\x00" .
111
+ pack("v", $lm_length) .
112
+ pack("v", $lm_length) .
113
+ pack("V", $lm_offset) .
114
+ pack("v", $ntlm_length) .
115
+ pack("v", $ntlm_length) .
116
+ pack("V", $ntlm_offset) .
117
+ pack("v", $domain_length) .
118
+ pack("v", $domain_length) .
119
+ pack("V", $domain_offset) .
120
+ pack("v", $user_length) .
121
+ pack("v", $user_length) .
122
+ pack("V", $user_offset) .
123
+ pack("v", $workstation_length) .
124
+ pack("v", $workstation_length) .
125
+ pack("V", $workstation_offset) .
126
+ pack("v", $session_length) .
127
+ pack("v", $session_length) .
128
+ pack("V", $session_offset) .
129
+ "\x01\x02\x00\x00" .
130
+ $domain_unicode .
131
+ $user_unicode .
132
+ $workstation_unicode .
133
+ $lm .
134
+ $ntlm
135
+ );
136
+ }
137
 
138
+ public function start(&$client, &$message, &$interactions)
139
+ {
140
+ if ($this->state != SASL_NTLM_STATE_START) {
141
+ $client->error = "NTLM authentication state is not at the start";
142
+ return (SASL_FAIL);
143
+ }
144
+ $this->credentials = array(
145
+ "user" => "",
146
+ "password" => "",
147
+ "realm" => "",
148
+ "workstation" => ""
149
+ );
150
+ $defaults = array();
151
+ $status = $client->GetCredentials($this->credentials, $defaults, $interactions);
152
+ if ($status == SASL_CONTINUE) {
153
+ $this->state = SASL_NTLM_STATE_IDENTIFY_DOMAIN;
154
+ }
155
+ unset($message);
156
+ return ($status);
157
+ }
158
 
159
+ public function step(&$client, $response, &$message, &$interactions)
160
+ {
161
+ switch ($this->state) {
162
+ case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
163
+ $message = $this->typeMsg1($this->credentials["realm"], $this->credentials["workstation"]);
164
+ $this->state = SASL_NTLM_STATE_RESPOND_CHALLENGE;
165
+ break;
166
+ case SASL_NTLM_STATE_RESPOND_CHALLENGE:
167
+ $ntlm_response = $this->NTLMResponse(substr($response, 24, 8), $this->credentials["password"]);
168
+ $message = $this->typeMsg3(
169
+ $ntlm_response,
170
+ $this->credentials["user"],
171
+ $this->credentials["realm"],
172
+ $this->credentials["workstation"]
173
+ );
174
+ $this->state = SASL_NTLM_STATE_DONE;
175
+ break;
176
+ case SASL_NTLM_STATE_DONE:
177
+ $client->error = "NTLM authentication was finished without success";
178
+ return (SASL_FAIL);
179
+ default:
180
+ $client->error = "invalid NTLM authentication step state";
181
+ return (SASL_FAIL);
182
+ }
183
+ return (SASL_CONTINUE);
184
+ }
185
+ }
phpmailer/get_oauth_token.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Get an OAuth2 token from Google.
4
+ * * Install this script on your server so that it's accessible
5
+ * as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
6
+ * e.g.: http://localhost/phpmail/get_oauth_token.php
7
+ * * Ensure dependencies are installed with 'composer install'
8
+ * * Set up an app in your Google developer console
9
+ * * Set the script address as the app's redirect URL
10
+ * If no refresh token is obtained when running this file, revoke access to your app
11
+ * using link: https://accounts.google.com/b/0/IssuedAuthSubTokens and run the script again.
12
+ * This script requires PHP 5.4 or later
13
+ * PHP Version 5.4
14
+ */
15
+
16
+ namespace League\OAuth2\Client\Provider;
17
+
18
+ require 'vendor/autoload.php';
19
+
20
+ use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
21
+ use League\OAuth2\Client\Token\AccessToken;
22
+ use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
23
+ use Psr\Http\Message\ResponseInterface;
24
+
25
+ session_start();
26
+
27
+ //If this automatic URL doesn't work, set it yourself manually
28
+ $redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
29
+ //$redirectUri = 'http://localhost/phpmailer/get_oauth_token.php';
30
+
31
+ //These details obtained are by setting up app in Google developer console.
32
+ $clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';
33
+ $clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';
34
+
35
+ class Google extends AbstractProvider
36
+ {
37
+ use BearerAuthorizationTrait;
38
+
39
+ const ACCESS_TOKEN_RESOURCE_OWNER_ID = 'id';
40
+
41
+ /**
42
+ * @var string If set, this will be sent to google as the "access_type" parameter.
43
+ * @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline
44
+ */
45
+ protected $accessType;
46
+
47
+ /**
48
+ * @var string If set, this will be sent to google as the "hd" parameter.
49
+ * @link https://developers.google.com/accounts/docs/OAuth2Login#hd-param
50
+ */
51
+ protected $hostedDomain;
52
+
53
+ /**
54
+ * @var string If set, this will be sent to google as the "scope" parameter.
55
+ * @link https://developers.google.com/gmail/api/auth/scopes
56
+ */
57
+ protected $scope;
58
+
59
+ public function getBaseAuthorizationUrl()
60
+ {
61
+ return 'https://accounts.google.com/o/oauth2/auth';
62
+ }
63
+
64
+ public function getBaseAccessTokenUrl(array $params)
65
+ {
66
+ return 'https://accounts.google.com/o/oauth2/token';
67
+ }
68
+
69
+ public function getResourceOwnerDetailsUrl(AccessToken $token)
70
+ {
71
+ return ' ';
72
+ }
73
+
74
+ protected function getAuthorizationParameters(array $options)
75
+ {
76
+ if (is_array($this->scope)) {
77
+ $separator = $this->getScopeSeparator();
78
+ $this->scope = implode($separator, $this->scope);
79
+ }
80
+
81
+ $params = array_merge(
82
+ parent::getAuthorizationParameters($options),
83
+ array_filter([
84
+ 'hd' => $this->hostedDomain,
85
+ 'access_type' => $this->accessType,
86
+ 'scope' => $this->scope,
87
+ // if the user is logged in with more than one account ask which one to use for the login!
88
+ 'authuser' => '-1'
89
+ ])
90
+ );
91
+ return $params;
92
+ }
93
+
94
+ protected function getDefaultScopes()
95
+ {
96
+ return [
97
+ 'email',
98
+ 'openid',
99
+ 'profile',
100
+ ];
101
+ }
102
+
103
+ protected function getScopeSeparator()
104
+ {
105
+ return ' ';
106
+ }
107
+
108
+ protected function checkResponse(ResponseInterface $response, $data)
109
+ {
110
+ if (!empty($data['error'])) {
111
+ $code = 0;
112
+ $error = $data['error'];
113
+
114
+ if (is_array($error)) {
115
+ $code = $error['code'];
116
+ $error = $error['message'];
117
+ }
118
+
119
+ throw new IdentityProviderException($error, $code, $data);
120
+ }
121
+ }
122
+
123
+ protected function createResourceOwner(array $response, AccessToken $token)
124
+ {
125
+ return new GoogleUser($response);
126
+ }
127
+ }
128
+
129
+
130
+ //Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
131
+ $provider = new Google(
132
+ array(
133
+ 'clientId' => $clientId,
134
+ 'clientSecret' => $clientSecret,
135
+ 'redirectUri' => $redirectUri,
136
+ 'scope' => array('https://mail.google.com/'),
137
+ 'accessType' => 'offline'
138
+ )
139
+ );
140
+
141
+ if (!isset($_GET['code'])) {
142
+ // If we don't have an authorization code then get one
143
+ $authUrl = $provider->getAuthorizationUrl();
144
+ $_SESSION['oauth2state'] = $provider->getState();
145
+ header('Location: ' . $authUrl);
146
+ exit;
147
+ // Check given state against previously stored one to mitigate CSRF attack
148
+ } elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
149
+ unset($_SESSION['oauth2state']);
150
+ exit('Invalid state');
151
+ } else {
152
+ // Try to get an access token (using the authorization code grant)
153
+ $token = $provider->getAccessToken(
154
+ 'authorization_code',
155
+ array(
156
+ 'code' => $_GET['code']
157
+ )
158
+ );
159
+
160
+ // Use this to get a new access token if the old one expires
161
+ echo 'Refresh Token: ' . $token->getRefreshToken();
162
+ }
phpmailer/language/phpmailer.lang-am.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Armenian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Hrayr Grigoryan <hrayr@bits.am>
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['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'] = 'Հասցեն սխալ է: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' փոստային սերվերի հետ չի աշխատում.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Անհրաժեշտ է տրամադրել գոնե մեկ ստացողի e-mail հասցե.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP -ի սխալ: չի հաջողվել ուղարկել հետևյալ ստացողների հասցեներին: ';
22
+ $PHPMAILER_LANG['signing'] = 'Ստորագրման սխալ: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP -ի connect() ֆունկցիան չի հաջողվել';
24
+ $PHPMAILER_LANG['smtp_error'] = 'SMTP սերվերի սխալ: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Չի հաջողվում ստեղծել կամ վերափոխել փոփոխականը: ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'Հավելվածը բացակայում է: ';
phpmailer/language/phpmailer.lang-ar.php CHANGED
@@ -1,26 +1,27 @@
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: ';
 
1
  <?php
2
  /**
3
+ * Arabic PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author bahjat al mostafa <bahjat983@hotmail.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['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'] = 'الإرسال غير ممكن لأن عنوان البريد الإلكتروني غير صالح: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' برنامج الإرسال غير مدعوم.';
20
+ $PHPMAILER_LANG['provide_address'] = 'يجب توفير عنوان البريد الإلكتروني لمستلم واحد على الأقل.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'خطأ SMTP: الأخطاء التالية ' .
22
  'فشل في الارسال لكل من : ';
23
  $PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: ';
24
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() غير ممكن.';
25
+ $PHPMAILER_LANG['smtp_error'] = 'خطأ على مستوى الخادم SMTP: ';
26
+ $PHPMAILER_LANG['variable_set'] = 'لا يمكن تعيين أو إعادة تعيين متغير: ';
27
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-az.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Azerbaijani PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author @mirjalal
6
+ */
7
+
8
+ $PHPMAILER_LANG['authenticate'] = 'SMTP xətası: Giriş uğursuz oldu.';
9
+ $PHPMAILER_LANG['connect_host'] = 'SMTP xətası: SMTP serverinə qoşulma uğursuz oldu.';
10
+ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP xətası: Verilənlər qəbul edilməyib.';
11
+ $PHPMAILER_LANG['empty_message'] = 'Boş mesaj göndərilə bilməz.';
12
+ $PHPMAILER_LANG['encoding'] = 'Qeyri-müəyyən kodlaşdırma: ';
13
+ $PHPMAILER_LANG['execute'] = 'Əmr yerinə yetirilmədi: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Fayla giriş yoxdur: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Fayl xətası: Fayl açıla bilmədi: ';
16
+ $PHPMAILER_LANG['from_failed'] = 'Göstərilən poçtlara göndərmə uğursuz oldu: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'Mail funksiyası işə salına bilmədi.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Düzgün olmayan e-mail adresi: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' - e-mail kitabxanası dəstəklənmir.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Ən azı bir e-mail adresi daxil edilməlidir.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP xətası: Aşağıdakı ünvanlar üzrə alıcılara göndərmə uğursuzdur: ';
22
+ $PHPMAILER_LANG['signing'] = 'İmzalama xətası: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP serverinə qoşulma uğursuz oldu.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'SMTP serveri xətası: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Dəyişənin quraşdırılması uğursuz oldu: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-be.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
2
  /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Belarusian Version by Aleksander Maksymiuk <info@setpro.pl>
5
- */
 
6
 
7
  $PHPMAILER_LANG['authenticate'] = 'Памылка SMTP: памылка ідэнтыфікацыі.';
8
  $PHPMAILER_LANG['connect_host'] = 'Памылка SMTP: нельга ўстанавіць сувязь з SMTP-серверам.';
@@ -22,3 +23,4 @@ $PHPMAILER_LANG['signing'] = 'Памылка подпісу пав
22
  $PHPMAILER_LANG['smtp_connect_failed'] = 'Памылка сувязі з SMTP-серверам.';
23
  $PHPMAILER_LANG['smtp_error'] = 'Памылка SMTP: ';
24
  $PHPMAILER_LANG['variable_set'] = 'Нельга ўстанавіць або перамяніць значэнне пераменнай: ';
 
1
  <?php
2
  /**
3
+ * Belarusian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Aleksander Maksymiuk <info@setpro.pl>
6
+ */
7
 
8
  $PHPMAILER_LANG['authenticate'] = 'Памылка SMTP: памылка ідэнтыфікацыі.';
9
  $PHPMAILER_LANG['connect_host'] = 'Памылка SMTP: нельга ўстанавіць сувязь з SMTP-серверам.';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'Памылка сувязі з SMTP-серверам.';
24
  $PHPMAILER_LANG['smtp_error'] = 'Памылка SMTP: ';
25
  $PHPMAILER_LANG['variable_set'] = 'Нельга ўстанавіць або перамяніць значэнне пераменнай: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-bg.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Bulgarian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Mikhail Kyosev <mialygk@gmail.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['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'] = 'Невалиден адрес: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' - пощенски сървър не се поддържа.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Трябва да предоставите поне един email адрес за получател.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP грешка: Следните адреси за Получател са невалидни: ';
22
+ $PHPMAILER_LANG['signing'] = 'Грешка при подписване: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP провален connect().';
24
+ $PHPMAILER_LANG['smtp_error'] = 'SMTP сървърна грешка: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Не може да се установи или възстанови променлива: ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'Липсва разширение: ';
phpmailer/language/phpmailer.lang-ca.php CHANGED
@@ -1,25 +1,26 @@
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: ';
 
1
  <?php
2
  /**
3
+ * Catalan PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Ivan <web AT microstudi DOT com>
6
+ */
7
 
8
+ $PHPMAILER_LANG['authenticate'] = 'Error SMTP: No s’ha pogut 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'] = 'El cos del missatge està buit.';
12
  $PHPMAILER_LANG['encoding'] = 'Codificació desconeguda: ';
13
  $PHPMAILER_LANG['execute'] = 'No es pot executar: ';
14
+ $PHPMAILER_LANG['file_access'] = 'No es pot accedir a larxiu: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Error dArxiu: No es pot obrir larxiu: ';
16
  $PHPMAILER_LANG['from_failed'] = 'La(s) següent(s) adreces de remitent han fallat: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'No sha pogut crear una instància de la funció Mail.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Adreça d’email invalida: ';
19
  $PHPMAILER_LANG['mailer_not_supported'] = ' mailer no està suportat';
20
+ $PHPMAILER_LANG['provide_address'] = 'Sha de proveir almenys una adreça demail com a destinatari.';
21
  $PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Els següents destinataris han fallat: ';
22
+ $PHPMAILER_LANG['signing'] = 'Error al signar: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'Ha fallat el SMTP Connect().';
24
+ $PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'No s’ha pogut establir o restablir la variable: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-ch.php CHANGED
@@ -1,25 +1,26 @@
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: ';
 
1
  <?php
2
  /**
3
+ * Chinese PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author LiuXin <http://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'] = 'Invalid address: ';
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: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-cs.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Czech PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
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: ';
25
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-da.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Danish PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
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'] = 'Invalid address: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Du skal indtaste mindst en modtagers emailadresse.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: ';
22
+ //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
+ //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
+ //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
+ //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-de.php CHANGED
@@ -1,24 +1,25 @@
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: ';
 
1
  <?php
2
  /**
3
+ * German PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
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'] = 'Unbekannte Kodierung: ';
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'] = 'Dateifehler: 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'] = '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ängeradresse 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 zum SMTP-Server fehlgeschlagen.';
23
+ $PHPMAILER_LANG['smtp_error'] = 'Fehler vom SMTP-Server: ';
24
  $PHPMAILER_LANG['variable_set'] = 'Kann Variable nicht setzen oder zurücksetzen: ';
25
+ $PHPMAILER_LANG['extension_missing'] = 'Fehlende Erweiterung: ';
phpmailer/language/phpmailer.lang-el.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Greek PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ */
6
+
7
+ $PHPMAILER_LANG['authenticate'] = 'SMTP Σφάλμα: Αδυναμία πιστοποίησης (authentication).';
8
+ $PHPMAILER_LANG['connect_host'] = 'SMTP Σφάλμα: Αδυναμία σύνδεσης στον SMTP-Host.';
9
+ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Σφάλμα: Τα δεδομένα δεν έγιναν αποδεκτά.';
10
+ $PHPMAILER_LANG['empty_message'] = 'Το E-Mail δεν έχει περιεχόμενο .';
11
+ $PHPMAILER_LANG['encoding'] = 'Αγνωστο Encoding-Format: ';
12
+ $PHPMAILER_LANG['execute'] = 'Αδυναμία εκτέλεσης ακόλουθης εντολής: ';
13
+ $PHPMAILER_LANG['file_access'] = 'Αδυναμία προσπέλασης του αρχείου: ';
14
+ $PHPMAILER_LANG['file_open'] = 'Σφάλμα Αρχείου: Δεν είναι δυνατό το άνοιγμα του ακόλουθου αρχείου: ';
15
+ $PHPMAILER_LANG['from_failed'] = 'Η παρακάτω διεύθυνση αποστολέα δεν είναι σωστή: ';
16
+ $PHPMAILER_LANG['instantiate'] = 'Αδυναμία εκκίνησης Mail function.';
17
+ $PHPMAILER_LANG['invalid_address'] = 'Το μήνυμα δεν εστάλη, η διεύθυνση δεν είναι έγκυρη: ';
18
+ $PHPMAILER_LANG['mailer_not_supported'] = ' mailer δεν υποστηρίζεται.';
19
+ $PHPMAILER_LANG['provide_address'] = 'Παρακαλούμε δώστε τουλάχιστον μια e-mail διεύθυνση παραλήπτη.';
20
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP Σφάλμα: Οι παρακάτω διευθύνσεις παραλήπτη δεν είναι έγκυρες: ';
21
+ $PHPMAILER_LANG['signing'] = 'Σφάλμα υπογραφής: ';
22
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'Αποτυχία σύνδεσης στον SMTP Server.';
23
+ $PHPMAILER_LANG['smtp_error'] = 'Σφάλμα από τον SMTP Server: ';
24
+ $PHPMAILER_LANG['variable_set'] = 'Αδυναμία ορισμού ή αρχικοποίησης μεταβλητής: ';
25
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-eo.php CHANGED
@@ -1,8 +1,8 @@
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.';
@@ -22,3 +22,4 @@ $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: ';
 
1
  <?php
2
  /**
3
+ * Esperanto PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
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.';
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: ';
25
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-es.php CHANGED
@@ -1,26 +1,26 @@
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: ';
 
1
  <?php
2
  /**
3
+ * Spanish PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Matt Sturdy <matt.sturdy@gmail.com>
6
+ */
 
7
 
8
+ $PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.';
9
+ $PHPMAILER_LANG['connect_host'] = 'Error SMTP: Imposible conectar al servidor SMTP.';
10
  $PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.';
11
+ $PHPMAILER_LANG['empty_message'] = 'El cuerpo del mensaje está vacío';
12
  $PHPMAILER_LANG['encoding'] = 'Codificación desconocida: ';
13
+ $PHPMAILER_LANG['execute'] = 'Imposible ejecutar: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Imposible acceder al archivo: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Error de Archivo: Imposible abrir el archivo: ';
16
  $PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'Imposible crear una instancia de la función Mail.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Imposible enviar: dirección de email inválido: ';
19
  $PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Debe proporcionar al menos una dirección de email de destino.';
21
  $PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Los siguientes destinos fallaron: ';
22
  $PHPMAILER_LANG['signing'] = 'Error al firmar: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
24
  $PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
phpmailer/language/phpmailer.lang-et.php CHANGED
@@ -1,10 +1,10 @@
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.';
@@ -16,7 +16,7 @@ $PHPMAILER_LANG['file_access'] = 'Pole piisavalt õiguseid järgneva fa
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: ';
@@ -24,3 +24,4 @@ $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: ';
 
1
  <?php
2
  /**
3
+ * Estonian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Indrek Päri
6
+ * @author 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.';
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: ';
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: ';
27
+ $PHPMAILER_LANG['extension_missing'] = 'Nõutud laiendus on puudu: ';
phpmailer/language/phpmailer.lang-fa.php CHANGED
@@ -1,25 +1,27 @@
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'] = 'امکان ارسال یا ارسال مجدد متغیرها وجود ندارد: ';
 
1
  <?php
2
  /**
3
+ * Persian/Farsi PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Ali Jazayeri <jaza.ali@gmail.com>
6
+ * @author Mohammad Hossein Mojtahedi <mhm5000@gmail.com>
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'] = 'بخش متن پیام خالی است.';
13
+ $PHPMAILER_LANG['encoding'] = 'کد‌گذاری نا‌شناخته: ';
14
  $PHPMAILER_LANG['execute'] = 'امکان اجرا وجود ندارد: ';
15
  $PHPMAILER_LANG['file_access'] = 'امکان دسترسی به فایل وجود ندارد: ';
16
+ $PHPMAILER_LANG['file_open'] = 'خطای File: امکان بازکردن فایل وجود ندارد: ';
17
  $PHPMAILER_LANG['from_failed'] = 'آدرس فرستنده اشتباه است: ';
18
  $PHPMAILER_LANG['instantiate'] = 'امکان معرفی تابع ایمیل وجود ندارد.';
19
  $PHPMAILER_LANG['invalid_address'] = 'آدرس ایمیل معتبر نیست: ';
20
+ $PHPMAILER_LANG['mailer_not_supported'] = ' mailer پشتیبانی نمی‌شود.';
21
  $PHPMAILER_LANG['provide_address'] = 'باید حداقل یک آدرس گیرنده وارد کنید.';
22
+ $PHPMAILER_LANG['recipients_failed'] = 'خطای SMTP: ارسال به آدرس گیرنده با خطا مواجه شد: ';
23
  $PHPMAILER_LANG['signing'] = 'خطا در امضا: ';
24
  $PHPMAILER_LANG['smtp_connect_failed'] = 'خطا در اتصال به SMTP.';
25
  $PHPMAILER_LANG['smtp_error'] = 'خطا در SMTP Server: ';
26
+ $PHPMAILER_LANG['variable_set'] = 'امکان ارسال یا ارسال مجدد متغیر‌ها وجود ندارد: ';
27
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-fi.php CHANGED
@@ -1,9 +1,9 @@
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.';
@@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Seuraavaan tiedostoon ei ole oikeuksi
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.';
@@ -24,3 +24,4 @@ $PHPMAILER_LANG['encoding'] = 'Tuntematon koodaustyyppi: ';
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: ';
 
1
  <?php
2
  /**
3
+ * Finnish PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author 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.';
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'] = 'Invalid address: ';
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.';
24
  //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
25
  //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
26
  //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
27
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-fo.php CHANGED
@@ -1,10 +1,9 @@
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.';
@@ -16,7 +15,7 @@ $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: ';
@@ -24,3 +23,4 @@ $PHPMAILER_LANG['recipients_failed'] = 'SMTP Feilur: Fylgjandi móttakarar mi
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: ';
 
1
  <?php
2
  /**
3
+ * Faroese PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Dávur Sørensen <http://www.profo-webdesign.dk>
6
+ */
 
7
 
8
  $PHPMAILER_LANG['authenticate'] = 'SMTP feilur: Kundi ikki góðkenna.';
9
  $PHPMAILER_LANG['connect_host'] = 'SMTP feilur: Kundi ikki knýta samband við SMTP vert.';
15
  $PHPMAILER_LANG['file_open'] = 'Fílu feilur: Kundi ikki opna fílu: ';
16
  $PHPMAILER_LANG['from_failed'] = 'fylgjandi Frá/From adressa miseydnaðist: ';
17
  $PHPMAILER_LANG['instantiate'] = 'Kuni ikki instantiera mail funktión.';
18
+ //$PHPMAILER_LANG['invalid_address'] = 'Invalid address: ';
19
  $PHPMAILER_LANG['mailer_not_supported'] = ' er ikki supporterað.';
20
  $PHPMAILER_LANG['provide_address'] = 'Tú skal uppgeva minst móttakara-emailadressu(r).';
21
  $PHPMAILER_LANG['recipients_failed'] = 'SMTP Feilur: Fylgjandi móttakarar miseydnaðust: ';
23
  //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
  //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
  //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-fr.php CHANGED
@@ -1,23 +1,22 @@
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é.';
@@ -26,4 +25,5 @@ $PHPMAILER_LANG['recipients_failed'] = 'Erreur SMTP : les destinataires sui
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 : ';
 
1
  <?php
2
  /**
3
+ * French PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
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
  $PHPMAILER_LANG['authenticate'] = 'Erreur SMTP : échec de l\'authentification.';
12
  $PHPMAILER_LANG['connect_host'] = 'Erreur SMTP : impossible de se connecter au serveur SMTP.';
13
  $PHPMAILER_LANG['data_not_accepted'] = 'Erreur SMTP : données incorrectes.';
14
+ $PHPMAILER_LANG['empty_message'] = 'Corps du message vide.';
15
  $PHPMAILER_LANG['encoding'] = 'Encodage inconnu : ';
16
  $PHPMAILER_LANG['execute'] = 'Impossible de lancer l\'exécution : ';
17
  $PHPMAILER_LANG['file_access'] = 'Impossible d\'accéder au fichier : ';
18
+ $PHPMAILER_LANG['file_open'] = 'Ouverture du fichier impossible : ';
19
+ $PHPMAILER_LANG['from_failed'] = 'L\'adresse d\'expéditeur suivante a échoué : ';
20
  $PHPMAILER_LANG['instantiate'] = 'Impossible d\'instancier la fonction mail.';
21
  $PHPMAILER_LANG['invalid_address'] = 'L\'adresse courriel n\'est pas valide : ';
22
  $PHPMAILER_LANG['mailer_not_supported'] = ' client de messagerie non supporté.';
25
  $PHPMAILER_LANG['signing'] = 'Erreur de signature : ';
26
  $PHPMAILER_LANG['smtp_connect_failed'] = 'Échec de la connexion SMTP.';
27
  $PHPMAILER_LANG['smtp_error'] = 'Erreur du serveur SMTP : ';
28
+ $PHPMAILER_LANG['variable_set'] = 'Impossible d\'initialiser ou de réinitialiser une variable : ';
29
+ $PHPMAILER_LANG['extension_missing'] = 'Extension manquante : ';
phpmailer/language/phpmailer.lang-gl.php CHANGED
@@ -1,10 +1,9 @@
1
  <?php
2
  /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Galician version
5
- * Versión en galego
6
- * Edited by Donato Rouco - donatorouco@gmail.com
7
- */
8
 
9
  $PHPMAILER_LANG['authenticate'] = 'Erro SMTP: Non puido ser autentificado.';
10
  $PHPMAILER_LANG['connect_host'] = 'Erro SMTP: Non puido conectar co servidor SMTP.';
@@ -24,3 +23,4 @@ $PHPMAILER_LANG['signing'] = 'Erro ó firmar: ';
24
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fallou.';
25
  $PHPMAILER_LANG['smtp_error'] = 'Erro do servidor SMTP: ';
26
  $PHPMAILER_LANG['variable_set'] = 'Non puidemos axustar ou reaxustar a variábel: ';
 
1
  <?php
2
  /**
3
+ * Galician PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author by Donato Rouco <donatorouco@gmail.com>
6
+ */
 
7
 
8
  $PHPMAILER_LANG['authenticate'] = 'Erro SMTP: Non puido ser autentificado.';
9
  $PHPMAILER_LANG['connect_host'] = 'Erro SMTP: Non puido conectar co servidor SMTP.';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fallou.';
24
  $PHPMAILER_LANG['smtp_error'] = 'Erro do servidor SMTP: ';
25
  $PHPMAILER_LANG['variable_set'] = 'Non puidemos axustar ou reaxustar a variábel: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-he.php CHANGED
@@ -1,15 +1,15 @@
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'] = 'לא ניתן לגשת לקובץ: ';
@@ -23,3 +23,4 @@ $PHPMAILER_LANG['signing'] = 'שגיאת חתימה: ';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
  $PHPMAILER_LANG['smtp_error'] = 'שגיאת שרת SMTP: ';
25
  $PHPMAILER_LANG['variable_set'] = 'לא ניתן לקבוע או לשנות את המשתנה: ';
 
1
  <?php
2
  /**
3
+ * Hebrew PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author 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'] = 'לא ניתן לגשת לקובץ: ';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
  $PHPMAILER_LANG['smtp_error'] = 'שגיאת שרת SMTP: ';
25
  $PHPMAILER_LANG['variable_set'] = 'לא ניתן לקבוע או לשנות את המשתנה: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-hr.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Croatian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Hrvoj3e <hrvoj3e@gmail.com>
6
+ */
7
+
8
+ $PHPMAILER_LANG['authenticate'] = 'SMTP Greška: Neuspjela autentikacija.';
9
+ $PHPMAILER_LANG['connect_host'] = 'SMTP Greška: Ne mogu se spojiti na SMTP poslužitelj.';
10
+ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Greška: Podatci nisu prihvaćeni.';
11
+ $PHPMAILER_LANG['empty_message'] = 'Sadržaj poruke je prazan.';
12
+ $PHPMAILER_LANG['encoding'] = 'Nepoznati encoding: ';
13
+ $PHPMAILER_LANG['execute'] = 'Nije moguće izvršiti naredbu: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Nije moguće pristupiti datoteci: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Nije moguće otvoriti datoteku: ';
16
+ $PHPMAILER_LANG['from_failed'] = 'SMTP Greška: Slanje s navedenih e-mail adresa nije uspjelo: ';
17
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP Greška: Slanje na navedenih e-mail adresa nije uspjelo: ';
18
+ $PHPMAILER_LANG['instantiate'] = 'Ne mogu pokrenuti mail funkcionalnost.';
19
+ $PHPMAILER_LANG['invalid_address'] = 'E-mail nije poslan. Neispravna e-mail adresa: ';
20
+ $PHPMAILER_LANG['mailer_not_supported'] = ' mailer nije podržan.';
21
+ $PHPMAILER_LANG['provide_address'] = 'Definirajte barem jednu adresu primatelja.';
22
+ $PHPMAILER_LANG['signing'] = 'Greška prilikom prijave: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'Spajanje na SMTP poslužitelj nije uspjelo.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'Greška SMTP poslužitelja: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Ne mogu postaviti varijablu niti ju vratiti nazad: ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'Nedostaje proširenje: ';
phpmailer/language/phpmailer.lang-hu.php CHANGED
@@ -1,8 +1,9 @@
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.';
@@ -22,3 +23,4 @@ $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: ';
 
1
  <?php
2
  /**
3
+ * Hungarian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author @dominicus-75
6
+ */
7
 
8
  $PHPMAILER_LANG['authenticate'] = 'SMTP hiba: az azonosítás sikertelen.';
9
  $PHPMAILER_LANG['connect_host'] = 'SMTP hiba: nem lehet kapcsolódni az SMTP-szerverhez.';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'Hiba az SMTP-kapcsolatban.';
24
  $PHPMAILER_LANG['smtp_error'] = 'SMTP-szerver hiba: ';
25
  $PHPMAILER_LANG['variable_set'] = 'A következő változók beállítása nem sikerült: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-id.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Indonesian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Cecep Prawiro <cecep.prawiro@gmail.com>
6
+ */
7
+
8
+ $PHPMAILER_LANG['authenticate'] = 'Kesalahan SMTP: Tidak dapat mengautentikasi.';
9
+ $PHPMAILER_LANG['connect_host'] = 'Kesalahan SMTP: Tidak dapat terhubung ke host SMTP.';
10
+ $PHPMAILER_LANG['data_not_accepted'] = 'Kesalahan SMTP: Data tidak diterima peladen.';
11
+ $PHPMAILER_LANG['empty_message'] = 'Isi pesan kosong';
12
+ $PHPMAILER_LANG['encoding'] = 'Pengkodean karakter tidak dikenali: ';
13
+ $PHPMAILER_LANG['execute'] = 'Tidak dapat menjalankan proses : ';
14
+ $PHPMAILER_LANG['file_access'] = 'Tidak dapat mengakses berkas : ';
15
+ $PHPMAILER_LANG['file_open'] = 'Kesalahan File: Berkas tidak bisa dibuka : ';
16
+ $PHPMAILER_LANG['from_failed'] = 'Alamat pengirim berikut mengakibatkan error : ';
17
+ $PHPMAILER_LANG['instantiate'] = 'Tidak dapat menginisialisasi fungsi email';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Gagal terkirim, alamat email tidak valid : ';
19
+ $PHPMAILER_LANG['provide_address'] = 'Harus disediakan minimal satu alamat tujuan';
20
+ $PHPMAILER_LANG['mailer_not_supported'] = 'Mailer tidak didukung';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'Kesalahan SMTP: Alamat tujuan berikut menghasilkan error : ';
22
+ $PHPMAILER_LANG['signing'] = 'Kesalahan dalam tanda tangan : ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() gagal.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'Kesalahan peladen SMTP : ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Tidak berhasil mengatur atau mengatur ulang variable : ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-it.php CHANGED
@@ -1,10 +1,10 @@
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.';
@@ -16,7 +16,7 @@ $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: ';
@@ -24,3 +24,4 @@ $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: ';
 
1
  <?php
2
  /**
3
+ * Italian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Ilias Bartolini <brain79@inwind.it>
6
+ * @author 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.';
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: ';
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: ';
27
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-ja.php CHANGED
@@ -1,26 +1,27 @@
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: ';
 
1
  <?php
2
  /**
3
+ * Japanese PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Mitsuhiro Yoshida <http://mitstek.com/>
6
+ * @author 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'] = 'Invalid address: ';
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: ';
27
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-ka.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Georgian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Avtandil Kikabidze aka LONGMAN <akalongman@gmail.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['encoding'] = 'კოდირების უცნობი ტიპი: ';
12
+ $PHPMAILER_LANG['execute'] = 'შეუძლებელია შემდეგი ბრძანების შესრულება: ';
13
+ $PHPMAILER_LANG['file_access'] = 'შეუძლებელია წვდომა ფაილთან: ';
14
+ $PHPMAILER_LANG['file_open'] = 'ფაილური სისტემის შეცდომა: არ იხსნება ფაილი: ';
15
+ $PHPMAILER_LANG['from_failed'] = 'გამგზავნის არასწორი მისამართი: ';
16
+ $PHPMAILER_LANG['instantiate'] = 'mail ფუნქციის გაშვება ვერ ხერხდება.';
17
+ $PHPMAILER_LANG['provide_address'] = 'გთხოვთ მიუთითოთ ერთი ადრესატის e-mail მისამართი მაინც.';
18
+ $PHPMAILER_LANG['mailer_not_supported'] = ' - საფოსტო სერვერის მხარდაჭერა არ არის.';
19
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP შეცდომა: შემდეგ მისამართებზე გაგზავნა ვერ მოხერხდა: ';
20
+ $PHPMAILER_LANG['empty_message'] = 'შეტყობინება ცარიელია';
21
+ $PHPMAILER_LANG['invalid_address'] = 'არ გაიგზავნა, e-mail მისამართის არასწორი ფორმატი: ';
22
+ $PHPMAILER_LANG['signing'] = 'ხელმოწერის შეცდომა: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'შეცდომა SMTP სერვერთან დაკავშირებისას';
24
+ $PHPMAILER_LANG['smtp_error'] = 'SMTP სერვერის შეცდომა: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'შეუძლებელია შემდეგი ცვლადის შექმნა ან შეცვლა: ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'ბიბლიოთეკა არ არსებობს: ';
phpmailer/language/phpmailer.lang-ko.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Korean PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author ChalkPE <amato0617@gmail.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['encoding'] = '알 수 없는 인코딩: ';
13
+ $PHPMAILER_LANG['execute'] = '실행 불가: ';
14
+ $PHPMAILER_LANG['file_access'] = '파일 접근 불가: ';
15
+ $PHPMAILER_LANG['file_open'] = '파일 오류: 파일을 열 수 없습니다: ';
16
+ $PHPMAILER_LANG['from_failed'] = '다음 From 주소에서 오류가 발생했습니다: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'mail 함수를 인스턴스화할 수 없습니다';
18
+ $PHPMAILER_LANG['invalid_address'] = '잘못된 주소: ';
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 연결을 실패하였습니다.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'SMTP 서버 오류: ';
25
+ $PHPMAILER_LANG['variable_set'] = '변수 설정 및 초기화 불가: ';
26
+ $PHPMAILER_LANG['extension_missing'] = '확장자 없음: ';
phpmailer/language/phpmailer.lang-lt.php CHANGED
@@ -1,8 +1,9 @@
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.';
@@ -14,7 +15,7 @@ $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: ';
@@ -22,3 +23,4 @@ $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: ';
 
1
  <?php
2
  /**
3
+ * Lithuanian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Dainius Kaupaitis <dk@sum.lt>
6
+ */
7
 
8
  $PHPMAILER_LANG['authenticate'] = 'SMTP klaida: autentifikacija nepavyko.';
9
  $PHPMAILER_LANG['connect_host'] = 'SMTP klaida: nepavyksta prisijungti prie SMTP stoties.';
15
  $PHPMAILER_LANG['file_open'] = 'Bylos klaida: Nepavyksta atidaryti: ';
16
  $PHPMAILER_LANG['from_failed'] = 'Neteisingas siuntėjo adresas: ';
17
  $PHPMAILER_LANG['instantiate'] = 'Nepavyko paleisti mail funkcijos.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Neteisingas adresas: ';
19
  $PHPMAILER_LANG['mailer_not_supported'] = ' pašto stotis nepalaikoma.';
20
  $PHPMAILER_LANG['provide_address'] = 'Nurodykite bent vieną gavėjo adresą.';
21
  $PHPMAILER_LANG['recipients_failed'] = 'SMTP klaida: nepavyko išsiųsti šiems gavėjams: ';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP susijungimo klaida';
24
  $PHPMAILER_LANG['smtp_error'] = 'SMTP stoties klaida: ';
25
  $PHPMAILER_LANG['variable_set'] = 'Nepavyko priskirti reikšmės kintamajam: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-lv.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
2
  /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Latvian version by Eduards M. <e@npd.lv>
5
- */
 
6
 
7
  $PHPMAILER_LANG['authenticate'] = 'SMTP kļūda: Autorizācija neizdevās.';
8
  $PHPMAILER_LANG['connect_host'] = 'SMTP Kļūda: Nevar izveidot savienojumu ar SMTP serveri.';
@@ -14,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Fails nav pieejams: ';
14
  $PHPMAILER_LANG['file_open'] = 'Faila kļūda: Nevar atvērt failu: ';
15
  $PHPMAILER_LANG['from_failed'] = 'Nepareiza sūtītāja adrese: ';
16
  $PHPMAILER_LANG['instantiate'] = 'Nevar palaist sūtīšanas funkciju.';
17
- $PHPMAILER_LANG['invalid_address'] = 'Nepareiza adrese';
18
  $PHPMAILER_LANG['mailer_not_supported'] = ' sūtītājs netiek atbalstīts.';
19
  $PHPMAILER_LANG['provide_address'] = 'Lūdzu, norādiet vismaz vienu adresātu.';
20
  $PHPMAILER_LANG['recipients_failed'] = 'SMTP kļūda: neizdevās nosūtīt šādiem saņēmējiem: ';
@@ -22,3 +23,4 @@ $PHPMAILER_LANG['signing'] = 'Autorizācijas kļūda: ';
22
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP savienojuma kļūda';
23
  $PHPMAILER_LANG['smtp_error'] = 'SMTP servera kļūda: ';
24
  $PHPMAILER_LANG['variable_set'] = 'Nevar piešķirt mainīgā vērtību: ';
 
1
  <?php
2
  /**
3
+ * Latvian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Eduards M. <e@npd.lv>
6
+ */
7
 
8
  $PHPMAILER_LANG['authenticate'] = 'SMTP kļūda: Autorizācija neizdevās.';
9
  $PHPMAILER_LANG['connect_host'] = 'SMTP Kļūda: Nevar izveidot savienojumu ar SMTP serveri.';
15
  $PHPMAILER_LANG['file_open'] = 'Faila kļūda: Nevar atvērt failu: ';
16
  $PHPMAILER_LANG['from_failed'] = 'Nepareiza sūtītāja adrese: ';
17
  $PHPMAILER_LANG['instantiate'] = 'Nevar palaist sūtīšanas funkciju.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Nepareiza adrese: ';
19
  $PHPMAILER_LANG['mailer_not_supported'] = ' sūtītājs netiek atbalstīts.';
20
  $PHPMAILER_LANG['provide_address'] = 'Lūdzu, norādiet vismaz vienu adresātu.';
21
  $PHPMAILER_LANG['recipients_failed'] = 'SMTP kļūda: neizdevās nosūtīt šādiem saņēmējiem: ';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP savienojuma kļūda';
24
  $PHPMAILER_LANG['smtp_error'] = 'SMTP servera kļūda: ';
25
  $PHPMAILER_LANG['variable_set'] = 'Nevar piešķirt mainīgā vērtību: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-ms.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Malaysian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Nawawi Jamili <nawawi@rutweb.com>
6
+ */
7
+
8
+ $PHPMAILER_LANG['authenticate'] = 'Ralat SMTP: Tidak dapat pengesahan.';
9
+ $PHPMAILER_LANG['connect_host'] = 'Ralat SMTP: Tidak dapat menghubungi hos pelayan SMTP.';
10
+ $PHPMAILER_LANG['data_not_accepted'] = 'Ralat SMTP: Data tidak diterima oleh pelayan.';
11
+ $PHPMAILER_LANG['empty_message'] = 'Tiada isi untuk mesej';
12
+ $PHPMAILER_LANG['encoding'] = 'Pengekodan tidak diketahui: ';
13
+ $PHPMAILER_LANG['execute'] = 'Tidak dapat melaksanakan: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Tidak dapat mengakses fail: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Ralat Fail: Tidak dapat membuka fail: ';
16
+ $PHPMAILER_LANG['from_failed'] = 'Berikut merupakan ralat dari alamat e-mel: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'Tidak dapat memberi contoh fungsi e-mel.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Alamat emel tidak sah: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' jenis penghantar emel tidak disokong.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Anda perlu menyediakan sekurang-kurangnya satu alamat e-mel penerima.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'Ralat SMTP: Penerima e-mel berikut telah gagal: ';
22
+ $PHPMAILER_LANG['signing'] = 'Ralat pada tanda tangan: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() telah gagal.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'Ralat pada pelayan SMTP: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Tidak boleh menetapkan atau menetapkan semula pembolehubah: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-nb.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Norwegian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ */
6
+
7
+ $PHPMAILER_LANG['authenticate'] = 'SMTP Feil: Kunne ikke autentisere.';
8
+ $PHPMAILER_LANG['connect_host'] = 'SMTP Feil: Kunne ikke koble til SMTP tjener.';
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
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-nl.php CHANGED
@@ -1,24 +1,26 @@
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:
 
1
  <?php
2
  /**
3
+ * Dutch PHPMailer language file: refer to class.phpmailer.php for definitive list.
4
+ * @package PHPMailer
5
+ * @author Tuxion <team@tuxion.nl>
6
+ */
7
 
8
+ $PHPMAILER_LANG['authenticate'] = 'SMTP-fout: authenticatie mislukt.';
9
+ $PHPMAILER_LANG['connect_host'] = 'SMTP-fout: kon niet verbinden met SMTP-host.';
10
+ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP-fout: data niet geaccepteerd.';
11
+ $PHPMAILER_LANG['empty_message'] = 'Berichttekst is leeg';
12
+ $PHPMAILER_LANG['encoding'] = 'Onbekende codering: ';
13
+ $PHPMAILER_LANG['execute'] = 'Kon niet uitvoeren: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Bestandsfout: kon bestand niet openen: ';
16
+ $PHPMAILER_LANG['from_failed'] = 'Het volgende afzendersadres is mislukt: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'Kon mailfunctie niet initialiseren.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Er moet minstens één ontvanger worden opgegeven.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP-fout: de volgende ontvangers zijn mislukt: ';
22
+ $PHPMAILER_LANG['signing'] = 'Signeerfout: ';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Verbinding mislukt.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfout: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Kan de volgende variabele niet instellen of resetten: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-pl.php CHANGED
@@ -1,10 +1,10 @@
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.';
@@ -14,11 +14,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: ';
 
1
  <?php
2
  /**
3
+ * Polish PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ */
6
 
7
+ $PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzić uwierzytelnienia.';
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.';
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, '.
18
+ 'następujący adres Odbiorcy jest nieprawidłowy: ';
19
  $PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email Odbiorcy.';
20
  $PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
21
  $PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi: ';
22
  $PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: ';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() zakończone niepowodzeniem.';
24
  $PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';
phpmailer/language/phpmailer.lang-pt.php CHANGED
@@ -1,10 +1,9 @@
1
  <?php
2
  /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * pt-PT
5
- * Portuguese (European) Version 1.0
6
- * By Jonadabe - jonadabe@hotmail.com
7
- */
8
 
9
  $PHPMAILER_LANG['authenticate'] = 'Erro do SMTP: Não foi possível realizar a autenticação.';
10
  $PHPMAILER_LANG['connect_host'] = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.';
@@ -24,3 +23,4 @@ $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 redefinir a variável: ';
 
1
  <?php
2
  /**
3
+ * Portuguese (European) PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Jonadabe <jonadabe@hotmail.com>
6
+ */
 
7
 
8
  $PHPMAILER_LANG['authenticate'] = 'Erro do SMTP: Não foi possível realizar a autenticação.';
9
  $PHPMAILER_LANG['connect_host'] = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.';
23
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.';
24
  $PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: ';
25
  $PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'Extensão em falta: ';
phpmailer/language/phpmailer.lang-pt_br.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Brazilian Portuguese PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Paulo Henrique Garcia <paulo@controllerweb.com.br>
6
+ * @author Lucas Guimarães <lucas@lucasguimaraes.com>
7
+ * @author Phelipe Alves <phelipealvesdesouza@gmail.com>
8
+ */
9
+
10
+ $PHPMAILER_LANG['authenticate'] = 'Erro de SMTP: Não foi possível autenticar.';
11
+ $PHPMAILER_LANG['connect_host'] = 'Erro de SMTP: Não foi possível conectar ao servidor SMTP.';
12
+ $PHPMAILER_LANG['data_not_accepted'] = 'Erro de SMTP: Dados rejeitados.';
13
+ $PHPMAILER_LANG['empty_message'] = 'Mensagem vazia';
14
+ $PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: ';
15
+ $PHPMAILER_LANG['execute'] = 'Não foi possível executar: ';
16
+ $PHPMAILER_LANG['file_access'] = 'Não foi possível acessar o arquivo: ';
17
+ $PHPMAILER_LANG['file_open'] = 'Erro de Arquivo: Não foi possível abrir o arquivo: ';
18
+ $PHPMAILER_LANG['from_failed'] = 'Os seguintes remententes falharam: ';
19
+ $PHPMAILER_LANG['instantiate'] = 'Não foi possível instanciar a função mail.';
20
+ $PHPMAILER_LANG['invalid_address'] = 'Endereço de e-mail inválido: ';
21
+ $PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';
22
+ $PHPMAILER_LANG['provide_address'] = 'Você deve informar pelo menos um destinatário.';
23
+ $PHPMAILER_LANG['recipients_failed'] = 'Erro de SMTP: Os seguintes destinatários falharam: ';
24
+ $PHPMAILER_LANG['signing'] = 'Erro de Assinatura: ';
25
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.';
26
+ $PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: ';
27
+ $PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: ';
28
+ $PHPMAILER_LANG['extension_missing'] = 'Extensão ausente: ';
phpmailer/language/phpmailer.lang-ro.php CHANGED
@@ -1,26 +1,26 @@
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: ';
 
1
  <?php
2
  /**
3
+ * Romanian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Alex Florea <alecz.fia@gmail.com>
6
+ */
 
7
 
8
+ $PHPMAILER_LANG['authenticate'] = 'Eroare SMTP: Autentificarea a eșuat.';
9
+ $PHPMAILER_LANG['connect_host'] = 'Eroare SMTP: Conectarea la serverul SMTP a eșuat.';
10
+ $PHPMAILER_LANG['data_not_accepted'] = 'Eroare SMTP: Datele nu au fost acceptate.';
11
+ $PHPMAILER_LANG['empty_message'] = 'Mesajul este gol.';
12
+ $PHPMAILER_LANG['encoding'] = 'Encodare necunoscută: ';
13
+ $PHPMAILER_LANG['execute'] = 'Nu se poate executa următoarea comandă: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Nu se poate accesa următorul fișier: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Eroare fișier: Nu se poate deschide următorul fișier: ';
16
+ $PHPMAILER_LANG['from_failed'] = 'Următoarele adrese From au dat eroare: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'Funcția mail nu a putut fi inițializată.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Adresa de email nu este validă: ';
19
  $PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Trebuie adăugați cel puțin o adresă de email.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'Eroare SMTP: Următoarele adrese de email au eșuat: ';
22
+ $PHPMAILER_LANG['signing'] = 'A aparut o problemă la semnarea emailului. ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'Conectarea la serverul SMTP a eșuat.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'Eroare server SMTP: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Nu se poate seta/reseta variabila. ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'Lipsește extensia: ';
phpmailer/language/phpmailer.lang-ru.php CHANGED
@@ -1,8 +1,10 @@
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.';
@@ -14,11 +16,12 @@ $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'] = 'Невозможно установить или переустановить переменную: ';
 
1
  <?php
2
  /**
3
+ * Russian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Alexey Chumakov <alex@chumakov.ru>
6
+ * @author Foster Snowhill <i18n@forstwoof.ru>
7
+ */
8
 
9
  $PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.';
10
  $PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к серверу SMTP.';
16
  $PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: ';
17
  $PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail.';
18
  $PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' почтовый сервер не поддерживается.';
20
  $PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: ';
21
+ $PHPMAILER_LANG['empty_message'] = 'Пустое сообщение';
22
+ $PHPMAILER_LANG['invalid_address'] = 'Не отослано, неправильный формат email адреса: ';
23
+ $PHPMAILER_LANG['signing'] = 'Ошибка подписи: ';
24
  $PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером';
25
  $PHPMAILER_LANG['smtp_error'] = 'Ошибка SMTP-сервера: ';
26
  $PHPMAILER_LANG['variable_set'] = 'Невозможно установить или переустановить переменную: ';
27
+ $PHPMAILER_LANG['extension_missing'] = 'Расширение отсутствует: ';
phpmailer/language/phpmailer.lang-sk.php CHANGED
@@ -1,9 +1,9 @@
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.';
@@ -15,7 +15,7 @@ $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 ';
@@ -23,3 +23,4 @@ $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ú: ';
 
1
  <?php
2
  /**
3
+ * Slovak PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
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.';
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 ';
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ú: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-sl.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Slovene PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Klemen Tušar <techouse@gmail.com>
6
+ */
7
+
8
+ $PHPMAILER_LANG['authenticate'] = 'SMTP napaka: Avtentikacija ni uspela.';
9
+ $PHPMAILER_LANG['connect_host'] = 'SMTP napaka: Ne morem vzpostaviti povezave s SMTP gostiteljem.';
10
+ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP napaka: Strežnik zavrača podatke.';
11
+ $PHPMAILER_LANG['empty_message'] = 'E-poštno sporočilo nima vsebine.';
12
+ $PHPMAILER_LANG['encoding'] = 'Nepoznan tip kodiranja: ';
13
+ $PHPMAILER_LANG['execute'] = 'Operacija ni uspela: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Nimam dostopa do datoteke: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Ne morem odpreti datoteke: ';
16
+ $PHPMAILER_LANG['from_failed'] = 'Neveljaven e-naslov pošiljatelja: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'Ne morem inicializirati mail funkcije.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'E-poštno sporočilo ni bilo poslano. E-naslov je neveljaven: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' mailer ni podprt.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Prosim vnesite vsaj enega naslovnika.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP napaka: Sledeči naslovniki so neveljavni: ';
22
+ $PHPMAILER_LANG['signing'] = 'Napaka pri podpisovanju: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'Ne morem vzpostaviti povezave s SMTP strežnikom.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'Napaka SMTP strežnika: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Ne morem nastaviti oz. ponastaviti spremenljivke: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-sr.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Serbian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Александар Јевремовић <ajevremovic@gmail.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['encoding'] = 'Непознато кодовање: ';
13
+ $PHPMAILER_LANG['execute'] = 'Није могуће извршити наредбу: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Није могуће приступити датотеци: ';
15
+ $PHPMAILER_LANG['file_open'] = 'Није могуће отворити датотеку: ';
16
+ $PHPMAILER_LANG['from_failed'] = 'SMTP грешка: слање са следећих адреса није успело: ';
17
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP грешка: слање на следеће адресе није успело: ';
18
+ $PHPMAILER_LANG['instantiate'] = 'Није могуће покренути mail функцију.';
19
+ $PHPMAILER_LANG['invalid_address'] = 'Порука није послата због неисправне адресе: ';
20
+ $PHPMAILER_LANG['mailer_not_supported'] = ' мејлер није подржан.';
21
+ $PHPMAILER_LANG['provide_address'] = 'Потребно је задати најмање једну адресу.';
22
+ $PHPMAILER_LANG['signing'] = 'Грешка приликом пријављивања: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'Повезивање са SMTP сервером није успело.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'Грешка SMTP сервера: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Није могуће задати променљиву, нити је вратити уназад: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-sv.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Swedish PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
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'] = 'Felaktig adress: ';
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'] = 'Signerings fel: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() misslyckades.';
24
+ $PHPMAILER_LANG['smtp_error'] = 'SMTP server fel: ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Kunde inte definiera eller återställa variabel: ';
26
+ $PHPMAILER_LANG['extension_missing'] = 'Tillägg ej tillgängligt: ';
phpmailer/language/phpmailer.lang-tr.php CHANGED
@@ -1,26 +1,29 @@
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: ';
 
1
  <?php
2
  /**
3
+ * Turkish PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Elçin Özel
6
+ * @author Can Yılmaz
7
+ * @author Mehmet Benlioğlu
8
+ * @author @yasinaydin
9
+ */
10
 
11
+ $PHPMAILER_LANG['authenticate'] = 'SMTP Hatası: Oturum açılamadı.';
12
+ $PHPMAILER_LANG['connect_host'] = 'SMTP Hatası: SMTP sunucusuna bağlanılamadı.';
13
  $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Hatası: Veri kabul edilmedi.';
14
+ $PHPMAILER_LANG['empty_message'] = 'Mesajın içeriği boş';
15
+ $PHPMAILER_LANG['encoding'] = 'Bilinmeyen karakter kodlama: ';
16
+ $PHPMAILER_LANG['execute'] = 'Çalıştırılamadı: ';
17
+ $PHPMAILER_LANG['file_access'] = 'Dosyaya erişilemedi: ';
18
+ $PHPMAILER_LANG['file_open'] = 'Dosya Hatası: Dosya açılamadı: ';
19
+ $PHPMAILER_LANG['from_failed'] = 'Belirtilen adreslere gönderme başarısız: ';
20
+ $PHPMAILER_LANG['instantiate'] = 'Örnek e-posta fonksiyonu oluşturulamadı.';
21
+ $PHPMAILER_LANG['invalid_address'] = 'Geçersiz e-posta adresi: ';
22
+ $PHPMAILER_LANG['mailer_not_supported'] = ' e-posta kütüphanesi desteklenmiyor.';
23
+ $PHPMAILER_LANG['provide_address'] = 'En az bir alıcı e-posta adresi belirtmelisiniz.';
24
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP Hatası: Belirtilen alıcılara ulaşılamadı: ';
25
  $PHPMAILER_LANG['signing'] = 'İmzalama hatası: ';
26
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP connect() fonksiyonu başarısız.';
27
  $PHPMAILER_LANG['smtp_error'] = 'SMTP sunucu hatası: ';
28
+ $PHPMAILER_LANG['variable_set'] = 'Değişken ayarlanamadı ya da sıfırlanamadı: ';
29
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-uk.php CHANGED
@@ -1,11 +1,13 @@
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'] = 'Неможливо виконати команду: ';
@@ -15,10 +17,11 @@ $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'] = 'Неможливо встановити або перевстановити змінну: ';
 
1
  <?php
2
  /**
3
+ * Ukrainian PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author Yuriy Rudyy <yrudyy@prs.net.ua>
6
+ * @fixed by Boris Yurchenko <boris@yurchenko.pp.ua>
7
+ */
8
 
9
  $PHPMAILER_LANG['authenticate'] = 'Помилка SMTP: помилка авторизації.';
10
+ $PHPMAILER_LANG['connect_host'] = 'Помилка SMTP: не вдається під\'єднатися до серверу SMTP.';
11
  $PHPMAILER_LANG['data_not_accepted'] = 'Помилка SMTP: дані не прийняті.';
12
  $PHPMAILER_LANG['encoding'] = 'Невідомий тип кодування: ';
13
  $PHPMAILER_LANG['execute'] = 'Неможливо виконати команду: ';
17
  $PHPMAILER_LANG['instantiate'] = 'Неможливо запустити функцію mail.';
18
  $PHPMAILER_LANG['provide_address'] = 'Будь-ласка, введіть хоча б одну адресу e-mail отримувача.';
19
  $PHPMAILER_LANG['mailer_not_supported'] = ' - поштовий сервер не підтримується.';
20
+ $PHPMAILER_LANG['recipients_failed'] = 'Помилка SMTP: відправлення наступним отримувачам не вдалося: ';
21
  $PHPMAILER_LANG['empty_message'] = 'Пусте тіло повідомлення';
22
+ $PHPMAILER_LANG['invalid_address'] = 'Не відправлено, невірний формат адреси e-mail: ';
23
  $PHPMAILER_LANG['signing'] = 'Помилка підпису: ';
24
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'Помилка з\'єднання із SMTP-сервером';
25
  $PHPMAILER_LANG['smtp_error'] = 'Помилка SMTP-сервера: ';
26
  $PHPMAILER_LANG['variable_set'] = 'Неможливо встановити або перевстановити змінну: ';
27
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-vi.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Vietnamese (Tiếng Việt) PHPMailer language file: refer to English translation for definitive list.
4
+ * @package PHPMailer
5
+ * @author VINADES.,JSC <contact@vinades.vn>
6
+ */
7
+
8
+ $PHPMAILER_LANG['authenticate'] = 'Lỗi SMTP: Không thể xác thực.';
9
+ $PHPMAILER_LANG['connect_host'] = 'Lỗi SMTP: Không thể kết nối máy chủ SMTP.';
10
+ $PHPMAILER_LANG['data_not_accepted'] = 'Lỗi SMTP: Dữ liệu không được chấp nhận.';
11
+ $PHPMAILER_LANG['empty_message'] = 'Không có nội dung';
12
+ $PHPMAILER_LANG['encoding'] = 'Mã hóa không xác định: ';
13
+ $PHPMAILER_LANG['execute'] = 'Không thực hiện được: ';
14
+ $PHPMAILER_LANG['file_access'] = 'Không thể truy cập tệp tin ';
15
+ $PHPMAILER_LANG['file_open'] = 'Lỗi Tập tin: Không thể mở tệp tin: ';
16
+ $PHPMAILER_LANG['from_failed'] = 'Lỗi địa chỉ gửi đi: ';
17
+ $PHPMAILER_LANG['instantiate'] = 'Không dùng được các hàm gửi thư.';
18
+ $PHPMAILER_LANG['invalid_address'] = 'Đại chỉ emai không đúng: ';
19
+ $PHPMAILER_LANG['mailer_not_supported'] = ' trình gửi thư không được hỗ trợ.';
20
+ $PHPMAILER_LANG['provide_address'] = 'Bạn phải cung cấp ít nhất một địa chỉ người nhận.';
21
+ $PHPMAILER_LANG['recipients_failed'] = 'Lỗi SMTP: lỗi địa chỉ người nhận: ';
22
+ $PHPMAILER_LANG['signing'] = 'Lỗi đăng nhập: ';
23
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'Lỗi kết nối với SMTP';
24
+ $PHPMAILER_LANG['smtp_error'] = 'Lỗi máy chủ smtp ';
25
+ $PHPMAILER_LANG['variable_set'] = 'Không thể thiết lập hoặc thiết lập lại biến: ';
26
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
phpmailer/language/phpmailer.lang-zh.php CHANGED
@@ -1,25 +1,28 @@
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: ';
 
1
  <?php
2
  /**
3
+ * Traditional Chinese PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author liqwei <liqwei@liqwei.com>
6
+ * @author Peter Dave Hello <@PeterDaveHello/>
7
+ * @author Jason Chiang <xcojad@gmail.com>
8
+ */
9
 
10
+ $PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登入失敗。';
11
+ $PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連線到 SMTP 主機。';
12
+ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 錯誤:無法接受的資料。';
13
+ $PHPMAILER_LANG['empty_message'] = '郵件內容為空';
14
+ $PHPMAILER_LANG['encoding'] = '未知編碼: ';
15
+ $PHPMAILER_LANG['execute'] = '無法執行:';
16
+ $PHPMAILER_LANG['file_access'] = '無法存取檔案:';
17
+ $PHPMAILER_LANG['file_open'] = '檔案錯誤:無法開啟檔案:';
18
+ $PHPMAILER_LANG['from_failed'] = '發送地址錯誤:';
19
+ $PHPMAILER_LANG['instantiate'] = '未知函數呼叫。';
20
+ $PHPMAILER_LANG['invalid_address'] = '因為電子郵件地址無效,無法傳送: ';
21
+ $PHPMAILER_LANG['mailer_not_supported'] = '不支援的發信客戶端。';
22
+ $PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。';
23
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:以下收件人地址錯誤:';
24
+ $PHPMAILER_LANG['signing'] = '電子簽章錯誤: ';
25
+ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP 連線失敗';
26
+ $PHPMAILER_LANG['smtp_error'] = 'SMTP 伺服器錯誤: ';
27
+ $PHPMAILER_LANG['variable_set'] = '無法設定或重設變數: ';
28
+ $PHPMAILER_LANG['extension_missing'] = '遺失模組 Extension: ';
phpmailer/language/phpmailer.lang-zh_cn.php CHANGED
@@ -1,26 +1,27 @@
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
- * @author young <masxy@foxmail.com> blog:binaryoung.com
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'] = '邮件正文为空。';
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['invalid_address'] = '发送失败,电子邮箱地址是无效的。';
20
  $PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。';
21
- $PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。';
22
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:';
23
  $PHPMAILER_LANG['signing'] = '登录失败:';
24
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP服务器连接失败。';
25
  $PHPMAILER_LANG['smtp_error'] = 'SMTP服务器出错: ';
26
  $PHPMAILER_LANG['variable_set'] = '无法设置或重置变量:';
 
1
  <?php
2
  /**
3
+ * Simplified Chinese PHPMailer language file: refer to English translation for definitive list
4
+ * @package PHPMailer
5
+ * @author liqwei <liqwei@liqwei.com>
6
+ * @author young <masxy@foxmail.com>
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'] = '邮件正文为空。';
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['invalid_address'] = '发送失败,电子邮箱地址是无效的:';
20
  $PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。';
21
+ $PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。';
22
+ $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:';
23
  $PHPMAILER_LANG['signing'] = '登录失败:';
24
  $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP服务器连接失败。';
25
  $PHPMAILER_LANG['smtp_error'] = 'SMTP服务器出错: ';
26
  $PHPMAILER_LANG['variable_set'] = '无法设置或重置变量:';
27
+ //$PHPMAILER_LANG['extension_missing'] = 'Extension missing: ';
readme.txt CHANGED
@@ -219,6 +219,10 @@ It is highly recommended that you upgrade to WP Live Chat Support version 4.4.0
219
 
220
  == Changelog ==
221
 
 
 
 
 
222
 
223
  = 7.0.00 - 2016-12-14 - Medium Priority =
224
  * Major performance improvements - 300% reduction in DB calls
@@ -766,4 +770,4 @@ It is highly recommended that you upgrade to WP Live Chat Support version 4.4.0
766
  * More text fields can be customized
767
 
768
  = 1.0 =
769
- * Launch!
219
 
220
  == Changelog ==
221
 
222
+ = 7.0.01 - 2017-01-03 =
223
+ * Fixed a bug that caused the chat to disappear after being opened for some users
224
+ * Changes made to the German language files
225
+ * PHPMailer has been updated to the latest version
226
 
227
  = 7.0.00 - 2016-12-14 - Medium Priority =
228
  * Major performance improvements - 300% reduction in DB calls
770
  * More text fields can be customized
771
 
772
  = 1.0 =
773
+ * Launch!
wp-live-chat-support.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: WP Live Chat Support
4
  Plugin URI: http://www.wp-livechat.com
5
  Description: The easiest to use website live chat plugin. Let your visitors chat with you and increase sales conversion rates with WP Live Chat Support. No third party connection required!
6
- Version: 7.0.00
7
  Author: WP-LiveChat
8
  Author URI: http://www.wp-livechat.com
9
  Text Domain: wplivechat
@@ -11,6 +11,11 @@
11
  */
12
 
13
  /*
 
 
 
 
 
14
  * 7.0.00 - 2016-12-14
15
  * Major performance improvements - 300% reduction in DB calls
16
  * Node Server Integration (Experimental)
@@ -464,7 +469,7 @@ global $wplc_tblname_offline_msgs;
464
  $wplc_tblname_offline_msgs = $wpdb->prefix . "wplc_offline_messages";
465
  $wplc_tblname_chats = $wpdb->prefix . "wplc_chat_sessions";
466
  $wplc_tblname_msgs = $wpdb->prefix . "wplc_chat_msgs";
467
- $wplc_version = "7.0.00";
468
 
469
  define('WPLC_BASIC_PLUGIN_DIR', dirname(__FILE__));
470
  define('WPLC_BASIC_PLUGIN_URL', plugins_url() . "/wp-live-chat-support/");
3
  Plugin Name: WP Live Chat Support
4
  Plugin URI: http://www.wp-livechat.com
5
  Description: The easiest to use website live chat plugin. Let your visitors chat with you and increase sales conversion rates with WP Live Chat Support. No third party connection required!
6
+ Version: 7.0.01
7
  Author: WP-LiveChat
8
  Author URI: http://www.wp-livechat.com
9
  Text Domain: wplivechat
11
  */
12
 
13
  /*
14
+ * 7.0.01 - 2017-01-03
15
+ * Fixed a bug that caused the chat to disappear after being opened for some users
16
+ * Changes made to the language files
17
+ * PHPMailer has been updated to the latest version
18
+ *
19
  * 7.0.00 - 2016-12-14
20
  * Major performance improvements - 300% reduction in DB calls
21
  * Node Server Integration (Experimental)
469
  $wplc_tblname_offline_msgs = $wpdb->prefix . "wplc_offline_messages";
470
  $wplc_tblname_chats = $wpdb->prefix . "wplc_chat_sessions";
471
  $wplc_tblname_msgs = $wpdb->prefix . "wplc_chat_msgs";
472
+ $wplc_version = "7.0.01";
473
 
474
  define('WPLC_BASIC_PLUGIN_DIR', dirname(__FILE__));
475
  define('WPLC_BASIC_PLUGIN_URL', plugins_url() . "/wp-live-chat-support/");