Custom Contact Forms - Version 4.0.3

Version Description

  • custom-contact-forms-front.php - PHPMailer bug fixed, form redirect fixed
  • custom-contact-forms-static.php - Form redirect function added
  • custom-contact-forms-admin.php - redirects fixed, phpmailer bug fixed
  • widget/phpmailer - deleted
  • widget/db/custom-contact-forms-db.php - table charsets changed to UTF8
Download this release

Release Info

Developer tlovett1
Plugin Icon 128x128 Custom Contact Forms
Version 4.0.3
Comparing to
See all releases

Code changes from version 4.0.2 to 4.0.3

custom-contact-forms-admin.php CHANGED
@@ -37,7 +37,7 @@ if (!class_exists('CustomContactFormsAdmin')) {
37
  $transit = new CustomContactFormsExport(parent::getAdminOptionsName());
38
  $transit->exportAll();
39
  $file = $transit->exportToFile();
40
- wp_redirect(WP_PLUGIN_URL . '/custom-contact-forms/download.php?location=export/' . $file);
41
  }
42
  }
43
 
@@ -54,14 +54,15 @@ if (!class_exists('CustomContactFormsAdmin')) {
54
  $settings['import_saved_submissions'] = ($_POST['ccf_import_saved_submissions'] == 1) ? true : false;
55
  $settings['mode'] = ($_POST['ccf_clear_import']) ? 'clear_import' : 'merge_import';
56
  $transit->importFromFile($_FILES['import_file'], $settings);
57
- wp_redirect('options-general.php?page=custom-contact-forms');
58
  }
59
  }
60
 
61
  function contactAuthor($name, $email, $website, $message, $type) {
62
  if (empty($message)) return false;
63
- require_once('modules/phpmailer/class.phpmailer.php');
64
- $mail = new PHPMailer();
 
65
  $body = "Name: $name<br />\n";
66
  $body .= "Email: $email<br />\n";
67
  $body .= "Website: $website<br />\n";
37
  $transit = new CustomContactFormsExport(parent::getAdminOptionsName());
38
  $transit->exportAll();
39
  $file = $transit->exportToFile();
40
+ CustomContactFormsStatic::redirect(WP_PLUGIN_URL . '/custom-contact-forms/download.php?location=export/' . $file);
41
  }
42
  }
43
 
54
  $settings['import_saved_submissions'] = ($_POST['ccf_import_saved_submissions'] == 1) ? true : false;
55
  $settings['mode'] = ($_POST['ccf_clear_import']) ? 'clear_import' : 'merge_import';
56
  $transit->importFromFile($_FILES['import_file'], $settings);
57
+ CustomContactFormsStatic::redirect('options-general.php?page=custom-contact-forms');
58
  }
59
  }
60
 
61
  function contactAuthor($name, $email, $website, $message, $type) {
62
  if (empty($message)) return false;
63
+ if (!class_exists('PHPMailer'))
64
+ require_once(ABSPATH . "wp-includes/class-phpmailer.php");
65
+ $mail = new PHPMailer(false);
66
  $body = "Name: $name<br />\n";
67
  $body .= "Email: $email<br />\n";
68
  $body .= "Website: $website<br />\n";
custom-contact-forms-front.php CHANGED
@@ -187,8 +187,7 @@ if (!class_exists('CustomContactFormsFront')) {
187
  $field_options .= '<option'.$option_sel.''.$option_value.'>' . $option->option_label . '</option>' . "\n";
188
  }
189
  if (!empty($options)) {
190
- if (!$is_sidebar) $out .= '<div>'."\n".'<select '.$instructions.' '.$input_id.' name="'.CustomContactFormsStatic::decodeOption($field->field_slug, 1, 1).'" class="'.$field->field_class.' '.$tooltip_class.'">'."\n".$field_options.'</select>'."\n".'<label class="checkbox" for="'.CustomContactFormsStatic::decodeOption($field->field_slug, 1, 1).'">'. $req .CustomContactFormsStatic::decodeOption($field->field_label, 1, 1).'</label>'."\n".'</div>' . "\n";
191
- else $out .= '<div>'."\n".'<label for="'.CustomContactFormsStatic::decodeOption($field->field_slug, 1, 1).'">'. $req .CustomContactFormsStatic::decodeOption($field->field_label, 1, 1).'</label>'."\n".'<select class="'.$field->field_class.' '.$tooltip_class.'" '.$instructions.' '.$input_id.' name="'.CustomContactFormsStatic::decodeOption($field->field_slug, 1, 1).'">'."\n".$field_options.'</select>'."\n".'</div>' . "\n";
192
  }
193
  } elseif ($field->field_type == 'Radio') {
194
  $field_options = '';
@@ -274,8 +273,9 @@ if (!class_exists('CustomContactFormsFront')) {
274
  parent::insertUserData($data_object);
275
  $body .= "<br />\n" . htmlspecialchars($lang['form_page']) . $_SERVER['SERVER_NAME']. $_SERVER['REQUEST_URI'] . "<br />\n" . $lang['sender_ip'] . $_SERVER['REMOTE_ADDR'] . "<br />\n";
276
  if ($admin_options['email_form_submissions'] == 1) {
277
- require_once('modules/phpmailer/class.phpmailer.php');
278
- $mail = new PHPMailer();
 
279
  if ($admin_options['mail_function'] == 'smtp') {
280
  $mail->IsSMTP();
281
  $mail->Host = $admin_options['smtp_host'];
@@ -287,14 +287,15 @@ if (!class_exists('CustomContactFormsFront')) {
287
  } else
288
  $mail->SMTPAuth = false;
289
  }
290
- $mail->SetFrom($admin_options['default_from_email'], 'Custom Contact Forms');
 
291
  $mail->AddAddress($_POST['destination_email']);
292
  $mail->Subject = $admin_options['default_form_subject'];
293
  $mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
294
  $mail->MsgHTML(stripslashes($body));
295
  $mail->Send();
296
  } if ($_POST['thank_you_page'])
297
- wp_redirect($_POST['thank_you_page']);
298
  $this->current_thank_you_message = (!empty($_POST['success_message'])) ? $_POST['success_message'] : $admin_options['form_success_message'];
299
  $this->current_form = 0;
300
  add_action('wp_footer', array(&$this, 'insertFormSuccessCode'), 1);
@@ -367,7 +368,8 @@ if (!class_exists('CustomContactFormsFront')) {
367
  parent::insertUserData($data_object);
368
  if ($admin_options['email_form_submissions'] == '1') {
369
  $body .= "<br />\n" . htmlspecialchars($lang['form_page']) . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] . "<br />\n" . $lang['sender_ip'] . $_SERVER['REMOTE_ADDR'] . "<br />\n";
370
- require_once('modules/phpmailer/class.phpmailer.php');
 
371
  $mail = new PHPMailer(false);
372
  if ($admin_options['mail_function'] == 'smtp') {
373
  $mail->IsSMTP();
@@ -386,14 +388,18 @@ if (!class_exists('CustomContactFormsFront')) {
386
  foreach ($dest_email_array as $em)
387
  $mail->AddAddress($em);
388
  }
389
- if ($reply != NULL && $this->validEmail($reply)) $mail->SetFrom($reply, 'Custom Contact Forms');
390
- else $mail->SetFrom($admin_options['default_from_email'], 'Custom Contact Forms');
 
 
 
 
391
  $mail->Subject = $admin_options['default_form_subject'];
392
  $mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
393
  $mail->MsgHTML(stripslashes($body));
394
  $mail->Send();
395
  } if (!empty($form->form_thank_you_page))
396
- wp_redirect($form->form_thank_you_page);
397
  $this->current_form = $form->id;
398
  add_action('wp_footer', array(&$this, 'insertFormSuccessCode'), 1);
399
  }
187
  $field_options .= '<option'.$option_sel.''.$option_value.'>' . $option->option_label . '</option>' . "\n";
188
  }
189
  if (!empty($options)) {
190
+ $out .= '<div>'."\n".'<label for="'.CustomContactFormsStatic::decodeOption($field->field_slug, 1, 1).'">'. $req .CustomContactFormsStatic::decodeOption($field->field_label, 1, 1).'</label>'."\n".'<select class="'.$field->field_class.' '.$tooltip_class.'" '.$instructions.' '.$input_id.' name="'.CustomContactFormsStatic::decodeOption($field->field_slug, 1, 1).'">'."\n".$field_options.'</select>'."\n".'</div>' . "\n";
 
191
  }
192
  } elseif ($field->field_type == 'Radio') {
193
  $field_options = '';
273
  parent::insertUserData($data_object);
274
  $body .= "<br />\n" . htmlspecialchars($lang['form_page']) . $_SERVER['SERVER_NAME']. $_SERVER['REQUEST_URI'] . "<br />\n" . $lang['sender_ip'] . $_SERVER['REMOTE_ADDR'] . "<br />\n";
275
  if ($admin_options['email_form_submissions'] == 1) {
276
+ if (!class_exists('PHPMailer'))
277
+ require_once(ABSPATH . "wp-includes/class-phpmailer.php");
278
+ $mail = new PHPMailer(false);
279
  if ($admin_options['mail_function'] == 'smtp') {
280
  $mail->IsSMTP();
281
  $mail->Host = $admin_options['smtp_host'];
287
  } else
288
  $mail->SMTPAuth = false;
289
  }
290
+ $mail->From = $admin_options['default_from_email'];
291
+ $mail->FromName = 'Custom Contact Forms';
292
  $mail->AddAddress($_POST['destination_email']);
293
  $mail->Subject = $admin_options['default_form_subject'];
294
  $mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
295
  $mail->MsgHTML(stripslashes($body));
296
  $mail->Send();
297
  } if ($_POST['thank_you_page'])
298
+ CustomContactFormsStatic::redirect($_POST['thank_you_page']);
299
  $this->current_thank_you_message = (!empty($_POST['success_message'])) ? $_POST['success_message'] : $admin_options['form_success_message'];
300
  $this->current_form = 0;
301
  add_action('wp_footer', array(&$this, 'insertFormSuccessCode'), 1);
368
  parent::insertUserData($data_object);
369
  if ($admin_options['email_form_submissions'] == '1') {
370
  $body .= "<br />\n" . htmlspecialchars($lang['form_page']) . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] . "<br />\n" . $lang['sender_ip'] . $_SERVER['REMOTE_ADDR'] . "<br />\n";
371
+ if (!class_exists('PHPMailer'))
372
+ require_once(ABSPATH . "wp-includes/class-phpmailer.php");
373
  $mail = new PHPMailer(false);
374
  if ($admin_options['mail_function'] == 'smtp') {
375
  $mail->IsSMTP();
388
  foreach ($dest_email_array as $em)
389
  $mail->AddAddress($em);
390
  }
391
+ $mail->FromName = 'Custom Contact Forms';
392
+ if ($reply != NULL && $this->validEmail($reply)) {
393
+ $mail->From = $reply;
394
+ } else {
395
+ $mail->From = $admin_options['default_from_email'];
396
+ }
397
  $mail->Subject = $admin_options['default_form_subject'];
398
  $mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
399
  $mail->MsgHTML(stripslashes($body));
400
  $mail->Send();
401
  } if (!empty($form->form_thank_you_page))
402
+ CustomContactFormsStatic::redirect($form->form_thank_you_page);
403
  $this->current_form = $form->id;
404
  add_action('wp_footer', array(&$this, 'insertFormSuccessCode'), 1);
405
  }
custom-contact-forms-static.php CHANGED
@@ -14,6 +14,13 @@ if (!class_exists('CustomContactFormsStatic')) {
14
  if (!session_id()) session_start();
15
  }
16
 
 
 
 
 
 
 
 
17
  function getWPTablePrefix() {
18
  global $wpdb;
19
  return $wpdb->prefix;
14
  if (!session_id()) session_start();
15
  }
16
 
