Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: \Zend\Mail\Transport\File Component Proposal

Proposed Component Name \Zend\Mail\Transport\File
Developer Notes\Zend\Mail\Transport\File
Proposers Alexander Steshenko
Zend Liaison TBD
Revision (wiki revision: 12)

Table of Contents

1. Overview

\Zend\Mail\Transport\File being used in place of a regular mail transport (like Smpt or Sendmail) instead of sending the mail just saves all email messages as they are in the file system.

2. References

Source Code (Working version with unit-tests)

3. Component Requirements, Constraints, and Acceptance Criteria

WILL save outgoing email in the file system
MUST provide some standard way to generate file names
MUST let users to use their own algorithms for generating file names
MUST allow configuration through Zend_Application_Resource_Mail options

WILL NOT really send an e-mail message

4. Dependencies on Other Framework Components

  • \Zend\Mail\Transport\Abstract
  • \Zend\Mail\Transport\Exception

5. Theory of Operation

When transport's internal sendMail() is called Zend\Mail\Transport\File takes prepared headers and body and dumps them in a file in the specified directory. Name for the file is generated based on the callback you provide. Standard callback uses 'ZendMail' . time() . '_' . mt_rand() . '.tmp' format.

Both path to the directory you want to save the files to and callback function may be passed to the transport's constructor in an array, which makes it also possible to be configured via the Zend_Application Mail resource like this:

So that it's convinient to use in development environments like default mail transport for various e-mail messagin testing without changing actual code at all.

If 'path' value is not set manually, default is defined by calling sys_get_temp_dir php function.

