<?php
/**
 * File containing the ezcMailComposer class
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @package Mail
 * @version //autogen//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * Convenience class for writing mail.
 *
 * This class allows you to create
 * text and/or HTML mail with attachments. If you need to create more
 * advanced mail use the ezcMail class and build the body from scratch.
 *
 * ezcMailComposer is used with the following steps:
 * 1. Create a composer object.
 * 2. Set the subject and recipients.
 * 3. Set the plainText and htmlText message parts. You can set only one
 *    or both. If you set both, the client will display the htmlText if it
 *    supports HTML. Otherwise the client will display plainText.
 * 4. Add any attachments (addFileAttachment() or addStringAttachment()).
 * 5. Call the build method.
 *
 * This example shows how to send an HTML mail with a text fallback and
 * attachments. The HTML message has an inline image.
 * <code>
 * $mail = new ezcMailComposer();
 * $mail->from = new ezcMailAddress( 'john@example.com', 'John Doe' );
 * $mail->addTo( new ezcMailAddress( 'cindy@example.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 = "<html>Here is the HTML version of your mail with an image: <img src='file://path_to_image.jpg' /></html>";
 * $mail->addFileAttachment( 'path_to_attachment.file' );
 * $mail->build();
 * $transport = new ezcMailMtaTransport();
 * $transport->send( $mail );
 * </code>
 *
 * By default, if the htmlText property contains an HTML image tag with file://
 * in href, that file will be included in the created message.
 *
 * Example:
 * <code>
 * <img src="file:///home/me/image.jpg" />
 * </code>
 *
 * This can be a security risk if a user links to another file, for example logs
 * or password files. With the automaticImageInclude option (default value true)
 * from {@link ezcMailComposerOptions}, the automatic inclusion of files can be
 * turned off.
 *
 * Example:
 * <code>
 * $options = new ezcMailComposerOptions();
 * $options->automaticImageInclude = false; // default value is true
 *
 * $mail = new ezcMailComposer( $options );
 *
 * // ... add To, From, Subject, etc to $mail
 * $mail->htmlText = "<html>Here is the image: <img src="file:///etc/passwd" /></html>";
 *
 * // ... send $mail
 * </code>
 *
 * After running the above code, the sent mail will not contain the file specified
 * in the htmlText property.
 *
 * The file name in the attachment can be different than the file name on disk, by
 * passing an {@link ezcMailContentDispositionHeader} object to the function
 * addFileAttachment(). Example:
 * <code>
 * $mail = new ezcMailComposer();
 * $mail->from = new ezcMailAddress( 'john@example.com', 'John Doe' );
 * $mail->addTo( new ezcMailAddress( 'cindy@example.com', 'Cindy Doe' ) );
 * $mail->subject = "Example of an HTML email with attachments and custom attachment file name";
 * $mail->plainText = "Here is the text version of the mail. This is displayed if the client can not understand HTML";
 * $mail->htmlText = "<html>Here is the HTML version of your mail with an image: <img src='file://path_to_image.jpg' /></html>";
 *
 * $disposition = new ezcMailContentDispositionHeader();
 * $disposition->fileName = 'custom name for attachment.txt';
 * $disposition->fileNameCharSet = 'utf-8'; // if using non-ascii characters in the file name
 * $disposition->disposition = 'attachment'; // default value is 'inline'
 *
 * $mail->addFileAttachment( 'path_to_attachment.file', null, null, $disposition );
 * $mail->build();
 *
 * $transport = new ezcMailMtaTransport();
 * $transport->send( $mail );
 * </code>
 *
 * Use the function addStringAttachment() if you want to add an attachment which
 * is stored in a string variable. A file name for a string attachment needs to
 * be specified as well. Example:
 *
 * <code>
 * $contents = 'contents for mail attachment'; // can be a binary string, eg. image file contents
 * $mail->addStringAttachment( 'filename', $contents );
 * </code>
 *
 * @property string $plainText
 *           Contains the message of the mail in plain text.
 * @property 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. You can use the option
 *           automaticImageInclude (default value is true) from
 *           {@link ezcMailComposerOptions} to turn off the
 *           automatic inclusion of files in the generated mail.
 * @property string $charset
 *           Contains the character set for both $plainText and $htmlText.
 *           Default value is 'us-ascii'. This does not set any specific
 *           charset for the subject, you need the subjectCharset property for
 *           that.
 * @property string $encoding
 *           Contains the encoding for both $plainText and $htmlText.
 *           Default value is ezcMail::EIGHT_BIT. Other values are found
 *           as constants in the class {@link ezcMail}.
 * @property ezcMailComposerOptions $options
 *           Options for composing mail. See {@link ezcMailComposerOptions}.
 *
 * @package Mail
 * @version //autogen//
 * @mainclass
 */
class ezcMailComposer extends ezcMail
{
    /**
     * Holds the attachments filenames.
     *
     * The array contains relative or absolute paths to the attachments.
     *
     * @var array(string)
     */
    private $attachments = array();

    /**
     * Holds the options for this class.
     *
     * @var ezcMailComposerOptions
     */
    protected $options;