17
+ function redirect($location) {
18
+ if (!empty($location)) {
19
+ wp_redirect($location);
20
+ exit();
21
+ }
22
+ }
23
+
24
  function getWPTablePrefix() {
25
  global $wpdb;
26
  return $wpdb->prefix;
custom-contact-forms.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Custom Contact Forms
4
  Plugin URI: http://taylorlovett.com/wordpress-plugins
5
  Description: Guaranteed to be 1000X more customizable and intuitive than Fast Secure Contact Forms or Contact Form 7. Customize every aspect of your forms without any knowledge of CSS: borders, padding, sizes, colors. Ton's of great features. Required fields, form submissions saved to database, captchas, tooltip popovers, unlimited fields/forms/form styles, import/export, use a custom thank you page or built-in popover with a custom success message set for each form.
6
- Version: 4.0.2
7
  Author: Taylor Lovett
8
  Author URI: http://www.taylorlovett.com
9
  */
3
  Plugin Name: Custom Contact Forms
4
  Plugin URI: http://taylorlovett.com/wordpress-plugins
5
  Description: Guaranteed to be 1000X more customizable and intuitive than Fast Secure Contact Forms or Contact Form 7. Customize every aspect of your forms without any knowledge of CSS: borders, padding, sizes, colors. Ton's of great features. Required fields, form submissions saved to database, captchas, tooltip popovers, unlimited fields/forms/form styles, import/export, use a custom thank you page or built-in popover with a custom success message set for each form.
6
+ Version: 4.0.3
7
  Author: Taylor Lovett
8
  Author URI: http://www.taylorlovett.com
9
  */
modules/db/custom-contact-forms-db.php CHANGED
@@ -88,6 +88,14 @@ if (!class_exists('CustomContactFormsDB')) {
88
  return str_replace('#', '', str_replace(';', '', $style));
89
  }
90
 
 
 
 
 
 
 
 
 
91
  function updateTables() {
92
  global $wpdb;
93
  if (!$this->columnExists('user_field', CCF_FIELDS_TABLE))
@@ -150,7 +158,7 @@ if (!class_exists('CustomContactFormsDB')) {
150
  $wpdb->query("ALTER TABLE `" . CCF_FIELDS_TABLE . "` ADD `field_class` VARCHAR( 50 ) NOT NULL");
151
  if (!$this->columnExists('field_error', CCF_FIELDS_TABLE))
152
  $wpdb->query("ALTER TABLE `" . CCF_FIELDS_TABLE . "` ADD `field_error` VARCHAR( 300 ) NOT NULL");
153
-
154
  }
155
 
156
  function insertFixedFields() {
88
  return str_replace('#', '', str_replace(';', '', $style));
89
  }
90
 
91
+ function updateTableCharSets() {
92
+ global $wpdb;
93
+ foreach ($GLOBALS['ccf_tables_array'] as $table) {
94
+ $wpdb->query("ALTER TABLE `" . $table . "` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
95
+ $wpdb->query("ALTER TABLE `" . $table . "` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci");
96
+ }
97
+ }
98
+
99
  function updateTables() {
100
  global $wpdb;
101
  if (!$this->columnExists('user_field', CCF_FIELDS_TABLE))
158
  $wpdb->query("ALTER TABLE `" . CCF_FIELDS_TABLE . "` ADD `field_class` VARCHAR( 50 ) NOT NULL");
159
  if (!$this->columnExists('field_error', CCF_FIELDS_TABLE))
160
  $wpdb->query("ALTER TABLE `" . CCF_FIELDS_TABLE . "` ADD `field_error` VARCHAR( 300 ) NOT NULL");
161
+ $this->updateTableCharSets();
162
  }
163
 
164
  function insertFixedFields() {
modules/phpmailer/class.phpmailer.php DELETED
@@ -1,2320 +0,0 @@
1
- <?php
2
- /*~ class.phpmailer.php
3
- .---------------------------------------------------------------------------.
4
- | Software: PHPMailer - PHP email class |
5
- | Version: 5.1 |
6
- | Contact: via sourceforge.net support pages (also www.worxware.com) |
7
- | Info: http://phpmailer.sourceforge.net |
8
- | Support: http://sourceforge.net/projects/phpmailer/ |
9
- | ------------------------------------------------------------------------- |
10
- | Admin: Andy Prevost (project admininistrator) |
11
- | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
12
- | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
13
- | Founder: Brent R. Matzelle (original founder) |
14
- | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
15
- | Copyright (c) 2001-2003, Brent R. Matzelle |
16
- | ------------------------------------------------------------------------- |
17
- | License: Distributed under the Lesser General Public License (LGPL) |
18
- | http://www.gnu.org/copyleft/lesser.html |
19
- | This program is distributed in the hope that it will be useful - WITHOUT |
20
- | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21
- | FITNESS FOR A PARTICULAR PURPOSE. |
22
- | ------------------------------------------------------------------------- |
23
- | We offer a number of paid services (www.worxware.com): |
24
- | - Web Hosting on highly optimized fast and secure servers |
25
- | - Technology Consulting |
26
- | - Oursourcing (highly qualified programmers and graphic designers) |
27
- '---------------------------------------------------------------------------'
28
- */
29
-
30
- /**
31
- * PHPMailer - PHP email transport class
32
- * NOTE: Requires PHP version 5 or later
33
- * @package PHPMailer
34
- * @author Andy Prevost
35
- * @author Marcus Bointon
36
- * @copyright 2004 - 2009 Andy Prevost
37
- * @version $Id: class.phpmailer.php 447 2009-05-25 01:36:38Z codeworxtech $
38
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
39
- */
40
-
41
- if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n");
42
-
43
- class PHPMailer {
44
-
45
- /////////////////////////////////////////////////
46
- // PROPERTIES, PUBLIC
47
- /////////////////////////////////////////////////
48
-
49
- /**
50
- * Email priority (1 = High, 3 = Normal, 5 = low).
51
- * @var int
52
- */
53
- public $Priority = 3;
54
-
55
- /**
56
- * Sets the CharSet of the message.
57
- * @var string
58
- */
59
- public $CharSet = 'iso-8859-1';
60
-
61
- /**
62
- * Sets the Content-type of the message.
63
- * @var string
64
- */
65
- public $ContentType = 'text/plain';
66
-
67
- /**
68
- * Sets the Encoding of the message. Options for this are
69
- * "8bit", "7bit", "binary", "base64", and "quoted-printable".
70
- * @var string
71
- */
72
- public $Encoding = '8bit';
73
-
74
- /**
75
- * Holds the most recent mailer error message.
76
- * @var string
77
- */
78
- public $ErrorInfo = '';
79
-
80
- /**
81
- * Sets the From email address for the message.
82
- * @var string
83
- */
84
- public $From = 'root@localhost';
85
-
86
- /**
87
- * Sets the From name of the message.
88
- * @var string
89
- */
90
- public $FromName = 'Root User';
91
-
92
- /**
93
- * Sets the Sender email (Return-Path) of the message. If not empty,
94
- * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
95
- * @var string
96
- */
97
- public $Sender = '';
98
-
99
- /**
100
- * Sets the Subject of the message.
101
- * @var string
102
- */
103
- public $Subject = '';
104
-
105
- /**
106
- * Sets the Body of the message. This can be either an HTML or text body.
107
- * If HTML then run IsHTML(true).
108
- * @var string
109
- */
110
- public $Body = '';
111
-
112
- /**
113
- * Sets the text-only body of the message. This automatically sets the
114
- * email to multipart/alternative. This body can be read by mail
115
- * clients that do not have HTML email capability such as mutt. Clients
116
- * that can read HTML will view the normal Body.
117
- * @var string
118
- */
119
- public $AltBody = '';
120
-
121
- /**
122
- * Sets word wrapping on the body of the message to a given number of
123
- * characters.
124
- * @var int
125
- */
126
- public $WordWrap = 0;
127
-
128
- /**
129
- * Method to send mail: ("mail", "sendmail", or "smtp").
130
- * @var string
131
- */
132
- public $Mailer = 'mail';
133
-
134
- /**
135
- * Sets the path of the sendmail program.
136
- * @var string
137
- */
138
- public $Sendmail = '/usr/sbin/sendmail';
139
-
140
- /**
141
- * Path to PHPMailer plugins. Useful if the SMTP class
142
- * is in a different directory than the PHP include path.
143
- * @var string
144
- */
145
- public $PluginDir = '';
146
-
147
- /**
148
- * Sets the email address that a reading confirmation will be sent.
149
- * @var string
150
- */
151
- public $ConfirmReadingTo = '';
152
-
153
- /**
154
- * Sets the hostname to use in Message-Id and Received headers
155
- * and as default HELO string. If empty, the value returned
156
- * by SERVER_NAME is used or 'localhost.localdomain'.
157
- * @var string
158
- */
159
- public $Hostname = '';
160
-
161
- /**
162
- * Sets the message ID to be used in the Message-Id header.
163
- * If empty, a unique id will be generated.
164
- * @var string
165
- */
166
- public $MessageID = '';
167
-
168
- /////////////////////////////////////////////////
169
- // PROPERTIES FOR SMTP
170
- /////////////////////////////////////////////////
171
-
172
- /**
173
- * Sets the SMTP hosts. All hosts must be separated by a
174
- * semicolon. You can also specify a different port
175
- * for each host by using this format: [hostname:port]
176
- * (e.g. "smtp1.example.com:25;smtp2.example.com").
177
- * Hosts will be tried in order.
178
- * @var string
179
- */
180
- public $Host = 'localhost';
181
-
182
- /**
183
- * Sets the default SMTP server port.
184
- * @var int
185
- */
186
- public $Port = 25;
187
-
188
- /**
189
- * Sets the SMTP HELO of the message (Default is $Hostname).
190
- * @var string
191
- */
192
- public $Helo = '';
193
-
194
- /**
195
- * Sets connection prefix.
196
- * Options are "", "ssl" or "tls"
197
- * @var string
198
- */
199
- public $SMTPSecure = '';
200
-
201
- /**
202
- * Sets SMTP authentication. Utilizes the Username and Password variables.
203
- * @var bool
204
- */
205
- public $SMTPAuth = false;
206
-
207
- /**
208
- * Sets SMTP username.
209
- * @var string
210
- */
211
- public $Username = '';
212
-
213
- /**
214
- * Sets SMTP password.
215
- * @var string
216
- */
217
- public $Password = '';
218
-
219
- /**
220
- * Sets the SMTP server timeout in seconds.
221
- * This function will not work with the win32 version.
222
- * @var int
223
- */
224
- public $Timeout = 10;
225
-
226
- /**
227
- * Sets SMTP class debugging on or off.
228
- * @var bool
229
- */
230
- public $SMTPDebug = false;
231
-
232
- /**
233
- * Prevents the SMTP connection from being closed after each mail
234
- * sending. If this is set to true then to close the connection
235
- * requires an explicit call to SmtpClose().
236
- * @var bool
237
- */
238
- public $SMTPKeepAlive = false;
239
-
240
- /**
241
- * Provides the ability to have the TO field process individual
242
- * emails, instead of sending to entire TO addresses
243
- * @var bool
244
- */
245
- public $SingleTo = false;
246
-
247
- /**
248
- * If SingleTo is true, this provides the array to hold the email addresses
249
- * @var bool
250
- */
251
- public $SingleToArray = array();
252
-
253
- /**
254
- * Provides the ability to change the line ending
255
- * @var string
256
- */
257
- public $LE = "\n";
258
-
259
- /**
260
- * Used with DKIM DNS Resource Record
261
- * @var string
262
- */
263
- public $DKIM_selector = 'phpmailer';
264
-
265
- /**
266
- * Used with DKIM DNS Resource Record
267
- * optional, in format of email address 'you@yourdomain.com'
268
- * @var string
269
- */
270
- public $DKIM_identity = '';
271
-
272
- /**
273
- * Used with DKIM DNS Resource Record
274
- * optional, in format of email address 'you@yourdomain.com'
275
- * @var string
276
- */
277
- public $DKIM_domain = '';
278
-
279
- /**
280
- * Used with DKIM DNS Resource Record
281
- * optional, in format of email address 'you@yourdomain.com'
282
- * @var string
283
- */
284
- public $DKIM_private = '';
285
-
286
- /**
287
- * Callback Action function name
288
- * the function that handles the result of the send email action. Parameters:
289
- * bool $result result of the send action
290
- * string $to email address of the recipient
291
- * string $cc cc email addresses
292
- * string $bcc bcc email addresses
293
- * string $subject the subject
294
- * string $body the email body
295
- * @var string
296
- */
297
- public $action_function = ''; //'callbackAction';
298
-
299
- /**
300
- * Sets the PHPMailer Version number
301
- * @var string
302
- */
303
- public $Version = '5.1';
304
-
305
- /////////////////////////////////////////////////
306
- // PROPERTIES, PRIVATE AND PROTECTED
307
- /////////////////////////////////////////////////
308
-
309
- private $smtp = NULL;
310
- private $to = array();
311
- private $cc = array();
312
- private $bcc = array();
313
- private $ReplyTo = array();
314
- private $all_recipients = array();
315
- private $attachment = array();
316
- private $CustomHeader = array();
317
- private $message_type = '';
318
- private $boundary = array();
319
- protected $language = array();
320
- private $error_count = 0;
321
- private $sign_cert_file = "";
322
- private $sign_key_file = "";
323
- private $sign_key_pass = "";
324
- private $exceptions = false;
325
-
326
- /////////////////////////////////////////////////
327
- // CONSTANTS
328
- /////////////////////////////////////////////////
329
-
330
- const STOP_MESSAGE = 0; // message only, continue processing
331
- const STOP_CONTINUE = 1; // message?, likely ok to continue processing
332
- const STOP_CRITICAL = 2; // message, plus full stop, critical error reached
333
-
334
- /////////////////////////////////////////////////
335
- // METHODS, VARIABLES
336
- /////////////////////////////////////////////////
337
-
338
- /**
339
- * Constructor
340
- * @param boolean $exceptions Should we throw external exceptions?
341
- */
342
- public function __construct($exceptions = false) {
343
- $this->exceptions = ($exceptions == true);
344
- }
345
-
346
- /**
347
- * Sets message type to HTML.
348
- * @param bool $ishtml
349
- * @return void
350
- */
351
- public function IsHTML($ishtml = true) {
352
- if ($ishtml) {
353
- $this->ContentType = 'text/html';
354
- } else {
355
- $this->ContentType = 'text/plain';
356
- }
357
- }
358
-
359
- /**
360
- * Sets Mailer to send message using SMTP.
361
- * @return void
362
- */
363
- public function IsSMTP() {
364
- $this->Mailer = 'smtp';
365
- }
366
-
367
- /**
368
- * Sets Mailer to send message using PHP mail() function.
369
- * @return void
370
- */
371
- public function IsMail() {
372
- $this->Mailer = 'mail';
373
- }
374
-
375
- /**
376
- * Sets Mailer to send message using the $Sendmail program.
377
- * @return void
378
- */
379
- public function IsSendmail() {
380
- if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
381
- $this->Sendmail = '/var/qmail/bin/sendmail';
382
- }
383
- $this->Mailer = 'sendmail';
384
- }
385
-
386
- /**
387
- * Sets Mailer to send message using the qmail MTA.
388
- * @return void
389
- */
390
- public function IsQmail() {
391
- if (stristr(ini_get('sendmail_path'), 'qmail')) {
392
- $this->Sendmail = '/var/qmail/bin/sendmail';
393
- }
394
- $this->Mailer = 'sendmail';
395
- }
396
-
397
- /////////////////////////////////////////////////
398
- // METHODS, RECIPIENTS
399
- /////////////////////////////////////////////////
400
-
401
- /**
402
- * Adds a "To" address.
403
- * @param string $address
404
- * @param string $name
405
- * @return boolean true on success, false if address already used
406
- */
407
- public function AddAddress($address, $name = '') {
408
- return $this->AddAnAddress('to', $address, $name);
409
- }
410
-
411
- /**
412
- * Adds a "Cc" address.
413
- * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
414
- * @param string $address
415
- * @param string $name
416
- * @return boolean true on success, false if address already used
417
- */
418
- public function AddCC($address, $name = '') {
419
- return $this->AddAnAddress('cc', $address, $name);
420
- }
421
-
422
- /**
423
- * Adds a "Bcc" address.
424
- * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
425
- * @param string $address
426
- * @param string $name
427
- * @return boolean true on success, false if address already used
428
- */
429
- public function AddBCC($address, $name = '') {
430
- return $this->AddAnAddress('bcc', $address, $name);
431
- }
432
-
433
- /**
434
- * Adds a "Reply-to" address.
435
- * @param string $address
436
- * @param string $name
437
- * @return boolean
438
- */
439
- public function AddReplyTo($address, $name = '') {
440
- return $this->AddAnAddress('ReplyTo', $address, $name);
441
- }
442
-
443
- /**
444
- * Adds an address to one of the recipient arrays
445
- * Addresses that have been added already return false, but do not throw exceptions
446
- * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
447
- * @param string $address The email address to send to
448
- * @param string $name
449
- * @return boolean true on success, false if address already used or invalid in some way
450
- * @access private
451
- */
452
- private function AddAnAddress($kind, $address, $name = '') {
453
- if (!preg_match('/^(to|cc|bcc|ReplyTo)$/', $kind)) {
454
- echo 'Invalid recipient array: ' . kind;
455
- return false;
456
- }
457
- $address = trim($address);
458
- $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
459
- if (!self::ValidateAddress($address)) {
460
- $this->SetError($this->Lang('invalid_address').': '. $address);
461
- if ($this->exceptions) {
462
- throw new phpmailerException($this->Lang('invalid_address').': '.$address);
463
- }
464
- echo $this->Lang('invalid_address').': '.$address;
465
- return false;
466
- }
467
- if ($kind != 'ReplyTo') {
468
- if (!isset($this->all_recipients[strtolower($address)])) {
469
- array_push($this->$kind, array($address, $name));
470
- $this->all_recipients[strtolower($address)] = true;
471
- return true;
472
- }
473
- } else {
474
- if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
475
- $this->ReplyTo[strtolower($address)] = array($address, $name);
476
- return true;
477
- }
478
- }
479
- return false;
480
- }
481
-
482
- /**
483
- * Set the From and FromName properties
484
- * @param string $address
485
- * @param string $name
486
- * @return boolean
487
- */
488
- public function SetFrom($address, $name = '',$auto=1) {
489
- $address = trim($address);
490
- $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
491
- if (!self::ValidateAddress($address)) {
492
- $this->SetError($this->Lang('invalid_address').': '. $address);
493
- if ($this->exceptions) {
494
- throw new phpmailerException($this->Lang('invalid_address').': '.$address);
495
- }
496
- echo $this->Lang('invalid_address').': '.$address;
497
- return false;
498
- }
499
- $this->From = $address;
500
- $this->FromName = $name;
501
- if ($auto) {
502
- if (empty($this->ReplyTo)) {
503
- $this->AddAnAddress('ReplyTo', $address, $name);
504
- }
505
- if (empty($this->Sender)) {
506
- $this->Sender = $address;
507
- }
508
- }
509
- return true;
510
- }
511
-
512
- /**
513
- * Check that a string looks roughly like an email address should
514
- * Static so it can be used without instantiation
515
- * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator
516
- * Conforms approximately to RFC2822
517
- * @link http://www.hexillion.com/samples/#Regex Original pattern found here
518
- * @param string $address The email address to check
519
- * @return boolean
520
- * @static
521
- * @access public
522
- */
523
- public static function ValidateAddress($address) {
524
- if (function_exists('filter_var')) { //Introduced in PHP 5.2
525
- if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
526
- return false;
527
- } else {
528
- return true;
529
- }
530
- } else {
531
- return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
532
- }
533
- }
534
-
535
- /////////////////////////////////////////////////
536
- // METHODS, MAIL SENDING
537
- /////////////////////////////////////////////////
538
-
539
- /**
540
- * Creates message and assigns Mailer. If the message is
541
- * not sent successfully then it returns false. Use the ErrorInfo
542
- * variable to view description of the error.
543
- * @return bool
544
- */
545
- public function Send() {
546
- try {
547
- if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
548
- throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL);
549
- }
550
-
551
- // Set whether the message is multipart/alternative
552
- if(!empty($this->AltBody)) {
553
- $this->ContentType = 'multipart/alternative';
554
- }
555
-
556
- $this->error_count = 0; // reset errors
557
- $this->SetMessageType();
558
- $header = $this->CreateHeader();
559
- $body = $this->CreateBody();
560
-
561
- if (empty($this->Body)) {
562
- throw new phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL);
563
- }
564
-
565
- // digitally sign with DKIM if enabled
566
- if ($this->DKIM_domain && $this->DKIM_private) {
567
- $header_dkim = $this->DKIM_Add($header,$this->Subject,$body);
568
- $header = str_replace("\r\n","\n",$header_dkim) . $header;
569
- }
570
-
571
- // Choose the mailer and send through it
572
- switch($this->Mailer) {
573
- case 'sendmail':
574
- return $this->SendmailSend($header, $body);
575
- case 'smtp':
576
- return $this->SmtpSend($header, $body);
577
- default:
578
- return $this->MailSend($header, $body);
579
- }
580
-
581
- } catch (phpmailerException $e) {
582
- $this->SetError($e->getMessage());
583
- if ($this->exceptions) {
584
- throw $e;
585
- }
586
- echo $e->getMessage()."\n";
587
- return false;
588
- }
589
- }
590
-
591
- /**
592
- * Sends mail using the $Sendmail program.
593
- * @param string $header The message headers
594
- * @param string $body The message body
595
- * @access protected
596
- * @return bool
597
- */
598
- protected function SendmailSend($header, $body) {
599
- if ($this->Sender != '') {
600
- $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
601
- } else {
602
- $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
603
- }
604
- if ($this->SingleTo === true) {
605
- foreach ($this->SingleToArray as $key => $val) {
606
- if(!@$mail = popen($sendmail, 'w')) {
607
- throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
608
- }
609
- fputs($mail, "To: " . $val . "\n");
610
- fputs($mail, $header);
611
- fputs($mail, $body);
612
- $result = pclose($mail);
613
- // implement call back function if it exists
614
- $isSent = ($result == 0) ? 1 : 0;
615
- $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body);
616
- if($result != 0) {
617
- throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
618
- }
619
- }
620
- } else {
621
- if(!@$mail = popen($sendmail, 'w')) {
622
- throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
623
- }
624
- fputs($mail, $header);
625
- fputs($mail, $body);
626
- $result = pclose($mail);
627
- // implement call back function if it exists
628
- $isSent = ($result == 0) ? 1 : 0;
629
- $this->doCallback($isSent,$this->to,$this->cc,$this->bcc,$this->Subject,$body);
630
- if($result != 0) {
631
- throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
632
- }
633
- }
634
- return true;
635
- }
636
-
637
- /**
638
- * Sends mail using the PHP mail() function.
639
- * @param string $header The message headers
640
- * @param string $body The message body
641
- * @access protected
642
- * @return bool
643
- */
644
- protected function MailSend($header, $body) {
645
- $toArr = array();
646
- foreach($this->to as $t) {
647
- $toArr[] = $this->AddrFormat($t);
648
- }
649
- $to = implode(', ', $toArr);
650
-
651
- $params = sprintf("-oi -f %s", $this->Sender);
652
- if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) {
653
- $old_from = ini_get('sendmail_from');
654
- ini_set('sendmail_from', $this->Sender);
655
- if ($this->SingleTo === true && count($toArr) > 1) {
656
- foreach ($toArr as $key => $val) {
657
- $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
658
- // implement call back function if it exists
659
- $isSent = ($rt == 1) ? 1 : 0;
660
- $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body);
661
- }
662
- } else {
663
- $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
664
- // implement call back function if it exists
665
- $isSent = ($rt == 1) ? 1 : 0;
666
- $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body);
667
- }
668
- } else {
669
- if ($this->SingleTo === true && count($toArr) > 1) {
670
- foreach ($toArr as $key => $val) {
671
- $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
672
- // implement call back function if it exists
673
- $isSent = ($rt == 1) ? 1 : 0;
674
- $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body);
675
- }
676
- } else {
677
- $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
678
- // implement call back function if it exists
679
- $isSent = ($rt == 1) ? 1 : 0;
680
- $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body);
681
- }
682
- }
683
- if (isset($old_from)) {
684
- ini_set('sendmail_from', $old_from);
685
- }
686
- if(!$rt) {
687
- throw new phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL);
688
- }
689
- return true;
690
- }
691
-
692
- /**
693
- * Sends mail via SMTP using PhpSMTP
694
- * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
695
- * @param string $header The message headers
696
- * @param string $body The message body
697
- * @uses SMTP
698
- * @access protected
699
- * @return bool
700
- */
701
- protected function SmtpSend($header, $body) {
702
- require_once $this->PluginDir . 'class.smtp.php';
703
- $bad_rcpt = array();
704
-
705
- if(!$this->SmtpConnect()) {
706
- throw new phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL);
707
- }
708
- $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
709
- if(!$this->smtp->Mail($smtp_from)) {
710
- throw new phpmailerException($this->Lang('from_failed') . $smtp_from, self::STOP_CRITICAL);
711
- }
712
-
713
- // Attempt to send attach all recipients
714
- foreach($this->to as $to) {
715
- if (!$this->smtp->Recipient($to[0])) {
716
- $bad_rcpt[] = $to[0];
717
- // implement call back function if it exists
718
- $isSent = 0;
719
- $this->doCallback($isSent,$to[0],'','',$this->Subject,$body);
720
- } else {
721
- // implement call back function if it exists
722
- $isSent = 1;
723
- $this->doCallback($isSent,$to[0],'','',$this->Subject,$body);
724
- }
725
- }
726
- foreach($this->cc as $cc) {
727
- if (!$this->smtp->Recipient($cc[0])) {
728
- $bad_rcpt[] = $cc[0];
729
- // implement call back function if it exists
730
- $isSent = 0;
731
- $this->doCallback($isSent,'',$cc[0],'',$this->Subject,$body);
732
- } else {
733
- // implement call back function if it exists
734
- $isSent = 1;
735
- $this->doCallback($isSent,'',$cc[0],'',$this->Subject,$body);
736
- }
737
- }
738
- foreach($this->bcc as $bcc) {
739
- if (!$this->smtp->Recipient($bcc[0])) {
740
- $bad_rcpt[] = $bcc[0];
741
- // implement call back function if it exists
742
- $isSent = 0;
743
- $this->doCallback($isSent,'','',$bcc[0],$this->Subject,$body);
744
- } else {
745
- // implement call back function if it exists
746
- $isSent = 1;
747
- $this->doCallback($isSent,'','',$bcc[0],$this->Subject,$body);
748
- }
749
- }
750
-
751
-
752
- if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses
753
- $badaddresses = implode(', ', $bad_rcpt);
754
- throw new phpmailerException($this->Lang('recipients_failed') . $badaddresses);
755
- }
756
- if(!$this->smtp->Data($header . $body)) {
757
- throw new phpmailerException($this->Lang('data_not_accepted'), self::STOP_CRITICAL);
758
- }
759
- if($this->SMTPKeepAlive == true) {
760
- $this->smtp->Reset();
761
- }
762
- return true;
763
- }
764
-
765
- /**
766
- * Initiates a connection to an SMTP server.
767
- * Returns false if the operation failed.
768
- * @uses SMTP
769
- * @access public
770
- * @return bool
771
- */
772
- public function SmtpConnect() {
773
- if(is_null($this->smtp)) {
774
- $this->smtp = new SMTP();
775
- }
776
-
777
- $this->smtp->do_debug = $this->SMTPDebug;
778
- $hosts = explode(';', $this->Host);
779
- $index = 0;
780
- $connection = $this->smtp->Connected();
781
-
782
- // Retry while there is no connection
783
- try {
784
- while($index < count($hosts) && !$connection) {
785
- $hostinfo = array();
786
- if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {
787
- $host = $hostinfo[1];
788
- $port = $hostinfo[2];
789
- } else {
790
- $host = $hosts[$index];
791
- $port = $this->Port;
792
- }
793
-
794
- $tls = ($this->SMTPSecure == 'tls');
795
- $ssl = ($this->SMTPSecure == 'ssl');
796
-
797
- if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) {
798
-
799
- $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname());
800
- $this->smtp->Hello($hello);
801
-
802
- if ($tls) {
803
- if (!$this->smtp->StartTLS()) {
804
- throw new phpmailerException($this->Lang('tls'));
805
- }
806
-
807
- //We must resend HELO after tls negotiation
808
- $this->smtp->Hello($hello);
809
- }
810
-
811
- $connection = true;
812
- if ($this->SMTPAuth) {
813
- if (!$this->smtp->Authenticate($this->Username, $this->Password)) {
814
- throw new phpmailerException($this->Lang('authenticate'));
815
- }
816
- }
817
- }
818
- $index++;
819
- if (!$connection) {
820
- throw new phpmailerException($this->Lang('connect_host'));
821
- }
822
- }
823
- } catch (phpmailerException $e) {
824
- $this->smtp->Reset();
825
- throw $e;
826
- }
827
- return true;
828
- }
829
-
830
- /**
831
- * Closes the active SMTP session if one exists.
832
- * @return void
833
- */
834
- public function SmtpClose() {
835
- if(!is_null($this->smtp)) {
836
- if($this->smtp->Connected()) {
837
- $this->smtp->Quit();
838
- $this->smtp->Close();
839
- }
840
- }
841
- }
842
-
843
- /**
844
- * Sets the language for all class error messages.
845
- * Returns false if it cannot load the language file. The default language is English.
846
- * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br")
847
- * @param string $lang_path Path to the language file directory
848
- * @access public
849
- */
850
- function SetLanguage($langcode = 'en', $lang_path = 'language/') {
851
- //Define full set of translatable strings
852
- $PHPMAILER_LANG = array(
853
- 'provide_address' => 'You must provide at least one recipient email address.',
854
- 'mailer_not_supported' => ' mailer is not supported.',
855
- 'execute' => 'Could not execute: ',
856
- 'instantiate' => 'Could not instantiate mail function.',
857
- 'authenticate' => 'SMTP Error: Could not authenticate.',
858
- 'from_failed' => 'The following From address failed: ',
859
- 'recipients_failed' => 'SMTP Error: The following recipients failed: ',
860
- 'data_not_accepted' => 'SMTP Error: Data not accepted.',
861
- 'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
862
- 'file_access' => 'Could not access file: ',
863
- 'file_open' => 'File Error: Could not open file: ',
864
- 'encoding' => 'Unknown encoding: ',
865
- 'signing' => 'Signing Error: ',
866
- 'smtp_error' => 'SMTP server error: ',
867
- 'empty_message' => 'Message body empty',
868
- 'invalid_address' => 'Invalid address',
869
- 'variable_set' => 'Cannot set or reset variable: '
870
- );
871
- //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"!
872
- $l = true;
873
- if ($langcode != 'en') { //There is no English translation file
874
- $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php';
875
- }
876
- $this->language = $PHPMAILER_LANG;
877
- return ($l == true); //Returns false if language not found
878
- }
879
-
880
- /**
881
- * Return the current array of language strings
882
- * @return array
883
- */
884
- public function GetTranslations() {
885
- return $this->language;
886
- }
887
-
888
- /////////////////////////////////////////////////
889
- // METHODS, MESSAGE CREATION
890
- /////////////////////////////////////////////////
891
-
892
- /**
893
- * Creates recipient headers.
894
- * @access public
895
- * @return string
896
- */
897
- public function AddrAppend($type, $addr) {
898
- $addr_str = $type . ': ';
899
- $addresses = array();
900
- foreach ($addr as $a) {
901
- $addresses[] = $this->AddrFormat($a);
902
- }
903
- $addr_str .= implode(', ', $addresses);
904
- $addr_str .= $this->LE;
905
-
906
- return $addr_str;
907
- }
908
-
909
- /**
910
- * Formats an address correctly.
911
- * @access public
912
- * @return string
913
- */
914
- public function AddrFormat($addr) {
915
- if (empty($addr[1])) {
916
- return $this->SecureHeader($addr[0]);
917
- } else {
918
- return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
919
- }
920
- }
921
-
922
- /**
923
- * Wraps message for use with mailers that do not
924
- * automatically perform wrapping and for quoted-printable.
925
- * Original written by philippe.
926
- * @param string $message The message to wrap
927
- * @param integer $length The line length to wrap to
928
- * @param boolean $qp_mode Whether to run in Quoted-Printable mode
929
- * @access public
930
- * @return string
931
- */
932
- public function WrapText($message, $length, $qp_mode = false) {
933
- $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
934
- // If utf-8 encoding is used, we will need to make sure we don't
935
- // split multibyte characters when we wrap
936
- $is_utf8 = (strtolower($this->CharSet) == "utf-8");
937
-
938
- $message = $this->FixEOL($message);
939
- if (substr($message, -1) == $this->LE) {
940
- $message = substr($message, 0, -1);
941
- }
942
-
943
- $line = explode($this->LE, $message);
944
- $message = '';
945
- for ($i=0 ;$i < count($line); $i++) {
946
- $line_part = explode(' ', $line[$i]);
947
- $buf = '';
948
- for ($e = 0; $e<count($line_part); $e++) {
949
- $word = $line_part[$e];
950
- if ($qp_mode and (strlen($word) > $length)) {
951
- $space_left = $length - strlen($buf) - 1;
952
- if ($e != 0) {
953
- if ($space_left > 20) {
954
- $len = $space_left;
955
- if ($is_utf8) {
956
- $len = $this->UTF8CharBoundary($word, $len);
957
- } elseif (substr($word, $len - 1, 1) == "=") {
958
- $len--;
959
- } elseif (substr($word, $len - 2, 1) == "=") {
960
- $len -= 2;
961
- }
962
- $part = substr($word, 0, $len);
963
- $word = substr($word, $len);
964
- $buf .= ' ' . $part;
965
- $message .= $buf . sprintf("=%s", $this->LE);
966
- } else {
967
- $message .= $buf . $soft_break;
968
- }
969
- $buf = '';
970
- }
971
- while (strlen($word) > 0) {
972
- $len = $length;
973
- if ($is_utf8) {
974
- $len = $this->UTF8CharBoundary($word, $len);
975
- } elseif (substr($word, $len - 1, 1) == "=") {
976
- $len--;
977
- } elseif (substr($word, $len - 2, 1) == "=") {
978
- $len -= 2;
979
- }
980
- $part = substr($word, 0, $len);
981
- $word = substr($word, $len);
982
-
983
- if (strlen($word) > 0) {
984
- $message .= $part . sprintf("=%s", $this->LE);
985
- } else {
986
- $buf = $part;
987
- }
988
- }
989
- } else {
990
- $buf_o = $buf;
991
- $buf .= ($e == 0) ? $word : (' ' . $word);
992
-
993
- if (strlen($buf) > $length and $buf_o != '') {
994
- $message .= $buf_o . $soft_break;
995
- $buf = $word;
996
- }
997
- }
998
- }
999
- $message .= $buf . $this->LE;
1000
- }
1001
-
1002
- return $message;
1003
- }
1004
-
1005
- /**
1006
- * Finds last character boundary prior to maxLength in a utf-8
1007
- * quoted (printable) encoded string.
1008
- * Original written by Colin Brown.
1009
- * @access public
1010
- * @param string $encodedText utf-8 QP text
1011
- * @param int $maxLength find last character boundary prior to this length
1012
- * @return int
1013
- */
1014
- public function UTF8CharBoundary($encodedText, $maxLength) {
1015
- $foundSplitPos = false;
1016
- $lookBack = 3;
1017
- while (!$foundSplitPos) {
1018
- $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
1019
- $encodedCharPos = strpos($lastChunk, "=");
1020
- if ($encodedCharPos !== false) {
1021
- // Found start of encoded character byte within $lookBack block.
1022
- // Check the encoded byte value (the 2 chars after the '=')
1023
- $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
1024
- $dec = hexdec($hex);
1025
- if ($dec < 128) { // Single byte character.
1026
- // If the encoded char was found at pos 0, it will fit
1027
- // otherwise reduce maxLength to start of the encoded char
1028
- $maxLength = ($encodedCharPos == 0) ? $maxLength :
1029
- $maxLength - ($lookBack - $encodedCharPos);
1030
- $foundSplitPos = true;
1031
- } elseif ($dec >= 192) { // First byte of a multi byte character
1032
- // Reduce maxLength to split at start of character
1033
- $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1034
- $foundSplitPos = true;
1035
- } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
1036
- $lookBack += 3;
1037
- }
1038
- } else {
1039
- // No encoded character found
1040
- $foundSplitPos = true;
1041
- }
1042
- }
1043
- return $maxLength;
1044
- }
1045
-
1046
-
1047
- /**
1048
- * Set the body wrapping.
1049
- * @access public
1050
- * @return void
1051
- */
1052
- public function SetWordWrap() {
1053
- if($this->WordWrap < 1) {
1054
- return;
1055
- }
1056
-
1057
- switch($this->message_type) {
1058
- case 'alt':
1059
- case 'alt_attachments':
1060
- $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
1061
- break;
1062
- default:
1063
- $this->Body = $this->WrapText($this->Body, $this->WordWrap);
1064
- break;
1065
- }
1066
- }
1067
-
1068
- /**
1069
- * Assembles message header.
1070
- * @access public
1071
- * @return string The assembled header
1072
- */
1073
- public function CreateHeader() {
1074
- $result = '';
1075
-
1076
- // Set the boundaries
1077
- $uniq_id = md5(uniqid(time()));
1078
- $this->boundary[1] = 'b1_' . $uniq_id;
1079
- $this->boundary[2] = 'b2_' . $uniq_id;
1080
-
1081
- $result .= $this->HeaderLine('Date', self::RFCDate());
1082
- if($this->Sender == '') {
1083
- $result .= $this->HeaderLine('Return-Path', trim($this->From));
1084
- } else {
1085
- $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
1086
- }
1087
-
1088
- // To be created automatically by mail()
1089
- if($this->Mailer != 'mail') {
1090
- if ($this->SingleTo === true) {
1091
- foreach($this->to as $t) {
1092
- $this->SingleToArray[] = $this->AddrFormat($t);
1093
- }
1094
- } else {
1095
- if(count($this->to) > 0) {
1096
- $result .= $this->AddrAppend('To', $this->to);
1097
- } elseif (count($this->cc) == 0) {
1098
- $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
1099
- }
1100
- }
1101
- }
1102
-
1103
- $from = array();
1104
- $from[0][0] = trim($this->From);
1105
- $from[0][1] = $this->FromName;
1106
- $result .= $this->AddrAppend('From', $from);
1107
-
1108
- // sendmail and mail() extract Cc from the header before sending
1109
- if(count($this->cc) > 0) {
1110
- $result .= $this->AddrAppend('Cc', $this->cc);
1111
- }
1112
-
1113
- // sendmail and mail() extract Bcc from the header before sending
1114
- if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
1115
- $result .= $this->AddrAppend('Bcc', $this->bcc);
1116
- }
1117
-
1118
- if(count($this->ReplyTo) > 0) {
1119
- $result .= $this->AddrAppend('Reply-to', $this->ReplyTo);
1120
- }
1121
-
1122
- // mail() sets the subject itself
1123
- if($this->Mailer != 'mail') {
1124
- $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
1125
- }
1126
-
1127
- if($this->MessageID != '') {
1128
- $result .= $this->HeaderLine('Message-ID',$this->MessageID);
1129
- } else {
1130
- $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
1131
- }
1132
- $result .= $this->HeaderLine('X-Priority', $this->Priority);
1133
- $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (phpmailer.sourceforge.net)');
1134
-
1135
- if($this->ConfirmReadingTo != '') {
1136
- $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
1137
- }
1138
-
1139
- // Add custom headers
1140
- for($index = 0; $index < count($this->CustomHeader); $index++) {
1141
- $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
1142
- }
1143
- if (!$this->sign_key_file) {
1144
- $result .= $this->HeaderLine('MIME-Version', '1.0');
1145
- $result .= $this->GetMailMIME();
1146
- }
1147
-
1148
- return $result;
1149
- }
1150
-
1151
- /**
1152
- * Returns the message MIME.
1153
- * @access public
1154
- * @return string
1155
- */
1156
- public function GetMailMIME() {
1157
- $result = '';
1158
- switch($this->message_type) {
1159
- case 'plain':
1160
- $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
1161
- $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
1162
- break;
1163
- case 'attachments':
1164
- case 'alt_attachments':
1165
- if($this->InlineImageExists()){
1166
- $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
1167
- } else {
1168
- $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
1169
- $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
1170
- }
1171
- break;
1172
- case 'alt':
1173
- $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
1174
- $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
1175
- break;
1176
- }
1177
-
1178
- if($this->Mailer != 'mail') {
1179
- $result .= $this->LE.$this->LE;
1180
- }
1181
-
1182
- return $result;
1183
- }
1184
-
1185
- /**
1186
- * Assembles the message body. Returns an empty string on failure.
1187
- * @access public
1188
- * @return string The assembled message body
1189
- */
1190
- public function CreateBody() {
1191
- $body = '';
1192
-
1193
- if ($this->sign_key_file) {
1194
- $body .= $this->GetMailMIME();
1195
- }
1196
-
1197
- $this->SetWordWrap();
1198
-
1199
- switch($this->message_type) {
1200
- case 'alt':
1201
- $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
1202
- $body .= $this->EncodeString($this->AltBody, $this->Encoding);
1203
- $body .= $this->LE.$this->LE;
1204
- $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
1205
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1206
- $body .= $this->LE.$this->LE;
1207
- $body .= $this->EndBoundary($this->boundary[1]);
1208
- break;
1209
- case 'plain':
1210
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1211
- break;
1212
- case 'attachments':
1213
- $body .= $this->GetBoundary($this->boundary[1], '', '', '');
1214
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1215
- $body .= $this->LE;
1216
- $body .= $this->AttachAll();
1217
- break;
1218
- case 'alt_attachments':
1219
- $body .= sprintf("--%s%s", $this->boundary[1], $this->LE);
1220
- $body .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
1221
- $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
1222
- $body .= $this->EncodeString($this->AltBody, $this->Encoding);
1223
- $body .= $this->LE.$this->LE;
1224
- $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
1225
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1226
- $body .= $this->LE.$this->LE;
1227
- $body .= $this->EndBoundary($this->boundary[2]);
1228
- $body .= $this->AttachAll();
1229
- break;
1230
- }
1231
-
1232
- if ($this->IsError()) {
1233
- $body = '';
1234
- } elseif ($this->sign_key_file) {
1235
- try {
1236
- $file = tempnam('', 'mail');
1237
- file_put_contents($file, $body); //TODO check this worked
1238
- $signed = tempnam("", "signed");
1239
- if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) {
1240
- @unlink($file);
1241
- @unlink($signed);
1242
- $body = file_get_contents($signed);
1243
- } else {
1244
- @unlink($file);
1245
- @unlink($signed);
1246
- throw new phpmailerException($this->Lang("signing").openssl_error_string());
1247
- }
1248
- } catch (phpmailerException $e) {
1249
- $body = '';
1250
- if ($this->exceptions) {
1251
- throw $e;
1252
- }
1253
- }
1254
- }
1255
-
1256
- return $body;
1257
- }
1258
-
1259
- /**
1260
- * Returns the start of a message boundary.
1261
- * @access private
1262
- */
1263
- private function GetBoundary($boundary, $charSet, $contentType, $encoding) {
1264
- $result = '';
1265
- if($charSet == '') {
1266
- $charSet = $this->CharSet;
1267
- }
1268
- if($contentType == '') {
1269
- $contentType = $this->ContentType;
1270
- }
1271
- if($encoding == '') {
1272
- $encoding = $this->Encoding;
1273
- }
1274
- $result .= $this->TextLine('--' . $boundary);
1275
- $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
1276
- $result .= $this->LE;
1277
- $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
1278
- $result .= $this->LE;
1279
-
1280
- return $result;
1281
- }
1282
-
1283
- /**
1284
- * Returns the end of a message boundary.
1285
- * @access private
1286
- */
1287
- private function EndBoundary($boundary) {
1288
- return $this->LE . '--' . $boundary . '--' . $this->LE;
1289
- }
1290
-
1291
- /**
1292
- * Sets the message type.
1293
- * @access private
1294
- * @return void
1295
- */
1296
- private function SetMessageType() {
1297
- if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
1298
- $this->message_type = 'plain';
1299
- } else {
1300
- if(count($this->attachment) > 0) {
1301
- $this->message_type = 'attachments';
1302
- }
1303
- if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) {
1304
- $this->message_type = 'alt';
1305
- }
1306
- if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) {
1307
- $this->message_type = 'alt_attachments';
1308
- }
1309
- }
1310
- }
1311
-
1312
- /**
1313
- * Returns a formatted header line.
1314
- * @access public
1315
- * @return string
1316
- */
1317
- public function HeaderLine($name, $value) {
1318
- return $name . ': ' . $value . $this->LE;
1319
- }
1320
-
1321
- /**
1322
- * Returns a formatted mail line.
1323
- * @access public
1324
- * @return string
1325
- */
1326
- public function TextLine($value) {
1327
- return $value . $this->LE;
1328
- }
1329
-
1330
- /////////////////////////////////////////////////
1331
- // CLASS METHODS, ATTACHMENTS
1332
- /////////////////////////////////////////////////
1333
-
1334
- /**
1335
- * Adds an attachment from a path on the filesystem.
1336
- * Returns false if the file could not be found
1337
- * or accessed.
1338
- * @param string $path Path to the attachment.
1339
- * @param string $name Overrides the attachment name.
1340
- * @param string $encoding File encoding (see $Encoding).
1341
- * @param string $type File extension (MIME) type.
1342
- * @return bool
1343
- */
1344
- public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
1345
- try {
1346
- if ( !@is_file($path) ) {
1347
- throw new phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE);
1348
- }
1349
- $filename = basename($path);
1350
- if ( $name == '' ) {
1351
- $name = $filename;
1352
- }
1353
-
1354
- $this->attachment[] = array(
1355
- 0 => $path,
1356
- 1 => $filename,
1357
- 2 => $name,
1358
- 3 => $encoding,
1359
- 4 => $type,
1360
- 5 => false, // isStringAttachment
1361
- 6 => 'attachment',
1362
- 7 => 0
1363
- );
1364
-
1365
- } catch (phpmailerException $e) {
1366
- $this->SetError($e->getMessage());
1367
- if ($this->exceptions) {
1368
- throw $e;
1369
- }
1370
- echo $e->getMessage()."\n";
1371
- if ( $e->getCode() == self::STOP_CRITICAL ) {
1372
- return false;
1373
- }
1374
- }
1375
- return true;
1376
- }
1377
-
1378
- /**
1379
- * Return the current array of attachments
1380
- * @return array
1381
- */
1382
- public function GetAttachments() {
1383
- return $this->attachment;
1384
- }
1385
-
1386
- /**
1387
- * Attaches all fs, string, and binary attachments to the message.
1388
- * Returns an empty string on failure.
1389
- * @access private
1390
- * @return string
1391
- */
1392
- private function AttachAll() {
1393
- // Return text of body
1394
- $mime = array();
1395
- $cidUniq = array();
1396
- $incl = array();
1397
-
1398
- // Add all attachments
1399
- foreach ($this->attachment as $attachment) {
1400
- // Check for string attachment
1401
- $bString = $attachment[5];
1402
- if ($bString) {
1403
- $string = $attachment[0];
1404
- } else {
1405
- $path = $attachment[0];
1406
- }
1407
-
1408
- if (in_array($attachment[0], $incl)) { continue; }
1409
- $filename = $attachment[1];
1410
- $name = $attachment[2];
1411
- $encoding = $attachment[3];
1412
- $type = $attachment[4];
1413
- $disposition = $attachment[6];
1414
- $cid = $attachment[7];
1415
- $incl[] = $attachment[0];
1416
- if ( $disposition == 'inline' && isset($cidUniq[$cid]) ) { continue; }
1417
- $cidUniq[$cid] = true;
1418
-
1419
- $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
1420
- $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
1421
- $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
1422
-
1423
- if($disposition == 'inline') {
1424
- $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
1425
- }
1426
-
1427
- $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE);
1428
-
1429
- // Encode as string attachment
1430
- if($bString) {
1431
- $mime[] = $this->EncodeString($string, $encoding);
1432
- if($this->IsError()) {
1433
- return '';
1434
- }
1435
- $mime[] = $this->LE.$this->LE;
1436
- } else {
1437
- $mime[] = $this->EncodeFile($path, $encoding);
1438
- if($this->IsError()) {
1439
- return '';
1440
- }
1441
- $mime[] = $this->LE.$this->LE;
1442
- }
1443
- }
1444
-
1445
- $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
1446
-
1447
- return join('', $mime);
1448
- }
1449
-
1450
- /**
1451
- * Encodes attachment in requested format.
1452
- * Returns an empty string on failure.
1453
- * @param string $path The full path to the file
1454
- * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
1455
- * @see EncodeFile()
1456
- * @access private
1457
- * @return string
1458
- */
1459
- private function EncodeFile($path, $encoding = 'base64') {
1460
- try {
1461
- if (!is_readable($path)) {
1462
- throw new phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE);
1463
- }
1464
- if (function_exists('get_magic_quotes')) {
1465
- function get_magic_quotes() {
1466
- return false;
1467
- }
1468
- }
1469
- if (PHP_VERSION < 6) {
1470
- $magic_quotes = get_magic_quotes_runtime();
1471
- set_magic_quotes_runtime(0);
1472
- }
1473
- $file_buffer = file_get_contents($path);
1474
- $file_buffer = $this->EncodeString($file_buffer, $encoding);
1475
- if (PHP_VERSION < 6) { set_magic_quotes_runtime($magic_quotes); }
1476
- return $file_buffer;
1477
- } catch (Exception $e) {
1478
- $this->SetError($e->getMessage());
1479
- return '';
1480
- }
1481
- }
1482
-
1483
- /**
1484
- * Encodes string to requested format.
1485
- * Returns an empty string on failure.
1486
- * @param string $str The text to encode
1487
- * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
1488
- * @access public
1489
- * @return string
1490
- */
1491
- public function EncodeString ($str, $encoding = 'base64') {
1492
- $encoded = '';
1493
- switch(strtolower($encoding)) {
1494
- case 'base64':
1495
- $encoded = chunk_split(base64_encode($str), 76, $this->LE);
1496
- break;
1497
- case '7bit':
1498
- case '8bit':
1499
- $encoded = $this->FixEOL($str);
1500
- //Make sure it ends with a line break
1501
- if (substr($encoded, -(strlen($this->LE))) != $this->LE)
1502
- $encoded .= $this->LE;
1503
- break;
1504
- case 'binary':
1505
- $encoded = $str;
1506
- break;
1507
- case 'quoted-printable':
1508
- $encoded = $this->EncodeQP($str);
1509
- break;
1510
- default:
1511
- $this->SetError($this->Lang('encoding') . $encoding);
1512
- break;
1513
- }
1514
- return $encoded;
1515
- }
1516
-
1517
- /**
1518
- * Encode a header string to best (shortest) of Q, B, quoted or none.
1519
- * @access public
1520
- * @return string
1521
- */
1522
- public function EncodeHeader($str, $position = 'text') {
1523
- $x = 0;
1524
-
1525
- switch (strtolower($position)) {
1526
- case 'phrase':
1527
- if (!preg_match('/[\200-\377]/', $str)) {
1528
- // Can't use addslashes as we don't know what value has magic_quotes_sybase
1529
- $encoded = addcslashes($str, "\0..\37\177\\\"");
1530
- if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
1531
- return ($encoded);
1532
- } else {
1533
- return ("\"$encoded\"");
1534
- }
1535
- }
1536
- $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
1537
- break;
1538
- case 'comment':
1539
- $x = preg_match_all('/[()"]/', $str, $matches);
1540
- // Fall-through
1541
- case 'text':
1542
- default:
1543
- $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
1544
- break;
1545
- }
1546
-
1547
- if ($x == 0) {
1548
- return ($str);
1549
- }
1550
-
1551
- $maxlen = 75 - 7 - strlen($this->CharSet);
1552
- // Try to select the encoding which should produce the shortest output
1553
- if (strlen($str)/3 < $x) {
1554
- $encoding = 'B';
1555
- if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
1556
- // Use a custom function which correctly encodes and wraps long
1557
- // multibyte strings without breaking lines within a character
1558
- $encoded = $this->Base64EncodeWrapMB($str);
1559
- } else {
1560
- $encoded = base64_encode($str);
1561
- $maxlen -= $maxlen % 4;
1562
- $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
1563
- }
1564
- } else {
1565
- $encoding = 'Q';
1566
- $encoded = $this->EncodeQ($str, $position);
1567
- $encoded = $this->WrapText($encoded, $maxlen, true);
1568
- $encoded = str_replace('='.$this->LE, "\n", trim($encoded));
1569
- }
1570
-
1571
- $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
1572
- $encoded = trim(str_replace("\n", $this->LE, $encoded));
1573
-
1574
- return $encoded;
1575
- }
1576
-
1577
- /**
1578
- * Checks if a string contains multibyte characters.
1579
- * @access public
1580
- * @param string $str multi-byte text to wrap encode
1581
- * @return bool
1582
- */
1583
- public function HasMultiBytes($str) {
1584
- if (function_exists('mb_strlen')) {
1585
- return (strlen($str) > mb_strlen($str, $this->CharSet));
1586
- } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
1587
- return false;
1588
- }
1589
- }
1590
-
1591
- /**
1592
- * Correctly encodes and wraps long multibyte strings for mail headers
1593
- * without breaking lines within a character.
1594
- * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
1595
- * @access public
1596
- * @param string $str multi-byte text to wrap encode
1597
- * @return string
1598
- */
1599
- public function Base64EncodeWrapMB($str) {
1600
- $start = "=?".$this->CharSet."?B?";
1601
- $end = "?=";
1602
- $encoded = "";
1603
-
1604
- $mb_length = mb_strlen($str, $this->CharSet);
1605
- // Each line must have length <= 75, including $start and $end
1606
- $length = 75 - strlen($start) - strlen($end);
1607
- // Average multi-byte ratio
1608
- $ratio = $mb_length / strlen($str);
1609
- // Base64 has a 4:3 ratio
1610
- $offset = $avgLength = floor($length * $ratio * .75);
1611
-
1612
- for ($i = 0; $i < $mb_length; $i += $offset) {
1613
- $lookBack = 0;
1614
-
1615
- do {
1616
- $offset = $avgLength - $lookBack;
1617
- $chunk = mb_substr($str, $i, $offset, $this->CharSet);
1618
- $chunk = base64_encode($chunk);
1619
- $lookBack++;
1620
- }
1621
- while (strlen($chunk) > $length);
1622
-
1623
- $encoded .= $chunk . $this->LE;
1624
- }
1625
-
1626
- // Chomp the last linefeed
1627
- $encoded = substr($encoded, 0, -strlen($this->LE));
1628
- return $encoded;
1629
- }
1630
-
1631
- /**
1632
- * Encode string to quoted-printable.
1633
- * Only uses standard PHP, slow, but will always work
1634
- * @access public
1635
- * @param string $string the text to encode
1636
- * @param integer $line_max Number of chars allowed on a line before wrapping
1637
- * @return string
1638
- */
1639
- public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) {
1640
- $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
1641
- $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
1642
- $eol = "\r\n";
1643
- $escape = '=';
1644
- $output = '';
1645
- while( list(, $line) = each($lines) ) {
1646
- $linlen = strlen($line);
1647
- $newline = '';
1648
- for($i = 0; $i < $linlen; $i++) {
1649
- $c = substr( $line, $i, 1 );
1650
- $dec = ord( $c );
1651
- if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
1652
- $c = '=2E';
1653
- }
1654
- if ( $dec == 32 ) {
1655
- if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
1656
- $c = '=20';
1657
- } else if ( $space_conv ) {
1658
- $c = '=20';
1659
- }
1660
- } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
1661
- $h2 = floor($dec/16);
1662
- $h1 = floor($dec%16);
1663
- $c = $escape.$hex[$h2].$hex[$h1];
1664
- }
1665
- if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
1666
- $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
1667
- $newline = '';
1668
- // check if newline first character will be point or not
1669
- if ( $dec == 46 ) {
1670
- $c = '=2E';
1671
- }
1672
- }
1673
- $newline .= $c;
1674
- } // end of for
1675
- $output .= $newline.$eol;
1676
- } // end of while
1677
- return $output;
1678
- }
1679
-
1680
- /**
1681
- * Encode string to RFC2045 (6.7) quoted-printable format
1682
- * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version
1683
- * Also results in same content as you started with after decoding
1684
- * @see EncodeQPphp()
1685
- * @access public
1686
- * @param string $string the text to encode
1687
- * @param integer $line_max Number of chars allowed on a line before wrapping
1688
- * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function
1689
- * @return string
1690
- * @author Marcus Bointon
1691
- */
1692
- public function EncodeQP($string, $line_max = 76, $space_conv = false) {
1693
- if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3)
1694
- return quoted_printable_encode($string);
1695
- }
1696
- $filters = stream_get_filters();
1697
- if (!in_array('convert.*', $filters)) { //Got convert stream filter?
1698
- return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation
1699
- }
1700
- $fp = fopen('php://temp/', 'r+');
1701
- $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks
1702
- $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE);
1703
- $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params);
1704
- fputs($fp, $string);
1705
- rewind($fp);
1706
- $out = stream_get_contents($fp);
1707
- stream_filter_remove($s);
1708
- $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange
1709
- fclose($fp);
1710
- return $out;
1711
- }
1712
-
1713
- /**
1714
- * Encode string to q encoding.
1715
- * @link http://tools.ietf.org/html/rfc2047
1716
- * @param string $str the text to encode
1717
- * @param string $position Where the text is going to be used, see the RFC for what that means
1718
- * @access public
1719
- * @return string
1720
- */
1721
- public function EncodeQ ($str, $position = 'text') {
1722
- // There should not be any EOL in the string
1723
- $encoded = preg_replace('/[\r\n]*/', '', $str);
1724
-
1725
- switch (strtolower($position)) {
1726
- case 'phrase':
1727
- $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1728
- break;
1729
- case 'comment':
1730
- $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1731
- case 'text':
1732
- default:
1733
- // Replace every high ascii, control =, ? and _ characters
1734
- //TODO using /e (equivalent to eval()) is probably not a good idea
1735
- $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
1736
- "'='.sprintf('%02X', ord('\\1'))", $encoded);
1737
- break;
1738
- }
1739
-
1740
- // Replace every spaces to _ (more readable than =20)
1741
- $encoded = str_replace(' ', '_', $encoded);
1742
-
1743
- return $encoded;
1744
- }
1745
-
1746
- /**
1747
- * Adds a string or binary attachment (non-filesystem) to the list.
1748
- * This method can be used to attach ascii or binary data,
1749
- * such as a BLOB record from a database.
1750
- * @param string $string String attachment data.
1751
- * @param string $filename Name of the attachment.
1752
- * @param string $encoding File encoding (see $Encoding).
1753
- * @param string $type File extension (MIME) type.
1754
- * @return void
1755
- */
1756
- public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
1757
- // Append to $attachment array
1758
- $this->attachment[] = array(
1759
- 0 => $string,
1760
- 1 => $filename,
1761
- 2 => basename($filename),
1762
- 3 => $encoding,
1763
- 4 => $type,
1764
- 5 => true, // isStringAttachment
1765
- 6 => 'attachment',
1766
- 7 => 0
1767
- );
1768
- }
1769
-
1770
- /**
1771
- * Adds an embedded attachment. This can include images, sounds, and
1772
- * just about any other document. Make sure to set the $type to an
1773
- * image type. For JPEG images use "image/jpeg" and for GIF images
1774
- * use "image/gif".
1775
- * @param string $path Path to the attachment.
1776
- * @param string $cid Content ID of the attachment. Use this to identify
1777
- * the Id for accessing the image in an HTML form.
1778
- * @param string $name Overrides the attachment name.
1779
- * @param string $encoding File encoding (see $Encoding).
1780
- * @param string $type File extension (MIME) type.
1781
- * @return bool
1782
- */
1783
- public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
1784
-
1785
- if ( !@is_file($path) ) {
1786
- $this->SetError($this->Lang('file_access') . $path);
1787
- return false;
1788
- }
1789
-
1790
- $filename = basename($path);
1791
- if ( $name == '' ) {
1792
- $name = $filename;
1793
- }
1794
-
1795
- // Append to $attachment array
1796
- $this->attachment[] = array(
1797
- 0 => $path,
1798
- 1 => $filename,
1799
- 2 => $name,
1800
- 3 => $encoding,
1801
- 4 => $type,
1802
- 5 => false, // isStringAttachment
1803
- 6 => 'inline',
1804
- 7 => $cid
1805
- );
1806
-
1807
- return true;
1808
- }
1809
-
1810
- /**
1811
- * Returns true if an inline attachment is present.
1812
- * @access public
1813
- * @return bool
1814
- */
1815
- public function InlineImageExists() {
1816
- foreach($this->attachment as $attachment) {
1817
- if ($attachment[6] == 'inline') {
1818
- return true;
1819
- }
1820
- }
1821
- return false;
1822
- }
1823
-
1824
- /////////////////////////////////////////////////
1825
- // CLASS METHODS, MESSAGE RESET
1826
- /////////////////////////////////////////////////
1827
-
1828
- /**
1829
- * Clears all recipients assigned in the TO array. Returns void.
1830
- * @return void
1831
- */
1832
- public function ClearAddresses() {
1833
- foreach($this->to as $to) {
1834
- unset($this->all_recipients[strtolower($to[0])]);
1835
- }
1836
- $this->to = array();
1837
- }
1838
-
1839
- /**
1840
- * Clears all recipients assigned in the CC array. Returns void.
1841
- * @return void
1842
- */
1843
- public function ClearCCs() {
1844
- foreach($this->cc as $cc) {
1845
- unset($this->all_recipients[strtolower($cc[0])]);
1846
- }
1847
- $this->cc = array();
1848
- }
1849
-
1850
- /**
1851
- * Clears all recipients assigned in the BCC array. Returns void.
1852
- * @return void
1853
- */
1854
- public function ClearBCCs() {
1855
- foreach($this->bcc as $bcc) {
1856
- unset($this->all_recipients[strtolower($bcc[0])]);
1857
- }
1858
- $this->bcc = array();
1859
- }
1860
-
1861
- /**
1862
- * Clears all recipients assigned in the ReplyTo array. Returns void.
1863
- * @return void
1864
- */
1865
- public function ClearReplyTos() {
1866
- $this->ReplyTo = array();
1867
- }
1868
-
1869
- /**
1870
- * Clears all recipients assigned in the TO, CC and BCC
1871
- * array. Returns void.
1872
- * @return void
1873
- */
1874
- public function ClearAllRecipients() {
1875
- $this->to = array();
1876
- $this->cc = array();
1877
- $this->bcc = array();
1878
- $this->all_recipients = array();
1879
- }
1880
-
1881
- /**
1882
- * Clears all previously set filesystem, string, and binary
1883
- * attachments. Returns void.
1884
- * @return void
1885
- */
1886
- public function ClearAttachments() {
1887
- $this->attachment = array();
1888
- }
1889
-
1890
- /**
1891
- * Clears all custom headers. Returns void.
1892
- * @return void
1893
- */
1894
- public function ClearCustomHeaders() {
1895
- $this->CustomHeader = array();
1896
- }
1897
-
1898
- /////////////////////////////////////////////////
1899
- // CLASS METHODS, MISCELLANEOUS
1900
- /////////////////////////////////////////////////
1901
-
1902
- /**
1903
- * Adds the error message to the error container.
1904
- * @access protected
1905
- * @return void
1906
- */
1907
- protected function SetError($msg) {
1908
- $this->error_count++;
1909
- if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
1910
- $lasterror = $this->smtp->getError();
1911
- if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
1912
- $msg .= '<p>' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
1913
- }
1914
- }
1915
- $this->ErrorInfo = $msg;
1916
- }
1917
-
1918
- /**
1919
- * Returns the proper RFC 822 formatted date.
1920
- * @access public
1921
- * @return string
1922
- * @static
1923
- */
1924
- public static function RFCDate() {
1925
- $tz = date('Z');
1926
- $tzs = ($tz < 0) ? '-' : '+';
1927
- $tz = abs($tz);
1928
- $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
1929
- $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
1930
-
1931
- return $result;
1932
- }
1933
-
1934
- /**
1935
- * Returns the server hostname or 'localhost.localdomain' if unknown.
1936
- * @access private
1937
- * @return string
1938
- */
1939
- private function ServerHostname() {
1940
- if (!empty($this->Hostname)) {
1941
- $result = $this->Hostname;
1942
- } elseif (isset($_SERVER['SERVER_NAME'])) {
1943
- $result = $_SERVER['SERVER_NAME'];
1944
- } else {
1945
- $result = 'localhost.localdomain';
1946
- }
1947
-
1948
- return $result;
1949
- }
1950
-
1951
- /**
1952
- * Returns a message in the appropriate language.
1953
- * @access private
1954
- * @return string
1955
- */
1956
- private function Lang($key) {
1957
- if(count($this->language) < 1) {
1958
- $this->SetLanguage('en'); // set the default language
1959
- }
1960
-
1961
- if(isset($this->language[$key])) {
1962
- return $this->language[$key];
1963
- } else {
1964
- return 'Language string failed to load: ' . $key;
1965
- }
1966
- }
1967
-
1968
- /**
1969
- * Returns true if an error occurred.
1970
- * @access public
1971
- * @return bool
1972
- */
1973
- public function IsError() {
1974
- return ($this->error_count > 0);
1975
- }
1976
-
1977
- /**
1978
- * Changes every end of line from CR or LF to CRLF.
1979
- * @access private
1980
- * @return string
1981
- */
1982
- private function FixEOL($str) {
1983
- $str = str_replace("\r\n", "\n", $str);
1984
- $str = str_replace("\r", "\n", $str);
1985
- $str = str_replace("\n", $this->LE, $str);
1986
- return $str;
1987
- }
1988
-
1989
- /**
1990
- * Adds a custom header.
1991
- * @access public
1992
- * @return void
1993
- */
1994
- public function AddCustomHeader($custom_header) {
1995
- $this->CustomHeader[] = explode(':', $custom_header, 2);
1996
- }
1997
-
1998
- /**
1999
- * Evaluates the message and returns modifications for inline images and backgrounds
2000
- * @access public
2001
- * @return $message
2002
- */
2003
- public function MsgHTML($message, $basedir = '') {
2004
- preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
2005
- if(isset($images[2])) {
2006
- foreach($images[2] as $i => $url) {
2007
- // do not change urls for absolute images (thanks to corvuscorax)
2008
- if (!preg_match('#^[A-z]+://#',$url)) {
2009
- $filename = basename($url);
2010
- $directory = dirname($url);
2011
- ($directory == '.')?$directory='':'';
2012
- $cid = 'cid:' . md5($filename);
2013
- $ext = pathinfo($filename, PATHINFO_EXTENSION);
2014
- $mimeType = self::_mime_types($ext);
2015
- if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; }
2016
- if ( strlen($directory) > 1 && substr($directory,-1) != '/') { $directory .= '/'; }
2017
- if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) {
2018
- $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message);
2019
- }
2020
- }
2021
- }
2022
- }
2023
- $this->IsHTML(true);
2024
- $this->Body = $message;
2025
- $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message)));
2026
- if (!empty($textMsg) && empty($this->AltBody)) {
2027
- $this->AltBody = html_entity_decode($textMsg);
2028
- }
2029
- if (empty($this->AltBody)) {
2030
- $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
2031
- }
2032
- }
2033
-
2034
- /**
2035
- * Gets the MIME type of the embedded or inline image
2036
- * @param string File extension
2037
- * @access public
2038
- * @return string MIME type of ext
2039
- * @static
2040
- */
2041
- public static function _mime_types($ext = '') {
2042
- $mimes = array(
2043
- 'hqx' => 'application/mac-binhex40',
2044
- 'cpt' => 'application/mac-compactpro',
2045
- 'doc' => 'application/msword',
2046
- 'bin' => 'application/macbinary',
2047
- 'dms' => 'application/octet-stream',
2048
- 'lha' => 'application/octet-stream',
2049
- 'lzh' => 'application/octet-stream',
2050
- 'exe' => 'application/octet-stream',
2051
- 'class' => 'application/octet-stream',
2052
- 'psd' => 'application/octet-stream',
2053
- 'so' => 'application/octet-stream',
2054
- 'sea' => 'application/octet-stream',
2055
- 'dll' => 'application/octet-stream',
2056
- 'oda' => 'application/oda',
2057
- 'pdf' => 'application/pdf',
2058
- 'ai' => 'application/postscript',
2059
- 'eps' => 'application/postscript',
2060
- 'ps' => 'application/postscript',
2061
- 'smi' => 'application/smil',
2062
- 'smil' => 'application/smil',
2063
- 'mif' => 'application/vnd.mif',
2064
- 'xls' => 'application/vnd.ms-excel',
2065
- 'ppt' => 'application/vnd.ms-powerpoint',
2066
- 'wbxml' => 'application/vnd.wap.wbxml',
2067
- 'wmlc' => 'application/vnd.wap.wmlc',
2068
- 'dcr' => 'application/x-director',
2069
- 'dir' => 'application/x-director',
2070
- 'dxr' => 'application/x-director',
2071
- 'dvi' => 'application/x-dvi',
2072
- 'gtar' => 'application/x-gtar',
2073
- 'php' => 'application/x-httpd-php',
2074
- 'php4' => 'application/x-httpd-php',
2075
- 'php3' => 'application/x-httpd-php',
2076
- 'phtml' => 'application/x-httpd-php',
2077
- 'phps' => 'application/x-httpd-php-source',
2078
- 'js' => 'application/x-javascript',
2079
- 'swf' => 'application/x-shockwave-flash',
2080
- 'sit' => 'application/x-stuffit',
2081
- 'tar' => 'application/x-tar',
2082
- 'tgz' => 'application/x-tar',
2083
- 'xhtml' => 'application/xhtml+xml',
2084
- 'xht' => 'application/xhtml+xml',
2085
- 'zip' => 'application/zip',
2086
- 'mid' => 'audio/midi',
2087
- 'midi' => 'audio/midi',
2088
- 'mpga' => 'audio/mpeg',
2089
- 'mp2' => 'audio/mpeg',
2090
- 'mp3' => 'audio/mpeg',
2091
- 'aif' => 'audio/x-aiff',
2092
- 'aiff' => 'audio/x-aiff',
2093
- 'aifc' => 'audio/x-aiff',
2094
- 'ram' => 'audio/x-pn-realaudio',
2095
- 'rm' => 'audio/x-pn-realaudio',
2096
- 'rpm' => 'audio/x-pn-realaudio-plugin',
2097
- 'ra' => 'audio/x-realaudio',
2098
- 'rv' => 'video/vnd.rn-realvideo',
2099
- 'wav' => 'audio/x-wav',
2100
- 'bmp' => 'image/bmp',
2101
- 'gif' => 'image/gif',
2102
- 'jpeg' => 'image/jpeg',
2103
- 'jpg' => 'image/jpeg',
2104
- 'jpe' => 'image/jpeg',
2105
- 'png' => 'image/png',
2106
- 'tiff' => 'image/tiff',
2107
- 'tif' => 'image/tiff',
2108
- 'css' => 'text/css',
2109
- 'html' => 'text/html',
2110
- 'htm' => 'text/html',
2111
- 'shtml' => 'text/html',
2112
- 'txt' => 'text/plain',
2113
- 'text' => 'text/plain',
2114
- 'log' => 'text/plain',
2115
- 'rtx' => 'text/richtext',
2116
- 'rtf' => 'text/rtf',
2117
- 'xml' => 'text/xml',
2118
- 'xsl' => 'text/xml',
2119
- 'mpeg' => 'video/mpeg',
2120
- 'mpg' => 'video/mpeg',
2121
- 'mpe' => 'video/mpeg',
2122
- 'qt' => 'video/quicktime',
2123
- 'mov' => 'video/quicktime',
2124
- 'avi' => 'video/x-msvideo',
2125
- 'movie' => 'video/x-sgi-movie',
2126
- 'doc' => 'application/msword',
2127
- 'word' => 'application/msword',
2128
- 'xl' => 'application/excel',
2129
- 'eml' => 'message/rfc822'
2130
- );
2131
- return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
2132
- }
2133
-
2134
- /**
2135
- * Set (or reset) Class Objects (variables)
2136
- *
2137
- * Usage Example:
2138
- * $page->set('X-Priority', '3');
2139
- *
2140
- * @access public
2141
- * @param string $name Parameter Name
2142
- * @param mixed $value Parameter Value
2143
- * NOTE: will not work with arrays, there are no arrays to set/reset
2144
- * @todo Should this not be using __set() magic function?
2145
- */
2146
- public function set($name, $value = '') {
2147
- try {
2148
- if (isset($this->$name) ) {
2149
- $this->$name = $value;
2150
- } else {
2151
- throw new phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL);
2152
- }
2153
- } catch (Exception $e) {
2154
- $this->SetError($e->getMessage());
2155
- if ($e->getCode() == self::STOP_CRITICAL) {
2156
- return false;
2157
- }
2158
- }
2159
- return true;
2160
- }
2161
-
2162
- /**
2163
- * Strips newlines to prevent header injection.
2164
- * @access public
2165
- * @param string $str String
2166
- * @return string
2167
- */
2168
- public function SecureHeader($str) {
2169
- $str = str_replace("\r", '', $str);
2170
- $str = str_replace("\n", '', $str);
2171
- return trim($str);
2172
- }
2173
-
2174
- /**
2175
- * Set the private key file and password to sign the message.
2176
- *
2177
- * @access public
2178
- * @param string $key_filename Parameter File Name
2179
- * @param string $key_pass Password for private key
2180
- */
2181
- public function Sign($cert_filename, $key_filename, $key_pass) {
2182
- $this->sign_cert_file = $cert_filename;
2183
- $this->sign_key_file = $key_filename;
2184
- $this->sign_key_pass = $key_pass;
2185
- }
2186
-
2187
- /**
2188
- * Set the private key file and password to sign the message.
2189
- *
2190
- * @access public
2191
- * @param string $key_filename Parameter File Name
2192
- * @param string $key_pass Password for private key
2193
- */
2194
- public function DKIM_QP($txt) {
2195
- $tmp="";
2196
- $line="";
2197
- for ($i=0;$i<strlen($txt);$i++) {
2198
- $ord=ord($txt[$i]);
2199
- if ( ((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E)) ) {
2200
- $line.=$txt[$i];
2201
- } else {
2202
- $line.="=".sprintf("%02X",$ord);
2203
- }
2204
- }
2205
- return $line;
2206
- }
2207
-
2208
- /**
2209
- * Generate DKIM signature
2210
- *
2211
- * @access public
2212
- * @param string $s Header
2213
- */
2214
- public function DKIM_Sign($s) {
2215
- $privKeyStr = file_get_contents($this->DKIM_private);
2216
- if ($this->DKIM_passphrase!='') {
2217
- $privKey = openssl_pkey_get_private($privKeyStr,$this->DKIM_passphrase);
2218
- } else {
2219
- $privKey = $privKeyStr;
2220
- }
2221
- if (openssl_sign($s, $signature, $privKey)) {
2222
- return base64_encode($signature);
2223
- }
2224
- }
2225
-
2226
- /**
2227
- * Generate DKIM Canonicalization Header
2228
- *
2229
- * @access public
2230
- * @param string $s Header
2231
- */
2232
- public function DKIM_HeaderC($s) {
2233
- $s=preg_replace("/\r\n\s+/"," ",$s);
2234
- $lines=explode("\r\n",$s);
2235
- foreach ($lines as $key=>$line) {
2236
- list($heading,$value)=explode(":",$line,2);
2237
- $heading=strtolower($heading);
2238
- $value=preg_replace("/\s+/"," ",$value) ; // Compress useless spaces
2239
- $lines[$key]=$heading.":".trim($value) ; // Don't forget to remove WSP around the value
2240
- }
2241
- $s=implode("\r\n",$lines);
2242
- return $s;
2243
- }
2244
-
2245
- /**
2246
- * Generate DKIM Canonicalization Body
2247
- *
2248
- * @access public
2249
- * @param string $body Message Body
2250
- */
2251
- public function DKIM_BodyC($body) {
2252
- if ($body == '') return "\r\n";
2253
- // stabilize line endings
2254
- $body=str_replace("\r\n","\n",$body);
2255
- $body=str_replace("\n","\r\n",$body);
2256
- // END stabilize line endings
2257
- while (substr($body,strlen($body)-4,4) == "\r\n\r\n") {
2258
- $body=substr($body,0,strlen($body)-2);
2259
- }
2260
- return $body;
2261
- }
2262
-
2263
- /**
2264
- * Create the DKIM header, body, as new header
2265
- *
2266
- * @access public
2267
- * @param string $headers_line Header lines
2268
- * @param string $subject Subject
2269
- * @param string $body Body
2270
- */
2271
- public function DKIM_Add($headers_line,$subject,$body) {
2272
- $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
2273
- $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
2274
- $DKIMquery = 'dns/txt'; // Query method
2275
- $DKIMtime = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
2276
- $subject_header = "Subject: $subject";
2277
- $headers = explode("\r\n",$headers_line);
2278
- foreach($headers as $header) {
2279
- if (strpos($header,'From:') === 0) {
2280
- $from_header=$header;
2281
- } elseif (strpos($header,'To:') === 0) {
2282
- $to_header=$header;
2283
- }
2284
- }
2285
- $from = str_replace('|','=7C',$this->DKIM_QP($from_header));
2286
- $to = str_replace('|','=7C',$this->DKIM_QP($to_header));
2287
- $subject = str_replace('|','=7C',$this->DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable
2288
- $body = $this->DKIM_BodyC($body);
2289
- $DKIMlen = strlen($body) ; // Length of body
2290
- $DKIMb64 = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body
2291
- $ident = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";";
2292
- $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n".
2293
- "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n".
2294
- "\th=From:To:Subject;\r\n".
2295
- "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n".
2296
- "\tz=$from\r\n".
2297
- "\t|$to\r\n".
2298
- "\t|$subject;\r\n".
2299
- "\tbh=" . $DKIMb64 . ";\r\n".
2300
- "\tb=";
2301
- $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs);
2302
- $signed = $this->DKIM_Sign($toSign);
2303
- return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n".$dkimhdrs.$signed."\r\n";
2304
- }
2305
-
2306
- protected function doCallback($isSent,$to,$cc,$bcc,$subject,$body) {
2307
- if (!empty($this->action_function) && function_exists($this->action_function)) {
2308
- $params = array($isSent,$to,$cc,$bcc,$subject,$body);
2309
- call_user_func_array($this->action_function,$params);
2310
- }
2311
- }
2312
- }
2313
-
2314
- class phpmailerException extends Exception {
2315
- public function errorMessage() {
2316
- $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
2317
- return $errorMsg;
2318
- }
2319
- }
2320
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/phpmailer/class.pop3.php DELETED
@@ -1,407 +0,0 @@
1
- <?php
2
- /*~ class.pop3.php
3
- .---------------------------------------------------------------------------.
4
- | Software: PHPMailer - PHP email class |
5
- | Version: 5.1 |
6
- | Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
7
- | Info: http://phpmailer.sourceforge.net |
8
- | Support: http://sourceforge.net/projects/phpmailer/ |
9
- | ------------------------------------------------------------------------- |
10
- | Admin: Andy Prevost (project admininistrator) |
11
- | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
12
- | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
13
- | Founder: Brent R. Matzelle (original founder) |
14
- | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
15
- | Copyright (c) 2001-2003, Brent R. Matzelle |
16
- | ------------------------------------------------------------------------- |
17
- | License: Distributed under the Lesser General Public License (LGPL) |
18
- | http://www.gnu.org/copyleft/lesser.html |
19
- | This program is distributed in the hope that it will be useful - WITHOUT |
20
- | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21
- | FITNESS FOR A PARTICULAR PURPOSE. |
22
- | ------------------------------------------------------------------------- |
23
- | We offer a number of paid services (www.codeworxtech.com): |
24
- | - Web Hosting on highly optimized fast and secure servers |
25
- | - Technology Consulting |
26
- | - Oursourcing (highly qualified programmers and graphic designers) |
27
- '---------------------------------------------------------------------------'
28
- */
29
-
30
- /**
31
- * PHPMailer - PHP POP Before SMTP Authentication Class
32
- * NOTE: Designed for use with PHP version 5 and up
33
- * @package PHPMailer
34
- * @author Andy Prevost
35
- * @author Marcus Bointon
36
- * @copyright 2004 - 2009 Andy Prevost
37
- * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
38
- * @version $Id: class.pop3.php 444 2009-05-05 11:22:26Z coolbru $
39
- */
40
-
41
- /**
42
- * POP Before SMTP Authentication Class
43
- * Version 5.0.0
44
- *
45
- * Author: Richard Davey (rich@corephp.co.uk)
46
- * Modifications: Andy Prevost
47
- * License: LGPL, see PHPMailer License
48
- *
49
- * Specifically for PHPMailer to allow POP before SMTP authentication.
50
- * Does not yet work with APOP - if you have an APOP account, contact Richard Davey
51
- * and we can test changes to this script.
52
- *
53
- * This class is based on the structure of the SMTP class originally authored by Chris Ryan
54
- *
55
- * This class is rfc 1939 compliant and implements all the commands
56
- * required for POP3 connection, authentication and disconnection.
57
- *
58
- * @package PHPMailer
59
- * @author Richard Davey
60
- */
61
-
62
- class POP3 {
63
- /**
64
- * Default POP3 port
65
- * @var int
66
- */
67
- public $POP3_PORT = 110;
68
-
69
- /**
70
- * Default Timeout
71
- * @var int
72
- */
73
- public $POP3_TIMEOUT = 30;
74
-
75
- /**
76
- * POP3 Carriage Return + Line Feed
77
- * @var string
78
- */
79
- public $CRLF = "\r\n";
80
-
81
- /**
82
- * Displaying Debug warnings? (0 = now, 1+ = yes)
83
- * @var int
84
- */
85
- public $do_debug = 2;
86
-
87
- /**
88
- * POP3 Mail Server
89
- * @var string
90
- */
91
- public $host;
92
-
93
- /**
94
- * POP3 Port
95
- * @var int
96
- */
97
- public $port;
98
-
99
- /**
100
- * POP3 Timeout Value
101
- * @var int
102
- */
103
- public $tval;
104
-
105
- /**
106
- * POP3 Username
107
- * @var string
108
- */
109
- public $username;
110
-
111
- /**
112
- * POP3 Password
113
- * @var string
114
- */
115
- public $password;
116
-
117
- /////////////////////////////////////////////////
118
- // PROPERTIES, PRIVATE AND PROTECTED
119
- /////////////////////////////////////////////////
120
-
121
- private $pop_conn;
122
- private $connected;
123
- private $error; // Error log array
124
-
125
- /**
126
- * Constructor, sets the initial values
127
- * @access public
128
- * @return POP3
129
- */
130
- public function __construct() {
131
- $this->pop_conn = 0;
132
- $this->connected = false;
133
- $this->error = null;
134
- }
135
-
136
- /**
137
- * Combination of public events - connect, login, disconnect
138
- * @access public
139
- * @param string $host
140
- * @param integer $port
141
- * @param integer $tval
142
- * @param string $username
143
- * @param string $password
144
- */
145
- public function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0) {
146
- $this->host = $host;
147
-
148
- // If no port value is passed, retrieve it
149
- if ($port == false) {
150
- $this->port = $this->POP3_PORT;
151
- } else {
152
- $this->port = $port;
153
- }
154
-
155
- // If no port value is passed, retrieve it
156
- if ($tval == false) {
157
- $this->tval = $this->POP3_TIMEOUT;
158
- } else {
159
- $this->tval = $tval;
160
- }
161
-
162
- $this->do_debug = $debug_level;
163
- $this->username = $username;
164
- $this->password = $password;
165
-
166
- // Refresh the error log
167
- $this->error = null;
168
-
169
- // Connect
170
- $result = $this->Connect($this->host, $this->port, $this->tval);
171
-
172
- if ($result) {
173
- $login_result = $this->Login($this->username, $this->password);
174
-
175
- if ($login_result) {
176
- $this->Disconnect();
177
-
178
- return true;
179
- }
180
-
181
- }
182
-
183
- // We need to disconnect regardless if the login succeeded
184
- $this->Disconnect();
185
-
186
- return false;
187
- }
188
-
189
- /**
190
- * Connect to the POP3 server
191
- * @access public
192
- * @param string $host
193
- * @param integer $port
194
- * @param integer $tval
195
- * @return boolean
196
- */
197
- public function Connect ($host, $port = false, $tval = 30) {
198
- // Are we already connected?
199
- if ($this->connected) {
200
- return true;
201
- }
202
-
203
- /*
204
- On Windows this will raise a PHP Warning error if the hostname doesn't exist.
205
- Rather than supress it with @fsockopen, let's capture it cleanly instead
206
- */
207
-
208
- set_error_handler(array(&$this, 'catchWarning'));
209
-
210
- // Connect to the POP3 server
211
- $this->pop_conn = fsockopen($host, // POP3 Host
212
- $port, // Port #
213
- $errno, // Error Number
214
- $errstr, // Error Message
215
- $tval); // Timeout (seconds)
216
-
217
- // Restore the error handler
218
- restore_error_handler();
219
-
220
- // Does the Error Log now contain anything?
221
- if ($this->error && $this->do_debug >= 1) {
222
- $this->displayErrors();
223
- }
224
-
225
- // Did we connect?
226
- if ($this->pop_conn == false) {
227
- // It would appear not...
228
- $this->error = array(
229
- 'error' => "Failed to connect to server $host on port $port",
230
- 'errno' => $errno,
231
- 'errstr' => $errstr
232
- );
233
-
234
- if ($this->do_debug >= 1) {
235
- $this->displayErrors();
236
- }
237
-
238
- return false;
239
- }
240
-
241
- // Increase the stream time-out
242
-
243
- // Check for PHP 4.3.0 or later
244
- if (version_compare(phpversion(), '5.0.0', 'ge')) {
245
- stream_set_timeout($this->pop_conn, $tval, 0);
246
- } else {
247
- // Does not work on Windows
248
- if (substr(PHP_OS, 0, 3) !== 'WIN') {
249
- socket_set_timeout($this->pop_conn, $tval, 0);
250
- }
251
- }
252
-
253
- // Get the POP3 server response
254
- $pop3_response = $this->getResponse();
255
-
256
- // Check for the +OK
257
- if ($this->checkResponse($pop3_response)) {
258
- // The connection is established and the POP3 server is talking
259
- $this->connected = true;
260
- return true;
261
- }
262
-
263
- }
264
-
265
- /**
266
- * Login to the POP3 server (does not support APOP yet)
267
- * @access public
268
- * @param string $username
269
- * @param string $password
270
- * @return boolean
271
- */
272
- public function Login ($username = '', $password = '') {
273
- if ($this->connected == false) {
274
- $this->error = 'Not connected to POP3 server';
275
-
276
- if ($this->do_debug >= 1) {
277
- $this->displayErrors();
278
- }
279
- }
280
-
281
- if (empty($username)) {
282
- $username = $this->username;
283
- }
284
-
285
- if (empty($password)) {
286
- $password = $this->password;
287
- }
288
-
289
- $pop_username = "USER $username" . $this->CRLF;
290
- $pop_password = "PASS $password" . $this->CRLF;
291
-
292
- // Send the Username
293
- $this->sendString($pop_username);
294
- $pop3_response = $this->getResponse();
295
-
296
- if ($this->checkResponse($pop3_response)) {
297
- // Send the Password
298
- $this->sendString($pop_password);
299
- $pop3_response = $this->getResponse();
300
-
301
- if ($this->checkResponse($pop3_response)) {
302
- return true;
303
- } else {
304
- return false;
305
- }
306
- } else {
307
- return false;
308
- }
309
- }
310
-
311
- /**
312
- * Disconnect from the POP3 server
313
- * @access public
314
- */
315
- public function Disconnect () {
316
- $this->sendString('QUIT');
317
-
318
- fclose($this->pop_conn);
319
- }
320
-
321
- /////////////////////////////////////////////////
322
- // Private Methods
323
- /////////////////////////////////////////////////
324
-
325
- /**
326
- * Get the socket response back.
327
- * $size is the maximum number of bytes to retrieve
328
- * @access private
329
- * @param integer $size
330
- * @return string
331
- */
332
- private function getResponse ($size = 128) {
333
- $pop3_response = fgets($this->pop_conn, $size);
334
-
335
- return $pop3_response;
336
- }
337
-
338
- /**
339
- * Send a string down the open socket connection to the POP3 server
340
- * @access private
341
- * @param string $string
342
- * @return integer
343
- */
344
- private function sendString ($string) {
345
- $bytes_sent = fwrite($this->pop_conn, $string, strlen($string));
346
-
347
- return $bytes_sent;
348
- }
349
-
350
- /**
351
- * Checks the POP3 server response for +OK or -ERR
352
- * @access private
353
- * @param string $string
354
- * @return boolean
355
- */
356
- private function checkResponse ($string) {
357
- if (substr($string, 0, 3) !== '+OK') {
358
- $this->error = array(
359
- 'error' => "Server reported an error: $string",
360
- 'errno' => 0,
361
- 'errstr' => ''
362
- );
363
-
364
- if ($this->do_debug >= 1) {
365
- $this->displayErrors();
366
- }
367
-
368
- return false;
369
- } else {
370
- return true;
371
- }
372
-
373
- }
374
-
375
- /**
376
- * If debug is enabled, display the error message array
377
- * @access private
378
- */
379
- private function displayErrors () {
380
- echo '<pre>';
381
-
382
- foreach ($this->error as $single_error) {
383
- print_r($single_error);
384
- }
385
-
386
- echo '</pre>';
387
- }
388
-
389
- /**
390
- * Takes over from PHP for the socket warning handler
391
- * @access private
392
- * @param integer $errno
393
- * @param string $errstr
394
- * @param string $errfile
395
- * @param integer $errline
396
- */
397
- private function catchWarning ($errno, $errstr, $errfile, $errline) {
398
- $this->error[] = array(
399
- 'error' => "Connecting to the POP3 server raised a PHP warning: ",
400
- 'errno' => $errno,
401
- 'errstr' => $errstr
402
- );
403
- }
404
-
405
- // End of class
406
- }
407
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/phpmailer/class.smtp.php DELETED
@@ -1,814 +0,0 @@
1
- <?php
2
- /*~ class.smtp.php
3
- .---------------------------------------------------------------------------.
4
- | Software: PHPMailer - PHP email class |
5
- | Version: 5.1 |
6
- | Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
7
- | Info: http://phpmailer.sourceforge.net |
8
- | Support: http://sourceforge.net/projects/phpmailer/ |
9
- | ------------------------------------------------------------------------- |
10
- | Admin: Andy Prevost (project admininistrator) |
11
- | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
12
- | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
13
- | Founder: Brent R. Matzelle (original founder) |
14
- | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
15
- | Copyright (c) 2001-2003, Brent R. Matzelle |
16
- | ------------------------------------------------------------------------- |
17
- | License: Distributed under the Lesser General Public License (LGPL) |
18
- | http://www.gnu.org/copyleft/lesser.html |
19
- | This program is distributed in the hope that it will be useful - WITHOUT |
20
- | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21
- | FITNESS FOR A PARTICULAR PURPOSE. |
22
- | ------------------------------------------------------------------------- |
23
- | We offer a number of paid services (www.codeworxtech.com): |
24
- | - Web Hosting on highly optimized fast and secure servers |
25
- | - Technology Consulting |
26
- | - Oursourcing (highly qualified programmers and graphic designers) |
27
- '---------------------------------------------------------------------------'
28
- */
29
-
30
- /**
31
- * PHPMailer - PHP SMTP email transport class
32
- * NOTE: Designed for use with PHP version 5 and up
33
- * @package PHPMailer
34
- * @author Andy Prevost
35
- * @author Marcus Bointon
36
- * @copyright 2004 - 2008 Andy Prevost
37
- * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
38
- * @version $Id: class.smtp.php 444 2009-05-05 11:22:26Z coolbru $
39
- */
40
-
41
- /**
42
- * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
43
- * commands except TURN which will always return a not implemented
44
- * error. SMTP also provides some utility methods for sending mail
45
- * to an SMTP server.
46
- * original author: Chris Ryan
47
- */
48
-
49
- class SMTP {
50
- /**
51
- * SMTP server port
52
- * @var int
53
- */
54
- public $SMTP_PORT = 25;
55
-
56
- /**
57
- * SMTP reply line ending
58
- * @var string
59
- */
60
- public $CRLF = "\r\n";
61
-
62
- /**
63
- * Sets whether debugging is turned on
64
- * @var bool
65
- */
66
- public $do_debug; // the level of debug to perform
67
-
68
- /**
69
- * Sets VERP use on/off (default is off)
70
- * @var bool
71
- */
72
- public $do_verp = false;
73
-
74
- /////////////////////////////////////////////////
75
- // PROPERTIES, PRIVATE AND PROTECTED
76
- /////////////////////////////////////////////////
77
-
78
- private $smtp_conn; // the socket to the server
79
- private $error; // error if any on the last call
80
- private $helo_rply; // the reply the server sent to us for HELO
81
-
82
- /**
83
- * Initialize the class so that the data is in a known state.
84
- * @access public
85
- * @return void
86
- */
87
- public function __construct() {
88
- $this->smtp_conn = 0;
89
- $this->error = null;
90
- $this->helo_rply = null;
91
-
92
- $this->do_debug = 0;
93
- }
94
-
95
- /////////////////////////////////////////////////
96
- // CONNECTION FUNCTIONS
97
- /////////////////////////////////////////////////
98
-
99
- /**
100
- * Connect to the server specified on the port specified.
101
- * If the port is not specified use the default SMTP_PORT.
102
- * If tval is specified then a connection will try and be
103
- * established with the server for that number of seconds.
104
- * If tval is not specified the default is 30 seconds to
105
- * try on the connection.
106
- *
107
- * SMTP CODE SUCCESS: 220
108
- * SMTP CODE FAILURE: 421
109
- * @access public
110
- * @return bool
111
- */
112
- public function Connect($host, $port = 0, $tval = 30) {
113
- // set the error val to null so there is no confusion
114
- $this->error = null;
115
-
116
- // make sure we are __not__ connected
117
- if($this->connected()) {
118
- // already connected, generate error
119
- $this->error = array("error" => "Already connected to a server");
120
- return false;
121
- }
122
-
123
- if(empty($port)) {
124
- $port = $this->SMTP_PORT;
125
- }
126
-
127
- // connect to the smtp server
128
- $this->smtp_conn = @fsockopen($host, // the host of the server
129
- $port, // the port to use
130
- $errno, // error number if any
131
- $errstr, // error message if any
132
- $tval); // give up after ? secs
133
- // verify we connected properly
134
- if(empty($this->smtp_conn)) {
135
- $this->error = array("error" => "Failed to connect to server",
136
- "errno" => $errno,
137
- "errstr" => $errstr);
138
- if($this->do_debug >= 1) {
139
- echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />';
140
- }
141
- return false;
142
- }
143
-
144
- // SMTP server can take longer to respond, give longer timeout for first read
145
- // Windows does not have support for this timeout function
146
- if(substr(PHP_OS, 0, 3) != "WIN")
147
- socket_set_timeout($this->smtp_conn, $tval, 0);
148
-
149
- // get any announcement
150
- $announce = $this->get_lines();
151
-
152
- if($this->do_debug >= 2) {
153
- echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />';
154
- }
155
-
156
- return true;
157
- }
158
-
159
- /**
160
- * Initiate a TLS communication with the server.
161
- *
162
- * SMTP CODE 220 Ready to start TLS
163
- * SMTP CODE 501 Syntax error (no parameters allowed)
164
- * SMTP CODE 454 TLS not available due to temporary reason
165
- * @access public
166
- * @return bool success
167
- */
168
- public function StartTLS() {
169
- $this->error = null; # to avoid confusion
170
-
171
- if(!$this->connected()) {
172
- $this->error = array("error" => "Called StartTLS() without being connected");
173
- return false;
174
- }
175
-
176
- fputs($this->smtp_conn,"STARTTLS" . $this->CRLF);
177
-
178
- $rply = $this->get_lines();
179
- $code = substr($rply,0,3);
180
-
181
- if($this->do_debug >= 2) {
182
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
183
- }
184
-
185
- if($code != 220) {
186
- $this->error =
187
- array("error" => "STARTTLS not accepted from server",
188
- "smtp_code" => $code,
189
- "smtp_msg" => substr($rply,4));
190
- if($this->do_debug >= 1) {
191
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
192
- }
193
- return false;
194
- }
195
-
196
- // Begin encrypted connection
197
- if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
198
- return false;
199
- }
200
-
201
- return true;
202
- }
203
-
204
- /**
205
- * Performs SMTP authentication. Must be run after running the
206
- * Hello() method. Returns true if successfully authenticated.
207
- * @access public
208
- * @return bool
209
- */
210
- public function Authenticate($username, $password) {
211
- // Start authentication
212
- fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
213
-
214
- $rply = $this->get_lines();
215
- $code = substr($rply,0,3);
216
-
217
- if($code != 334) {
218
- $this->error =
219
- array("error" => "AUTH not accepted from server",
220
- "smtp_code" => $code,
221
- "smtp_msg" => substr($rply,4));
222
- if($this->do_debug >= 1) {
223
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
224
- }
225
- return false;
226
- }
227
-
228
- // Send encoded username
229
- fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
230
-
231
- $rply = $this->get_lines();
232
- $code = substr($rply,0,3);
233
-
234
- if($code != 334) {
235
- $this->error =
236
- array("error" => "Username not accepted from server",
237
- "smtp_code" => $code,
238
- "smtp_msg" => substr($rply,4));
239
- if($this->do_debug >= 1) {
240
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
241
- }
242
- return false;
243
- }
244
-
245
- // Send encoded password
246
- fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
247
-
248
- $rply = $this->get_lines();
249
- $code = substr($rply,0,3);
250
-
251
- if($code != 235) {
252
- $this->error =
253
- array("error" => "Password not accepted from server",
254
- "smtp_code" => $code,
255
- "smtp_msg" => substr($rply,4));
256
- if($this->do_debug >= 1) {
257
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
258
- }
259
- return false;
260
- }
261
-
262
- return true;
263
- }
264
-
265
- /**
266
- * Returns true if connected to a server otherwise false
267
- * @access public
268
- * @return bool
269
- */
270
- public function Connected() {
271
- if(!empty($this->smtp_conn)) {
272
- $sock_status = socket_get_status($this->smtp_conn);
273
- if($sock_status["eof"]) {
274
- // the socket is valid but we are not connected
275
- if($this->do_debug >= 1) {
276
- echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected";
277
- }
278
- $this->Close();
279
- return false;
280
- }
281
- return true; // everything looks good
282
- }
283
- return false;
284
- }
285
-
286
- /**
287
- * Closes the socket and cleans up the state of the class.
288
- * It is not considered good to use this function without
289
- * first trying to use QUIT.
290
- * @access public
291
- * @return void
292
- */
293
- public function Close() {
294
- $this->error = null; // so there is no confusion
295
- $this->helo_rply = null;
296
- if(!empty($this->smtp_conn)) {
297
- // close the connection and cleanup
298
- fclose($this->smtp_conn);
299
- $this->smtp_conn = 0;
300
- }
301
- }
302
-
303
- /////////////////////////////////////////////////
304
- // SMTP COMMANDS
305
- /////////////////////////////////////////////////
306
-
307
- /**
308
- * Issues a data command and sends the msg_data to the server
309
- * finializing the mail transaction. $msg_data is the message
310
- * that is to be send with the headers. Each header needs to be
311
- * on a single line followed by a <CRLF> with the message headers
312
- * and the message body being seperated by and additional <CRLF>.
313
- *
314
- * Implements rfc 821: DATA <CRLF>
315
- *
316
- * SMTP CODE INTERMEDIATE: 354
317
- * [data]
318
- * <CRLF>.<CRLF>
319
- * SMTP CODE SUCCESS: 250
320
- * SMTP CODE FAILURE: 552,554,451,452
321
- * SMTP CODE FAILURE: 451,554
322
- * SMTP CODE ERROR : 500,501,503,421
323
- * @access public
324
- * @return bool
325
- */
326
- public function Data($msg_data) {
327
- $this->error = null; // so no confusion is caused
328
-
329
- if(!$this->connected()) {
330
- $this->error = array(
331
- "error" => "Called Data() without being connected");
332
- return false;
333
- }
334
-
335
- fputs($this->smtp_conn,"DATA" . $this->CRLF);
336
-
337
- $rply = $this->get_lines();
338
- $code = substr($rply,0,3);
339
-
340
- if($this->do_debug >= 2) {
341
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
342
- }
343
-
344
- if($code != 354) {
345
- $this->error =
346
- array("error" => "DATA command not accepted from server",
347
- "smtp_code" => $code,
348
- "smtp_msg" => substr($rply,4));
349
- if($this->do_debug >= 1) {
350
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
351
- }
352
- return false;
353
- }
354
-
355
- /* the server is ready to accept data!
356
- * according to rfc 821 we should not send more than 1000
357
- * including the CRLF
358
- * characters on a single line so we will break the data up
359
- * into lines by \r and/or \n then if needed we will break
360
- * each of those into smaller lines to fit within the limit.
361
- * in addition we will be looking for lines that start with
362
- * a period '.' and append and additional period '.' to that
363
- * line. NOTE: this does not count towards limit.
364
- */
365
-
366
- // normalize the line breaks so we know the explode works
367
- $msg_data = str_replace("\r\n","\n",$msg_data);
368
- $msg_data = str_replace("\r","\n",$msg_data);
369
- $lines = explode("\n",$msg_data);
370
-
371
- /* we need to find a good way to determine is headers are
372
- * in the msg_data or if it is a straight msg body
373
- * currently I am assuming rfc 822 definitions of msg headers
374
- * and if the first field of the first line (':' sperated)
375
- * does not contain a space then it _should_ be a header
376
- * and we can process all lines before a blank "" line as
377
- * headers.
378
- */
379
-
380
- $field = substr($lines[0],0,strpos($lines[0],":"));
381
- $in_headers = false;
382
- if(!empty($field) && !strstr($field," ")) {
383
- $in_headers = true;
384
- }
385
-
386
- $max_line_length = 998; // used below; set here for ease in change
387
-
388
- while(list(,$line) = @each($lines)) {
389
- $lines_out = null;
390
- if($line == "" && $in_headers) {
391
- $in_headers = false;
392
- }
393
- // ok we need to break this line up into several smaller lines
394
- while(strlen($line) > $max_line_length) {
395
- $pos = strrpos(substr($line,0,$max_line_length)," ");
396
-
397
- // Patch to fix DOS attack
398
- if(!$pos) {
399
- $pos = $max_line_length - 1;
400
- $lines_out[] = substr($line,0,$pos);
401
- $line = substr($line,$pos);
402
- } else {
403
- $lines_out[] = substr($line,0,$pos);
404
- $line = substr($line,$pos + 1);
405
- }
406
-
407
- /* if processing headers add a LWSP-char to the front of new line
408
- * rfc 822 on long msg headers
409
- */
410
- if($in_headers) {
411
- $line = "\t" . $line;
412
- }
413
- }
414
- $lines_out[] = $line;
415
-
416
- // send the lines to the server
417
- while(list(,$line_out) = @each($lines_out)) {
418
- if(strlen($line_out) > 0)
419
- {
420
- if(substr($line_out, 0, 1) == ".") {
421
- $line_out = "." . $line_out;
422
- }
423
- }
424
- fputs($this->smtp_conn,$line_out . $this->CRLF);
425
- }
426
- }
427
-
428
- // message data has been sent
429
- fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
430
-
431
- $rply = $this->get_lines();
432
- $code = substr($rply,0,3);
433
-
434
- if($this->do_debug >= 2) {
435
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
436
- }
437
-
438
- if($code != 250) {
439
- $this->error =
440
- array("error" => "DATA not accepted from server",
441
- "smtp_code" => $code,
442
- "smtp_msg" => substr($rply,4));
443
- if($this->do_debug >= 1) {
444
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
445
- }
446
- return false;
447
- }
448
- return true;
449
- }
450
-
451
- /**
452
- * Sends the HELO command to the smtp server.
453
- * This makes sure that we and the server are in
454
- * the same known state.
455
- *
456
- * Implements from rfc 821: HELO <SP> <domain> <CRLF>
457
- *
458
- * SMTP CODE SUCCESS: 250
459
- * SMTP CODE ERROR : 500, 501, 504, 421
460
- * @access public
461
- * @return bool
462
- */
463
- public function Hello($host = '') {
464
- $this->error = null; // so no confusion is caused
465
-
466
- if(!$this->connected()) {
467
- $this->error = array(
468
- "error" => "Called Hello() without being connected");
469
- return false;
470
- }
471
-
472
- // if hostname for HELO was not specified send default
473
- if(empty($host)) {
474
- // determine appropriate default to send to server
475
- $host = "localhost";
476
- }
477
-
478
- // Send extended hello first (RFC 2821)
479
- if(!$this->SendHello("EHLO", $host)) {
480
- if(!$this->SendHello("HELO", $host)) {
481
- return false;
482
- }
483
- }
484
-
485
- return true;
486
- }
487
-
488
- /**
489
- * Sends a HELO/EHLO command.
490
- * @access private
491
- * @return bool
492
- */
493
- private function SendHello($hello, $host) {
494
- fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
495
-
496
- $rply = $this->get_lines();
497
- $code = substr($rply,0,3);
498
-
499
- if($this->do_debug >= 2) {
500
- echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />';
501
- }
502
-
503
- if($code != 250) {
504
- $this->error =
505
- array("error" => $hello . " not accepted from server",
506
- "smtp_code" => $code,
507
- "smtp_msg" => substr($rply,4));
508
- if($this->do_debug >= 1) {
509
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
510
- }
511
- return false;
512
- }
513
-
514
- $this->helo_rply = $rply;
515
-
516
- return true;
517
- }
518
-
519
- /**
520
- * Starts a mail transaction from the email address specified in
521
- * $from. Returns true if successful or false otherwise. If True
522
- * the mail transaction is started and then one or more Recipient
523
- * commands may be called followed by a Data command.
524
- *
525
- * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
526
- *
527
- * SMTP CODE SUCCESS: 250
528
- * SMTP CODE SUCCESS: 552,451,452
529
- * SMTP CODE SUCCESS: 500,501,421
530
- * @access public
531
- * @return bool
532
- */
533
- public function Mail($from) {
534
- $this->error = null; // so no confusion is caused
535
-
536
- if(!$this->connected()) {
537
- $this->error = array(
538
- "error" => "Called Mail() without being connected");
539
- return false;
540
- }
541
-
542
- $useVerp = ($this->do_verp ? "XVERP" : "");
543
- fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
544
-
545
- $rply = $this->get_lines();
546
- $code = substr($rply,0,3);
547
-
548
- if($this->do_debug >= 2) {
549
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
550
- }
551
-
552
- if($code != 250) {
553
- $this->error =
554
- array("error" => "MAIL not accepted from server",
555
- "smtp_code" => $code,
556
- "smtp_msg" => substr($rply,4));
557
- if($this->do_debug >= 1) {
558
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
559
- }
560
- return false;
561
- }
562
- return true;
563
- }
564
-
565
- /**
566
- * Sends the quit command to the server and then closes the socket
567
- * if there is no error or the $close_on_error argument is true.
568
- *
569
- * Implements from rfc 821: QUIT <CRLF>
570
- *
571
- * SMTP CODE SUCCESS: 221
572
- * SMTP CODE ERROR : 500
573
- * @access public
574
- * @return bool
575
- */
576
- public function Quit($close_on_error = true) {
577
- $this->error = null; // so there is no confusion
578
-
579
- if(!$this->connected()) {
580
- $this->error = array(
581
- "error" => "Called Quit() without being connected");
582
- return false;
583
- }
584
-
585
- // send the quit command to the server
586
- fputs($this->smtp_conn,"quit" . $this->CRLF);
587
-
588
- // get any good-bye messages
589
- $byemsg = $this->get_lines();
590
-
591
- if($this->do_debug >= 2) {
592
- echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />';
593
- }
594
-
595
- $rval = true;
596
- $e = null;
597
-
598
- $code = substr($byemsg,0,3);
599
- if($code != 221) {
600
- // use e as a tmp var cause Close will overwrite $this->error
601
- $e = array("error" => "SMTP server rejected quit command",
602
- "smtp_code" => $code,
603
- "smtp_rply" => substr($byemsg,4));
604
- $rval = false;
605
- if($this->do_debug >= 1) {
606
- echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />';
607
- }
608
- }
609
-
610
- if(empty($e) || $close_on_error) {
611
- $this->Close();
612
- }
613
-
614
- return $rval;
615
- }
616
-
617
- /**
618
- * Sends the command RCPT to the SMTP server with the TO: argument of $to.
619
- * Returns true if the recipient was accepted false if it was rejected.
620
- *
621
- * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
622
- *
623
- * SMTP CODE SUCCESS: 250,251
624
- * SMTP CODE FAILURE: 550,551,552,553,450,451,452
625
- * SMTP CODE ERROR : 500,501,503,421
626
- * @access public
627
- * @return bool
628
- */
629
- public function Recipient($to) {
630
- $this->error = null; // so no confusion is caused
631
-
632
- if(!$this->connected()) {
633
- $this->error = array(
634
- "error" => "Called Recipient() without being connected");
635
- return false;
636
- }
637
-
638
- fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
639
-
640
- $rply = $this->get_lines();
641
- $code = substr($rply,0,3);
642
-
643
- if($this->do_debug >= 2) {
644
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
645
- }
646
-
647
- if($code != 250 && $code != 251) {
648
- $this->error =
649
- array("error" => "RCPT not accepted from server",
650
- "smtp_code" => $code,
651
- "smtp_msg" => substr($rply,4));
652
- if($this->do_debug >= 1) {
653
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
654
- }
655
- return false;
656
- }
657
- return true;
658
- }
659
-
660
- /**
661
- * Sends the RSET command to abort and transaction that is
662
- * currently in progress. Returns true if successful false
663
- * otherwise.
664
- *
665
- * Implements rfc 821: RSET <CRLF>
666
- *
667
- * SMTP CODE SUCCESS: 250
668
- * SMTP CODE ERROR : 500,501,504,421
669
- * @access public
670
- * @return bool
671
- */
672
- public function Reset() {
673
- $this->error = null; // so no confusion is caused
674
-
675
- if(!$this->connected()) {
676
- $this->error = array(
677
- "error" => "Called Reset() without being connected");
678
- return false;
679
- }
680
-
681
- fputs($this->smtp_conn,"RSET" . $this->CRLF);
682
-
683
- $rply = $this->get_lines();
684
- $code = substr($rply,0,3);
685
-
686
- if($this->do_debug >= 2) {
687
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
688
- }
689
-
690
- if($code != 250) {
691
- $this->error =
692
- array("error" => "RSET failed",
693
- "smtp_code" => $code,
694
- "smtp_msg" => substr($rply,4));
695
- if($this->do_debug >= 1) {
696
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
697
- }
698
- return false;
699
- }
700
-
701
- return true;
702
- }
703
-
704
- /**
705
- * Starts a mail transaction from the email address specified in
706
- * $from. Returns true if successful or false otherwise. If True
707
- * the mail transaction is started and then one or more Recipient
708
- * commands may be called followed by a Data command. This command
709
- * will send the message to the users terminal if they are logged
710
- * in and send them an email.
711
- *
712
- * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
713
- *
714
- * SMTP CODE SUCCESS: 250
715
- * SMTP CODE SUCCESS: 552,451,452
716
- * SMTP CODE SUCCESS: 500,501,502,421
717
- * @access public
718
- * @return bool
719
- */
720
- public function SendAndMail($from) {
721
- $this->error = null; // so no confusion is caused
722
-
723
- if(!$this->connected()) {
724
- $this->error = array(
725
- "error" => "Called SendAndMail() without being connected");
726
- return false;
727
- }
728
-
729
- fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
730
-
731
- $rply = $this->get_lines();
732
- $code = substr($rply,0,3);
733
-
734
- if($this->do_debug >= 2) {
735
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
736
- }
737
-
738
- if($code != 250) {
739
- $this->error =
740
- array("error" => "SAML not accepted from server",
741
- "smtp_code" => $code,
742
- "smtp_msg" => substr($rply,4));
743
- if($this->do_debug >= 1) {
744
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
745
- }
746
- return false;
747
- }
748
- return true;
749
- }
750
-
751
- /**
752
- * This is an optional command for SMTP that this class does not
753
- * support. This method is here to make the RFC821 Definition
754
- * complete for this class and __may__ be implimented in the future
755
- *
756
- * Implements from rfc 821: TURN <CRLF>
757
- *
758
- * SMTP CODE SUCCESS: 250
759
- * SMTP CODE FAILURE: 502
760
- * SMTP CODE ERROR : 500, 503
761
- * @access public
762
- * @return bool
763
- */
764
- public function Turn() {
765
- $this->error = array("error" => "This method, TURN, of the SMTP ".
766
- "is not implemented");
767
- if($this->do_debug >= 1) {
768
- echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />';
769
- }
770
- return false;
771
- }
772
-
773
- /**
774
- * Get the current error
775
- * @access public
776
- * @return array
777
- */
778
- public function getError() {
779
- return $this->error;
780
- }
781
-
782
- /////////////////////////////////////////////////
783
- // INTERNAL FUNCTIONS
784
- /////////////////////////////////////////////////
785
-
786
- /**
787
- * Read in as many lines as possible
788
- * either before eof or socket timeout occurs on the operation.
789
- * With SMTP we can tell if we have more lines to read if the
790
- * 4th character is '-' symbol. If it is a space then we don't
791
- * need to read anything else.
792
- * @access private
793
- * @return string
794
- */
795
- private function get_lines() {
796
- $data = "";
797
- while($str = @fgets($this->smtp_conn,515)) {
798
- if($this->do_debug >= 4) {
799
- echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />';
800
- echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />';
801
- }
802
- $data .= $str;
803
- if($this->do_debug >= 4) {
804
- echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />';
805
- }
806
- // if 4th character is a space, we are done reading, break the loop
807
- if(substr($str,3,1) == " ") { break; }
808
- }
809
- return $data;
810
- }
811
-
812
- }
813
-
814
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.taylorlovett.com
4
  Tags: contact form, web form, custom contact form, custom forms, captcha form, contact fields, form mailers
