2
0
Prechádzať zdrojové kódy

[1.11] Promoted Zend_Mail_Transport_File to trunk

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@23128 44c647ce-9c0f-0410-b52a-842ac1e357ba
matthew 15 rokov pred
rodič
commit
40c8eea9f8

+ 1 - 1
documentation/manual/en/manual.xml.in

@@ -1347,7 +1347,7 @@
                     <xi:include href="../en/module_specs/Zend_Mail-MultipleEmails.xml" />
                 </xi:fallback>
             </xi:include>
-            <xi:include href="module_specs/Zend_Mail-DifferentTransports.xml">
+            <xi:include href="module_specs/Zend_Mail-DifferentTransports.xml" parse="xml">
                 <xi:fallback>
                     <xi:include href="../en/module_specs/Zend_Mail-DifferentTransports.xml" />
                 </xi:fallback>

+ 4 - 2
documentation/manual/en/module_specs/Zend_Mail-DifferentTransports.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- Reviewed: no -->
-<sect1 id="zend.mail.different-transports">
+<sect1 id="zend.mail.different-transports" xmlns:xi="http://www.w3.org/2001/XInclude">
     <title>Using Different Transports</title>
 
     <para>
@@ -29,9 +29,11 @@ $mail->send();  // use default again
 
         <para>
             Additional transports can be written by implementing
-            <classname>Zend_Mail_Transport_Interface</classname>.
+            <classname>Zend_Mail_Transport_Interface</classname>. 
         </para>
     </note>
+
+    <xi:include href="Zend_Mail-UsingFileTransport.xml" />
 </sect1>
 <!--
 vim:se ts=4 sw=4 et:

+ 52 - 0
documentation/manual/en/module_specs/Zend_Mail-UsingFileTransport.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect2 id="zend.mail.file-transport">
+    <title>Using File Transport</title>
+    
+    <para>
+        <classname>Zend_Mail_Transport_File</classname> is useful in a
+        development environment or for testing purposes. Instead of sending any real
+        emails it simply dumps the email's body and headers to a file in the filesystem.
+        Like the other transports, it may be configured using
+        <classname>Zend_Application_Resource_Mail</classname>, or by passing an instance to the
+        <methodname>send()</methodname> method of a <classname>Zend_Mail</classname> instance.
+    </para>
+    
+    <para>
+        The transport has two optional parameters that can be passed to the constructor or
+        via <methodname>setOptions()</methodname> method. The <property>path</property>
+        option specifies the base path where new files are saved. If nothing is set, the transport
+        uses the default system directory for temporary files.  The second parameter,
+        <property>callback</property>, defines what PHP callback should be used to generate a
+        filename. As an example, assume we need to use the recipient's email plus some
+        hash as the filename:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+function recipientFilename($transport)
+{
+    return $transport->recipients . '_' . mt_rand() . '.tmp';
+}
+
+$mail = new Zend_Mail();
+$mail->addTo('somebody@example.com', 'Some Recipient');
+// build message...
+$tr = new Zend_Mail_Transport_File(array('callback' => 'recipientFilename'));
+$mail->send($tr);
+]]></programlisting>
+
+    <para>
+        The resulting file will be something like <filename>somebody@example.com_1493362665.tmp</filename>
+    </para>
+
+    <note>
+        <title>Include randomness in filename generation</title>
+
+        <para>
+            When generating filenames, you should inject some sort of randomness into the generation
+            to ensure that the filenames are unique. This is especially important on servers where
+            you may expect high load, as it will ensure that despite a number of requests coming in
+            during the same second or millisecond, the filename will still be unique.
+        </para>
+    </note>
+</sect2>

+ 134 - 0
library/Zend/Mail/Transport/File.php