    /**
     * Constructs an empty ezcMailComposer object.
     *
     * @param ezcMailComposerOptions $options
     */
    public function __construct( ezcMailComposerOptions $options = null )
    {
        $this->properties['plainText'] = null;
        $this->properties['htmlText'] = null;
        $this->properties['charset'] = 'us-ascii';
        $this->properties['encoding'] = ezcMail::EIGHT_BIT;
        if ( $options === null )
        {
            $options = new ezcMailComposerOptions();
        }

        $this->options = $options;

        parent::__construct( $options );
    }

    /**
     * Sets the property $name to $value.
     *
     * @throws ezcBasePropertyNotFoundException
     *         if the property does not exist.
     * @param string $name
     * @param mixed $value
     * @ignore
     */
    public function __set( $name, $value )
    {
        switch ( $name )
        {
            case 'plainText':
            case 'htmlText':
            case 'charset':
            case 'encoding':
                $this->properties[$name] = $value;
                break;

            case 'options':
                if ( !$value instanceof ezcMailComposerOptions )
                {
                    throw new ezcBaseValueException( $name, $value, 'ezcMailComposerOptions' );
                }

                $this->options = $value;
                break;

            default:
                parent::__set( $name, $value );
        }
    }

    /**
     * Returns the property $name.
     *
     * @throws ezcBasePropertyNotFoundException
     *         if the property does not exist.
     * @param string $name
     * @return mixed
     * @ignore
     */
    public function __get( $name )
    {
        switch ( $name )
        {
            case 'plainText':
            case 'htmlText':
            case 'charset':
            case 'encoding':
                return $this->properties[$name];

            case 'options':
                return $this->options;

            default:
                return parent::__get( $name );
        }
    }

    /**
     * Returns true if the property $name is set, otherwise false.
     *
     * @param string $name
     * @return bool
     * @ignore
     */
    public function __isset( $name )
    {
        switch ( $name )
        {
            case 'plainText':
            case 'htmlText':
            case 'charset':
            case 'encoding':
                return isset( $this->properties[$name] );

            case 'options':
                return isset( $this->options );

            default:
                return parent::__isset( $name );
        }
    }

    /**
     * Adds the file $fileName to the list of attachments.
     *
     * If $content is specified, $fileName is not checked if it exists.
     * $this->attachments will also contain in this case the $content,
     * $contentType and $mimeType.
     *
     * The $contentType (default = application) and $mimeType (default =
     * octet-stream) control the complete mime-type of the attachment.
     *
     * If $contentDisposition is specified, the attached file will have its
     * Content-Disposition header set according to the $contentDisposition
     * object and the filename of the attachment in the generated mail will be
     * the one from the $contentDisposition object.
     * 
     * @throws ezcBaseFileNotFoundException
     *         if $fileName does not exists.
     * @throws ezcBaseFilePermissionProblem
     *         if $fileName could not be read.
     * @param string $fileName
     * @param string $content
     * @param string $contentType
     * @param string $mimeType
     * @param ezcMailContentDispositionHeader $contentDisposition
     * @apichange This function might be removed in a future iteration of
     *            the Mail component. Use addFileAttachment() and
     *            addStringAttachment() instead.
     */
    public function addAttachment( $fileName, $content = null, $contentType = null, $mimeType = null, ezcMailContentDispositionHeader $contentDisposition = null )
    {
        if ( is_null( $content ) )
        {
            $this->addFileAttachment( $fileName, $contentType, $mimeType, $contentDisposition );
        }
        else
        {
            $this->addStringAttachment( $fileName, $content, $contentType, $mimeType, $contentDisposition );
        }
    }

    /**
     * Adds the file $fileName to the list of attachments.
     *
     * The $contentType (default = application) and $mimeType (default =
     * octet-stream) control the complete mime-type of the attachment.
     *
     * If $contentDisposition is specified, the attached file will have its
     * Content-Disposition header set according to the $contentDisposition
     * object and the filename of the attachment in the generated mail will be
     * the one from the $contentDisposition object.
     * 
     * @throws ezcBaseFileNotFoundException
     *         if $fileName does not exists.
     * @throws ezcBaseFilePermissionProblem
     *         if $fileName could not be read.
     * @param string $fileName
     * @param string $contentType
     * @param string $mimeType
     * @param ezcMailContentDispositionHeader $contentDisposition
     */
    public function addFileAttachment( $fileName, $contentType = null, $mimeType = null, ezcMailContentDispositionHeader $contentDisposition = null )
    {
        if ( is_readable( $fileName ) )
        {
            $this->attachments[] = array( $fileName, null, $contentType, $mimeType, $contentDisposition );
        }
        else
        {
            if ( file_exists( $fileName ) )
            {
                throw new ezcBaseFilePermissionException( $fileName, ezcBaseFileException::READ );
            }
            else
            {
                throw new ezcBaseFileNotFoundException( $fileName );
            }
        }
    }

