* $mail = new ezcMailComposer(); * $mail->from = new ezcMailAddress( 'john@doe.com', 'John Doe' ); * $mail->addTo( new ezcMailAddress( 'cindy@doe.com', 'Cindy Doe' ) ); * $mail->subject = "Example of an HTML email with attachments"; * $mail->plainText = "Here is the text version of the mail. This is displayed if the client can not understand HTML"; * $mail->htmlText = "Here is the HTML version of your mail with an image: "; * $mail->addAttachment( 'path_to_attachment.file' ); * $mail->build(); * $transport = new ezcMailTransportMta(); * $transport->send( $mail ); * * * This class has the following properties: * - string plainText, contains the message of the mail in plain text. * - string htmlText, contains the message of the mail in HTML. You should * also provide the text of the HTML message in the * plainText property. Both will be sent and the receiver * will see the HTML message if his/her client supports HTML. * If the HTML message contains links to local images and/or * files these will be included into the mail when * generateBody is called. Links to local files must start * with "file://" in order to be recognized. * * * @todo What about character set for the textPart * @package Mail * @version 1.1.1 */ class ezcMailComposer extends ezcMail { /** * Holds the attachments. * * The array contains relative or absolute paths to the attachments. * * @var array(string) */ private $attachments = array(); /** * Holds the properties of this class. * * @var array(string=>mixed) */ private $properties = array(); /** * Constructs an empty ezcMailComposer object. */ public function __construct() { $this->properties['plainText'] = null; $this->properties['htmlText'] = null; parent::__construct(); } /** * Sets the property $name to $value. * * @throws ezcBasePropertyNotFoundException if the property does not exist. * @param string $name * @param mixed $value * @return void */ public function __set( $name, $value ) { switch ( $name ) { case 'plainText': $this->properties['plainText'] = $value; break; case 'htmlText': $this->properties['htmlText'] = $value; break; default: parent::__set( $name, $value ); break; } } /** * Returns the property $name. * * @throws ezcBasePropertyNotFoundException if the property does not exist. * @param string $name * @return mixed */ public function __get( $name ) { switch ( $name ) { case 'plainText': return $this->properties['plainText']; break; case 'htmlText': return $this->properties['htmlText']; break; default: return parent::__get( $name ); break; } } /** * Adds the file $fileName to the list of attachments. * * @throws ezcBaseFileNotFoundException if $fileName does not exists. * @throws ezcBaseFilePermissionProblem if $fileName could not be read. * @param string $fileName * @return void */ public function addAttachment( $fileName ) { if ( is_readable( $fileName ) ) { $this->attachments[] = $fileName; } else { if ( file_exists( $fileName ) ) { throw new ezcBaseFilePermissionException( $fileName, ezcBaseFileException::READ ); } else { throw new ezcBaseFileNotFoundException( $fileName ); } } } /** * Builds the complete email message in RFC822 format. * * This method must be called before the message is sent. * * @throws ezcBaseFileNotFoundException if any of the attachment files can not be found. * @return void */ public function build() { $mainPart = false; // create the text part if there is one if ( $this->plainText != '' ) { $mainPart = new ezcMailText( $this->plainText ); } // create the HTML part if there is one $htmlPart = false; if ( $this->htmlText != '' ) { $htmlPart = $this->generateHtmlPart(); // create a MultiPartAlternative if a text part exists if ( $mainPart != false ) { $mainPart = new ezcMailMultipartAlternative( $mainPart, $htmlPart ); } else { $mainPart = $htmlPart; } } // build all attachments // special case, mail with no text and one attachment if ( $mainPart == false && count( $this->attachments ) == 1 ) { $mainPart = new ezcMailFile( $this->attachments[0] ); } else if ( count( $this->attachments ) > 0 ) { $mainPart = ( $mainPart == false ) ? new ezcMailMultipartMixed() : new ezcMailMultipartMixed( $mainPart ); // add the attachments to the mixed part foreach ( $this->attachments as $attachment ) { $mainPart->appendPart( new ezcMailFile( $attachment ) ); } } $this->body = $mainPart; } /** * Returns an ezcMailPart based on the HTML provided. * * This method adds local files/images to the mail itself using a * {@link ezcMailMultipartRelated} object. * * @throws ezcMailException If an inline local file is not found or can't be read. * @return ezcMailPart */ private function generateHtmlPart() { $result = false; if ( $this->htmlText != '' ) { // recognize file:// and file:///, pick out the image, add it as a part and then..:) preg_match_all( "/file:\/\/[^ >\'\"]+/i", $this->htmlText, $matches ); // pictures/files can be added multiple times. We only need them once. $matches = array_unique( $matches[0] ); $result = new ezcMailText( $this->htmlText ); $result->subType = "html"; if ( count( $matches ) > 0 ) { $htmlPart = $result; // wrap already existing message in an alternative part $result = new ezcMailMultipartRelated( $result ); // create a filepart and add it to the related part // also store the ID for each part since we need those // when we replace the originals in the HTML message. foreach ( $matches as $fileName ) { if ( is_readable( $fileName ) ) { $filePart = new ezcMailFile( $fileName ); $cid = $result->addRelatedPart( $filePart ); // replace the original file reference with a reference to the cid $this->htmlText = str_replace( $fileName, 'cid:' . $cid, $this->htmlText ); } else { if ( file_exists( $fileName ) ) { throw new ezcBaseFilePermissionException( $fileName, ezcBaseFileException::READ ); } else { throw new ezcBaseFileNotFoundException( $fileName ); } // throw } } // update mail, with replaced url's $htmlPart->text = $this->htmlText; } } return $result; } } ?>