The callback used for generating filenames gets the transport instance as the only parameter, so that it can use email message details for composing the filename and also it can use default callback (let's say to prepend something to the filename it generates).


About different storage options / adapters etc. I suggest keeping this transport as easy as it is now. It would allow great but simple posibility for different email messaging testings especially for systems where bulk emails and mass messaging take place.

For different storage formats (if it is required and desirable to be implemented as a Zend_Mail transport) I suggest implementing another transport, like \Zend\Mail\Transport\Storage which would utilize already implemented storages from Zend/Mail/Storage/*. I see Zend_Mail_Storage_Writable_Maildir currently implements Zend_Mail_Storage_Writable_Interface, the others may be tweaked same way probably, not went into much details about that yet.

Any comments on this one?

6. Milestones / Tasks

  • DONE Milestone 1: Complete theory of operation
  • Milestone 2: Define if some additional features are required (using feedback).
  • Milestone 3: Documentation

7. Class Index

  • \Zend\Mail\Transport\File

8. Use Cases

UC-01: Configuring the transport using Zend_Application_Resource_Mail

This is how the configuration might be done in application.ini configuration file. This would make File mail transport the default transport for the development environment, while keeping regular smtp for the production:

UC-02: Using a custom callback to generate file names

To use a custom callback just pass a function that accepts the transport's instance as first parameter as 'callback' option to the \Zend\Mail\Transport\File constructor (or to setOptions method). In the use case below, callback utilizes default callback, but prepends the file name with the recipient email:

In the target folder a file with name like "oleg@example.com_ZendMail_1276322086_1871539247.tmp" appears and the content is

9. Class Skeletons



mail mail Delete
transport transport Delete
proposal proposal Delete
zf2 zf2 Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jun 13, 2010

    <p>Looks very, very usefull for development!</p>

  2. Jun 13, 2010

    <p>It would be nice to have an option to set output message format to XML in order to be able to do assertions against sent messages.</p>

    <p>Good luck.</p>

  3. Jun 14, 2010

    <p>Sounds interesting!</p>

    <p>What I'm asking me is: Why not implement a different method to store/read mails (not send) and handle different formats like the following:</p>
    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    namespace Zend\Mail;

    $mail = new Mail();
    // ...

    // store a mail
    $fileFormat = FileFormat::factory('eml'); // mbox, xml, emlx (Apple Mail), msg (Outlook) ...
    $fileFormat->save('/tmp/my_mail.eml', $mail, $flags, $context);
    // or
    $mail->save('/tmp/my_mail.eml', $fileFormat, $flags, $context);
    // $fileFormat could be optional by defining a default Mail::setDefaultFileFormat($fileFormat)

    // read a mail
    $mail = $fileFormat->read('/tmp/my_mail.eml', $flags, $context);

    <p>Now you can simply define your own format.</p>

    1. Jun 14, 2010

      <p>Hi Mark,</p>

      <p>The general purpose of this transport is to substitute regular mail transport when you do testing and don't need to actually send the messages. Instead you get them dumped in a directory and can do assertions agains messges and their content (like sender, recepient, body etc).</p>

    2. Jun 14, 2010

      <p>Hi Mark, thanks for the comment.</p>

      <p>If I understand you correctly, what you're asking is essentially what Zend_Mail storages are for. Check them out in \Zend\Mail\Storage* and in the manual.</p>

      <p>The question whether this transport needs to be able to work with different storages as well or not is the biggest question now. I'm waiting for some feedback from Dolf (Freeaqingme). He's going to discuss this question with Mathew.</p>

      <p>Check my note about that in 5. Theory of Operation >> Adapters</p>

      1. Jun 15, 2010

        <p><strong>\Zend\Mail\Storage</strong> is a storage for handling more than one mails.<br />
        What I mean is only a reader/writer for one mail.<br />
        -> For example the MBox storage uses the mbox format to read/write one mail within the storage</p>

        <p><strong>different formats</strong><br />
        It would be useful not only for debugging<br />
        -> e.g: upload/download a mail to/from a web mailer</p>

        <p><strong>Adapters</strong><br />
        The same - adaptable formats like \Zend\Mail\FileFormat\<Format> - nothing todo with storages</p>

        <p><strong>Transport</strong><br />
        In my mind it's confusing to define a transport to format a mail.<br />
        For debugging we can define a file transport as a wrapper for formats.</p>

  4. Jul 28, 2010

    <p>Thanks everyone for your comments.</p>

    <p>Mark, I see your point, it does make sense. However I am not sure what direction will be chosen by CR team and/or zf core team (they did tell me it needed to be discussed seriously) and, what's the most important - what is more desired for the community.</p>

    <p>I did get different suggestions from people but nothing from the people "who decide" (like the Zend_Mail's maintainer). I fully understand it's a minor feature and everyone's busy etc, but don't want it to be another 'orphaned',dead proposal, so I have decided to move it further as much as I can to get more attention finally. No urgency here at all ofc, but still...</p>

    <p>So, as nobody but me is willing to think about this one so far I think that "minimally" what is done is enough (and worth it) to have it as a part of the framework.</p>

    1. Jul 28, 2010

      <p>As far as I can remember I did give some response to this proposal? If there's anything specific you'd like to hear from me being Zend_Mail's maintainer, just let me know.</p>

      1. Jul 29, 2010

        <p>You were going to discuss the issue with adapters with Mathew i.e. should we or should we not add some kind of adapters to the transport or utilize Writable storages interface in the transport/adapters.</p>

  5. Aug 03, 2010

    <ac:macro ac:name="note"><ac:rich-text-body><p><strong>Community Review Team Recommendation</strong></p>

    <p>The CR Team advises accepting this proposal as-is.</p></ac:rich-text-body></ac:macro>

  6. Feb 06, 2011

    <p>I would love to see this component. I'm writing a webmailer which has to save a copy of the sent mail to the IMAPs "Sent" folder, so I need the source code of the mail as string to append it to the IMAP folder.<br />
    Writing it to a file and reading it again would not be perfect, the ability to optionally get it as a string would be cool (at the moment I put the<br />
    $email = $this->header . $this->EOL . $this->body; <br />
    into a class attribute and then use a getter.</p>

  7. Feb 22, 2011

    <p>Zend_Mail_Transport_File is released into the stable branch. Maybe we can archive this proposal <ac:emoticon ac:name="smile" /></p>