    /**
     * Adds the file $fileName to the list of attachments, with contents $content.
     *
     * The file $fileName is not checked if it exists. An attachment is added
     * to the mail, with the name $fileName, and the contents $content.
     *
     * The $contentType (default = application) and $mimeType (default =
     * octet-stream) control the complete mime-type of the attachment.
     *
     * If $contentDisposition is specified, the attached file will have its
     * Content-Disposition header set according to the $contentDisposition
     * object and the filename of the attachment in the generated mail will be
     * the one from the $contentDisposition object.
     * 
     * @param string $fileName
     * @param string $content
     * @param string $contentType
     * @param string $mimeType
     * @param ezcMailContentDispositionHeader $contentDisposition
     */
    public function addStringAttachment( $fileName, $content, $contentType = null, $mimeType = null, ezcMailContentDispositionHeader $contentDisposition = null )
    {
        $this->attachments[] = array( $fileName, $content, $contentType, $mimeType, $contentDisposition );
    }

    /**
     * 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.
     */
    public function build()
    {
        $mainPart = false;

        // create the text part if there is one
        if ( $this->plainText != '' )
        {
            $mainPart = new ezcMailText( $this->plainText, $this->charset );
        }

        // 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.
        // A fix for issue #14220 was added by wrapping the attachment in
        // an ezcMailMultipartMixed part
        if ( $mainPart == false && count( $this->attachments ) == 1 )
        {
            if ( isset( $this->attachments[0][1] ) )
            {
                if ( is_resource( $this->attachments[0][1] ) )
                {
                    $mainPart = new ezcMailMultipartMixed( new ezcMailStreamFile( $this->attachments[0][0], $this->attachments[0][1], $this->attachments[0][2], $this->attachments[0][3] ) );
                }
                else
                {
                    $mainPart = new ezcMailMultipartMixed( new ezcMailVirtualFile( $this->attachments[0][0], $this->attachments[0][1], $this->attachments[0][2], $this->attachments[0][3] ) );
                }
            }
            else
            {
                $mainPart = new ezcMailMultipartMixed( new ezcMailFile( $this->attachments[0][0], $this->attachments[0][2], $this->attachments[0][3] ) );
            }
            $mainPart->contentDisposition = $this->attachments[0][4];
        }
        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 )
            {
                if ( isset( $attachment[1] ) )
                {
                    if ( is_resource( $attachment[1] ) )
                    {
                        $part = new ezcMailStreamFile( $attachment[0], $attachment[1], $attachment[2], $attachment[3] );
                    }
                    else
                    {
                        $part = new ezcMailVirtualFile( $attachment[0], $attachment[1], $attachment[2], $attachment[3] );
                    }
                }
                else
                {
                    $part = new ezcMailFile( $attachment[0], $attachment[2], $attachment[3] );
                }
                $part->contentDisposition = $attachment[4];
                $mainPart->appendPart( $part );
            }
        }

        $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 ezcBaseFileNotFoundException
     *         if $fileName does not exists.
     * @throws ezcBaseFilePermissionProblem
     *         if $fileName could not be read.
     * @return ezcMailPart
     */
    private function generateHtmlPart()
    {
        $result = false;
        if ( $this->htmlText != '' )
        {
            $matches = array();
            if ( $this->options->automaticImageInclude === true )
            {
                // recognize file:// and file:///, pick out the image, add it as a part and then..:)
                preg_match_all( '(
                    <img \\s+[^>]*
                        src\\s*=\\s*
                            (?:
                                (?# Match quoted attribute)
                                ([\'"])file://(?P<quoted>[^>]+)\\1

                                (?# Match unquoted attribute, which may not contain spaces)
                            |   file://(?P<unquoted>[^>\\s]+)
                        )
                    [^>]* >)ix', $this->htmlText, $matches );
                // pictures/files can be added multiple times. We only need them once.
                $matches = array_filter( array_unique( array_merge( $matches['quoted'], $matches['unquoted'] ) ) );
            }

            $result = new ezcMailText( $this->htmlText, $this->charset, $this->encoding );
            $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 ) )
                    {
                        // @todo waiting for fix of the fileinfo extension
                        // $contents = file_get_contents( $fileName );
                        $mimeType = null;
                        $contentType = null;
                        if ( ezcBaseFeatures::hasExtensionSupport( 'fileinfo' ) )
                        {
                            // if fileinfo extension is available
                            $filePart = new ezcMailFile( $fileName );
                        }
                        elseif ( ezcMailTools::guessContentType( $fileName, $contentType, $mimeType ) )
                        {
                            // if fileinfo extension is not available try to get content/mime type
                            // from the file extension
                            $filePart = new ezcMailFile( $fileName, $contentType, $mimeType );
                        }
                        else
                        {
                            // fallback in case fileinfo is not available and could not get content/mime
                            // type from file extension
                            $filePart = new ezcMailFile( $fileName, "application", "octet-stream" );
                        }
                        $cid = $result->addRelatedPart( $filePart );
                        // replace the original file reference with a reference to the cid
                        $this->htmlText = str_replace( 'file://' . $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 URLs
                $htmlPart->text = $this->htmlText;
            }
        }
        return $result;
    }
}
?>
