Ver Fonte

ZF-9990: implement Zend_Log_Writer_Mail::factory()

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@22962 44c647ce-9c0f-0410-b52a-842ac1e357ba
intiilapa há 15 anos atrás
pai
commit
204efe5172

+ 143 - 6
documentation/manual/en/module_specs/Zend_Log-Factory.xml

@@ -175,12 +175,149 @@ $logger = Zend_Log::factory(array(
 
         <sect3 id="zend.log.factory.writer-options.mail">
             <title>Zend_Log_Writer_Mail Options</title>
-
-            <para>
-                <classname>Zend_Log_Writer_Mail</classname> currently (as of 1.10) does not
-                implement a factory, and will raise an exception if you attempt to instantiate it
-                via <methodname>Zend_Log::factory()</methodname>.
-            </para>
+    
+            <table id="zend.log.factory.writer-options.mail.table">
+                <title>Zend_Log_Writer_Mail Options</title>
+
+                <tgroup cols="4">
+                    <thead>
+                        <row>
+                            <entry>Option</entry>
+                            <entry>Data Type</entry>
+                            <entry>Default Value</entry>
+                            <entry>Description</entry>
+                        </row>
+                    </thead>
+
+                    <tbody>
+                        <row>
+                            <entry><emphasis>mail</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><classname>Zend_Mail</classname></entry>
+
+                            <entry>
+                                An <classname>Zend_Mail</classname> instance
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>charset</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry>iso-8859-1</entry>
+
+                            <entry>
+                                Charset of the mail
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>from</emphasis></entry>
+                            <entry><type>String</type> or <type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Sender of the mail
+
+                                The parameters for <type>Array</type> type are :
+                                <itemizedlist>
+                                    <listitem>
+                                        <para>
+                                            <property>email</property> : address of sender
+                                        </para>
+                                    </listitem>
+
+                                    <listitem>
+                                        <para>
+                                            <property>name</property> : name of sender
+                                        </para>
+                                    </listitem>
+                                </itemizedlist>
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>to</emphasis></entry>
+                            <entry><type>String</type> or <type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Recipient(s) of the mail
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>cc</emphasis></entry>
+                            <entry><type>String</type> or <type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Carbon copy recipient(s) of the mail
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>bcc</emphasis></entry>
+                            <entry><type>String</type> or <type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Blind carbon copy recipient(s) of the mail
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>subject</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Subject of the mail
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>subjectPrependText</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                A summary of number of errors per priority is appended to the 
+                                subject of the mail
+                            </entry>
+                        </row>
+                    
+                        <row>
+                            <entry><emphasis>layout</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                An <classname>Zend_Layout</classname> instance
+                            </entry>
+                        </row>
+                    
+                        <row>
+                            <entry><emphasis>layoutOptions</emphasis></entry>
+                            <entry><type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                See the section <xref linked="zend.layout.options" />
+                            </entry>
+                        </row>
+                    
+                        <row>
+                            <entry><emphasis>layoutFormatter</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                An <classname>Zend_Log_Formatter_Interface</classname> instance
+                            </entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
         </sect3>
 
         <sect3 id="zend.log.factory.writer-options.mock">

+ 148 - 5
documentation/manual/fr/module_specs/Zend_Log-Factory.xml

@@ -171,11 +171,154 @@ $logger = Zend_Log::factory(array(
         <sect3 id="zend.log.factory.writer-options.mail">
             <title>Zend_Log_Writer_Mail Options</title>
 
-            <para>
-                <classname>Zend_Log_Writer_Mail</classname> actuellement (en 1.10) n'implémente pas la
-                fabrique, et renverra une exception si vous tentez de l'utiliser via
-                <methodname>Zend_Log::factory()</methodname>.
-            </para>
+            <table id="zend.log.factory.writer-options.mail.table">
+                <title>Zend_Log_Writer_Mail Options</title>
+
+                <tgroup cols="4">
+                    <thead>
+                        <row>
+                            <entry>Option</entry>
+                            <entry>Type de données</entry>
+                            <entry>Valeur par défaut</entry>
+                            <entry>Description</entry>
+                        </row>
+                    </thead>
+
+                    <tbody>
+                        <row>
+                            <entry><emphasis>mail</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><classname>Zend_Mail</classname></entry>
+
+                            <entry>
+                                Une instance de <classname>Zend_Mail</classname>
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>charset</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry>iso-8859-1</entry>
+
+                            <entry>
+                                L'encodage pour le courriel
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>from</emphasis></entry>
+                            <entry><type>String</type> or <type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Expéditeur du courriel.
+
+                                Les paramètres pour un type <type>Array</type> sont :
+                                <itemizedlist>
+                                    <listitem>
+                                        <para>
+                                            <property>email</property> : adresse de l'expéditeur
+                                        </para>
+                                    </listitem>
+
+                                    <listitem>
+                                        <para>
+                                            <property>name</property> : nom de l'expéditeur
+                                        </para>
+                                    </listitem>
+                                </itemizedlist>
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>to</emphasis></entry>
+                            <entry><type>String</type> or <type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Destinataire(s) du courriel
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>cc</emphasis></entry>
+                            <entry><type>String</type> or <type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Destinataire(s) en copie(s) du courriel
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>bcc</emphasis></entry>
+                            <entry><type>String</type> or <type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Destinataire(s) en copie(s) cachée(s) du courriel
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>subject</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Sujet du courriel
+                            </entry>
+                        </row>
+
+                        <row>
+                            <entry><emphasis>subjectPrependText</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Un résumé du nombre de chaque niveau d'erreurs sera ajouté
+                                à la suite du sujet du courriel
+                            </entry>
+                        </row>
+                    
+                        <row>
+                            <entry><emphasis>layout</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Une instance de <classname>Zend_Layout</classname>
+                            </entry>
+                        </row>
+                    
+                        <row>
+                            <entry><emphasis>layoutOptions</emphasis></entry>
+                            <entry><type>Array</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Voir la section <xref linked="zend.layout.options" />
+                            </entry>
+                        </row>
+                    
+                        <row>
+                            <entry><emphasis>layoutFormatter</emphasis></entry>
+                            <entry><type>String</type></entry>
+                            <entry><constant>NULL</constant></entry>
+
+                            <entry>
+                                Une instance de <classname>Zend_Log_Formatter_Interface</classname>
+                            </entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+
+            <note>
+                <para>
+                    
+                </para>
+            </note>
         </sect3>
 
         <sect3 id="zend.log.factory.writer-options.mock">

+ 125 - 5
library/Zend/Log/Writer/Mail.php

@@ -101,6 +101,18 @@ class Zend_Log_Writer_Mail extends Zend_Log_Writer_Abstract
     protected $_subjectPrependText;
 
     /**
+     * MethodMap for Zend_Mail's headers
+     * 
+     * @var array
+     */
+    protected static $_methodMapHeaders = array(
+    	'from' => 'setFrom',
+        'to' => 'addTo',
+        'cc' => 'addCc',
+        'bcc' => 'addBcc',
+    );
+
+    /**
      * Class constructor.
      *
      * Constructs the mail writer; requires a Zend_Mail instance, and takes an
@@ -113,21 +125,129 @@ class Zend_Log_Writer_Mail extends Zend_Log_Writer_Abstract
      */
     public function __construct(Zend_Mail $mail, Zend_Layout $layout = null)
     {
-        $this->_mail      = $mail;
-        $this->_layout    = $layout;
+        $this->_mail = $mail;
+        if (null !== $layout) {
+            $this->setLayout($layout);
+        }
         $this->_formatter = new Zend_Log_Formatter_Simple();
     }
-    
+
     /**
      * Create a new instance of Zend_Log_Writer_Mail
      * 
      * @param  array|Zend_Config $config
      * @return Zend_Log_Writer_Mail
-     * @throws Zend_Log_Exception
      */
     static public function factory($config)
     {
-        throw new Zend_Exception('Zend_Log_Writer_Mail does not currently implement a factory');
+        $config = self::_parseConfig($config);
+        $mail = self::_constructMailFromConfig($config);
+        $writer = new self($mail);
+
+        if (isset($config['layout']) || isset($config['layoutOptions'])) {
+            $writer->setLayout($config);
+        }
+        if (isset($config['layoutFormatter'])) {
+        	$layoutFormatter = new $config['layoutFormatter'];
+            $writer->setLayoutFormatter($layoutFormatter);
+        }
+        if (isset($config['subjectPrependText'])) {
+            $writer->setSubjectPrependText($config['subjectPrependText']);
+        }
+
+        return $writer;
+    }
+
+    /**
+     * Set the layout
+     * 
+     * @param Zend_Layout|array $layout
+     * @return Zend_Log_Writer_Mail
+     * @throws Zend_Log_Exception
+     */
+    public function setLayout($layout)
+    {
+        if (is_array($layout)) {
+            $layout = $this->_constructLayoutFromConfig($layout);
+        }
+
+        if (!$layout instanceof Zend_Layout) {
+            require_once 'Zend/Log/Exception.php';
+            throw new Zend_Log_Exception('Mail must be an instance of Zend_Layout or an array');
+        }
+        $this->_layout = $layout;
+
+        return $this;
+    }
+
+    /**
+     * Construct a Zend_Mail instance based on a configuration array
+     * 
+     * @param array $config
+     * @return Zend_Mail
+     */
+    protected static function _constructMailFromConfig(array $config)
+    {
+        $mailClass = 'Zend_Mail';
+        if (isset($config['mail'])) {
+            $mailClass = $config['mail'];
+        }
+
+        if (!array_key_exists('charset', $config)) {
+            $config['charset'] = null;
+        }
+        $mail = new $mailClass($config['charset']);
+        if (!$mail instanceof Zend_Mail) {
+            throw new Zend_Log_Exception($mail . 'must extend Zend_Mail');
+        }
+
+        if (isset($config['subject'])) {
+            $mail->setSubject($config['subject']);
+        }
+
+        $headerAddresses = array_intersect_key($config, self::$_methodMapHeaders);
+        if (count($headerAddresses)) {
+            foreach ($headerAddresses as $header => $address) {
+                $method = self::$_methodMapHeaders[$header];
+                if (is_array($address) && isset($address['name']) 
+                    && !is_numeric($address['name'])
+                ) {
+                    $params = array(
+                    	$address['email'],
+                    	$address['name']
+                    );
+                } else if (is_array($address) && isset($address['email'])) {
+                    $params = $address['email'];
+                } else {
+                    $params = array($address);
+                }
+                call_user_func_array(array($mail, $method), $params);
+            }
+        }
+
+        return $mail;
+    }
+
+    /**
+     * Construct a Zend_Layout instance based on a configuration array
+     * 
+     * @param array $config
+     * @return Zend_Layout
+     */
+    protected function _constructLayoutFromConfig(array $config)
+    {
+        $config = array_merge(array(
+            'layout' => 'Zend_Layout',
+            'layoutOptions' => null
+        ), $config);
+
+        $layoutClass = $config['layout'];
+        $layout = new $layoutClass($config['layoutOptions']);
+        if (!$layout instanceof Zend_Layout) {
+            throw new Zend_Log_Exception($layout . 'must extend Zend_Layout');
+        }
+
+        return $layout;
     }
 
     /**

+ 193 - 1
tests/Zend/Log/Writer/MailTest.php

@@ -59,6 +59,13 @@ require_once 'Zend/View/Exception.php';
 class Zend_Log_Writer_MailTest extends PHPUnit_Framework_TestCase
 {
     /**
+     * Mock Transport for Zend_Mail
+     * 
+     * @var Zend_Mail_Transport_Abstract
+     */
+    protected $_transport;
+
+    /**
      * Runs the test methods of this class.
      *
      * @return void
@@ -70,6 +77,20 @@ class Zend_Log_Writer_MailTest extends PHPUnit_Framework_TestCase
         $result = PHPUnit_TextUI_TestRunner::run($suite);
     }
 
+    protected function setUp()
+    {
+        $this->_transport = $this->getMockForAbstractClass(
+            'Zend_Mail_Transport_Abstract',
+            array()
+        );
+        Zend_Mail::setDefaultTransport($this->_transport);
+    }
+
+    protected function tearDown()
+    {
+        Zend_Mail::clearDefaultTransport();
+    }
+
     /**
      * Tests normal logging, but with multiple messages for a level.
      *
@@ -287,6 +308,162 @@ class Zend_Log_Writer_MailTest extends PHPUnit_Framework_TestCase
     }
 
     /**
+     * @group ZF-9990
+     */
+    public function testFactory()
+    {
+    	$config = array(
+    		'from' => array(
+    		    'email' => 'log@test.framework.zend.com'
+    	    ),
+    		'to' => 'admin@domain.com',
+    		'subject' => '[error] exceptions on my application'
+    	);
+
+    	$writer = Zend_Log_Writer_Mail::factory($config);
+    	$this->assertType('Zend_Log_Writer_Mail', $writer);
+
+    	$writer->write($this->_getEvent());
+    	$writer->shutdown();
+
+    	$this->assertEquals('admin@domain.com', $this->_transport->recipients);
+    	$this->assertContains('an info message', $this->_transport->body);
+    	$this->assertContains('From: log@test.framework.zend.com', $this->_transport->header);
+    	$this->assertContains('To: admin@domain.com', $this->_transport->header);
+    	$this->assertContains('Subject: [error] exceptions on my application', $this->_transport->header);
+    }
+
+    /**
+     * @group ZF-9990
+     */
+    public function testFactoryShouldSetSubjectPrependText()
+    {
+    	$config = array(
+    		'subjectPrependText' => '[error] exceptions on my application'
+    	);
+
+    	$writer = Zend_Log_Writer_Mail::factory($config);
+    	$writer->write($this->_getEvent());
+    	$writer->shutdown();
+
+    	$this->assertContains('Subject: [error] exceptions on my application (INFO=1)', $this->_transport->header);
+    }
+
+    /**
+     * @group ZF-9990
+     */
+    public function testFactoryShouldAcceptCustomMailClass()
+    {
+        $this->getMock('Zend_Mail', array(), array(), 'Zend_Stub_Mail_Custom');
+        $config = array(
+            'class' => 'Zend_Stub_Mail_Custom'
+    	);
+
+    	$writer = Zend_Log_Writer_Mail::factory($config);
+    	$this->assertType('Zend_Log_Writer_Mail', $writer);
+    }
+
+    /**
+     * @group ZF-9990
+     */
+    public function testFactoryShouldSetCharsetForMail()
+    {
+        $config = array(
+            'charset' => 'UTF-8'
+    	);
+
+    	$writer = Zend_Log_Writer_Mail::factory($config);
+    	$writer->write($this->_getEvent());
+    	$writer->shutdown();
+
+    	$this->assertContains('Content-Type: text/plain; charset=UTF-8', $this->_transport->header);
+    }
+
+    /**
+     * @group ZF-9990
+     */
+    public function testFactoryShouldAllowToSetMultipleRecipientsInArray()
+    {
+    	$config = array(
+    		'to' => array(
+    		    'John Doe' => 'admin1@domain.com',
+    	        'admin2@domain.com'
+    	    ),
+    	    'cc' => array(
+    	        'bug@domain.com',
+    		    'project' => 'projectname@domain.com'
+    	    )
+    	);
+
+    	$writer = Zend_Log_Writer_Mail::factory($config);
+    	$writer->write($this->_getEvent());
+    	$writer->shutdown();
+
+    	$this->assertContains('admin1@domain.com', $this->_transport->recipients);
+    	$this->assertContains('admin2@domain.com', $this->_transport->recipients);
+    	$this->assertContains('bug@domain.com', $this->_transport->recipients);
+    	$this->assertContains('projectname@domain.com', $this->_transport->recipients);
+    	$this->assertContains('To: John Doe <admin1@domain.com>', $this->_transport->header);
+    	$this->assertContains('admin2@domain.com', $this->_transport->header);
+    	$this->assertContains('Cc: bug@domain.com', $this->_transport->header);
+    	$this->assertContains('project <projectname@domain.com>', $this->_transport->header);
+    }
+
+    /**
+     * @group ZF-9990
+     */
+    public function testFactoryWithLayout()
+    {
+    	$config = array(
+    	    'layoutOptions' => array(
+    	        'layoutPath' => dirname(__FILE__) . '/_files'
+    	    )
+    	);
+
+    	$writer = Zend_Log_Writer_Mail::factory($config);
+    	$writer->write($this->_getEvent());
+    	$writer->shutdown();
+
+        $this->assertFalse(empty($this->_transport->boundary));
+        $this->assertContains('Content-Type: multipart/', $this->_transport->header);
+        $this->assertContains('boundary=', $this->_transport->header);
+        $this->assertContains('Content-Type: text/plain', $this->_transport->body);
+        $this->assertContains('Content-Type: text/html', $this->_transport->body);
+        $this->assertContains($this->_transport->boundary, $this->_transport->body);
+        $this->assertEquals(2, substr_count($this->_transport->body, 'an info message'));
+    }
+
+    /**
+     * @group ZF-9990
+     */
+    public function testFactoryShouldSetLayoutFormatter()
+    {
+    	$config = array(
+    	    'layoutOptions' => array(
+    	        'layoutPath' => '/path/to/layout/scripts'
+    	    ),
+    	    'layoutFormatter' => 'Zend_Log_Formatter_Simple'
+    	);
+
+    	$writer = Zend_Log_Writer_Mail::factory($config);
+    	$this->assertType('Zend_Log_Formatter_Simple', $writer->getLayoutFormatter());
+    }
+
+    /**
+     * @group ZF-9990
+     */
+    public function testFactoryWithCustomLayoutClass()
+    {
+        $this->getMock('Zend_Layout', null, array(), 'Zend_Stub_Layout_Custom');
+    	$config = array(
+    	    'layout' => 'Zend_Stub_Layout_Custom'
+    	);
+
+    	$writer = Zend_Log_Writer_Mail::factory($config);
+    	$this->assertType('Zend_Log_Writer_Mail', $writer);
+    }
+
+    /**
      * Returns an array of the Zend_Mail mock object, Zend_Log_Writer_Mail
      * object, and Zend_Log objects.
      *
@@ -324,9 +501,24 @@ class Zend_Log_Writer_MailTest extends PHPUnit_Framework_TestCase
 
         return array($mail, $writer, $log, $layout);
     }
+
+    /**
+     * Returns a sample of an event
+     * 
+     * @return array
+     */
+    protected function _getEvent()
+    {
+        return array(
+    	    'timestamp'    => date('c'),
+            'message'      => 'an info message',
+            'priority'     => 6,
+            'priorityName' => 'INFO'
+    	);
+    }
 }
 
 // Call Zend_Log_Writer_MailTest::main() if this source file is executed directly.
 if (PHPUnit_MAIN_METHOD == "Zend_Log_Writer_MailTest::main") {
     Zend_Log_Writer_MailTest::main();
-}
+}

+ 1 - 0
tests/Zend/Log/Writer/_files/layout.phtml

@@ -0,0 +1 @@
+<?php echo $this->layout()->events;