5
  Requires at least: 2.8.1
6
  Tested up to: 3.0.1
7
- Stable tag: 4.0.2
8
 
9
  Gauranteed to be the most customizable and intuitive contact form plugin for Wordpress.
10
 
@@ -18,7 +18,7 @@ Custom Contact Forms 4.0 will revolutionize the idea of a Wordpress plugin.
18
 
19
  * __NEW__ - All form submissions saved and displayed in admin panel as well as emailed to you
20
  * __NEW__ - Import and export forms/fields/styles/etc. with ease!
21
- * __NEW__ - This plugin can now be translated in to different languages.
22
  * __NEW__ - Error messages can be customized for each field
23
  * Choose between XHTML or HTML. All code is clean and valid!
24
  * Create __unlimited__ forms and fields
@@ -101,6 +101,13 @@ Visit http://www.taylorlovett.com/wordpress-plugins for screenshots. Right now a
101
 
102
  == Changelog ==
103
 
 
 
 
 
 
 
 
104
  = 4.0.2 =
105
  * custom-contact-forms-front.php - Field instructions bug fixed
106
  * custom-contact-forms-admin.php - Display change
4
  Tags: contact form, web form, custom contact form, custom forms, captcha form, contact fields, form mailers
5
  Requires at least: 2.8.1
6
  Tested up to: 3.0.1
7
+ Stable tag: 4.0.3
8
 
9
  Gauranteed to be the most customizable and intuitive contact form plugin for Wordpress.
10
 
18
 
19
  * __NEW__ - All form submissions saved and displayed in admin panel as well as emailed to you
20
  * __NEW__ - Import and export forms/fields/styles/etc. with ease!
21
+ * __NEW__ - This plugin can now be translated in to different languages - UTF8 character encoding.
22
  * __NEW__ - Error messages can be customized for each field
23
  * Choose between XHTML or HTML. All code is clean and valid!
24
  * Create __unlimited__ forms and fields
101
 
102
  == Changelog ==
103
 
104
+ = 4.0.3 =
105
+ * custom-contact-forms-front.php - PHPMailer bug fixed, form redirect fixed
106
+ * custom-contact-forms-static.php - Form redirect function added
107
+ * custom-contact-forms-admin.php - redirects fixed, phpmailer bug fixed
108
+ * widget/phpmailer - deleted
109
+ * widget/db/custom-contact-forms-db.php - table charsets changed to UTF8
110
+
111
  = 4.0.2 =
112
  * custom-contact-forms-front.php - Field instructions bug fixed
113
  * custom-contact-forms-admin.php - Display change