tbrehm
2013-02-22 526b997c9891a796b152cdbab8e329b356b1f596
commit | author | age
a59498 1 <?php
M 2
3 /*
4 Copyright (c) 2012, Marius Cramer, pixcept KG
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /**
32  * email class
33  * 
34  * @package pxFramework
35  *
36  */
37 class ispcmail {
38     
39     /**#@+
40      * @access private
41      */
42     private $html_part;
43     private $text_part;
44     
45     private $headers;
46     
47     private $_logged_in = false;
48     private $_smtp_conn = null;
49     
50     private $_crlf = "\n";
51     
52     private $attach_type = 'application/octet-stream';
53     private $attachments;
54     private $mime_boundary;
55     private $body = '';
56     private $_mail_sender = '';
d93be9 57     private $_sent_mails = 0;
a00888 58     private $user_agent = 'ISPConfig/3 (Mailer Class)';
a59498 59     /**#@-*/
M 60     
61     /**
62      * set the mail charset
63      */
64     private $mail_charset  = 'UTF-8';//'ISO-8859-1';
65     
66     /**#@+
67      * Provide smtp credentials for smtp mail sending
68      *
69      * @access public
70      */
71     /**
72      * if set to true smtp is used instead of mail() to send emails
73      * @see mail
74      */
75     private $use_smtp = false;
76     /**
77      * the smtp helo string - use the mail server name here!
78      */
79     private $smtp_helo = '';
80     /**
81      * the smtp server to send mails
82      */
83     private $smtp_host = '';
84     /**
85      * the smtp port
86      */
87     private $smtp_port = 25;
88     /**
89      * if the smtp server needs authentication you can set the smtp user here
90      */
91     private $smtp_user = '';
92     /**
93      * if the smtp server needs authentication you can set the smtp password here
94      */
95     private $smtp_pass = '';
96     /**
97      * If you want to use tls/ssl specify it here
98      */
99     private $smtp_crypt = ''; // tls or ssl
d93be9 100     /**
M 101      * How many mails should be sent via one single smtp connection
102      */
103     private $smtp_max_mails = 20;
a00888 104     /**
T 105      * Should the mail be signed
106      */
107     private $sign_email = false;
108     /**
109      * The cert and key to use for email signing
110      */
111     private $sign_key = '';
112     private $sign_key_pass = '';
113     private $sign_cert = '';
114     private $sign_bundle = '';
115     private $_is_signed = false;
116     /**
117      * get disposition notification
118      */
119     private $notification = false;
a59498 120     /**#@-*/
M 121     
122     public function __construct($options = array()) {
123         $rand = md5(microtime());
124         $this->mime_boundary = '==Multipart_Boundary_x' . $rand . 'x';
125         
126         $this->headers = array();
127         $this->attachments = array();
128         
129         $this->headers['MIME-Version'] = '1.0';
a00888 130         $this->headers['User-Agent'] = $this->user_agent;
d93be9 131         if(is_array($options) && count($options) > 0) $this->setOptions($options);
a59498 132     }
M 133     
134     public function __destruct() {
135         $this->finish();
136     }
137     
138     /**
139      * Set option
140      * 
141      * @param string $key the option to set
142      * @param string $value the option value to set
143      */
144     public function setOption($key, $value) {
145         switch($key) {
146             case 'smtp_helo':
147                 $this->smtp_helo = $value;
148                 break;
149             case 'smtp_host':
150                 $this->smtp_host = $value;
151                 break;
152             case 'smtp_server':
153                 $this->smtp_host = $value;
154                 break;
155             case 'smtp_port':
156                 $this->smtp_port = $value;
157                 break;
158             case 'smtp_user':
159                 $this->smtp_user = $value;
160                 break;
161             case 'smtp_pass':
162                 $this->smtp_pass = $value;
163                 break;
d93be9 164             case 'smtp_max_mails':
M 165                 $this->smtp_max_mails = intval($value);
166                 if($this->smtp_max_mails < 1) $this->smtp_max_mails = 1;
167                 break;
a59498 168             case 'use_smtp':
M 169                 $this->use_smtp = ($value == true ? true : false);
170                 if($value == true) $this->_crlf = "\r\n";
171                 break;
172             case 'smtp_crypt':
173                 if($value != 'ssl' && $value != 'tls') $value = '';
174                 $this->smtp_crypt = $value;
175                 break;
a00888 176             case 'sign_email':
T 177                 $this->sign_email = ($value == true ? true : false);
178                 break;
179             case 'sign_key':
180                 $this->sign_key = $value;
181                 break;
182             case 'sign_key_pass':
183                 $this->sign_key_pass = $value;
184                 break;
185             case 'sign_cert':
186                 $this->sign_cert = $value;
187                 break;
188             case 'sign_bundle':
189                 $this->sign_bundle = $value;
190                 break;
a59498 191             case 'mail_charset':
M 192                 $this->mail_charset = $value;
a00888 193                 break;
T 194             case 'notify':
195                 $this->notification = ($value == true ? true : false);
a59498 196                 break;
M 197         }
198     }
199     
d93be9 200     /** Detect the helo string if none given
M 201      * 
202      */
a59498 203     private function detectHelo() {
d93be9 204         if(isset($_SERVER['HTTP_HOST'])) $this->smtp_helo = $_SERVER['HTTP_HOST'];
M 205         elseif(isset($_SERVER['SERVER_NAME'])) $this->smtp_helo = $_SERVER['SERVER_NAME'];
a59498 206         else $this->smtp_helo = php_uname('n');
M 207         if($this->smtp_helo == '') $this->smtp_helo = 'localhost';
208     }
209     
210     /**
211      * Set options
212      * 
213      * @param array $options the options to set as an associative array key => value
214      */
215     public function setOptions($options) {
216         foreach($options as $key => $value) $this->setOption($key, $value);
217     }
218     
219     /**
220      * Read a file's contents
221      *
222      * Simply gets the file's content
223      *
224      * @access public
225      * @param string $filename name and path of file to read
226      * @return string file content (can be binary)
227      */
228     public function read_File($filename) {
229         $content = '';
230         
231         $fp = fopen($filename, 'r');
232         if(!$fp) return false;
233         
234         while(!feof($fp)) {
235             $content .= fread($fp, 1024);
236         }
237         fclose($fp);
238         
239         return $content;
240     }
241     
242     /**
243      * set smtp connection encryption
244      * 
245      * @access public
246      * @param string $mode encryption mode (tls, ssl or empty string)
247      */
248     public function setSMTPEncryption($mode = '') {
249         if($mode != 'ssl' && $mode != 'tls') $mode = '';
250         $this->smtp_crypt = $mode;
251     }
252
253     /**
254      * set a mail header
255      *
256      * Sets a single mail header to a given value
257      *
258      * @access public
259      * @param string $header header name to set
260      * @param string $value value to set in header field
261      */
262     public function setHeader($header, $value) {
d93be9 263         if(strtolower($header) == 'bcc') $header = 'Bcc';
M 264         elseif(strtolower($header) == 'cc') $header = 'Cc';
265         elseif(strtolower($header) == 'from') $header = 'From';
a59498 266         $this->headers["$header"] = $value;
M 267     }
268     
269     /**
270      * get a mail header value
271      *
272      * Returns a value of a single mail header
273      *
274      * @access public
275      * @param string $header header name to get
276      * @return string header value
277      */
278     public function getHeader($header) {
d93be9 279         if(strtolower($header) == 'bcc') $header = 'Bcc';
M 280         elseif(strtolower($header) == 'cc') $header = 'Cc';
281         elseif(strtolower($header) == 'from') $header = 'From';
282         return (isset($this->headers["$header"]) ? $this->headers["$header"] : '');
a59498 283     }
M 284     
285     /**
286      * Set email sender
287      *
288      * Sets the email sender and optionally the sender's name
289      *
290      * @access public
291      * @param string $email sender email address
292      * @param string $name sender name
293      */
294     public function setSender($email, $name = '') {
295         if($name) $header = '"' . $name . '" <' . $email . '>';
296         else $header = '<' . $email . '>';
297         
298         $this->_mail_sender = $email;
299         
300         $this->setHeader('From', $header);
301     }
302     
303     /**
304      * Set mail subject
305      *
306      * @access public
307      * @param string $subject the mail subject
308      * @return string where-string for db query
309      */
310     public function setSubject($subject) {
311         $this->setHeader('Subject', $subject);
312     }
313     
314     /**
315      * Get current mail subject
316      *
317      * @access public
318      * @return string mail subject
319      */
320     public function getSubject() {
321         return $this->headers['Subject'];
322     }
323     
324     /**
325      * Set mail content
326      *
327      * Sets the mail html and plain text content
328      *
329      * @access public
330      * @param string $text plain text mail content (can be empty)
331      * @param string $html html mail content
332      */
333     public function setMailText($text, $html = '') {
334         $this->text_part = $text;
335         $this->html_part = $html;
336     }
337     
338     /**
339      * Read and attach a file
340      *
341      * Reads a file and attaches it to the current email
342      *
343      * @access public
344      * @param string $filename the file to read and attach
345      * @param string $display_name the name that will be displayed in the mail
346      * @see read_File
347      */
348     public function readAttachFile($filename, $display_name = '') {
349         if($display_name == '') {
350             $path_parts = pathinfo($filename);
351             $display_name = $path_parts["basename"];
352             unset($path_parts);
353         }
354         $this->attachFile($this->read_File($filename), $display_name);
355     }
356     
357     /**
358      * Attach a file
359      *
360      * Attaches a string (can be binary) as a file to the mail
361      *
362      * @access public
363      * @param string $content attachment data string
364      * @param string $filename name for file attachment
365      */
366     public function attachFile($content, $filename) {
367         $attachment = array('content' => $content,
368                             'filename' => $filename,
369                             'type' => 'application/octet-stream',
370                             'encoding' => 'base64'
371                            );
372         $this->attachments[] = $attachment;
373     }
374     
375     /**
376      * @access private
377      */
378     private function create() {
379         $attach = false;
380         $html = false;
381         $text = false;
382         
383         if($this->html_part) $html = true;
384         if($this->text_part) $text = true;
385         if(count($this->attachments) > 0) $attach = true;
386         
387         $textonly = false;
388         $htmlonly = false;
389         if($text == true && $html == false && $attach == false) {
390             // only text
391             $content_type = 'text/plain; charset="' . strtolower($this->mail_charset) . '"';
392             $textonly = true;
393         } elseif($text == true && $html == false && $attach == true) {
394             // text and attachment
395             $content_type = 'multipart/mixed;';
396             $content_type .= "\n" . ' boundary="' . $this->mime_boundary . '"';
397         } elseif($html == true && $text == true && $attach == false) {
398             // html only (or text too)
399             $content_type = 'multipart/alternative;';
400             $content_type .= "\n" . ' boundary="' . $this->mime_boundary . '"';
401         } elseif($html == true && $text == false && $attach == false) {
402             // html only (or text too)
403             $content_type = 'text/html; charset="' . strtolower($this->mail_charset) . '"';
404             $htmlonly = true;
405         } elseif($html == true && $attach == true) {
406             // html and attachments
407             $content_type = 'multipart/mixed;';
408             $content_type .= "\n" . ' boundary="' . $this->mime_boundary . '"';
409         }
410         
411         $this->headers['Content-Type'] = $content_type;
412         
413         if($textonly == false && $htmlonly == false) {
414             $this->body = "This is a multi-part message in MIME format.\n\n";
415             
416             if($text) {
417                 $this->body .= "--{$this->mime_boundary}\n" .
418                               "Content-Type:text/plain; charset=\"" . strtolower($this->mail_charset) . "\"\n" .
419                               "Content-Transfer-Encoding: 7bit\n\n" . $this->text_part . "\n\n";
420             }
421             
422             if($html) {
423                 $this->body .= "--{$this->mime_boundary}\n" .
424                                "Content-Type:text/html; charset=\"" . strtolower($this->mail_charset) . "\"\n" . 
425                                "Content-Transfer-Encoding: 7bit\n\n" . $this->html_part . "\n\n";
426             }
427             
428             if($attach) {
429                 foreach($this->attachments as $att) {
430                     $this->body .= "--{$this->mime_boundary}\n" .
431                                    "Content-Type: " . $att['type'] . ";\n" .
432                                    " name=\"" . $att['filename'] . "\"\n" .
a00888 433                                    "Content-Transfer-Encoding: base64\n" . 
T 434                                    "Content-Disposition: attachment;\n\n" .
a59498 435                                    chunk_split(base64_encode($att['content'])) . "\n\n";
M 436                 }
437             }
438             $this->body .= "--{$this->mime_boundary}--\n";
439         } elseif($htmlonly == true) {
440             $this->body = $this->html_part;
441         } else {
442             $this->body = $this->text_part;
443         }
444         
445         if (isset($this->body)) {
446             // Add message ID header
d93be9 447             $message_id = sprintf('<%s.%s@%s>', base_convert(time(), 10, 36), base_convert(rand(), 10, 36), $this->smtp_helo != '' ? $this->smtp_helo : $this->detectHelo());
a59498 448             $this->headers['Message-ID'] = $message_id;
M 449             return true;
450         } else {
451             return false;
452         }
a00888 453     }
T 454     
455     /**
456      * Function to sign an email body
457      */
458     private function sign() {
459         if($this->sign_email == false || $this->sign_key == '' || $this->sign_cert == '') return false;
460         if(function_exists('openssl_pkcs7_sign') == false) return false;
461         
462         $tmpin = tempnam(sys_get_temp_dir(), 'sign');
463         $tmpout = tempnam(sys_get_temp_dir(), 'sign');
464         if(!file_exists($tmpin) || !is_writable($tmpin)) return false;
465         
466         file_put_contents($tmpin, 'Content-Type: ' . $this->getHeader('Content-Type') . "\n\n" . $this->body);
467         $tmpf_key = tempnam(sys_get_temp_dir(), 'sign');
468         file_put_contents($tmpf_key, $this->sign_key);
469         $tmpf_cert = tempnam(sys_get_temp_dir(), 'sign');
470         file_put_contents($tmpf_cert, $this->sign_cert);
471         if($this->sign_bundle != '')  {
472             $tmpf_bundle = tempnam(sys_get_temp_dir(), 'sign');
473             file_put_contents($tmpf_bundle, $this->sign_bundle);
474             openssl_pkcs7_sign($tmpin, $tmpout, 'file://' . realpath($tmpf_cert), array('file://' . realpath($tmpf_key), $this->sign_key_pass), array(), PKCS7_DETACHED, realpath($tmpf_bundle));
475         } else {
476             openssl_pkcs7_sign($tmpin, $tmpout, 'file://' . realpath($tmpf_cert), array('file://' . realpath($tmpf_key), $this->sign_key_pass), array());
477         }
478         unlink($tmpin);
479         unlink($tmpf_cert);
480         unlink($tmpf_key);
481         if(file_exists($tmpf_bundle)) unlink($tmpf_bundle);
482         
483         if(!file_exists($tmpout) || !is_readable($tmpout)) return false;
484         $this->body = file_get_contents($tmpout);
485         unlink($tmpout);
486         
487         unset($this->headers['Content-Type']);
488         unset($this->headers['MIME-Version']);
489         
490         $this->_is_signed = true;
a59498 491     }
M 492     
493     /**
494     * Function to encode a header if necessary
495     * according to RFC2047
496     * @access private
497     */
498     private function _encodeHeader($input, $charset = 'ISO-8859-1') {
499         preg_match_all('/(\s?\w*[\x80-\xFF]+\w*\s?)/', $input, $matches);
500         foreach ($matches[1] as $value) {
501             $replacement = preg_replace('/([\x20\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);
502             $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input);
503         }
504         
505         return $input;
506     }
507     
508     /**
509      * @access private
510      */
511     private function _smtp_login() {
512         $this->_smtp_conn = fsockopen(($this->smtp_crypt == 'ssl' ? 'ssl://' : '') . $this->smtp_host, $this->smtp_port, $errno, $errstr, 30);
513         $response = fgets($this->_smtp_conn, 515);
514         if(empty($this->_smtp_conn)) return false;
515         
516         // ENCRYPTED?
517         if($this->smtp_crypt == 'tls') {
518             fputs($this->_smtp_conn, 'STARTTLS' . $this->_crlf);
519             fgets($this->_smtp_conn, 515);
520             stream_socket_enable_crypto($this->_smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
521         }
522         
523         //Say Hello to SMTP
524         if($this->smtp_helo == '') $this->detectHelo();
525         fputs($this->_smtp_conn, 'HELO ' . $this->smtp_helo . $this->_crlf);
526         $response = fgets($this->_smtp_conn, 515);
527         
528         //AUTH LOGIN
529         fputs($this->_smtp_conn, 'AUTH LOGIN' . $this->_crlf);
530         $response = fgets($this->_smtp_conn, 515);
531         
532         //Send username
533         fputs($this->_smtp_conn, base64_encode($this->smtp_user) . $this->_crlf);
534         $response = fgets($this->_smtp_conn, 515);
535         
536         //Send password
537         fputs($this->_smtp_conn, base64_encode($this->smtp_pass) . $this->_crlf);
538         $response = fgets($this->_smtp_conn, 515);
539         
540         $this->_logged_in = true;
541         return true;
542     }
543     
544     /**
545      * @access private
546      */
547     private function _smtp_close() {
548         $this->_logged_in = false;
549         
550         if(empty($this->_smtp_conn)) {
551             return false;
552         }
553         
554         fputs($this->_smtp_conn, 'QUIT' . $this->_crlf);
555         $response = @fgets($this->_smtp_conn, 515);
556         return true;
557     }
558     
559     /**
560      * Send the mail to one or more recipients
561      *
562      * The recipients can be either a string (1 recipient email without name) or an associative array of recipients with names as keys and email addresses as values.
563      *
564      * @access public
565      * @param mixed $recipients one email address or array of recipients with names as keys and email addresses as values
566      */
567     public function send($recipients) {
568         if(!is_array($recipients)) $recipients = array($recipients);
569         
ecce33 570         if($this->use_smtp == true) $this->_crlf = "\r\n";
M 571         else $this->_crlf = "\n";
572         
a59498 573         $this->create();
a00888 574         if($this->sign_email == true) $this->sign();
a59498 575         
M 576         $subject = '';
577         if (!empty($this->headers['Subject'])) {
578             //$subject = $this->_encodeHeader($this->headers['Subject'], $this->mail_charset);
579             $subject = $this->headers['Subject'];
580             
581             $enc_subject = $this->_encodeHeader($subject, $this->mail_charset);
582             unset($this->headers['Subject']);
583         }
a00888 584         
T 585         if($this->notification == true) $this->setHeader('Disposition-Notification-To', $this->getHeader('From'));
a59498 586         
M 587         unset($this->headers['To']); // always reset the To header to prevent from sending to multiple users at once
588         $this->headers['Date'] = date('r'); //date('D, d M Y H:i:s O');
589
590         // Get flat representation of headers
591         foreach ($this->headers as $name => $value) {
d93be9 592             if(strtolower($name) == 'to' || strtolower($name) == 'cc' || strtolower($name) == 'bcc') continue; // never add the To header
a59498 593             $headers[] = $name . ': ' . $this->_encodeHeader($value, $this->mail_charset);
M 594         }
595         
596         if($this->use_smtp == true) {
597             if(!$this->_logged_in || !$this->_smtp_conn) {
598                 $result = $this->_smtp_login();
599                 if(!$result) return false;
600             }
601             foreach($recipients as $recipname => $recip) {
d93be9 602                 if($this->_sent_mails >= $this->smtp_max_mails) {
M 603                     // close connection to smtp and reconnect
604                     $this->_sent_mails = 0;
605                     $this->_smtp_close();
606                     $result = $this->_smtp_login();
607                     if(!$result) return false;
608                 }
609                 $this->_sent_mails += 1;
610                 
a59498 611                 $recipname = trim(str_replace('"', '', $recipname));
M 612                 $recip = $this->_encodeHeader($recip, $this->mail_charset);
613                 $recipname = $this->_encodeHeader($recipname, $this->mail_charset);
614                 
615                 //Email From
616                 fputs($this->_smtp_conn, 'MAIL FROM: ' . $this->_mail_sender . $this->_crlf);
617                 $response = fgets($this->_smtp_conn, 515);
618                 
619                 //Email To
620                 fputs($this->_smtp_conn, 'RCPT TO: ' . $recip . $this->_crlf);
621                 $response = fgets($this->_smtp_conn, 515);
622                 
623                 //The Email
624                 fputs($this->_smtp_conn, 'DATA' . $this->_crlf);
625                 $response = fgets($this->_smtp_conn, 515);
626                 
627                 //Construct Headers
628                 if($recipname && !is_numeric($recipname)) $this->setHeader('To', $recipname . ' <' . $recip . '>');
629                 else $this->setHeader('To', $recip);
630                 
ecce33 631                 $mail_content = 'Subject: ' . $enc_subject . $this->_crlf;
M 632                 $mail_content .= 'To: ' . $this->getHeader('To') . $this->_crlf;
d93be9 633                 if($this->getHeader('Bcc') != '') $mail_content .= 'Bcc: ' . $this->_encodeHeader($this->getHeader('Bcc'), $this->mail_charset) . $this->_crlf;
M 634                 if($this->getHeader('Cc') != '') $mail_content .= 'Cc: ' . $this->_encodeHeader($this->getHeader('Cc'), $this->mail_charset) . $this->_crlf;
a00888 635                 $mail_content .= implode($this->_crlf, $headers) . $this->_crlf . ($this->_is_signed == false ? $this->_crlf : '') . $this->body;
a59498 636                 
M 637                 fputs($this->_smtp_conn, $mail_content . $this->_crlf . '.' . $this->_crlf);
638                 $response = fgets($this->_smtp_conn, 515);
639                 
640                 // hopefully message was correctly sent now
641                 $result = true;
642             }
643         } else {
d93be9 644             if($this->getHeader('Bcc') != '') $headers[] = 'Bcc: ' . $this->_encodeHeader($this->getHeader('Bcc'), $this->mail_charset);
M 645             if($this->getHeader('Cc') != '') $headers[] = 'Cc: ' . $this->_encodeHeader($this->getHeader('Cc'), $this->mail_charset);
a59498 646             $rec_string = '';
M 647             foreach($recipients as $recipname => $recip) {
648                 $recipname = trim(str_replace('"', '', $recipname));
649                 
650                 if($rec_string != '') $rec_string .= ', ';
651                 if($recipname && !is_numeric($recipname)) $rec_string .= $recipname . '<' . $recip . '>';
652                 else $rec_string .= $recip;
653             }
654             $to = $this->_encodeHeader($rec_string, $this->mail_charset);
526b99 655             //$result = mail($to, $subject, $this->body, implode($this->_crlf, $headers));
T 656             $result = mail($to, $enc_subject, $this->body, implode($this->_crlf, $headers));
a59498 657         }
M 658         
659         // Reset the subject in case mail is resent
660         if ($subject !== '') {
661             $this->headers['Subject'] = $subject;
662         }
663         
664         // Return
665         return $result;
666     }
667     
668     /**
669      * Close mail connections
670      *
671      * This closes an open smtp connection so you should always call this function in your script if you have finished sending all emails
672      *
673      * @access public
674      */
675     public function finish() {
676         if($this->use_smtp == true) $this->_smtp_close();
b0191f 677         
M 678         $rand = md5(microtime());
679         $this->mime_boundary = '==Multipart_Boundary_x' . $rand . 'x';
680         
681         $this->headers = array();
682         $this->attachments = array();
683         $this->text_part = '';
684         $this->html_part = '';
685         
686         $this->headers['MIME-Version'] = '1.0';
a00888 687         $this->headers['User-Agent'] = $this->user_agent;
b0191f 688         
M 689         $this->smtp_helo = '';
690         $this->smtp_host = '';
691         $this->smtp_port = '';
692         $this->smtp_user = '';
693         $this->smtp_pass = '';
694         $this->use_smtp = false;
695         $this->smtp_crypt = false;
696         $this->mail_charset = 'UTF-8';
d93be9 697         $this->_sent_mails = 0;
a00888 698         
a59498 699         return;
M 700     }
701 }
702
703 ?>