@@ -0,0 +1,134 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Mail
+ * @subpackage Transport
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * @see Zend_Mail_Transport_Abstract
+ */
+require_once 'Zend/Mail/Transport/Abstract.php';
+
+
+/**
+ * File transport
+ *
+ * Class for saving outgoing emails in filesystem
+ *
+ * @category   Zend
+ * @package    Zend_Mail
+ * @subpackage Transport
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Mail_Transport_File extends Zend_Mail_Transport_Abstract
+{
+    /**
+     * Target directory for saving sent email messages
+     *
+     * @var string
+     */
+    protected $_path;
+
+    /**
+     * Callback function generating a file name
+     *
+     * @var string|array
+     */
+    protected $_callback;
+
+    /**
+     * Constructor
+     *
+     * @param  array|Zend_Config $options OPTIONAL (Default: null)
+     * @return void
+     */
+    public function __construct($options = null)
+    {
+        if ($options instanceof Zend_Config) {
+            $options = $options->toArray();
+        } elseif (!is_array($options)) {
+            $options = array();
+        }
+
+        // Making sure we have some defaults to work with
+        if (!isset($options['path'])) {
+            $options['path'] = sys_get_temp_dir();
+        }
+        if (!isset($options['callback'])) {
+            $options['callback'] = array($this, 'defaultCallback');
+        }
+
+        $this->setOptions($options);
+    }
+
+    /**
+     * Sets options
+     *
+     * @param  array $options
+     * @return void
+     */
+    public function setOptions(array $options)
+    {
+        if (isset($options['path'])&& is_dir($options['path'])) {
+            $this->_path = $options['path'];
+        }
+        if (isset($options['callback']) && is_callable($options['callback'])) {
+            $this->_callback = $options['callback'];
+        }
+    }
+
+    /**
+     * Saves e-mail message to a file
+     *
+     * @return void
+     * @throws Zend_Mail_Transport_Exception on not writable target directory
+     * @throws Zend_Mail_Transport_Exception on file_put_contents() failure
+     */
+    protected function _sendMail()
+    {
+        $file = $this->_path . DIRECTORY_SEPARATOR . call_user_func($this->_callback, $this);
+
+        if (!is_writable(dirname($file))) {
+            require_once 'Zend/Mail/Transport/Exception.php';
+            throw new Zend_Mail_Transport_Exception(sprintf(
+                'Target directory "%s" does not exist or is not writable',
+                dirname($file)
+            ));
+        }
+
+        $email = $this->header . $this->EOL . $this->body;
+
+        if (!file_put_contents($file, $email)) {
+            require_once 'Zend/Mail/Transport/Exception.php';
+            throw new Zend_Mail_Transport_Exception('Unable to send mail');
+        }
+    }
+
+    /**
+     * Default callback for generating filenames
+     *
+     * @param Zend_Mail_Transport_File File transport instance
+     * @return string
+     */
+    public function defaultCallback($transport) 
+    {
+        return 'ZendMail_' . $_SERVER['REQUEST_TIME'] . '_' . mt_rand() . '.tmp';
+    }
+}

+ 2 - 0
tests/Zend/Mail/AllTests.php

@@ -39,6 +39,7 @@ require_once 'Zend/Mail/ImapTest.php';
 require_once 'Zend/Mail/InterfaceTest.php';
 require_once 'Zend/Mail/MessageTest.php';
 require_once 'Zend/Mail/SmtpTest.php';
