eZ Publish  [4.0]
ezmail.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // $Id: ezmail.php,v 1.44.2.7 2002/06/10 16:41:45 fh Exp $
00004 //
00005 // Definition of eZMail class
00006 //
00007 // Created on: <15-Mar-2001 20:40:06 fh>
00008 //
00009 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00010 // SOFTWARE NAME: eZ Publish
00011 // SOFTWARE RELEASE: 4.0.x
00012 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00013 // SOFTWARE LICENSE: GNU General Public License v2.0
00014 // NOTICE: >
00015 //   This program is free software; you can redistribute it and/or
00016 //   modify it under the terms of version 2.0  of the GNU General
00017 //   Public License as published by the Free Software Foundation.
00018 //
00019 //   This program is distributed in the hope that it will be useful,
00020 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 //   GNU General Public License for more details.
00023 //
00024 //   You should have received a copy of version 2.0 of the GNU General
00025 //   Public License along with this program; if not, write to the Free
00026 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00027 //   MA 02110-1301, USA.
00028 //
00029 //
00030 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00031 //
00032 
00033 /*! \defgroup eZUtils Utility classes */
00034 
00035 /*!
00036   \class eZMail ezmail.php
00037   \ingroup eZUtils
00038   \brief Mail handler
00039 
00040   Class for storing the details about en email and providing
00041   text serialization.
00042 
00043  \note It's important to note that most methods that return values do an automatic conversion if not specified.
00044 
00045 */
00046 
00047 //include_once( 'lib/ezi18n/classes/eztextcodec.php' );
00048 //include_once( 'lib/ezutils/classes/ezini.php' );
00049 
00050 class eZMail
00051 {
00052     const REGEXP = '(((\"[^\"\f\n\r\t\v\b]+\")|([A-Za-z0-9_\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[A-Za-z0-9_\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]{2,})))';
00053 
00054     /*!
00055       Constructs a new eZMail object.
00056     */
00057     function eZMail()
00058     {
00059         $this->ReceiverElements = array();
00060         $this->From = false;
00061         $this->CcElements = array();
00062         $this->BccElements = array();
00063         $this->ReplyTo = false;
00064         $this->Subject = false;
00065         $this->BodyText = false;
00066         $this->ExtraHeaders = array();
00067         $this->TextCodec = false;
00068         $this->MessageID = false;
00069 
00070         // Sets some default values
00071         //include_once( 'lib/version.php' );
00072         $version = eZPublishSDK::version();
00073 
00074         $this->MIMEVersion = '1.0';
00075         $this->ContentType = array( 'type' => 'text/plain',
00076                                     'charset' => eZTextCodec::internalCharset(),
00077                                     'transfer-encoding' => '8bit',
00078                                     'disposition' => 'inline',
00079                                     'boundary' => false );
00080         $this->UserAgent = "eZ Publish, Version $version";
00081 
00082         $ini = eZINI::instance();
00083 
00084         if ( $ini->hasVariable( 'MailSettings', 'ContentType' ) )
00085             $this->setContentType( $ini->variable( 'MailSettings', 'ContentType' ) );
00086     }
00087 
00088     /*!
00089       Returns the receiver addresses as text with only the email address.
00090     */
00091     function receiverEmailText( $convert = true )
00092     {
00093         return $this->composeEmailItems( $this->ReceiverElements, true, 'email', $convert );
00094     }
00095 
00096     /*!
00097       Returns the receiver addresses as text.
00098     */
00099     function receiverText( $convert = true )
00100     {
00101         return $this->composeEmailItems( $this->ReceiverElements, true, false, $convert );
00102     }
00103 
00104     /*!
00105       Returns the receiver cc addresses as an array with texts.
00106     */
00107     function ccReceiverTextList( $convert = true )
00108     {
00109         return $this->composeEmailItems( $this->CcElements, false, 'email', $convert );
00110     }
00111 
00112     function bccReceiverTextList( $convert = true )
00113     {
00114         return $this->composeEmailItems( $this->BccElements, false, 'email', $convert );
00115     }
00116 
00117     /*!
00118       Returns the receiver addresses as an array with texts.
00119     */
00120     function receiverTextList( $convert = true )
00121     {
00122         return $this->composeEmailItems( $this->ReceiverElements, false, 'email', $convert );
00123     }
00124 
00125     /*!
00126       Returns the receiver addresses.
00127     */
00128     function receiverElements()
00129     {
00130         return $this->ReceiverElements;
00131     }
00132 
00133     /*!
00134       Returns the addresses which should get a carbon copy.
00135      */
00136     function ccElements()
00137     {
00138         return $this->CcElements;
00139     }
00140 
00141     /*!
00142       Returns the addresses which should get a blind carbon copy.
00143      */
00144     function bccElements()
00145     {
00146         return $this->BccElements;
00147     }
00148 
00149 
00150     /*!
00151       Returns the receiver address.
00152     */
00153     function replyTo( $convert = true )
00154     {
00155         if ( !$convert )
00156             return $this->ReplyTo;
00157         return $this->convertHeaderText( $this->ReplyTo );
00158     }
00159 
00160     /*!
00161       Returns the sender address.
00162     */
00163     function sender( $convert = true )
00164     {
00165         if ( !$convert )
00166             return $this->From;
00167 
00168         if ( is_array( $this->From ) )
00169         {
00170             $convertedSender = $this->From;
00171             if ( $this->From['name'] )
00172             {
00173                 $convertedSender['name'] = $this->convertHeaderText( $this->From['name'] );
00174             }
00175             return $convertedSender;
00176         }
00177         else if ( is_string( $this->From ) )
00178         {
00179             return $this->convertHeaderText( $this->From );
00180         }
00181 
00182         return $this->From;
00183     }
00184 
00185     /*!
00186       Returns the sender address as text.
00187     */
00188     function senderText( $convert = true )
00189     {
00190         $text = eZMail::composeEmailName( $this->From );
00191         if ( !$convert )
00192             return $text;
00193         return $this->convertHeaderText( $text );
00194     }
00195 
00196     /*!
00197      \return the MIME version for this email, normally this is 1.0.
00198      \note The value is returned as a string.
00199     */
00200     function mimeVersion()
00201     {
00202         return $this->MIMEVersion;
00203     }
00204 
00205     /*!
00206      \return the content type for this email, this is normally text/plain.
00207     */
00208     function contentType()
00209     {
00210         return $this->ContentType['type'];
00211     }
00212 
00213     /*!
00214      \return the charset for this email, this is normally taken from the internal charset.
00215      \sa usedCharset
00216     */
00217     function contentCharset()
00218     {
00219         return $this->ContentType['charset'];
00220     }
00221 
00222     /*!
00223      \return the content transfer encoding, normally this is 8bit.
00224     */
00225     function contentTransferEncoding()
00226     {
00227         return $this->ContentType['transfer-encoding'];
00228     }
00229 
00230     /*!
00231      \return the content disposition, normally this is inline.
00232     */
00233     function contentDisposition()
00234     {
00235         return $this->ContentType['disposition'];
00236     }
00237 
00238     /*!
00239      \return the user agent for this email, the user agent is automatically created if not specfied.
00240     */
00241    function userAgent( $convert = true )
00242     {
00243         if ( !$convert )
00244             return $this->UserAgent;
00245         return $this->convertHeaderText( $this->UserAgent );
00246     }
00247 
00248     /*!
00249      Sets the MIME version to \a $version.
00250     */
00251     function setMIMEVersion( $version )
00252     {
00253         $this->MIMEVersion = $version;
00254     }
00255 
00256     /*!
00257      Sets the various content variables, any parameter which is set to something other than \c false
00258      will overwrite the old value.
00259     */
00260     function setContentType( $type = false, $charset = false,
00261                              $transferEncoding = false, $disposition = false, $boundary = false )
00262     {
00263         if ( $type )
00264             $this->ContentType['type'] = $type;
00265         if ( $charset )
00266             $this->ContentType['charset'] = $charset;
00267         if ( $transferEncoding )
00268             $this->ContentType['transfer-encoding'] = $transferEncoding;
00269         if ( $disposition )
00270             $this->ContentType['disposition'] = $disposition;
00271         if ( $boundary )
00272             $this->ContentType['boundary'] = $boundary;
00273     }
00274 
00275     /*!
00276      Sets the user agent for the email to \a $agent.
00277     */
00278     function setUserAgent( $agent )
00279     {
00280         $this->UserAgent = $agent;
00281     }
00282 
00283     /*!
00284       Sets the receiver addresses.
00285     */
00286     function setReceiverElements( $toElements )
00287     {
00288         $this->ReceiverElements = $toElements;
00289     }
00290 
00291     /*!
00292       Sets the receiver address.
00293       \note This will remove all other receivers
00294       \sa addReceiver, setReceiverElements
00295     */
00296     function setReceiver( $email, $name = false )
00297     {
00298         $this->ReceiverElements = array( array( 'name' => $name,
00299                                                 'email' => $email ) );
00300     }
00301 
00302     /*!
00303       Sets the receiver address, the email and name will be extracted from \a $text.
00304       \note This will remove all other receivers
00305       \sa addReceiver, setReceiverElements
00306     */
00307     function setReceiverText( $text )
00308     {
00309         $this->extractEmail( $text, $email, $name );
00310         $this->ReceiverElements = array( array( 'name' => $name,
00311                                                 'email' => $email ) );
00312     }
00313 
00314     /*!
00315       Adds a new receiver address.
00316     */
00317     function addReceiver( $email, $name = false )
00318     {
00319         $this->ReceiverElements[] = array( 'name' => $name,
00320                                            'email' => $email );
00321     }
00322 
00323 
00324     /*!
00325       Sets the receiver address.
00326     */
00327     function setReplyTo( $email, $name = false )
00328     {
00329         $this->ReplyTo = array( 'name' => $name,
00330                                 'email' => $email );
00331     }
00332 
00333     /*!
00334       Sets the sender address.
00335     */
00336     function setSender( $email, $name = false )
00337     {
00338         $this->From = array( 'name' => $name,
00339                              'email' => $email );
00340     }
00341 
00342     /*!
00343       Sets the sender address, the email and name will be extracted from \a $text.
00344     */
00345     function setSenderText( $text )
00346     {
00347         $this->extractEmail( $text, $email, $name );
00348         $this->From = array( 'name' => $name,
00349                              'email' => $email );
00350     }
00351 
00352     /*!
00353       Sets the cc addresses.
00354      */
00355     function setCcElements( $newCc )
00356     {
00357         $this->CcElements = $newCc;
00358     }
00359 
00360     /*!
00361       Adds a new Cc address.
00362     */
00363     function addCc( $email, $name = false )
00364     {
00365         $this->CcElements[] = array( 'name' => $name,
00366                                      'email' => $email );
00367     }
00368 
00369     /*!
00370       Sets the bcc addresses.
00371      */
00372     function setBccElements( $newBcc )
00373     {
00374         $this->BccElements = $newBcc;
00375     }
00376 
00377     /*!
00378       Adds a new Bcc address.
00379     */
00380     function addBcc( $email, $name = false )
00381     {
00382         $this->BccElements[] = array( 'name' => $name,
00383                                       'email' => $email );
00384     }
00385 
00386     /*!
00387      Return the extra headers
00388     */
00389     function extraHeaders()
00390     {
00391         return $this->ExtraHeaders;
00392     }
00393 
00394     /*!
00395      Adds the headers \a $headerName with header value \a $headerValue to the extra headers.
00396     */
00397     function addExtraHeader( $headerName, $headerValue )
00398     {
00399         return $this->ExtraHeaders[] = array( 'name' => $headerName,
00400                                               'content' => $headerValue );
00401     }
00402 
00403     /*!
00404      Similar to addExtraHeader() but will overwrite existing entries.
00405     */
00406     function setExtraHeader( $headerName, $headerValue )
00407     {
00408         for ( $i = 0; $i < count( $this->ExtraHeaders ); ++$i )
00409         {
00410             $extraHeader =& $this->ExtraHeaders[$i];
00411             if ( isset( $extraHeader['name'] ) and
00412                  $extraHeader['name'] == $headerName )
00413             {
00414                 $extraHeader = array( 'name' => $headerName,
00415                                       'content' => $headerValue );
00416                 return true;
00417             }
00418         }
00419         $this->addExtraHeader( $headerName, $headerValue );
00420     }
00421 
00422     /*!
00423      Sets the extra headers to \a $headers.
00424     */
00425     function setExtraHeaders( $headers )
00426     {
00427         return $this->ExtraHeaders = $headers;
00428     }
00429 
00430     /*!
00431       Returns the message ID format : <number@serverID>
00432       Read in the RFC's if you want to know more about it..
00433      */
00434     function messageID()
00435     {
00436         return $this->MessageID;
00437     }
00438 
00439     /*!
00440       Sets the message ID. This is a server setting only so BE CAREFUL WITH THIS.
00441     */
00442     function setMessageID( $newMessageID )
00443     {
00444         $this->MessageID = $newMessageID;
00445     }
00446 
00447     /*!
00448       Returns the messageID that this message is a reply to.
00449     */
00450     function references()
00451     {
00452         return $this->References;
00453     }
00454 
00455     /*!
00456       Sets the messageID that this message is a reply to.
00457     */
00458     function setReferences( $newReference )
00459     {
00460         $this->References = $newReference;
00461     }
00462 
00463     /*!
00464       Returns the subject.
00465     */
00466     function subject( $convert = true )
00467     {
00468         if ( !$convert )
00469             return $this->Subject;
00470         return $this->convertHeaderText( $this->Subject );
00471     }
00472 
00473     /*!
00474       Sets the subject of the mail.
00475     */
00476     function setSubject( $newSubject )
00477     {
00478         $this->Subject = trim( $newSubject );
00479     }
00480 
00481     /*!
00482       returns the body.
00483     */
00484     function body( $convert = true )
00485     {
00486         if ( !$convert )
00487             return $this->BodyText;
00488         return $this->convertText( $this->BodyText );
00489     }
00490 
00491     /*!
00492       Sets the body.
00493     */
00494     function setBody( $newBody )
00495     {
00496         $newBody = preg_replace( "/\r\n|\r|\n/", eZMail::lineSeparator(), $newBody );
00497         $this->BodyText = $newBody;
00498     }
00499 
00500     /*!
00501       \static
00502       Splits a list of email addresses into an array where each entry is an email address.
00503     */
00504     static function &splitList( $emails )
00505     {
00506         $emails = preg_split( "/[,;]/", $emails );
00507         return $emails;
00508     }
00509 
00510     /*!
00511       \static
00512       Static function for validating e-mail addresses.
00513 
00514       Returns true if successful, false if not.
00515     */
00516     static function validate( $address )
00517     {
00518         return preg_match( '/^' . eZMail::REGEXP . '$/', $address );
00519     }
00520 
00521     static function extractEmail( $text, &$email, &$name )
00522     {
00523         if ( preg_match( "/([^<]+)<" . eZMail::REGEXP . ">/", $text, $matches ) )
00524         {
00525             $email = $matches[2];
00526             $name = trim( $matches[1], '" ' );
00527         }
00528         else
00529         {
00530             $email = $text;
00531             $name = false;
00532         }
00533     }
00534 
00535     /*!
00536       \static
00537       Static function for extracting an e-mail from text
00538 
00539       Returns the first valid e-mail in address, returns false if no e-mail addresses found
00540     */
00541     static function stripEmail( $address )
00542     {
00543         $res = preg_match( "/" . eZMail::REGEXP . "/", $address, $email );
00544 
00545         if ( $res )
00546             return $email[0];
00547         else
00548             return 0;
00549     }
00550 
00551     /*!
00552      \static
00553      \returns a text which does not contain newlines, newlines are converted to spaces.
00554     */
00555     static function blankNewlines( $text )
00556     {
00557         return preg_replace( "/\r\n|\r|\n/", ' ', $text );
00558     }
00559 
00560     /*!
00561      \static
00562      \returns the header content as a simple string, will deflate arrays.
00563      \sa blankNewLines
00564     */
00565     static function contentString( $content )
00566     {
00567         if ( is_array( $content ) )
00568             return implode( '; ', $content );
00569         else
00570             return (string)$content;
00571     }
00572 
00573     /*!
00574      Composes a text out of the email and name and returns it.
00575 
00576      Example: John Doe <john@doe.com> or just john@doe.com
00577     */
00578     function composeEmailName( $item, $key = false, $convert = true )
00579     {
00580         if ( $key !== false and
00581              isset( $item[$key] ) )
00582             return $item[$key];
00583         if ( $item['name'] )
00584         {
00585             if ( $convert )
00586                 $item['name'] = $this->convertHeaderText( $item['name'] );
00587             $text = $item['name'] . ' <' . $item['email'] . '>';
00588         }
00589         else
00590             $text = $item['email'];
00591         return $text;
00592     }
00593 
00594     /*!
00595      Composes an email text out of all items in \a $items and returns it.
00596      All items are comma separated.
00597     */
00598     function composeEmailItems( $items, $join = true, $key = false, $convert = true )
00599     {
00600         $textElements = array();
00601         foreach ( $items as $item )
00602         {
00603             $textElements[] = eZMail::composeEmailName( $item, $key, $convert );
00604         }
00605 
00606         if ( $join )
00607             $text = implode( ', ', $textElements );
00608         else
00609             $text = $textElements;
00610 
00611         return $text;
00612     }
00613 
00614     /*!
00615      \return an array with headers, each header item is an associative array with the keys \c name and \c content.
00616              \c content will either be a string or an array with strings.
00617 
00618      The parameter \a $parameters contains optional parameters, they can be:
00619      - exclude-headers - \c Array of header names which will not be included in the result array.
00620      \sa contentString, blankNewLines
00621     */
00622     function headers( $parameters = array() )
00623     {
00624         $parameters = array_merge( array( 'exclude-headers' => false ),
00625                                    $parameters );
00626         $excludeHeaders = array();
00627         if ( $parameters['exclude-headers'] )
00628         {
00629             foreach ( $parameters['exclude-headers'] as $excludeHeader )
00630             {
00631                 $excludeHeaders[] = strtolower( $excludeHeader );
00632             }
00633         }
00634         $headers = array();
00635         $headerNames = array();
00636         if ( !in_array( 'to', $excludeHeaders ) )
00637         {
00638             $toHeaderContent = count( $this->ReceiverElements ) > 0 ? $this->composeEmailItems( $this->ReceiverElements ) : 'undisclosed-recipients:;';
00639             $headers[] = array( 'name' => 'To',
00640                                 'content' => $toHeaderContent );
00641             $headerNames[] = 'to';
00642         }
00643         if ( !in_array( 'date', $excludeHeaders ) )
00644         {
00645             $headers[] = array( 'name' => 'Date',
00646                                 'content' => date( 'r' ) );
00647             $headerNames[] = 'date';
00648         }
00649         if ( $this->Subject !== false and
00650              !in_array( 'subject', $excludeHeaders ) )
00651         {
00652             $headers[] = array( 'name' => 'Subject',
00653                                 'content' => $this->subject() );
00654             $headerNames[] = 'subject';
00655         }
00656         if ( $this->From !== false and
00657              !in_array( 'from', $excludeHeaders ) )
00658         {
00659             $headers[] = array( 'name' => 'From',
00660                                 'content' => $this->composeEmailName( $this->From ) );
00661             $headerNames[] = 'from';
00662         }
00663         if ( count( $this->CcElements ) > 0 and
00664              !in_array( 'cc', $excludeHeaders ) )
00665         {
00666             $headers[] = array( 'name' => 'Cc',
00667                                 'content' => $this->composeEmailItems( $this->CcElements ) );
00668             $headerNames[] = 'cc';
00669         }
00670         if ( count( $this->BccElements ) > 0 and
00671              !in_array( 'bcc', $excludeHeaders ) )
00672         {
00673             $headers[] = array( 'name' => 'Bcc',
00674                                 'content' => $this->composeEmailItems( $this->BccElements ) );
00675             $headerNames[] = 'bcc';
00676         }
00677         if ( $this->ReplyTo !== false and
00678              !in_array( 'reply-to', $excludeHeaders ) )
00679         {
00680             $headers[] = array( 'name' => 'Reply-To',
00681                                 'content' => $this->composeEmailName( $this->ReplyTo ) );
00682             $headerNames[] = 'reply-to';
00683         }
00684         if ( !in_array( 'mime-version', $excludeHeaders ) )
00685         {
00686             $headers[] = array( 'name' => 'MIME-Version',
00687                                 'content' => $this->MIMEVersion );
00688             $headerNames[] = 'mime-version';
00689         }
00690         if ( !in_array( 'content-type', $excludeHeaders ) )
00691         {
00692             $charset = $this->usedCharset();
00693             if ( $this->ContentType['boundary'] )
00694             {
00695             $headers[] = array( 'name' => 'Content-Type',
00696                                 'content' => array( $this->ContentType['type'], 'charset='. $charset, 'boundary="'. $this->ContentType['boundary'] . '"' ) );
00697             }
00698             else
00699             {
00700                 $headers[] = array( 'name' => 'Content-Type',
00701                                     'content' => array( $this->ContentType['type'], 'charset='. $charset ) );
00702             }
00703             $headerNames[] = 'content-type';
00704         }
00705         if ( !in_array( 'content-transfer-encoding', $excludeHeaders ) )
00706         {
00707             $headers[] = array( 'name' => 'Content-Transfer-Encoding',
00708                                 'content' => $this->ContentType['transfer-encoding'] );
00709             $headerNames[] = 'content-transfer-encoding';
00710         }
00711         if ( !in_array( 'content-disposition', $excludeHeaders ) )
00712         {
00713             $headers[] = array( 'name' => 'Content-Disposition',
00714                                 'content' => $this->ContentType['disposition'] );
00715             $headerNames[] = 'content-disposition';
00716         }
00717         if ( !in_array( 'user-agent', $excludeHeaders ) )
00718         {
00719             $headers[] = array( 'name' => 'User-Agent',
00720                                 'content' => $this->UserAgent );
00721             $headerNames[] = 'user-agent';
00722         }
00723         if ( !in_array( 'message-id', $excludeHeaders ) )
00724         {
00725             if ( $this->MessageID )
00726             {
00727                 $headers[] = array( 'name' => 'Message-Id',
00728                                     'content' => $this->MessageID );
00729                 $headerNames[] = 'message-id';
00730             }
00731         }
00732 
00733         $extraHeaders = $this->ExtraHeaders;
00734         foreach ( $extraHeaders as $extraHeader )
00735         {
00736             if ( !in_array( strtolower( $extraHeader['name'] ), $excludeHeaders ) and
00737                  !in_array( strtolower( $extraHeader['name'] ), $headerNames ) )
00738                 $headers[] = $extraHeader;
00739         }
00740         return $headers;
00741     }
00742 
00743     /*!
00744      Extracts all headers and generates a text string out of it.
00745      The parameter \a $parameters will be passed to the headers() function.
00746     */
00747     function headerTextList( $parameters = array() )
00748     {
00749         $convert = true;
00750         if ( isset( $parameters['convert'] ) )
00751             $convert = $parameters['convert'];
00752         $textElements = array();
00753         $headers = $this->headers( $parameters );
00754         foreach ( $headers as $header )
00755         {
00756             $headerText = $this->blankNewlines( $header['name'] ) . ': ';
00757             $contentText = $this->blankNewlines( $this->contentString( $header['content'] ) );
00758             $headerText .= $contentText;
00759             $textElements[] = $headerText;
00760         }
00761         return $textElements;
00762     }
00763 
00764     /*!
00765      Composes a text field out of all the headers and returns it.
00766      The parameter \a $parameters will be passed to the headers() function.
00767     */
00768     function headerText( $parameters = array() )
00769     {
00770         $convert = true;
00771         if ( isset( $parameters['convert'] ) )
00772             $convert = $parameters['convert'];
00773         $text = '';
00774         $headers = $this->headers( $parameters );
00775         $headerCount = 0;
00776         foreach ( $headers as $header )
00777         {
00778             if ( $headerCount++ > 0 )
00779                 $text .= eZMail::lineSeparator();
00780             $text .= $this->blankNewlines( $header['name'] ) . ': ';
00781             $contentText = $this->blankNewlines( $this->contentString( $header['content'] ) );
00782             $text .= $contentText;
00783         }
00784         return $text;
00785     }
00786 
00787     /*!
00788      Calls convertText with \a $isHeader set to \c true.
00789     */
00790     function convertHeaderText( $text )
00791     {
00792         $charset = $this->contentCharset();
00793         if ( $charset != 'us-ascii' )
00794         {
00795             $newText = $this->encodeMimeHeader( $text );
00796             return $newText;
00797         }
00798         return $text;
00799     }
00800 
00801     /*!
00802       Encodes $str using mb_encode_mimeheader() if it is aviable, or does base64 encodin of a header if not.
00803      */
00804     function encodeMimeHeader( $str )
00805     {
00806         if ( !$this->TextCodec )
00807         {
00808              $this->TextCodec = eZTextCodec::instance( $this->contentCharset(), $this->outputCharset() );
00809         }
00810 
00811         if ( function_exists( "mb_encode_mimeheader" ) )
00812         {
00813             $encoded = mb_encode_mimeheader( $str, $this->TextCodec->InputCharsetCode, "B", eZMail::lineSeparator() );
00814         }
00815         else
00816         {
00817             if (  0 == preg_match_all( '/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches ) )
00818                 return $str;
00819 
00820             $maxlen = 75 - 7 - strlen( $this->TextCodec->InputCharsetCode );
00821 
00822             $encoding = 'B';
00823             $encoded = base64_encode( $str );
00824             $maxlen -= $maxlen % 4;
00825             $encoded = trim( chunk_split( $encoded, $maxlen, "\n" ) );
00826 
00827             $encoded = preg_replace( '/^(.*)$/m', " =?".$this->TextCodec->InputCharsetCode."?$encoding?\\1?=", $encoded );
00828 
00829             $encoded = trim( str_replace( "\n", eZMail::lineSeparator(), $encoded ) );
00830         }
00831 
00832         return $encoded;
00833     }
00834 
00835 
00836     /*!
00837      Converts the text \a $text to a suitable output format.
00838      \note Header conversion is not supported yet, for now it will only return original text when \a $isHeader is set to \c true.
00839     */
00840     function convertText( $text, $isHeader = false )
00841     {
00842 
00843         $charset = $this->contentCharset();
00844         if ( $this->isAllowedCharset( $charset ) )
00845             return $text;
00846         $outputCharset = $this->outputCharset();
00847         if ( !$this->TextCodec )
00848         {
00849             $this->TextCodec = eZTextCodec::instance( $charset, $outputCharset );
00850         }
00851         $newText = $this->TextCodec->convertString( $text );
00852         return $newText;
00853     }
00854 
00855     /*!
00856      \return \c true if the charset \a $charset is allowed as output charset.
00857      \sa allowedCharsets.
00858     */
00859     function isAllowedCharset( $charset )
00860     {
00861         //include_once( 'lib/ezi18n/classes/ezcharsetinfo.php' );
00862         $realCharset = eZCharsetInfo::realCharsetCode( $charset );
00863         $charsets = $this->allowedCharsets();
00864         foreach ( $charsets as $charsetName )
00865         {
00866             $realName = eZCharsetInfo::realCharsetCode( $charsetName );
00867             if ( $realName == $realCharset )
00868                 return true;
00869         }
00870         return false;
00871     }
00872 
00873     /*!
00874      \return an array with charsets that can be used directly as output charsets.
00875     */
00876     function allowedCharsets()
00877     {
00878         $ini = eZINI::instance();
00879         $charsets = $ini->variable( 'MailSettings', 'AllowedCharsets' );
00880         return $charsets;
00881     }
00882 
00883     /*!
00884      \return the charset which will be used for output.
00885     */
00886     function usedCharset()
00887     {
00888         $charset = $this->contentCharset();
00889         if ( $this->isAllowedCharset( $charset ) )
00890             return $charset;
00891         return $this->outputCharset();
00892     }
00893 
00894     /*!
00895      \return the default output charset.
00896     */
00897     function outputCharset()
00898     {
00899         $ini = eZINI::instance();
00900         $outputCharset = $ini->variable( 'MailSettings', 'OutputCharset' );
00901         return $outputCharset;
00902     }
00903 
00904     static function lineSeparator()
00905     {
00906         $ini = eZINI::instance( 'site.ini' );
00907         $ending = $ini->variable( 'MailSettings', 'HeaderLineEnding' );
00908         if ( $ending == 'auto' )
00909         {
00910             $sys = eZSys::instance();
00911             // For windows we use \r\n which is the endline defined in RFC 2045
00912             if ( $sys->osType() == 'win32' )
00913             {
00914                 $separator = "\r\n";
00915             }
00916             else // for linux/unix/mac we use \n only due to some mail transfer agents destroying
00917                  // emails containing \r\n
00918             {
00919                 $separator = "\n";
00920             }
00921         }
00922         else
00923         {
00924             $separator = urldecode( $ending );
00925         }
00926 
00927         return $separator;
00928     }
00929 
00930 /*
00931 //        $subj = "=?$iso?B?" . trim( chunk_split( base64_encode( $subj ))) . "?=";
00932 */
00933 
00934     /// \privatesection
00935     public $ReceiverElements;
00936     public $From;
00937     public $CcElements;
00938     public $BccElements;
00939     public $ContentType;
00940     public $UserAgent;
00941     public $ReplyTo;
00942     public $Subject;
00943     public $BodyText;
00944     public $ExtraHeaders;
00945     public $TextCodec;
00946     public $MessageID;
00947 }
00948 
00949 ?>