about summary refs log tree commit diff stats
path: root/central/trunk/includes
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2008-09-28 21:53:20 +0000
committerKelly Rauchenberger <fefferburbia@gmail.com>2008-09-28 21:53:20 +0000
commit433efccd36add54061868af33d1ebf1d61dae554 (patch)
tree4201d99cd159251520cd319d85a62e4e3faca363 /central/trunk/includes
parentfb1b67b6922a20fdc3538dd6ae4659dfc1d8d7d2 (diff)
downloadinstadisc-433efccd36add54061868af33d1ebf1d61dae554.tar.gz
instadisc-433efccd36add54061868af33d1ebf1d61dae554.tar.bz2
instadisc-433efccd36add54061868af33d1ebf1d61dae554.zip
Central: Continued to remove UI
Also removed unnecessary things. Refs #63
Diffstat (limited to 'central/trunk/includes')
-rw-r--r--central/trunk/includes/class.phpmailer.php1897
-rw-r--r--central/trunk/includes/class.smtp.php1113
-rw-r--r--central/trunk/includes/instadisc.php108
-rw-r--r--central/trunk/includes/template.php160
4 files changed, 3 insertions, 3275 deletions
diff --git a/central/trunk/includes/class.phpmailer.php b/central/trunk/includes/class.phpmailer.php deleted file mode 100644 index 51a50e7..0000000 --- a/central/trunk/includes/class.phpmailer.php +++ /dev/null
@@ -1,1897 +0,0 @@
1<?php
2/*~ class.phpmailer.php
3.---------------------------------------------------------------------------.
4| Software: PHPMailer - PHP email class |
5| Version: 2.2.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| Author: Andy Prevost (project admininistrator) |
11| Author: Brent R. Matzelle (original founder) |
12| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
13| Copyright (c) 2001-2003, Brent R. Matzelle |
14| ------------------------------------------------------------------------- |
15| License: Distributed under the Lesser General Public License (LGPL) |
16| http://www.gnu.org/copyleft/lesser.html |
17| This program is distributed in the hope that it will be useful - WITHOUT |
18| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
19| FITNESS FOR A PARTICULAR PURPOSE. |
20| ------------------------------------------------------------------------- |
21| We offer a number of paid services (www.codeworxtech.com): |
22| - Web Hosting on highly optimized fast and secure servers |
23| - Technology Consulting |
24| - Oursourcing (highly qualified programmers and graphic designers) |
25'---------------------------------------------------------------------------'
26
27/**
28 * PHPMailer - PHP email transport class
29 * NOTE: Designed for use with PHP version 5 and up
30 * @package PHPMailer
31 * @author Andy Prevost
32 * @copyright 2004 - 2008 Andy Prevost
33 */
34
35class PHPMailer {
36
37 /////////////////////////////////////////////////
38 // PROPERTIES, PUBLIC
39 /////////////////////////////////////////////////
40
41 /**
42 * Email priority (1 = High, 3 = Normal, 5 = low).
43 * @var int
44 */
45 public $Priority = 3;
46
47 /**
48 * Sets the CharSet of the message.
49 * @var string
50 */
51 public $CharSet = 'iso-8859-1';
52
53 /**
54 * Sets the Content-type of the message.
55 * @var string
56 */
57 public $ContentType = 'text/plain';
58
59 /**
60 * Sets the Encoding of the message. Options for this are "8bit",
61 * "7bit", "binary", "base64", and "quoted-printable".
62 * @var string
63 */
64 public $Encoding = '8bit';
65
66 /**
67 * Holds the most recent mailer error message.
68 * @var string
69 */
70 public $ErrorInfo = '';
71
72 /**
73 * Sets the From email address for the message.
74 * @var string
75 */
76 public $From = 'root@localhost';
77
78 /**
79 * Sets the From name of the message.
80 * @var string
81 */
82 public $FromName = 'Root User';
83
84 /**
85 * Sets the Sender email (Return-Path) of the message. If not empty,
86 * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
87 * @var string
88 */
89 public $Sender = '';
90
91 /**
92 * Sets the Subject of the message.
93 * @var string
94 */
95 public $Subject = '';
96
97 /**
98 * Sets the Body of the message. This can be either an HTML or text body.
99 * If HTML then run IsHTML(true).
100 * @var string
101 */
102 public $Body = '';
103
104 /**
105 * Sets the text-only body of the message. This automatically sets the
106 * email to multipart/alternative. This body can be read by mail
107 * clients that do not have HTML email capability such as mutt. Clients
108 * that can read HTML will view the normal Body.
109 * @var string
110 */
111 public $AltBody = '';
112
113 /**
114 * Sets word wrapping on the body of the message to a given number of
115 * characters.
116 * @var int
117 */
118 public $WordWrap = 0;
119
120 /**
121 * Method to send mail: ("mail", "sendmail", or "smtp").
122 * @var string
123 */
124 public $Mailer = 'mail';
125
126 /**
127 * Sets the path of the sendmail program.
128 * @var string
129 */
130 public $Sendmail = '/usr/sbin/sendmail';
131
132 /**
133 * Path to PHPMailer plugins. This is now only useful if the SMTP class
134 * is in a different directory than the PHP include path.
135 * @var string
136 */
137 public $PluginDir = '';
138
139 /**
140 * Holds PHPMailer version.
141 * @var string
142 */
143 public $Version = "2.2";
144
145 /**
146 * Sets the email address that a reading confirmation will be sent.
147 * @var string
148 */
149 public $ConfirmReadingTo = '';
150
151 /**
152 * Sets the hostname to use in Message-Id and Received headers
153 * and as default HELO string. If empty, the value returned
154 * by SERVER_NAME is used or 'localhost.localdomain'.
155 * @var string
156 */
157 public $Hostname = '';
158
159 /**
160 * Sets the message ID to be used in the Message-Id header.
161 * If empty, a unique id will be generated.
162 * @var string
163 */
164 public $MessageID = '';
165
166 /////////////////////////////////////////////////
167 // PROPERTIES FOR SMTP
168 /////////////////////////////////////////////////
169
170 /**
171 * Sets the SMTP hosts. All hosts must be separated by a
172 * semicolon. You can also specify a different port
173 * for each host by using this format: [hostname:port]
174 * (e.g. "smtp1.example.com:25;smtp2.example.com").
175 * Hosts will be tried in order.
176 * @var string
177 */
178 public $Host = 'localhost';
179
180 /**
181 * Sets the default SMTP server port.
182 * @var int
183 */
184 public $Port = 25;
185
186 /**
187 * Sets the SMTP HELO of the message (Default is $Hostname).
188 * @var string
189 */
190 public $Helo = '';
191
192 /**
193 * Sets connection prefix.
194 * Options are "", "ssl" or "tls"
195 * @var string
196 */
197 public $SMTPSecure = "";
198
199 /**
200 * Sets SMTP authentication. Utilizes the Username and Password variables.
201 * @var bool
202 */
203 public $SMTPAuth = false;
204
205 /**
206 * Sets SMTP username.
207 * @var string
208 */
209 public $Username = '';
210
211 /**
212 * Sets SMTP password.
213 * @var string
214 */
215 public $Password = '';
216
217 /**
218 * Sets the SMTP server timeout in seconds. This function will not
219 * work with the win32 version.
220 * @var int
221 */
222 public $Timeout = 10;
223
224 /**
225 * Sets SMTP class debugging on or off.
226 * @var bool
227 */
228 public $SMTPDebug = false;
229
230 /**
231 * Prevents the SMTP connection from being closed after each mail
232 * sending. If this is set to true then to close the connection
233 * requires an explicit call to SmtpClose().
234 * @var bool
235 */
236 public $SMTPKeepAlive = false;
237
238 /**
239 * Provides the ability to have the TO field process individual
240 * emails, instead of sending to entire TO addresses
241 * @var bool
242 */
243 public $SingleTo = false;
244
245 /////////////////////////////////////////////////
246 // PROPERTIES, PRIVATE
247 /////////////////////////////////////////////////
248
249 private $smtp = NULL;
250 private $to = array();
251 private $cc = array();
252 private $bcc = array();
253 private $ReplyTo = array();
254 private $attachment = array();
255 private $CustomHeader = array();
256 private $message_type = '';
257 private $boundary = array();
258 private $language = array();
259 private $error_count = 0;
260 private $LE = "\n";
261 private $sign_cert_file = "";
262 private $sign_key_file = "";
263 private $sign_key_pass = "";
264
265 /////////////////////////////////////////////////
266 // METHODS, VARIABLES
267 /////////////////////////////////////////////////
268
269 /**
270 * Sets message type to HTML.
271 * @param bool $bool
272 * @return void
273 */
274 public function IsHTML($bool) {
275 if($bool == true) {
276 $this->ContentType = 'text/html';
277 } else {
278 $this->ContentType = 'text/plain';
279 }
280 }
281
282 /**
283 * Sets Mailer to send message using SMTP.
284 * @return void
285 */
286 public function IsSMTP() {
287 $this->Mailer = 'smtp';
288 }
289
290 /**
291 * Sets Mailer to send message using PHP mail() function.
292 * @return void
293 */
294 public function IsMail() {
295 $this->Mailer = 'mail';
296 }
297
298 /**
299 * Sets Mailer to send message using the $Sendmail program.
300 * @return void
301 */
302 public function IsSendmail() {
303 $this->Mailer = 'sendmail';
304 }
305
306 /**
307 * Sets Mailer to send message using the qmail MTA.
308 * @return void
309 */
310 public function IsQmail() {
311 $this->Sendmail = '/var/qmail/bin/sendmail';
312 $this->Mailer = 'sendmail';
313 }
314
315 /////////////////////////////////////////////////
316 // METHODS, RECIPIENTS
317 /////////////////////////////////////////////////
318
319 /**
320 * Adds a "To" address.
321 * @param string $address
322 * @param string $name
323 * @return void
324 */
325 public function AddAddress($address, $name = '') {
326 $cur = count($this->to);
327 $this->to[$cur][0] = trim($address);
328 $this->to[$cur][1] = $name;
329 }
330
331 /**
332 * Adds a "Cc" address. Note: this function works
333 * with the SMTP mailer on win32, not with the "mail"
334 * mailer.
335 * @param string $address
336 * @param string $name
337 * @return void
338 */
339 public function AddCC($address, $name = '') {
340 $cur = count($this->cc);
341 $this->cc[$cur][0] = trim($address);
342 $this->cc[$cur][1] = $name;
343 }
344
345 /**
346 * Adds a "Bcc" address. Note: this function works
347 * with the SMTP mailer on win32, not with the "mail"
348 * mailer.
349 * @param string $address
350 * @param string $name
351 * @return void
352 */
353 public function AddBCC($address, $name = '') {
354 $cur = count($this->bcc);
355 $this->bcc[$cur][0] = trim($address);
356 $this->bcc[$cur][1] = $name;
357 }
358
359 /**
360 * Adds a "Reply-to" address.
361 * @param string $address
362 * @param string $name
363 * @return void
364 */
365 public function AddReplyTo($address, $name = '') {
366 $cur = count($this->ReplyTo);
367 $this->ReplyTo[$cur][0] = trim($address);
368 $this->ReplyTo[$cur][1] = $name;
369 }
370
371 /////////////////////////////////////////////////
372 // METHODS, MAIL SENDING
373 /////////////////////////////////////////////////
374
375 /**
376 * Creates message and assigns Mailer. If the message is
377 * not sent successfully then it returns false. Use the ErrorInfo
378 * variable to view description of the error.
379 * @return bool
380 */
381 public function Send() {
382 $header = '';
383 $body = '';
384 $result = true;
385
386 if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
387 $this->SetError($this->Lang('provide_address'));
388 return false;
389 }
390
391 /* Set whether the message is multipart/alternative */
392 if(!empty($this->AltBody)) {
393 $this->ContentType = 'multipart/alternative';
394 }
395
396 $this->error_count = 0; // reset errors
397 $this->SetMessageType();
398 $header .= $this->CreateHeader();
399 $body = $this->CreateBody();
400
401 if($body == '') {
402 return false;
403 }
404
405 /* Choose the mailer */
406 switch($this->Mailer) {
407 case 'sendmail':
408 $result = $this->SendmailSend($header, $body);
409 break;
410 case 'smtp':
411 $result = $this->SmtpSend($header, $body);
412 break;
413 case 'mail':
414 $result = $this->MailSend($header, $body);
415 break;
416 default:
417 $result = $this->MailSend($header, $body);
418 break;
419 //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported'));
420 //$result = false;
421 //break;
422 }
423
424 return $result;
425 }
426
427 /**
428 * Sends mail using the $Sendmail program.
429 * @access public
430 * @return bool
431 */
432 public function SendmailSend($header, $body) {
433 if ($this->Sender != '') {
434 $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
435 } else {
436 $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
437 }
438
439 if(!@$mail = popen($sendmail, 'w')) {
440 $this->SetError($this->Lang('execute') . $this->Sendmail);
441 return false;
442 }
443
444 fputs($mail, $header);
445 fputs($mail, $body);
446
447 $result = pclose($mail);
448 if (version_compare(phpversion(), '4.2.3') == -1) {
449 $result = $result >> 8 & 0xFF;
450 }
451 if($result != 0) {
452 $this->SetError($this->Lang('execute') . $this->Sendmail);
453 return false;
454 }
455
456 return true;
457 }
458
459 /**
460 * Sends mail using the PHP mail() function.
461 * @access public
462 * @return bool
463 */
464 public function MailSend($header, $body) {
465
466 $to = '';
467 for($i = 0; $i < count($this->to); $i++) {
468 if($i != 0) { $to .= ', '; }
469 $to .= $this->AddrFormat($this->to[$i]);
470 }
471
472 $toArr = split(',', $to);
473
474 $params = sprintf("-oi -f %s", $this->Sender);
475 if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) {
476 $old_from = ini_get('sendmail_from');
477 ini_set('sendmail_from', $this->Sender);
478 if ($this->SingleTo === true && count($toArr) > 1) {
479 foreach ($toArr as $key => $val) {
480 $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
481 }
482 } else {
483 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
484 }
485 } else {
486 if ($this->SingleTo === true && count($toArr) > 1) {
487 foreach ($toArr as $key => $val) {
488 $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
489 }
490 } else {
491 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
492 }
493 }
494
495 if (isset($old_from)) {
496 ini_set('sendmail_from', $old_from);
497 }
498
499 if(!$rt) {
500 $this->SetError($this->Lang('instantiate'));
501 return false;
502 }
503
504 return true;
505 }
506
507 /**
508 * Sends mail via SMTP using PhpSMTP (Author:
509 * Chris Ryan). Returns bool. Returns false if there is a
510 * bad MAIL FROM, RCPT, or DATA input.
511 * @access public
512 * @return bool
513 */
514 public function SmtpSend($header, $body) {
515 include_once($this->PluginDir . 'class.smtp.php');
516 $error = '';
517 $bad_rcpt = array();
518
519 if(!$this->SmtpConnect()) {
520 return false;
521 }
522
523 $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
524 if(!$this->smtp->Mail($smtp_from)) {
525 $error = $this->Lang('from_failed') . $smtp_from;
526 $this->SetError($error);
527 $this->smtp->Reset();
528 return false;
529 }
530
531 /* Attempt to send attach all recipients */
532 for($i = 0; $i < count($this->to); $i++) {
533 if(!$this->smtp->Recipient($this->to[$i][0])) {
534 $bad_rcpt[] = $this->to[$i][0];
535 }
536 }
537 for($i = 0; $i < count($this->cc); $i++) {
538 if(!$this->smtp->Recipient($this->cc[$i][0])) {
539 $bad_rcpt[] = $this->cc[$i][0];
540 }
541 }
542 for($i = 0; $i < count($this->bcc); $i++) {
543 if(!$this->smtp->Recipient($this->bcc[$i][0])) {
544 $bad_rcpt[] = $this->bcc[$i][0];
545 }
546 }
547
548 if(count($bad_rcpt) > 0) { // Create error message
549 for($i = 0; $i < count($bad_rcpt); $i++) {
550 if($i != 0) {
551 $error .= ', ';
552 }
553 $error .= $bad_rcpt[$i];
554 }
555 $error = $this->Lang('recipients_failed') . $error;
556 $this->SetError($error);
557 $this->smtp->Reset();
558 return false;
559 }
560
561 if(!$this->smtp->Data($header . $body)) {
562 $this->SetError($this->Lang('data_not_accepted'));
563 $this->smtp->Reset();
564 return false;
565 }
566 if($this->SMTPKeepAlive == true) {
567 $this->smtp->Reset();
568 } else {
569 $this->SmtpClose();
570 }
571
572 return true;
573 }
574
575 /**
576 * Initiates a connection to an SMTP server. Returns false if the
577 * operation failed.
578 * @access public
579 * @return bool
580 */
581 public function SmtpConnect() {
582 if($this->smtp == NULL) {
583 $this->smtp = new SMTP();
584 }
585
586 $this->smtp->do_debug = $this->SMTPDebug;
587 $hosts = explode(';', $this->Host);
588 $index = 0;
589 $connection = ($this->smtp->Connected());
590
591 /* Retry while there is no connection */
592 while($index < count($hosts) && $connection == false) {
593 $hostinfo = array();
594 if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) {
595 $host = $hostinfo[1];
596 $port = $hostinfo[2];
597 } else {
598 $host = $hosts[$index];
599 $port = $this->Port;
600 }
601
602 $tls = ($this->SMTPSecure == 'tls');
603 $ssl = ($this->SMTPSecure == 'ssl');
604
605 if($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) {
606
607 $hello = ($this->Helo != '' ? $this->Hello : $this->ServerHostname());
608 $this->smtp->Hello($hello);
609
610 if($tls) {
611 if(!$this->smtp->StartTLS()) {
612 $this->SetError($this->Lang("tls"));
613 $this->smtp->Reset();
614 $connection = false;
615 }
616
617 //We must resend HELLO after tls negociation
618 $this->smtp->Hello($hello);
619 }
620
621 $connection = true;
622 if($this->SMTPAuth) {
623 if(!$this->smtp->Authenticate($this->Username, $this->Password)) {
624 $this->SetError($this->Lang('authenticate'));
625 $this->smtp->Reset();
626 $connection = false;
627 }
628 }
629 }
630 $index++;
631 }
632 if(!$connection) {
633 $this->SetError($this->Lang('connect_host'));
634 }
635
636 return $connection;
637 }
638
639 /**
640 * Closes the active SMTP session if one exists.
641 * @return void
642 */
643 public function SmtpClose() {
644 if($this->smtp != NULL) {
645 if($this->smtp->Connected()) {
646 $this->smtp->Quit();
647 $this->smtp->Close();
648 }
649 }
650 }
651
652 /**
653 * Sets the language for all class error messages. Returns false
654 * if it cannot load the language file. The default language type
655 * is English.
656 * @param string $lang_type Type of language (e.g. Portuguese: "br")
657 * @param string $lang_path Path to the language file directory
658 * @access public
659 * @return bool
660 */
661 function SetLanguage($lang_type = 'en', $lang_path = 'language/') {
662 if( !(@include $lang_path.'phpmailer.lang-'.$lang_type.'.php') ) {
663 $this->SetError('Could not load language file');
664 return false;
665 }
666 $this->language = $PHPMAILER_LANG;
667 return true;
668 }
669
670 /////////////////////////////////////////////////
671 // METHODS, MESSAGE CREATION
672 /////////////////////////////////////////////////
673
674 /**
675 * Creates recipient headers.
676 * @access public
677 * @return string
678 */
679 public function AddrAppend($type, $addr) {
680 $addr_str = $type . ': ';
681 $addr_str .= $this->AddrFormat($addr[0]);
682 if(count($addr) > 1) {
683 for($i = 1; $i < count($addr); $i++) {
684 $addr_str .= ', ' . $this->AddrFormat($addr[$i]);
685 }
686 }
687 $addr_str .= $this->LE;
688
689 return $addr_str;
690 }
691
692 /**
693 * Formats an address correctly.
694 * @access public
695 * @return string
696 */
697 public function AddrFormat($addr) {
698 if(empty($addr[1])) {
699 $formatted = $this->SecureHeader($addr[0]);
700 } else {
701 $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
702 }
703
704 return $formatted;
705 }
706
707 /**
708 * Wraps message for use with mailers that do not
709 * automatically perform wrapping and for quoted-printable.
710 * Original written by philippe.
711 * @access public
712 * @return string
713 */
714 public function WrapText($message, $length, $qp_mode = false) {
715 $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
716 // If utf-8 encoding is used, we will need to make sure we don't
717 // split multibyte characters when we wrap
718 $is_utf8 = (strtolower($this->CharSet) == "utf-8");
719
720 $message = $this->FixEOL($message);
721 if (substr($message, -1) == $this->LE) {
722 $message = substr($message, 0, -1);
723 }
724
725 $line = explode($this->LE, $message);
726 $message = '';
727 for ($i=0 ;$i < count($line); $i++) {
728 $line_part = explode(' ', $line[$i]);
729 $buf = '';
730 for ($e = 0; $e<count($line_part); $e++) {
731 $word = $line_part[$e];
732 if ($qp_mode and (strlen($word) > $length)) {
733 $space_left = $length - strlen($buf) - 1;
734 if ($e != 0) {
735 if ($space_left > 20) {
736 $len = $space_left;
737 if ($is_utf8) {
738 $len = $this->UTF8CharBoundary($word, $len);
739 } elseif (substr($word, $len - 1, 1) == "=") {
740 $len--;
741 } elseif (substr($word, $len - 2, 1) == "=") {
742 $len -= 2;
743 }
744 $part = substr($word, 0, $len);
745 $word = substr($word, $len);
746 $buf .= ' ' . $part;
747 $message .= $buf . sprintf("=%s", $this->LE);
748 } else {
749 $message .= $buf . $soft_break;
750 }
751 $buf = '';
752 }
753 while (strlen($word) > 0) {
754 $len = $length;
755 if ($is_utf8) {
756 $len = $this->UTF8CharBoundary($word, $len);
757 } elseif (substr($word, $len - 1, 1) == "=") {
758 $len--;
759 } elseif (substr($word, $len - 2, 1) == "=") {
760 $len -= 2;
761 }
762 $part = substr($word, 0, $len);
763 $word = substr($word, $len);
764
765 if (strlen($word) > 0) {
766 $message .= $part . sprintf("=%s", $this->LE);
767 } else {
768 $buf = $part;
769 }
770 }
771 } else {
772 $buf_o = $buf;
773 $buf .= ($e == 0) ? $word : (' ' . $word);
774
775 if (strlen($buf) > $length and $buf_o != '') {
776 $message .= $buf_o . $soft_break;
777 $buf = $word;
778 }
779 }
780 }
781 $message .= $buf . $this->LE;
782 }
783
784 return $message;
785 }
786
787 /**
788 * Finds last character boundary prior to maxLength in a utf-8
789 * quoted (printable) encoded string.
790 * Original written by Colin Brown.
791 * @access public
792 * @param string $encodedText utf-8 QP text
793 * @param int $maxLength find last character boundary prior to this length
794 * @return int
795 */
796 public function UTF8CharBoundary($encodedText, $maxLength) {
797 $foundSplitPos = false;
798 $lookBack = 3;
799 while (!$foundSplitPos) {
800 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
801 $encodedCharPos = strpos($lastChunk, "=");
802 if ($encodedCharPos !== false) {
803 // Found start of encoded character byte within $lookBack block.
804 // Check the encoded byte value (the 2 chars after the '=')
805 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
806 $dec = hexdec($hex);
807 if ($dec < 128) { // Single byte character.
808 // If the encoded char was found at pos 0, it will fit
809 // otherwise reduce maxLength to start of the encoded char
810 $maxLength = ($encodedCharPos == 0) ? $maxLength :
811 $maxLength - ($lookBack - $encodedCharPos);
812 $foundSplitPos = true;
813 } elseif ($dec >= 192) { // First byte of a multi byte character
814 // Reduce maxLength to split at start of character
815 $maxLength = $maxLength - ($lookBack - $encodedCharPos);
816 $foundSplitPos = true;
817 } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
818 $lookBack += 3;
819 }
820 } else {
821 // No encoded character found
822 $foundSplitPos = true;
823 }
824 }
825 return $maxLength;
826 }
827
828
829 /**
830 * Set the body wrapping.
831 * @access public
832 * @return void
833 */
834 public function SetWordWrap() {
835 if($this->WordWrap < 1) {
836 return;
837 }
838
839 switch($this->message_type) {
840 case 'alt':
841 /* fall through */
842 case 'alt_attachments':
843 $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
844 break;
845 default:
846 $this->Body = $this->WrapText($this->Body, $this->WordWrap);
847 break;
848 }
849 }
850
851 /**
852 * Assembles message header.
853 * @access public
854 * @return string
855 */
856 public function CreateHeader() {
857 $result = '';
858
859 /* Set the boundaries */
860 $uniq_id = md5(uniqid(time()));
861 $this->boundary[1] = 'b1_' . $uniq_id;
862 $this->boundary[2] = 'b2_' . $uniq_id;
863
864 $result .= $this->HeaderLine('Date', $this->RFCDate());
865 if($this->Sender == '') {
866 $result .= $this->HeaderLine('Return-Path', trim($this->From));
867 } else {
868 $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
869 }
870
871 /* To be created automatically by mail() */
872 if($this->Mailer != 'mail') {
873 if(count($this->to) > 0) {
874 $result .= $this->AddrAppend('To', $this->to);
875 } elseif (count($this->cc) == 0) {
876 $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
877 }
878 if(count($this->cc) > 0) {
879 $result .= $this->AddrAppend('Cc', $this->cc);
880 }
881 }
882
883 $from = array();
884 $from[0][0] = trim($this->From);
885 $from[0][1] = $this->FromName;
886 $result .= $this->AddrAppend('From', $from);
887
888 /* sendmail and mail() extract Cc from the header before sending */
889 if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) {
890 $result .= $this->AddrAppend('Cc', $this->cc);
891 }
892
893 /* sendmail and mail() extract Bcc from the header before sending */
894 if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
895 $result .= $this->AddrAppend('Bcc', $this->bcc);
896 }
897
898 if(count($this->ReplyTo) > 0) {
899 $result .= $this->AddrAppend('Reply-to', $this->ReplyTo);
900 }
901
902 /* mail() sets the subject itself */
903 if($this->Mailer != 'mail') {
904 $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
905 }
906
907 if($this->MessageID != '') {
908 $result .= $this->HeaderLine('Message-ID',$this->MessageID);
909 } else {
910 $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
911 }
912 $result .= $this->HeaderLine('X-Priority', $this->Priority);
913 $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.codeworxtech.com) [version ' . $this->Version . ']');
914
915 if($this->ConfirmReadingTo != '') {
916 $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
917 }
918
919 // Add custom headers
920 for($index = 0; $index < count($this->CustomHeader); $index++) {
921 $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
922 }
923 if (!$this->sign_key_file) {
924 $result .= $this->HeaderLine('MIME-Version', '1.0');
925 $result .= $this->GetMailMIME();
926 }
927
928 return $result;
929 }
930
931 /**
932 * Returns the message MIME.
933 * @access public
934 * @return string
935 */
936 public function GetMailMIME() {
937 $result = '';
938 switch($this->message_type) {
939 case 'plain':
940 $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
941 $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
942 break;
943 case 'attachments':
944 /* fall through */
945 case 'alt_attachments':
946 if($this->InlineImageExists()){
947 $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
948 } else {
949 $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
950 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
951 }
952 break;
953 case 'alt':
954 $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
955 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
956 break;
957 }
958
959 if($this->Mailer != 'mail') {
960 $result .= $this->LE.$this->LE;
961 }
962
963 return $result;
964 }
965
966 /**
967 * Assembles the message body. Returns an empty string on failure.
968 * @access public
969 * @return string
970 */
971 public function CreateBody() {
972 $result = '';
973
974 if ($this->sign_key_file) {
975 $result .= $this->GetMailMIME();
976 }
977
978 $this->SetWordWrap();
979
980 switch($this->message_type) {
981 case 'alt':
982 $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
983 $result .= $this->EncodeString($this->AltBody, $this->Encoding);
984 $result .= $this->LE.$this->LE;
985 $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
986 $result .= $this->EncodeString($this->Body, $this->Encoding);
987 $result .= $this->LE.$this->LE;
988 $result .= $this->EndBoundary($this->boundary[1]);
989 break;
990 case 'plain':
991 $result .= $this->EncodeString($this->Body, $this->Encoding);
992 break;
993 case 'attachments':
994 $result .= $this->GetBoundary($this->boundary[1], '', '', '');
995 $result .= $this->EncodeString($this->Body, $this->Encoding);
996 $result .= $this->LE;
997 $result .= $this->AttachAll();
998 break;
999 case 'alt_attachments':
1000 $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
1001 $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
1002 $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
1003 $result .= $this->EncodeString($this->AltBody, $this->Encoding);
1004 $result .= $this->LE.$this->LE;
1005 $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
1006 $result .= $this->EncodeString($this->Body, $this->Encoding);
1007 $result .= $this->LE.$this->LE;
1008 $result .= $this->EndBoundary($this->boundary[2]);
1009 $result .= $this->AttachAll();
1010 break;
1011 }
1012
1013 if($this->IsError()) {
1014 $result = '';
1015 } else if ($this->sign_key_file) {
1016 $file = tempnam("", "mail");
1017 $fp = fopen($file, "w");
1018 fwrite($fp, $result);
1019 fclose($fp);
1020 $signed = tempnam("", "signed");
1021
1022 if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) {
1023 $fp = fopen($signed, "r");
1024 $result = '';
1025 while(!feof($fp)){
1026 $result = $result . fread($fp, 1024);
1027 }
1028 fclose($fp);
1029 } else {
1030 $this->SetError($this->Lang("signing").openssl_error_string());
1031 $result = '';
1032 }
1033
1034 unlink($file);
1035 unlink($signed);
1036 }
1037
1038 return $result;
1039 }
1040
1041 /**
1042 * Returns the start of a message boundary.
1043 * @access public
1044 */
1045 public function GetBoundary($boundary, $charSet, $contentType, $encoding) {
1046 $result = '';
1047 if($charSet == '') {
1048 $charSet = $this->CharSet;
1049 }
1050 if($contentType == '') {
1051 $contentType = $this->ContentType;
1052 }
1053 if($encoding == '') {
1054 $encoding = $this->Encoding;
1055 }
1056 $result .= $this->TextLine('--' . $boundary);
1057 $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
1058 $result .= $this->LE;
1059 $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
1060 $result .= $this->LE;
1061
1062 return $result;
1063 }
1064
1065 /**
1066 * Returns the end of a message boundary.
1067 * @access public
1068 */
1069 public function EndBoundary($boundary) {
1070 return $this->LE . '--' . $boundary . '--' . $this->LE;
1071 }
1072
1073 /**
1074 * Sets the message type.
1075 * @access public
1076 * @return void
1077 */
1078 public function SetMessageType() {
1079 if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
1080 $this->message_type = 'plain';
1081 } else {
1082 if(count($this->attachment) > 0) {
1083 $this->message_type = 'attachments';
1084 }
1085 if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) {
1086 $this->message_type = 'alt';
1087 }
1088 if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) {
1089 $this->message_type = 'alt_attachments';
1090 }
1091 }
1092 }
1093
1094 /* Returns a formatted header line.
1095 * @access public
1096 * @return string
1097 */
1098 public function HeaderLine($name, $value) {
1099 return $name . ': ' . $value . $this->LE;
1100 }
1101
1102 /**
1103 * Returns a formatted mail line.
1104 * @access public
1105 * @return string
1106 */
1107 public function TextLine($value) {
1108 return $value . $this->LE;
1109 }
1110
1111 /////////////////////////////////////////////////
1112 // CLASS METHODS, ATTACHMENTS
1113 /////////////////////////////////////////////////
1114
1115 /**
1116 * Adds an attachment from a path on the filesystem.
1117 * Returns false if the file could not be found
1118 * or accessed.
1119 * @param string $path Path to the attachment.
1120 * @param string $name Overrides the attachment name.
1121 * @param string $encoding File encoding (see $Encoding).
1122 * @param string $type File extension (MIME) type.
1123 * @return bool
1124 */
1125 public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
1126 if(!@is_file($path)) {
1127 $this->SetError($this->Lang('file_access') . $path);
1128 return false;
1129 }
1130
1131 $filename = basename($path);
1132 if($name == '') {
1133 $name = $filename;
1134 }
1135
1136 $cur = count($this->attachment);
1137 $this->attachment[$cur][0] = $path;
1138 $this->attachment[$cur][1] = $filename;
1139 $this->attachment[$cur][2] = $name;
1140 $this->attachment[$cur][3] = $encoding;
1141 $this->attachment[$cur][4] = $type;
1142 $this->attachment[$cur][5] = false; // isStringAttachment
1143 $this->attachment[$cur][6] = 'attachment';
1144 $this->attachment[$cur][7] = 0;
1145
1146 return true;
1147 }
1148
1149 /**
1150 * Attaches all fs, string, and binary attachments to the message.
1151 * Returns an empty string on failure.
1152 * @access public
1153 * @return string
1154 */
1155 public function AttachAll() {
1156 /* Return text of body */
1157 $mime = array();
1158
1159 /* Add all attachments */
1160 for($i = 0; $i < count($this->attachment); $i++) {
1161 /* Check for string attachment */
1162 $bString = $this->attachment[$i][5];
1163 if ($bString) {
1164 $string = $this->attachment[$i][0];
1165 } else {
1166 $path = $this->attachment[$i][0];
1167 }
1168
1169 $filename = $this->attachment[$i][1];
1170 $name = $this->attachment[$i][2];
1171 $encoding = $this->attachment[$i][3];
1172 $type = $this->attachment[$i][4];
1173 $disposition = $this->attachment[$i][6];
1174 $cid = $this->attachment[$i][7];
1175
1176 $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
1177 //$mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);
1178 $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
1179 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
1180
1181 if($disposition == 'inline') {
1182 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
1183 }
1184
1185 //$mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE);
1186 $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE);
1187
1188 /* Encode as string attachment */
1189 if($bString) {
1190 $mime[] = $this->EncodeString($string, $encoding);
1191 if($this->IsError()) {
1192 return '';
1193 }
1194 $mime[] = $this->LE.$this->LE;
1195 } else {
1196 $mime[] = $this->EncodeFile($path, $encoding);
1197 if($this->IsError()) {
1198 return '';
1199 }
1200 $mime[] = $this->LE.$this->LE;
1201 }
1202 }
1203
1204 $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
1205
1206 return join('', $mime);
1207 }
1208
1209 /**
1210 * Encodes attachment in requested format. Returns an
1211 * empty string on failure.
1212 * @access public
1213 * @return string
1214 */
1215 public function EncodeFile ($path, $encoding = 'base64') {
1216 if(!@$fd = fopen($path, 'rb')) {
1217 $this->SetError($this->Lang('file_open') . $path);
1218 return '';
1219 }
1220 if (function_exists('get_magic_quotes')) {
1221 function get_magic_quotes() {
1222 return false;
1223 }
1224}
1225 if (PHP_VERSION < 6) {
1226 $magic_quotes = get_magic_quotes_runtime();
1227 set_magic_quotes_runtime(0);
1228 }
1229 $file_buffer = file_get_contents($path);
1230 $file_buffer = $this->EncodeString($file_buffer, $encoding);
1231 fclose($fd);
1232 if (PHP_VERSION < 6) { set_magic_quotes_runtime($magic_quotes); }
1233 return $file_buffer;
1234 }
1235
1236 /**
1237 * Encodes string to requested format. Returns an
1238 * empty string on failure.
1239 * @access public
1240 * @return string
1241 */
1242 public function EncodeString ($str, $encoding = 'base64') {
1243 $encoded = '';
1244 switch(strtolower($encoding)) {
1245 case 'base64':
1246 $encoded = chunk_split(base64_encode($str), 76, $this->LE);
1247 break;
1248 case '7bit':
1249 case '8bit':
1250 $encoded = $this->FixEOL($str);
1251 if (substr($encoded, -(strlen($this->LE))) != $this->LE)
1252 $encoded .= $this->LE;
1253 break;
1254 case 'binary':
1255 $encoded = $str;
1256 break;
1257 case 'quoted-printable':
1258 $encoded = $this->EncodeQP($str);
1259 break;
1260 default:
1261 $this->SetError($this->Lang('encoding') . $encoding);
1262 break;
1263 }
1264 return $encoded;
1265 }
1266
1267 /**
1268 * Encode a header string to best of Q, B, quoted or none.
1269 * @access public
1270 * @return string
1271 */
1272 public function EncodeHeader ($str, $position = 'text') {
1273 $x = 0;
1274
1275 switch (strtolower($position)) {
1276 case 'phrase':
1277 if (!preg_match('/[\200-\377]/', $str)) {
1278 /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */
1279 $encoded = addcslashes($str, "\0..\37\177\\\"");
1280 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
1281 return ($encoded);
1282 } else {
1283 return ("\"$encoded\"");
1284 }
1285 }
1286 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
1287 break;
1288 case 'comment':
1289 $x = preg_match_all('/[()"]/', $str, $matches);
1290 /* Fall-through */
1291 case 'text':
1292 default:
1293 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
1294 break;
1295 }
1296
1297 if ($x == 0) {
1298 return ($str);
1299 }
1300
1301 $maxlen = 75 - 7 - strlen($this->CharSet);
1302 /* Try to select the encoding which should produce the shortest output */
1303 if (strlen($str)/3 < $x) {
1304 $encoding = 'B';
1305 if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
1306 // Use a custom function which correctly encodes and wraps long
1307 // multibyte strings without breaking lines within a character
1308 $encoded = $this->Base64EncodeWrapMB($str);
1309 } else {
1310 $encoded = base64_encode($str);
1311 $maxlen -= $maxlen % 4;
1312 $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
1313 }
1314 } else {
1315 $encoding = 'Q';
1316 $encoded = $this->EncodeQ($str, $position);
1317 $encoded = $this->WrapText($encoded, $maxlen, true);
1318 $encoded = str_replace('='.$this->LE, "\n", trim($encoded));
1319 }
1320
1321 $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
1322 $encoded = trim(str_replace("\n", $this->LE, $encoded));
1323
1324 return $encoded;
1325 }
1326
1327 /**
1328 * Checks if a string contains multibyte characters.
1329 * @access public
1330 * @param string $str multi-byte text to wrap encode
1331 * @return bool
1332 */
1333 public function HasMultiBytes($str) {
1334 if (function_exists('mb_strlen')) {
1335 return (strlen($str) > mb_strlen($str, $this->CharSet));
1336 } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
1337 return False;
1338 }
1339 }
1340
1341 /**
1342 * Correctly encodes and wraps long multibyte strings for mail headers
1343 * without breaking lines within a character.
1344 * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
1345 * @access public
1346 * @param string $str multi-byte text to wrap encode
1347 * @return string
1348 */
1349 public function Base64EncodeWrapMB($str) {
1350 $start = "=?".$this->CharSet."?B?";
1351 $end = "?=";
1352 $encoded = "";
1353
1354 $mb_length = mb_strlen($str, $this->CharSet);
1355 // Each line must have length <= 75, including $start and $end
1356 $length = 75 - strlen($start) - strlen($end);
1357 // Average multi-byte ratio
1358 $ratio = $mb_length / strlen($str);
1359 // Base64 has a 4:3 ratio
1360 $offset = $avgLength = floor($length * $ratio * .75);
1361
1362 for ($i = 0; $i < $mb_length; $i += $offset) {
1363 $lookBack = 0;
1364
1365 do {
1366 $offset = $avgLength - $lookBack;
1367 $chunk = mb_substr($str, $i, $offset, $this->CharSet);
1368 $chunk = base64_encode($chunk);
1369 $lookBack++;
1370 }
1371 while (strlen($chunk) > $length);
1372
1373 $encoded .= $chunk . $this->LE;
1374 }
1375
1376 // Chomp the last linefeed
1377 $encoded = substr($encoded, 0, -strlen($this->LE));
1378 return $encoded;
1379 }
1380
1381 /**
1382 * Encode string to quoted-printable.
1383 * @access public
1384 * @param string $string the text to encode
1385 * @param integer $line_max Number of chars allowed on a line before wrapping
1386 * @return string
1387 */
1388 public function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) {
1389 $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
1390 $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
1391 $eol = "\r\n";
1392 $escape = '=';
1393 $output = '';
1394 while( list(, $line) = each($lines) ) {
1395 $linlen = strlen($line);
1396 $newline = '';
1397 for($i = 0; $i < $linlen; $i++) {
1398 $c = substr( $line, $i, 1 );
1399 $dec = ord( $c );
1400 if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
1401 $c = '=2E';
1402 }
1403 if ( $dec == 32 ) {
1404 if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
1405 $c = '=20';
1406 } else if ( $space_conv ) {
1407 $c = '=20';
1408 }
1409 } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
1410 $h2 = floor($dec/16);
1411 $h1 = floor($dec%16);
1412 $c = $escape.$hex[$h2].$hex[$h1];
1413 }
1414 if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
1415 $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
1416 $newline = '';
1417 // check if newline first character will be point or not
1418 if ( $dec == 46 ) {
1419 $c = '=2E';
1420 }
1421 }
1422 $newline .= $c;
1423 } // end of for
1424 $output .= $newline.$eol;
1425 } // end of while
1426 return trim($output);
1427 }
1428
1429 /**
1430 * Encode string to q encoding.
1431 * @access public
1432 * @return string
1433 */
1434 public function EncodeQ ($str, $position = 'text') {
1435 /* There should not be any EOL in the string */
1436 $encoded = preg_replace("[\r\n]", '', $str);
1437
1438 switch (strtolower($position)) {
1439 case 'phrase':
1440 $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1441 break;
1442 case 'comment':
1443 $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1444 case 'text':
1445 default:
1446 /* Replace every high ascii, control =, ? and _ characters */
1447 $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
1448 "'='.sprintf('%02X', ord('\\1'))", $encoded);
1449 break;
1450 }
1451
1452 /* Replace every spaces to _ (more readable than =20) */
1453 $encoded = str_replace(' ', '_', $encoded);
1454
1455 return $encoded;
1456 }
1457
1458 /**
1459 * Adds a string or binary attachment (non-filesystem) to the list.
1460 * This method can be used to attach ascii or binary data,
1461 * such as a BLOB record from a database.
1462 * @param string $string String attachment data.
1463 * @param string $filename Name of the attachment.
1464 * @param string $encoding File encoding (see $Encoding).
1465 * @param string $type File extension (MIME) type.
1466 * @return void
1467 */
1468 public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
1469 /* Append to $attachment array */
1470 $cur = count($this->attachment);
1471 $this->attachment[$cur][0] = $string;
1472 $this->attachment[$cur][1] = $filename;
1473 $this->attachment[$cur][2] = $filename;
1474 $this->attachment[$cur][3] = $encoding;
1475 $this->attachment[$cur][4] = $type;
1476 $this->attachment[$cur][5] = true; // isString
1477 $this->attachment[$cur][6] = 'attachment';
1478 $this->attachment[$cur][7] = 0;
1479 }
1480
1481 /**
1482 * Adds an embedded attachment. This can include images, sounds, and
1483 * just about any other document. Make sure to set the $type to an
1484 * image type. For JPEG images use "image/jpeg" and for GIF images
1485 * use "image/gif".
1486 * @param string $path Path to the attachment.
1487 * @param string $cid Content ID of the attachment. Use this to identify
1488 * the Id for accessing the image in an HTML form.
1489 * @param string $name Overrides the attachment name.
1490 * @param string $encoding File encoding (see $Encoding).
1491 * @param string $type File extension (MIME) type.
1492 * @return bool
1493 */
1494 public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
1495
1496 if(!@is_file($path)) {
1497 $this->SetError($this->Lang('file_access') . $path);
1498 return false;
1499 }
1500
1501 $filename = basename($path);
1502 if($name == '') {
1503 $name = $filename;
1504 }
1505
1506 /* Append to $attachment array */
1507 $cur = count($this->attachment);
1508 $this->attachment[$cur][0] = $path;
1509 $this->attachment[$cur][1] = $filename;
1510 $this->attachment[$cur][2] = $name;
1511 $this->attachment[$cur][3] = $encoding;
1512 $this->attachment[$cur][4] = $type;
1513 $this->attachment[$cur][5] = false;
1514 $this->attachment[$cur][6] = 'inline';
1515 $this->attachment[$cur][7] = $cid;
1516
1517 return true;
1518 }
1519
1520 /**
1521 * Returns true if an inline attachment is present.
1522 * @access public
1523 * @return bool
1524 */
1525 public function InlineImageExists() {
1526 $result = false;
1527 for($i = 0; $i < count($this->attachment); $i++) {
1528 if($this->attachment[$i][6] == 'inline') {
1529 $result = true;
1530 break;
1531 }
1532 }
1533
1534 return $result;
1535 }
1536
1537 /////////////////////////////////////////////////
1538 // CLASS METHODS, MESSAGE RESET
1539 /////////////////////////////////////////////////
1540
1541 /**
1542 * Clears all recipients assigned in the TO array. Returns void.
1543 * @return void
1544 */
1545 public function ClearAddresses() {
1546 $this->to = array();
1547 }
1548
1549 /**
1550 * Clears all recipients assigned in the CC array. Returns void.
1551 * @return void
1552 */
1553 public function ClearCCs() {
1554 $this->cc = array();
1555 }
1556
1557 /**
1558 * Clears all recipients assigned in the BCC array. Returns void.
1559 * @return void
1560 */
1561 public function ClearBCCs() {
1562 $this->bcc = array();
1563 }
1564
1565 /**
1566 * Clears all recipients assigned in the ReplyTo array. Returns void.
1567 * @return void
1568 */
1569 public function ClearReplyTos() {
1570 $this->ReplyTo = array();
1571 }
1572
1573 /**
1574 * Clears all recipients assigned in the TO, CC and BCC
1575 * array. Returns void.
1576 * @return void
1577 */
1578 public function ClearAllRecipients() {
1579 $this->to = array();
1580 $this->cc = array();
1581 $this->bcc = array();
1582 }
1583
1584 /**
1585 * Clears all previously set filesystem, string, and binary
1586 * attachments. Returns void.
1587 * @return void
1588 */
1589 public function ClearAttachments() {
1590 $this->attachment = array();
1591 }
1592
1593 /**
1594 * Clears all custom headers. Returns void.
1595 * @return void
1596 */
1597 public function ClearCustomHeaders() {
1598 $this->CustomHeader = array();
1599 }
1600
1601 /////////////////////////////////////////////////
1602 // CLASS METHODS, MISCELLANEOUS
1603 /////////////////////////////////////////////////
1604
1605 /**
1606 * Adds the error message to the error container.
1607 * Returns void.
1608 * @access private
1609 * @return void
1610 */
1611 private function SetError($msg) {
1612 $this->error_count++;
1613 $this->ErrorInfo = $msg;
1614 }
1615
1616 /**
1617 * Returns the proper RFC 822 formatted date.
1618 * @access private
1619 * @return string
1620 */
1621 private static function RFCDate() {
1622 $tz = date('Z');
1623 $tzs = ($tz < 0) ? '-' : '+';
1624 $tz = abs($tz);
1625 $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
1626 $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
1627
1628 return $result;
1629 }
1630
1631 /**
1632 * Returns the server hostname or 'localhost.localdomain' if unknown.
1633 * @access private
1634 * @return string
1635 */
1636 private function ServerHostname() {
1637 if (!empty($this->Hostname)) {
1638 $result = $this->Hostname;
1639 } elseif (isset($_SERVER['SERVER_NAME'])) {
1640 $result = $_SERVER['SERVER_NAME'];
1641 } else {
1642 $result = "localhost.localdomain";
1643 }
1644
1645 return $result;
1646 }
1647
1648 /**
1649 * Returns a message in the appropriate language.
1650 * @access private
1651 * @return string
1652 */
1653 private function Lang($key) {
1654 if(count($this->language) < 1) {
1655 $this->SetLanguage('en'); // set the default language
1656 }
1657
1658 if(isset($this->language[$key])) {
1659 return $this->language[$key];
1660 } else {
1661 return 'Language string failed to load: ' . $key;
1662 }
1663 }
1664
1665 /**
1666 * Returns true if an error occurred.
1667 * @access public
1668 * @return bool
1669 */
1670 public function IsError() {
1671 return ($this->error_count > 0);
1672 }
1673
1674 /**
1675 * Changes every end of line from CR or LF to CRLF.
1676 * @access private
1677 * @return string
1678 */
1679 private function FixEOL($str) {
1680 $str = str_replace("\r\n", "\n", $str);
1681 $str = str_replace("\r", "\n", $str);
1682 $str = str_replace("\n", $this->LE, $str);
1683 return $str;
1684 }
1685
1686 /**
1687 * Adds a custom header.
1688 * @access public
1689 * @return void
1690 */
1691 public function AddCustomHeader($custom_header) {
1692 $this->CustomHeader[] = explode(':', $custom_header, 2);
1693 }
1694
1695 /**
1696 * Evaluates the message and returns modifications for inline images and backgrounds
1697 * @access public
1698 * @return $message
1699 */
1700 public function MsgHTML($message,$basedir='') {
1701 preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
1702 if(isset($images[2])) {
1703 foreach($images[2] as $i => $url) {
1704 // do not change urls for absolute images (thanks to corvuscorax)
1705 if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) {
1706 $filename = basename($url);
1707 $directory = dirname($url);
1708 ($directory == '.')?$directory='':'';
1709 $cid = 'cid:' . md5($filename);
1710 $fileParts = split("\.", $filename);
1711 $ext = $fileParts[1];
1712 $mimeType = $this->_mime_types($ext);
1713 if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; }
1714 if ( strlen($directory) > 1 && substr($basedir,-1) != '/') { $directory .= '/'; }
1715 $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType);
1716 if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) {
1717 $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message);
1718 }
1719 }
1720 }
1721 }
1722 $this->IsHTML(true);
1723 $this->Body = $message;
1724 $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message)));
1725 if ( !empty($textMsg) && empty($this->AltBody) ) {
1726 $this->AltBody = $textMsg;
1727 }
1728 if ( empty($this->AltBody) ) {
1729 $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n";
1730 }
1731 }
1732
1733 /**
1734 * Gets the mime type of the embedded or inline image
1735 * @access public
1736 * @return mime type of ext
1737 */
1738 public function _mime_types($ext = '') {
1739 $mimes = array(
1740 'hqx' => 'application/mac-binhex40',
1741 'cpt' => 'application/mac-compactpro',
1742 'doc' => 'application/msword',
1743 'bin' => 'application/macbinary',
1744 'dms' => 'application/octet-stream',
1745 'lha' => 'application/octet-stream',
1746 'lzh' => 'application/octet-stream',
1747 'exe' => 'application/octet-stream',
1748 'class' => 'application/octet-stream',
1749 'psd' => 'application/octet-stream',
1750 'so' => 'application/octet-stream',
1751 'sea' => 'application/octet-stream',
1752 'dll' => 'application/octet-stream',
1753 'oda' => 'application/oda',
1754 'pdf' => 'application/pdf',
1755 'ai' => 'application/postscript',
1756 'eps' => 'application/postscript',
1757 'ps' => 'application/postscript',
1758 'smi' => 'application/smil',
1759 'smil' => 'application/smil',
1760 'mif' => 'application/vnd.mif',
1761 'xls' => 'application/vnd.ms-excel',
1762 'ppt' => 'application/vnd.ms-powerpoint',
1763 'wbxml' => 'application/vnd.wap.wbxml',
1764 'wmlc' => 'application/vnd.wap.wmlc',
1765 'dcr' => 'application/x-director',
1766 'dir' => 'application/x-director',
1767 'dxr' => 'application/x-director',
1768 'dvi' => 'application/x-dvi',
1769 'gtar' => 'application/x-gtar',
1770 'php' => 'application/x-httpd-php',
1771 'php4' => 'application/x-httpd-php',
1772 'php3' => 'application/x-httpd-php',
1773 'phtml' => 'application/x-httpd-php',
1774 'phps' => 'application/x-httpd-php-source',
1775 'js' => 'application/x-javascript',
1776 'swf' => 'application/x-shockwave-flash',
1777 'sit' => 'application/x-stuffit',
1778 'tar' => 'application/x-tar',
1779 'tgz' => 'application/x-tar',
1780 'xhtml' => 'application/xhtml+xml',
1781 'xht' => 'application/xhtml+xml',
1782 'zip' => 'application/zip',
1783 'mid' => 'audio/midi',
1784 'midi' => 'audio/midi',
1785 'mpga' => 'audio/mpeg',
1786 'mp2' => 'audio/mpeg',
1787 'mp3' => 'audio/mpeg',
1788 'aif' => 'audio/x-aiff',
1789 'aiff' => 'audio/x-aiff',
1790 'aifc' => 'audio/x-aiff',
1791 'ram' => 'audio/x-pn-realaudio',
1792 'rm' => 'audio/x-pn-realaudio',
1793 'rpm' => 'audio/x-pn-realaudio-plugin',
1794 'ra' => 'audio/x-realaudio',
1795 'rv' => 'video/vnd.rn-realvideo',
1796 'wav' => 'audio/x-wav',
1797 'bmp' => 'image/bmp',
1798 'gif' => 'image/gif',
1799 'jpeg' => 'image/jpeg',
1800 'jpg' => 'image/jpeg',
1801 'jpe' => 'image/jpeg',
1802 'png' => 'image/png',
1803 'tiff' => 'image/tiff',
1804 'tif' => 'image/tiff',
1805 'css' => 'text/css',
1806 'html' => 'text/html',
1807 'htm' => 'text/html',
1808 'shtml' => 'text/html',
1809 'txt' => 'text/plain',
1810 'text' => 'text/plain',
1811 'log' => 'text/plain',
1812 'rtx' => 'text/richtext',
1813 'rtf' => 'text/rtf',
1814 'xml' => 'text/xml',
1815 'xsl' => 'text/xml',
1816 'mpeg' => 'video/mpeg',
1817 'mpg' => 'video/mpeg',
1818 'mpe' => 'video/mpeg',
1819 'qt' => 'video/quicktime',
1820 'mov' => 'video/quicktime',
1821 'avi' => 'video/x-msvideo',
1822 'movie' => 'video/x-sgi-movie',
1823 'doc' => 'application/msword',
1824 'word' => 'application/msword',
1825 'xl' => 'application/excel',
1826 'eml' => 'message/rfc822'
1827 );
1828 return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
1829 }
1830
1831 /**
1832 * Set (or reset) Class Objects (variables)
1833 *
1834 * Usage Example:
1835 * $page->set('X-Priority', '3');
1836 *
1837 * @access public
1838 * @param string $name Parameter Name
1839 * @param mixed $value Parameter Value
1840 * NOTE: will not work with arrays, there are no arrays to set/reset
1841 */
1842 public function set ( $name, $value = '' ) {
1843 if ( isset($this->$name) ) {
1844 $this->$name = $value;
1845 } else {
1846 $this->SetError('Cannot set or reset variable ' . $name);
1847 return false;
1848 }
1849 }
1850
1851 /**
1852 * Read a file from a supplied filename and return it.
1853 *
1854 * @access public
1855 * @param string $filename Parameter File Name
1856 */
1857 public function getFile($filename) {
1858 $return = '';
1859 if ($fp = fopen($filename, 'rb')) {
1860 while (!feof($fp)) {
1861 $return .= fread($fp, 1024);
1862 }
1863 fclose($fp);
1864 return $return;
1865 } else {
1866 return false;
1867 }
1868 }
1869
1870 /**
1871 * Strips newlines to prevent header injection.
1872 * @access public
1873 * @param string $str String
1874 * @return string
1875 */
1876 public function SecureHeader($str) {
1877 $str = trim($str);
1878 $str = str_replace("\r", "", $str);
1879 $str = str_replace("\n", "", $str);
1880 return $str;
1881 }
1882
1883 /**
1884 * Set the private key file and password to sign the message.
1885 *
1886 * @access public
1887 * @param string $key_filename Parameter File Name
1888 * @param string $key_pass Password for private key
1889 */
1890 public function Sign($cert_filename, $key_filename, $key_pass) {
1891 $this->sign_cert_file = $cert_filename;
1892 $this->sign_key_file = $key_filename;
1893 $this->sign_key_pass = $key_pass;
1894 }
1895}
1896
1897?>
diff --git a/central/trunk/includes/class.smtp.php b/central/trunk/includes/class.smtp.php deleted file mode 100644 index f1c9cfe..0000000 --- a/central/trunk/includes/class.smtp.php +++ /dev/null
@@ -1,1113 +0,0 @@
1<?php
2/*~ class.smtp.php
3.---------------------------------------------------------------------------.
4| Software: PHPMailer - PHP email class |
5| Version: 2.2.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| Author: Andy Prevost (project admininistrator) |
11| Author: Brent R. Matzelle (original founder) |
12| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
13| Copyright (c) 2001-2003, Brent R. Matzelle |
14| ------------------------------------------------------------------------- |
15| License: Distributed under the Lesser General Public License (LGPL) |
16| http://www.gnu.org/copyleft/lesser.html |
17| This program is distributed in the hope that it will be useful - WITHOUT |
18| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
19| FITNESS FOR A PARTICULAR PURPOSE. |
20| ------------------------------------------------------------------------- |
21| We offer a number of paid services (www.codeworxtech.com): |
22| - Web Hosting on highly optimized fast and secure servers |
23| - Technology Consulting |
24| - Oursourcing (highly qualified programmers and graphic designers) |
25'---------------------------------------------------------------------------'
26
27/**
28 * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
29 * commands except TURN which will always return a not implemented
30 * error. SMTP also provides some utility methods for sending mail
31 * to an SMTP server.
32 * @package PHPMailer
33 * @author Chris Ryan
34 */
35
36class SMTP {
37 /**
38 * SMTP server port
39 * @var int
40 */
41 public $SMTP_PORT = 25;
42
43 /**
44 * SMTP reply line ending
45 * @var string
46 */
47 public $CRLF = "\r\n";
48
49 /**
50 * Sets whether debugging is turned on
51 * @var bool
52 */
53 public $do_debug; // the level of debug to perform
54
55 /**
56 * Sets VERP use on/off (default is off)
57 * @var bool
58 */
59 public $do_verp = false;
60
61 /**#@+
62 * @access private
63 */
64 private $smtp_conn; // the socket to the server
65 private $error; // error if any on the last call
66 private $helo_rply; // the reply the server sent to us for HELO
67 /**#@-*/
68
69 /**
70 * Initialize the class so that the data is in a known state.
71 * @access public
72 * @return void
73 */
74 public function __construct() {
75 $this->smtp_conn = 0;
76 $this->error = null;
77 $this->helo_rply = null;
78
79 $this->do_debug = 0;
80 }
81
82 /*************************************************************
83 * CONNECTION FUNCTIONS *
84 ***********************************************************/
85
86 /**
87 * Connect to the server specified on the port specified.
88 * If the port is not specified use the default SMTP_PORT.
89 * If tval is specified then a connection will try and be
90 * established with the server for that number of seconds.
91 * If tval is not specified the default is 30 seconds to
92 * try on the connection.
93 *
94 * SMTP CODE SUCCESS: 220
95 * SMTP CODE FAILURE: 421
96 * @access public
97 * @return bool
98 */
99 public function Connect($host,$port=0,$tval=30) {
100 /* set the error val to null so there is no confusion */
101 $this->error = null;
102
103 /* make sure we are __not__ connected */
104 if($this->connected()) {
105 /* ok we are connected! what should we do?
106 * for now we will just give an error saying we
107 * are already connected
108 */
109 $this->error = array("error" => "Already connected to a server");
110 return false;
111 }
112
113 if(empty($port)) {
114 $port = $this->SMTP_PORT;
115 }
116
117 /* connect to the smtp server */
118 $this->smtp_conn = fsockopen($host, // the host of the server
119 $port, // the port to use
120 $errno, // error number if any
121 $errstr, // error message if any
122 $tval); // give up after ? secs
123 /* verify we connected properly */
124 if(empty($this->smtp_conn)) {
125 $this->error = array("error" => "Failed to connect to server",
126 "errno" => $errno,
127 "errstr" => $errstr);
128 if($this->do_debug >= 1) {
129 echo "SMTP -> ERROR: " . $this->error["error"] .
130 ": $errstr ($errno)" . $this->CRLF;
131 }
132 return false;
133 }
134
135 /* sometimes the SMTP server takes a little longer to respond
136 * so we will give it a longer timeout for the first read
137 * - Windows still does not have support for this timeout function
138 */
139 if(substr(PHP_OS, 0, 3) != "WIN")
140 socket_set_timeout($this->smtp_conn, $tval, 0);
141
142 /* get any announcement stuff */
143 $announce = $this->get_lines();
144
145 /* set the timeout of any socket functions at 1/10 of a second */
146 //if(function_exists("socket_set_timeout"))
147 // socket_set_timeout($this->smtp_conn, 0, 100000);
148
149 if($this->do_debug >= 2) {
150 echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
151 }
152
153 return true;
154 }
155
156 /**
157 * Initiate a TSL communication with the server.
158 *
159 * SMTP CODE 220 Ready to start TLS
160 * SMTP CODE 501 Syntax error (no parameters allowed)
161 * SMTP CODE 454 TLS not available due to temporary reason
162 * @access public
163 * @return bool success
164 */
165 public function StartTLS() {
166 $this->error = null; # to avoid confusion
167
168 if(!$this->connected()) {
169 $this->error = array("error" => "Called StartTLS() without being connected");
170 return false;
171 }
172
173 fputs($this->smtp_conn,"STARTTLS" . $extra . $this->CRLF);
174
175 $rply = $this->get_lines();
176 $code = substr($rply,0,3);
177
178 if($this->do_debug >= 2) {
179 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
180 }
181
182 if($code != 220) {
183 $this->error =
184 array("error" => "STARTTLS not accepted from server",
185 "smtp_code" => $code,
186 "smtp_msg" => substr($rply,4));
187 if($this->do_debug >= 1) {
188 echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF;
189 }
190 return false;
191 }
192
193 //Begin encrypted connection
194 if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
195 return false;
196 }
197
198 return true;
199 }
200
201 /**
202 * Performs SMTP authentication. Must be run after running the
203 * Hello() method. Returns true if successfully authenticated.
204 * @access public
205 * @return bool
206 */
207 public function Authenticate($username, $password) {
208 // Start authentication
209 fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
210
211 $rply = $this->get_lines();
212 $code = substr($rply,0,3);
213
214 if($code != 334) {
215 $this->error =
216 array("error" => "AUTH not accepted from server",
217 "smtp_code" => $code,
218 "smtp_msg" => substr($rply,4));
219 if($this->do_debug >= 1) {
220 echo "SMTP -> ERROR: " . $this->error["error"] .
221 ": " . $rply . $this->CRLF;
222 }
223 return false;
224 }
225
226 // Send encoded username
227 fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
228
229 $rply = $this->get_lines();
230 $code = substr($rply,0,3);
231
232 if($code != 334) {
233 $this->error =
234 array("error" => "Username not accepted from server",
235 "smtp_code" => $code,
236 "smtp_msg" => substr($rply,4));
237 if($this->do_debug >= 1) {
238 echo "SMTP -> ERROR: " . $this->error["error"] .
239 ": " . $rply . $this->CRLF;
240 }
241 return false;
242 }
243
244 // Send encoded password
245 fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
246
247 $rply = $this->get_lines();
248 $code = substr($rply,0,3);
249
250 if($code != 235) {
251 $this->error =
252 array("error" => "Password not accepted from server",
253 "smtp_code" => $code,
254 "smtp_msg" => substr($rply,4));
255 if($this->do_debug >= 1) {
256 echo "SMTP -> ERROR: " . $this->error["error"] .
257 ": " . $rply . $this->CRLF;
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 // hmm this is an odd situation... the socket is
275 // valid but we are not connected anymore
276 if($this->do_debug >= 1) {
277 echo "SMTP -> NOTICE:" . $this->CRLF .
278 "EOF caught while checking if connected";
279 }
280 $this->Close();
281 return false;
282 }
283 return true; // everything looks good
284 }
285 return false;
286 }
287
288 /**
289 * Closes the socket and cleans up the state of the class.
290 * It is not considered good to use this function without
291 * first trying to use QUIT.
292 * @access public
293 * @return void
294 */
295 public function Close() {
296 $this->error = null; // so there is no confusion
297 $this->helo_rply = null;
298 if(!empty($this->smtp_conn)) {
299 // close the connection and cleanup
300 fclose($this->smtp_conn);
301 $this->smtp_conn = 0;
302 }
303 }
304
305 /***************************************************************
306 * SMTP COMMANDS *
307 *************************************************************/
308
309 /**
310 * Issues a data command and sends the msg_data to the server
311 * finializing the mail transaction. $msg_data is the message
312 * that is to be send with the headers. Each header needs to be
313 * on a single line followed by a <CRLF> with the message headers
314 * and the message body being seperated by and additional <CRLF>.
315 *
316 * Implements rfc 821: DATA <CRLF>
317 *
318 * SMTP CODE INTERMEDIATE: 354
319 * [data]
320 * <CRLF>.<CRLF>
321 * SMTP CODE SUCCESS: 250
322 * SMTP CODE FAILURE: 552,554,451,452
323 * SMTP CODE FAILURE: 451,554
324 * SMTP CODE ERROR : 500,501,503,421
325 * @access public
326 * @return bool
327 */
328 public function Data($msg_data) {
329 $this->error = null; // so no confusion is caused
330
331 if(!$this->connected()) {
332 $this->error = array(
333 "error" => "Called Data() without being connected");
334 return false;
335 }
336
337 fputs($this->smtp_conn,"DATA" . $this->CRLF);
338
339 $rply = $this->get_lines();
340 $code = substr($rply,0,3);
341
342 if($this->do_debug >= 2) {
343 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
344 }
345
346 if($code != 354) {
347 $this->error =
348 array("error" => "DATA command not accepted from server",
349 "smtp_code" => $code,
350 "smtp_msg" => substr($rply,4));
351 if($this->do_debug >= 1) {
352 echo "SMTP -> ERROR: " . $this->error["error"] .
353 ": " . $rply . $this->CRLF;
354 }
355 return false;
356 }
357
358 /* the server is ready to accept data!
359 * according to rfc 821 we should not send more than 1000
360 * including the CRLF
361 * characters on a single line so we will break the data up
362 * into lines by \r and/or \n then if needed we will break
363 * each of those into smaller lines to fit within the limit.
364 * in addition we will be looking for lines that start with
365 * a period '.' and append and additional period '.' to that
366 * line. NOTE: this does not count towards are limit.
367 */
368
369 // normalize the line breaks so we know the explode works
370 $msg_data = str_replace("\r\n","\n",$msg_data);
371 $msg_data = str_replace("\r","\n",$msg_data);
372 $lines = explode("\n",$msg_data);
373
374 /* we need to find a good way to determine is headers are
375 * in the msg_data or if it is a straight msg body
376 * currently I am assuming rfc 822 definitions of msg headers
377 * and if the first field of the first line (':' sperated)
378 * does not contain a space then it _should_ be a header
379 * and we can process all lines before a blank "" line as
380 * headers.
381 */
382 $field = substr($lines[0],0,strpos($lines[0],":"));
383 $in_headers = false;
384 if(!empty($field) && !strstr($field," ")) {
385 $in_headers = true;
386 }
387
388 $max_line_length = 998; // used below; set here for ease in change
389
390 while(list(,$line) = @each($lines)) {
391 $lines_out = null;
392 if($line == "" && $in_headers) {
393 $in_headers = false;
394 }
395 // ok we need to break this line up into several smaller lines
396 while(strlen($line) > $max_line_length) {
397 $pos = strrpos(substr($line,0,$max_line_length)," ");
398
399 // Patch to fix DOS attack
400 if(!$pos) {
401 $pos = $max_line_length - 1;
402 $lines_out[] = substr($line,0,$pos);
403 $line = substr($line,$pos);
404 } else {
405 $lines_out[] = substr($line,0,$pos);
406 $line = substr($line,$pos + 1);
407 }
408
409 /* if we are processing headers we need to
410 * add a LWSP-char to the front of the new line
411 * rfc 822 on long msg headers
412 */
413 if($in_headers) {
414 $line = "\t" . $line;
415 }
416 }
417 $lines_out[] = $line;
418
419 // now send the lines to the server
420 while(list(,$line_out) = @each($lines_out)) {
421 if(strlen($line_out) > 0)
422 {
423 if(substr($line_out, 0, 1) == ".") {
424 $line_out = "." . $line_out;
425 }
426 }
427 fputs($this->smtp_conn,$line_out . $this->CRLF);
428 }
429 }
430
431 // ok all the message data has been sent so lets get this
432 // over with aleady
433 fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
434
435 $rply = $this->get_lines();
436 $code = substr($rply,0,3);
437
438 if($this->do_debug >= 2) {
439 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
440 }
441
442 if($code != 250) {
443 $this->error =
444 array("error" => "DATA not accepted from server",
445 "smtp_code" => $code,
446 "smtp_msg" => substr($rply,4));
447 if($this->do_debug >= 1) {
448 echo "SMTP -> ERROR: " . $this->error["error"] .
449 ": " . $rply . $this->CRLF;
450 }
451 return false;
452 }
453 return true;
454 }
455
456 /**
457 * Expand takes the name and asks the server to list all the
458 * people who are members of the _list_. Expand will return
459 * back and array of the result or false if an error occurs.
460 * Each value in the array returned has the format of:
461 * [ <full-name> <sp> ] <path>
462 * The definition of <path> is defined in rfc 821
463 *
464 * Implements rfc 821: EXPN <SP> <string> <CRLF>
465 *
466 * SMTP CODE SUCCESS: 250
467 * SMTP CODE FAILURE: 550
468 * SMTP CODE ERROR : 500,501,502,504,421
469 * @access public
470 * @return string array
471 */
472 public function Expand($name) {
473 $this->error = null; // so no confusion is caused
474
475 if(!$this->connected()) {
476 $this->error = array(
477 "error" => "Called Expand() without being connected");
478 return false;
479 }
480
481 fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
482
483 $rply = $this->get_lines();
484 $code = substr($rply,0,3);
485
486 if($this->do_debug >= 2) {
487 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
488 }
489
490 if($code != 250) {
491 $this->error =
492 array("error" => "EXPN not accepted from server",
493 "smtp_code" => $code,
494 "smtp_msg" => substr($rply,4));
495 if($this->do_debug >= 1) {
496 echo "SMTP -> ERROR: " . $this->error["error"] .
497 ": " . $rply . $this->CRLF;
498 }
499 return false;
500 }
501
502 // parse the reply and place in our array to return to user
503 $entries = explode($this->CRLF,$rply);
504 while(list(,$l) = @each($entries)) {
505 $list[] = substr($l,4);
506 }
507
508 return $list;
509 }
510
511 /**
512 * Sends the HELO command to the smtp server.
513 * This makes sure that we and the server are in
514 * the same known state.
515 *
516 * Implements from rfc 821: HELO <SP> <domain> <CRLF>
517 *
518 * SMTP CODE SUCCESS: 250
519 * SMTP CODE ERROR : 500, 501, 504, 421
520 * @access public
521 * @return bool
522 */
523 public function Hello($host="") {
524 $this->error = null; // so no confusion is caused
525
526 if(!$this->connected()) {
527 $this->error = array(
528 "error" => "Called Hello() without being connected");
529 return false;
530 }
531
532 // if a hostname for the HELO was not specified determine
533 //a suitable one to send
534 if(empty($host)) {
535 // we need to determine some sort of appopiate default
536 // to send to the server
537 $host = "localhost";
538 }
539
540 // Send extended hello first (RFC 2821)
541 if(!$this->SendHello("EHLO", $host))
542 {
543 if(!$this->SendHello("HELO", $host))
544 return false;
545 }
546
547 return true;
548 }
549
550 /**
551 * Sends a HELO/EHLO command.
552 * @access private
553 * @return bool
554 */
555 private function SendHello($hello, $host) {
556 fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
557
558 $rply = $this->get_lines();
559 $code = substr($rply,0,3);
560
561 if($this->do_debug >= 2) {
562 echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
563 }
564
565 if($code != 250) {
566 $this->error =
567 array("error" => $hello . " not accepted from server",
568 "smtp_code" => $code,
569 "smtp_msg" => substr($rply,4));
570 if($this->do_debug >= 1) {
571 echo "SMTP -> ERROR: " . $this->error["error"] .
572 ": " . $rply . $this->CRLF;
573 }
574 return false;
575 }
576
577 $this->helo_rply = $rply;
578
579 return true;
580 }
581
582 /**
583 * Gets help information on the keyword specified. If the keyword
584 * is not specified then returns generic help, ussually contianing
585 * A list of keywords that help is available on. This function
586 * returns the results back to the user. It is up to the user to
587 * handle the returned data. If an error occurs then false is
588 * returned with $this->error set appropiately.
589 *
590 * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
591 *
592 * SMTP CODE SUCCESS: 211,214
593 * SMTP CODE ERROR : 500,501,502,504,421
594 * @access public
595 * @return string
596 */
597 public function Help($keyword="") {
598 $this->error = null; // to avoid confusion
599
600 if(!$this->connected()) {
601 $this->error = array(
602 "error" => "Called Help() without being connected");
603 return false;
604 }
605
606 $extra = "";
607 if(!empty($keyword)) {
608 $extra = " " . $keyword;
609 }
610
611 fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
612
613 $rply = $this->get_lines();
614 $code = substr($rply,0,3);
615
616 if($this->do_debug >= 2) {
617 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
618 }
619
620 if($code != 211 && $code != 214) {
621 $this->error =
622 array("error" => "HELP not accepted from server",
623 "smtp_code" => $code,
624 "smtp_msg" => substr($rply,4));
625 if($this->do_debug >= 1) {
626 echo "SMTP -> ERROR: " . $this->error["error"] .
627 ": " . $rply . $this->CRLF;
628 }
629 return false;
630 }
631
632 return $rply;
633 }
634
635 /**
636 * Starts a mail transaction from the email address specified in
637 * $from. Returns true if successful or false otherwise. If True
638 * the mail transaction is started and then one or more Recipient
639 * commands may be called followed by a Data command.
640 *
641 * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
642 *
643 * SMTP CODE SUCCESS: 250
644 * SMTP CODE SUCCESS: 552,451,452
645 * SMTP CODE SUCCESS: 500,501,421
646 * @access public
647 * @return bool
648 */
649 public function Mail($from) {
650 $this->error = null; // so no confusion is caused
651
652 if(!$this->connected()) {
653 $this->error = array(
654 "error" => "Called Mail() without being connected");
655 return false;
656 }
657
658 $useVerp = ($this->do_verp ? "XVERP" : "");
659 fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
660
661 $rply = $this->get_lines();
662 $code = substr($rply,0,3);
663
664 if($this->do_debug >= 2) {
665 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
666 }
667
668 if($code != 250) {
669 $this->error =
670 array("error" => "MAIL not accepted from server",
671 "smtp_code" => $code,
672 "smtp_msg" => substr($rply,4));
673 if($this->do_debug >= 1) {
674 echo "SMTP -> ERROR: " . $this->error["error"] .
675 ": " . $rply . $this->CRLF;
676 }
677 return false;
678 }
679 return true;
680 }
681
682 /**
683 * Sends the command NOOP to the SMTP server.
684 *
685 * Implements from rfc 821: NOOP <CRLF>
686 *
687 * SMTP CODE SUCCESS: 250
688 * SMTP CODE ERROR : 500, 421
689 * @access public
690 * @return bool
691 */
692 public function Noop() {
693 $this->error = null; // so no confusion is caused
694
695 if(!$this->connected()) {
696 $this->error = array(
697 "error" => "Called Noop() without being connected");
698 return false;
699 }
700
701 fputs($this->smtp_conn,"NOOP" . $this->CRLF);
702
703 $rply = $this->get_lines();
704 $code = substr($rply,0,3);
705
706 if($this->do_debug >= 2) {
707 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
708 }
709
710 if($code != 250) {
711 $this->error =
712 array("error" => "NOOP not accepted from server",
713 "smtp_code" => $code,
714 "smtp_msg" => substr($rply,4));
715 if($this->do_debug >= 1) {
716 echo "SMTP -> ERROR: " . $this->error["error"] .
717 ": " . $rply . $this->CRLF;
718 }
719 return false;
720 }
721 return true;
722 }
723
724 /**
725 * Sends the quit command to the server and then closes the socket
726 * if there is no error or the $close_on_error argument is true.
727 *
728 * Implements from rfc 821: QUIT <CRLF>
729 *
730 * SMTP CODE SUCCESS: 221
731 * SMTP CODE ERROR : 500
732 * @access public
733 * @return bool
734 */
735 public function Quit($close_on_error=true) {
736 $this->error = null; // so there is no confusion
737
738 if(!$this->connected()) {
739 $this->error = array(
740 "error" => "Called Quit() without being connected");
741 return false;
742 }
743
744 // send the quit command to the server
745 fputs($this->smtp_conn,"quit" . $this->CRLF);
746
747 // get any good-bye messages
748 $byemsg = $this->get_lines();
749
750 if($this->do_debug >= 2) {
751 echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
752 }
753
754 $rval = true;
755 $e = null;
756
757 $code = substr($byemsg,0,3);
758 if($code != 221) {
759 // use e as a tmp var cause Close will overwrite $this->error
760 $e = array("error" => "SMTP server rejected quit command",
761 "smtp_code" => $code,
762 "smtp_rply" => substr($byemsg,4));
763 $rval = false;
764 if($this->do_debug >= 1) {
765 echo "SMTP -> ERROR: " . $e["error"] . ": " .
766 $byemsg . $this->CRLF;
767 }
768 }
769
770 if(empty($e) || $close_on_error) {
771 $this->Close();
772 }
773
774 return $rval;
775 }
776
777 /**
778 * Sends the command RCPT to the SMTP server with the TO: argument of $to.
779 * Returns true if the recipient was accepted false if it was rejected.
780 *
781 * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
782 *
783 * SMTP CODE SUCCESS: 250,251
784 * SMTP CODE FAILURE: 550,551,552,553,450,451,452
785 * SMTP CODE ERROR : 500,501,503,421
786 * @access public
787 * @return bool
788 */
789 public function Recipient($to) {
790 $this->error = null; // so no confusion is caused
791
792 if(!$this->connected()) {
793 $this->error = array(
794 "error" => "Called Recipient() without being connected");
795 return false;
796 }
797
798 fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
799
800 $rply = $this->get_lines();
801 $code = substr($rply,0,3);
802
803 if($this->do_debug >= 2) {
804 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
805 }
806
807 if($code != 250 && $code != 251) {
808 $this->error =
809 array("error" => "RCPT not accepted from server",
810 "smtp_code" => $code,
811 "smtp_msg" => substr($rply,4));
812 if($this->do_debug >= 1) {
813 echo "SMTP -> ERROR: " . $this->error["error"] .
814 ": " . $rply . $this->CRLF;
815 }
816 return false;
817 }
818 return true;
819 }
820
821 /**
822 * Sends the RSET command to abort and transaction that is
823 * currently in progress. Returns true if successful false
824 * otherwise.
825 *
826 * Implements rfc 821: RSET <CRLF>
827 *
828 * SMTP CODE SUCCESS: 250
829 * SMTP CODE ERROR : 500,501,504,421
830 * @access public
831 * @return bool
832 */
833 public function Reset() {
834 $this->error = null; // so no confusion is caused
835
836 if(!$this->connected()) {
837 $this->error = array(
838 "error" => "Called Reset() without being connected");
839 return false;
840 }
841
842 fputs($this->smtp_conn,"RSET" . $this->CRLF);
843
844 $rply = $this->get_lines();
845 $code = substr($rply,0,3);
846
847 if($this->do_debug >= 2) {
848 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
849 }
850
851 if($code != 250) {
852 $this->error =
853 array("error" => "RSET failed",
854 "smtp_code" => $code,
855 "smtp_msg" => substr($rply,4));
856 if($this->do_debug >= 1) {
857 echo "SMTP -> ERROR: " . $this->error["error"] .
858 ": " . $rply . $this->CRLF;
859 }
860 return false;
861 }
862
863 return true;
864 }
865
866 /**
867 * Starts a mail transaction from the email address specified in
868 * $from. Returns true if successful or false otherwise. If True
869 * the mail transaction is started and then one or more Recipient
870 * commands may be called followed by a Data command. This command
871 * will send the message to the users terminal if they are logged
872 * in.
873 *
874 * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
875 *
876 * SMTP CODE SUCCESS: 250
877 * SMTP CODE SUCCESS: 552,451,452
878 * SMTP CODE SUCCESS: 500,501,502,421
879 * @access public
880 * @return bool
881 */
882 public function Send($from) {
883 $this->error = null; // so no confusion is caused
884
885 if(!$this->connected()) {
886 $this->error = array(
887 "error" => "Called Send() without being connected");
888 return false;
889 }
890
891 fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
892
893 $rply = $this->get_lines();
894 $code = substr($rply,0,3);
895
896 if($this->do_debug >= 2) {
897 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
898 }
899
900 if($code != 250) {
901 $this->error =
902 array("error" => "SEND not accepted from server",
903 "smtp_code" => $code,
904 "smtp_msg" => substr($rply,4));
905 if($this->do_debug >= 1) {
906 echo "SMTP -> ERROR: " . $this->error["error"] .
907 ": " . $rply . $this->CRLF;
908 }
909 return false;
910 }
911 return true;
912 }
913
914 /**
915 * Starts a mail transaction from the email address specified in
916 * $from. Returns true if successful or false otherwise. If True
917 * the mail transaction is started and then one or more Recipient
918 * commands may be called followed by a Data command. This command
919 * will send the message to the users terminal if they are logged
920 * in and send them an email.
921 *
922 * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
923 *
924 * SMTP CODE SUCCESS: 250
925 * SMTP CODE SUCCESS: 552,451,452
926 * SMTP CODE SUCCESS: 500,501,502,421
927 * @access public
928 * @return bool
929 */
930 public function SendAndMail($from) {
931 $this->error = null; // so no confusion is caused
932
933 if(!$this->connected()) {
934 $this->error = array(
935 "error" => "Called SendAndMail() without being connected");
936 return false;
937 }
938
939 fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
940
941 $rply = $this->get_lines();
942 $code = substr($rply,0,3);
943
944 if($this->do_debug >= 2) {
945 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
946 }
947
948 if($code != 250) {
949 $this->error =
950 array("error" => "SAML not accepted from server",
951 "smtp_code" => $code,
952 "smtp_msg" => substr($rply,4));
953 if($this->do_debug >= 1) {
954 echo "SMTP -> ERROR: " . $this->error["error"] .
955 ": " . $rply . $this->CRLF;
956 }
957 return false;
958 }
959 return true;
960 }
961
962 /**
963 * Starts a mail transaction from the email address specified in
964 * $from. Returns true if successful or false otherwise. If True
965 * the mail transaction is started and then one or more Recipient
966 * commands may be called followed by a Data command. This command
967 * will send the message to the users terminal if they are logged
968 * in or mail it to them if they are not.
969 *
970 * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
971 *
972 * SMTP CODE SUCCESS: 250
973 * SMTP CODE SUCCESS: 552,451,452
974 * SMTP CODE SUCCESS: 500,501,502,421
975 * @access public
976 * @return bool
977 */
978 public function SendOrMail($from) {
979 $this->error = null; // so no confusion is caused
980
981 if(!$this->connected()) {
982 $this->error = array(
983 "error" => "Called SendOrMail() without being connected");
984 return false;
985 }
986
987 fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
988
989 $rply = $this->get_lines();
990 $code = substr($rply,0,3);
991
992 if($this->do_debug >= 2) {
993 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
994 }
995
996 if($code != 250) {
997 $this->error =
998 array("error" => "SOML not accepted from server",
999 "smtp_code" => $code,
1000 "smtp_msg" => substr($rply,4));
1001 if($this->do_debug >= 1) {
1002 echo "SMTP -> ERROR: " . $this->error["error"] .
1003 ": " . $rply . $this->CRLF;
1004 }
1005 return false;
1006 }
1007 return true;
1008 }
1009
1010 /**
1011 * This is an optional command for SMTP that this class does not
1012 * support. This method is here to make the RFC821 Definition
1013 * complete for this class and __may__ be implimented in the future
1014 *
1015 * Implements from rfc 821: TURN <CRLF>
1016 *
1017 * SMTP CODE SUCCESS: 250
1018 * SMTP CODE FAILURE: 502
1019 * SMTP CODE ERROR : 500, 503
1020 * @access public
1021 * @return bool
1022 */
1023 public function Turn() {
1024 $this->error = array("error" => "This method, TURN, of the SMTP ".
1025 "is not implemented");
1026 if($this->do_debug >= 1) {
1027 echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
1028 }
1029 return false;
1030 }
1031
1032 /**
1033 * Verifies that the name is recognized by the server.
1034 * Returns false if the name could not be verified otherwise
1035 * the response from the server is returned.
1036 *
1037 * Implements rfc 821: VRFY <SP> <string> <CRLF>
1038 *
1039 * SMTP CODE SUCCESS: 250,251
1040 * SMTP CODE FAILURE: 550,551,553
1041 * SMTP CODE ERROR : 500,501,502,421
1042 * @access public
1043 * @return int
1044 */
1045 public function Verify($name) {
1046 $this->error = null; // so no confusion is caused
1047
1048 if(!$this->connected()) {
1049 $this->error = array(
1050 "error" => "Called Verify() without being connected");
1051 return false;
1052 }
1053
1054 fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
1055
1056 $rply = $this->get_lines();
1057 $code = substr($rply,0,3);
1058
1059 if($this->do_debug >= 2) {
1060 echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
1061 }
1062
1063 if($code != 250 && $code != 251) {
1064 $this->error =
1065 array("error" => "VRFY failed on name '$name'",
1066 "smtp_code" => $code,
1067 "smtp_msg" => substr($rply,4));
1068 if($this->do_debug >= 1) {
1069 echo "SMTP -> ERROR: " . $this->error["error"] .
1070 ": " . $rply . $this->CRLF;
1071 }
1072 return false;
1073 }
1074 return $rply;
1075 }
1076
1077 /*******************************************************************
1078 * INTERNAL FUNCTIONS *
1079 ******************************************************************/
1080
1081 /**
1082 * Read in as many lines as possible
1083 * either before eof or socket timeout occurs on the operation.
1084 * With SMTP we can tell if we have more lines to read if the
1085 * 4th character is '-' symbol. If it is a space then we don't
1086 * need to read anything else.
1087 * @access private
1088 * @return string
1089 */
1090 private function get_lines() {
1091 $data = "";
1092 while($str = @fgets($this->smtp_conn,515)) {
1093 if($this->do_debug >= 4) {
1094 echo "SMTP -> get_lines(): \$data was \"$data\"" .
1095 $this->CRLF;
1096 echo "SMTP -> get_lines(): \$str is \"$str\"" .
1097 $this->CRLF;
1098 }
1099 $data .= $str;
1100 if($this->do_debug >= 4) {
1101 echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
1102 }
1103 // if the 4th character is a space then we are done reading
1104 // so just break the loop
1105 if(substr($str,3,1) == " ") { break; }
1106 }
1107 return $data;
1108 }
1109
1110}
1111
1112
1113 ?>
diff --git a/central/trunk/includes/instadisc.php b/central/trunk/includes/instadisc.php index 1f40b7a..320ff80 100644 --- a/central/trunk/includes/instadisc.php +++ b/central/trunk/includes/instadisc.php
@@ -3,7 +3,6 @@
3/* InstaDisc Server - A Four Island Project */ 3/* InstaDisc Server - A Four Island Project */
4 4
5include_once('includes/db.php'); 5include_once('includes/db.php');
6include_once('includes/class.phpmailer.php');
7 6
8function instaDisc_checkVerification($username, $verification, $verificationID, $table, $nameField, $passField) 7function instaDisc_checkVerification($username, $verification, $verificationID, $table, $nameField, $passField)
9{ 8{
@@ -99,111 +98,10 @@ function instaDisc_addItem($username, $subscription, $title, $author, $url, $sem
99 } 98 }
100} 99}
101 100
102function instaDisc_phpMailer() 101function instaDisc_createUser($username, $password, $email)
103{ 102{
104 $mail = new PHPMailer(); 103 $insuser = "INSERT INTO users (username, password, email) VALUES (\"" . mysql_real_escape_string($username) . "\", \"" . mysql_real_escape_string($password) . "\", \"" . mysql_real_escape_string($email) . "\")";
105 $mail->IsSMTP(); 104 $insuser2 = mysql_query($insuser);
106 $mail->From = 'instadisc@' . instaDisc_getConfig('mailDomain');
107 $mail->FromName = 'InstaDisc';
108 $mail->Host = instaDisc_getConfig('smtpHost');
109 if (instaDisc_getConfig('smtpAuth') == 'true')
110 {
111 $mail->SMTPAuth = true;
112 $mail->Username = instaDisc_getConfig('smtpUser');
113 $mail->Password = instaDisc_getConfig('smtpPass');
114 }
115 $mail->Helo = $_SERVER['SERVER_NAME'];
116 $mail->ClearAddresses();
117
118 return $mail;
119}
120
121function instaDisc_sendActivationEmail($username, $password, $email)
122{
123 $penKey = md5(rand(1,2147483647));
124
125 $inspending = "INSERT INTO pending (username, password, email, code) VALUES (\"" . mysql_real_escape_string($username) . "\", \"" . mysql_real_escape_string(md5($password)) . "\", \"" . mysql_real_escape_string($email) . "\", \"" . mysql_real_escape_string($penKey) . "\")";
126 $inspending2 = mysql_query($inspending);
127
128 $mail = instaDisc_phpMailer();
129 $mail->AddAddress($email, $username);
130 $mail->Subject = 'InstaDisc Account Verification';
131 $mail->Body = "Hello, someone has recently registered an account at " . $_SERVER['SERVER_NAME'] . " with your email address. If that was you, and your chosen username IS " . $username . ", then copy the account verification code below to our Account Verification page, enter your username and press Activate!\r\n\r\n" . $penKey . "\r\n\r\nIf that was not you, copy the above code to our Account Verification page, enter the above username, and click Delete.";
132 $mail->Send();
133
134 return ($mail->IsError() ? $mail->ErrorInfo : true);
135}
136
137function instaDisc_activateAccount($username, $penKey)
138{
139 $getuser = "SELECT * FROM pending WHERE username = \"" . mysql_real_escape_string($username) . "\" AND code = \"" . mysql_real_escape_string($penKey) . "\"";
140 $getuser2 = mysql_query($getuser);
141 $getuser3 = mysql_fetch_array($getuser2);
142 if ($getuser3['username'] == $username)
143 {
144 $insuser = "INSERT INTO users (username, password, email) VALUES (\"" . mysql_real_escape_string($username) . "\", \"" . mysql_real_escape_string($getuser3['password']) . "\", \"" . mysql_real_escape_string($getuser3['email']) . "\")";
145 $insuser2 = mysql_query($insuser);
146
147 $delpending = "DELETE FROM pending WHERE username = \"" . mysql_real_escape_string($username) . "\"";
148 $delpending2 = mysql_query($delpending);
149
150 $mail = instaDisc_phpMailer();
151 $mail->AddAddress($getuser3['email'], $username);
152 $mail->Subject = 'Welcome to InstaDisc!';
153 $mail->Body = "Welcome to InstaDisc! Thank you for registering at " . instaDisc_getConfig('siteName') . " Central Server, we hope you enjoy our service! Now, when you download an InstaDisc Client, it will ask you for the following information which you will need to enter into it for it to work:\r\n\r\nUsername: " . $username . "\r\nPassword: (you should know this, it's not displayed here for security reasons)\r\nCentral Server URL: " . instaDisc_getConfig("xmlrpcURL") . "\r\n\r\nOnce again, thank you for choosing " . instaDisc_getConfig("siteName") . "!";
154 $mail->Send();
155
156 return ($mail->IsError() ? $mail->ErrorInfo : true);
157 } else {
158 return false;
159 }
160}
161
162function instaDisc_deactivateAccount($username, $penKey)
163{
164 $getuser = "SELECT * FROM pending WHERE username = \"" . mysql_real_escape_string($username) . "\" AND code = \"" . mysql_real_escape_string($penKey) . "\"";
165 $getuser2 = mysql_query($getuser);
166 $getuser3 = mysql_fetch_array($getuser2);
167 if ($getuser3['username'] == $username)
168 {
169 $delpending = "DELETE FROM pending WHERE username = \"" . mysql_real_escape_string($username) . "\"";
170 $delpending2 = mysql_query($delpending);
171
172 return true;
173 } else {
174 return false;
175 }
176}
177
178function instaDisc_verifyUser($username, $password)
179{
180 $getuser = "SELECT * FROM users WHERE username = \"" . mysql_real_escape_string($username). "\" AND password = \"" . mysql_real_escape_string(md5($password)) . "\"";
181 $getuser2 = mysql_query($getuser);
182 $getuser3 = mysql_fetch_array($getuser2);
183
184 return ($getuser3['username'] == $username);
185}
186
187function instaDisc_deleteAccount($username)
188{
189 $getuser = "SELECT * FROM users WHERE username = \"" . mysql_real_escape_string($username) . "\"";
190 $getuser2 = mysql_query($getuser);
191 $getuser3 = mysql_fetch_array($getuser2);
192 if ($getuser3['username'] == $username)
193 {
194 $deluser = "DELETE FROM users WHERE username = \"" . mysql_real_escape_string($username) . "\"";
195 $deluser2 = mysql_query($deluser);
196
197 $delsubs = "DELETE FROM subscriptions WHERE username = \"" . mysql_real_escape_string($username) . "\"";
198 $delsubs2 = mysql_query($delsubs);
199
200 $delitems = "DELETE FROM inbox WHERE username = \"" . mysql_real_escape_string($username) . "\"";
201 $delitems2 = mysql_query($delitems);
202
203 return true;
204 }
205
206 return false;
207} 105}
208 106
209function instaDisc_getConfig($key) 107function instaDisc_getConfig($key)
diff --git a/central/trunk/includes/template.php b/central/trunk/includes/template.php deleted file mode 100644 index b4ec16b..0000000 --- a/central/trunk/includes/template.php +++ /dev/null
@@ -1,160 +0,0 @@
1<?php
2/*
3 444444444
4 4::::::::4
5 4:::::::::4
6 4::::44::::4
7 4::::4 4::::4 Four Island
8 4::::4 4::::4
9 4::::4 4::::4 Written and maintained by Starla Insigna
104::::444444::::444
114::::::::::::::::4 includes/template.php
124444444444:::::444
13 4::::4 Please do not use, reproduce or steal the
14 4::::4 contents of this file without explicit
15 4::::4 permission from Hatkirby.
16 44::::::44
17 4::::::::4
18 4444444444
19*/
20
21class FITemplate
22{
23
24 var $file;
25 var $tags;
26 var $blocks;
27 var $refs;
28
29 function FITemplate($filename)
30 {
31 $tfn = 'theme/' . $filename . '.tpl';
32 if (file_exists($tfn))
33 {
34 $this->file = $tfn;
35 } else {
36 throw new Exception($tfn . ' does not exist');
37 }
38 }
39
40 function add($name, $value)
41 {
42 $this->tags[$name] = $value;
43 }
44
45 function adds($tagarr)
46 {
47 foreach ($tagarr as $name => $value)
48 {
49 $this->add($name,$value);
50 }
51 }
52
53 function adds_block($block, $tagarr)
54 {
55 if (!isset($this->blocks[$block]))
56 {
57 $this->blocks[$block] = array('count' => 1);
58 }
59 foreach ($tagarr as $name => $value)
60 {
61 $this->blocks[$block][$this->blocks[$block]['count']][$name] = $value;
62 }
63 $this->blocks[$block]['count']++;
64 }
65
66 function add_ref($id, $block, $tagarr)
67 {
68 $this->adds_block($block,$tagarr);
69 $this->refs[$id] = &$this->blocks[$block][$this->blocks[$block]['count']-1];//'$this->blocks[\'' . $block . '\'][' . ($this->blocks[$block]['count']-1) . ']';
70 }
71
72 function adds_ref($id, $tagarr)
73 {
74 foreach ($tagarr as $name => $value)
75 {
76 $this->refs[$id][$name] = $value;
77 }
78 }
79
80 function adds_ref_sub($id, $block, $tagarr)
81 {
82 if (!isset($this->refs[$id][$block]))
83 {
84 $this->refs[$id][$block] = array('count' => 1);
85 }
86 foreach ($tagarr as $name => $value)
87 {
88 $this->refs[$id][$block][$this->refs[$id][$block]['count']][$name] = $value;
89 }
90 $this->refs[$id][$block]['count']++;
91 }
92
93 function display()
94 {
95 $template = file_get_contents($this->file);
96 while (preg_match('/<!--INCLUDE ([^>]*)-->/',$template) == 1)
97 {
98 preg_match('/<!--INCLUDE ([^>]*)-->/',$template,$mat);
99 $fname = $mat[1];
100 $itmp = new FITemplate($fname);
101 $template = str_replace('<!--INCLUDE ' . $fname . '-->',file_get_contents($itmp->file),$template);
102 }
103 if (isset($this->tags))
104 {
105 foreach ($this->tags as $name => $value)
106 {
107 $template = str_replace('<!--' . $name . '-->',$value,$template);
108 }
109 }
110 if (isset($this->blocks))
111 {
112 foreach ($this->blocks as $bname => $block)
113 {
114 $this->parseBlock($template, $bname, $block);
115 }
116 }
117 while (preg_match('/<!--BEGIN ([^>]*)-->/',$template) == 1)
118 {
119 preg_match('/<!--BEGIN ([^>]*)-->/',$template,$mat);
120 $bname = $mat[1];
121 $start = strpos($template,'<!--BEGIN ' . $bname . '-->');
122 $end = strpos($template,'<!--END ' . $bname . '-->');
123 $template = str_replace(substr($template,$start,$end-$start+strlen($bname)+11),'',$template);
124 }
125 $template = preg_replace('/<!--([^>]*)-->/','',$template);
126 echo($template);
127 }
128
129 function parseBlock(&$template, $bname, $block)
130 {
131 while (strpos($template,'<!--BEGIN ' . $bname . '-->') !== FALSE)
132 {
133 $start = strpos($template,'<!--BEGIN ' . $bname . '-->');
134 $end = strpos($template,'<!--END ' . $bname . '-->');
135 $gencont = substr($template,$start+strlen($bname)+13,$end-$start-strlen($bname)-13);
136 $blockcont = '';
137 foreach ($block as $lname => $blocktags)
138 {
139 if ($lname != 'count')
140 {
141 $scrcont = $gencont;
142 foreach ($blocktags as $name => $value)
143 {
144 if (!is_array($value))
145 {
146 $scrcont = str_replace('<!--' . $bname . '.' . $name . '-->',$value,$scrcont);
147 } else {
148 $this->parseBlock($scrcont, $bname . '.' . $name, $value);
149 }
150 }
151 $blockcont .= $scrcont;
152 }
153 }
154 $template = str_replace(substr($template,$start,$end-$start+strlen($bname)+11),$blockcont,$template);
155 }
156 }
157
158}
159
160?>