+require_once 'Zend/Mail/FileTransportTest.php';
 
 /**
  * @category   Zend
@@ -80,6 +81,7 @@ class Zend_Mail_AllTests
         if (defined('TESTS_ZEND_MAIL_SMTP_ENABLED') && constant('TESTS_ZEND_MAIL_SMTP_ENABLED') == true) {
             $suite->addTestSuite('Zend_Mail_SmtpTest');
         }
+        $suite->addTestSuite('Zend_Mail_FileTransportTest');
 
         return $suite;
     }

+ 189 - 0
tests/Zend/Mail/FileTransportTest.php

@@ -0,0 +1,189 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Mail
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../TestHelper.php';
+
+/**
+ * Zend_Mail
+ */
+require_once 'Zend/Mail.php';
+
+/**
+ * Zend_Mail_Transport_File
+ */
+require_once 'Zend/Mail/Transport/File.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Mail
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @group      Zend_Mail
+ */
+class Zend_Mail_FileTransportTest extends PHPUnit_Framework_TestCase
+{
+    protected $_params;
+    protected $_transport;
+    protected $_tmpdir;
+
+    public function setUp()
+    {
+        $this->createdTmpDir = false;
+
+        $tmpDir = null;
+        if (defined('TESTS_ZEND_MAIL_TEMPDIR')) {
+            $tmpDir = constant('TESTS_ZEND_MAIL_TEMPDIR');
+        }
+        if (empty($tmpDir)) {
+            $tmpDir = sys_get_temp_dir() . '/zend_test_mail.file/';
+        }
+        $this->_tmpdir = $tmpDir;
+
+        if (!is_dir($this->_tmpdir)) {
+            if (!mkdir($this->_tmpdir)) {
+                $this->markTestSkipped('Unable to create temporary dir for testing Zend_Mail_Transport_File');
+            }
+            $this->createdTmpDir = true;
+        }
+
+        $this->_cleanDir($this->_tmpdir);
+    }
+
+    public function tearDown()
+    {
+        $this->_cleanDir($this->_tmpdir);
+        if ($this->createdTmpDir) {
+            rmdir($this->_tmpdir);
+        }
+    }
+
+    protected function _cleanDir($dir)
+    {
+        $entries = scandir($dir);
+        foreach ($entries as $entry) {
+            if ($entry == '.' || $entry == '..') {
+                continue;
+            }
+
+            $fullname = $dir . DIRECTORY_SEPARATOR . $entry;
+
+            if (is_dir($fullname)) {
+                $this->_cleanDir($fullname);
+                rmdir($fullname);
+            } else {
+                unlink($fullname);
+            }
+        }
+    }
+
+    public function testTransportSetup()
+    {
+        $transport = new Zend_Mail_Transport_File();
+
+        $transport = new Zend_Mail_Transport_File(array(
+            'path'     => $this->_tmpdir,
+            'callback' => 'test_function'
+        ));
+    }
+
+    protected function _prepareMail()
+    {
+        $mail = new Zend_Mail();
+        $mail->setBodyText('This is the text of the mail.');
+        $mail->setFrom('alexander@example.com', 'Alexander Steshenko');
+        $mail->addTo('oleg@example.com', 'Oleg Lobach');
+        $mail->setSubject('TestSubject');
+
+        return $mail;
+    }
+
+    public function testNotWritablePathFailure()
+    {
+        $transport = new Zend_Mail_Transport_File(array(
+            'path' => $this->_tmpdir . '/not_existing/directory'
+        ));
+
+        $mail = $this->_prepareMail();
+
+        $this->setExpectedException('Zend_Mail_Transport_Exception');
+        $mail->send($transport);
+    }
+
+    public function testTransportSendMail()
+    {
+        $transport = new Zend_Mail_Transport_File(array('path' => $this->_tmpdir));
+
+        $mail = $this->_prepareMail();
+        $mail->send($transport);
+
+        $entries = scandir($this->_tmpdir);
+        $this->assertTrue(count($entries) == 3);
+        foreach ($entries as $entry) {
+            if ($entry == '.' || $entry == '..') {
+                continue;
+            }
+            $filename = $this->_tmpdir . DIRECTORY_SEPARATOR . $entry;
+        }
+
+        $email = file_get_contents($filename);
+        $this->assertContains('To: Oleg Lobach <oleg@example.com>', $email);
+        $this->assertContains('Subject: TestSubject', $email);
+        $this->assertContains('From: Alexander Steshenko <alexander@example.com>', $email);
+        $this->assertContains("This is the text of the mail.", $email);
+    }
+
+    public function prependCallback($transport)
+    {
+        // callback utilizes default callback and prepends recipient email
+        return $transport->recipients . '_' . $transport->defaultCallback($transport);
+    }
+
+    public function testPrependToCallback()
+    {
+        $transport = new Zend_Mail_Transport_File(array(
+            'path' => $this->_tmpdir,
+            'callback' => array($this, 'prependCallback')
+        ));
+
+        $mail = $this->_prepareMail();
+        $mail->send($transport);
+
+        $entries = scandir($this->_tmpdir);
+        $this->assertTrue(count($entries) == 3);
+        foreach ($entries as $entry) {
+            if ($entry == '.' || $entry == '..') {
+                continue;
+            } else {
+                break;
+            }
+        }
+
+        // file name should now contain recipient email address
+        $this->assertContains('oleg@example.com', $entry);
+        // and default callback part
+        $this->assertContains('ZendMail', $entry);
+    }
+}