Index: documentation/manual/en/module_specs/Zend_Log-Factory.xml
===================================================================
--- documentation/manual/en/module_specs/Zend_Log-Factory.xml (revision 22824)
+++ documentation/manual/en/module_specs/Zend_Log-Factory.xml (working copy)
@@ -175,12 +175,149 @@
Zend_Log_Writer_Mail Options
+
+
+ Zend_Log_Writer_Mail Options
-
- Zend_Log_Writer_Mail currently (as of 1.10) does not
- implement a factory, and will raise an exception if you attempt to instantiate it
- via Zend_Log::factory().
-
+
+
+
+ Option
+ Data Type
+ Default Value
+ Description
+
+
+
+
+
+ mail
+ String
+ Zend_Mail
+
+
+ An Zend_Mail instance
+
+
+
+
+ charset
+ String
+ iso-8859-1
+
+
+ Charset of the mail
+
+
+
+
+ from
+ String or Array
+ NULL
+
+
+ Sender of the mail
+
+ The parameters for Array type are :
+
+
+
+ email : address of sender
+
+
+
+
+
+ name : name of sender
+
+
+
+
+
+
+
+ to
+ String or Array
+ NULL
+
+
+ Recipient(s) of the mail
+
+
+
+
+ cc
+ String or Array
+ NULL
+
+
+ Carbon copy recipient(s) of the mail
+
+
+
+
+ bcc
+ String or Array
+ NULL
+
+
+ Blind carbon copy recipient(s) of the mail
+
+
+
+
+ subject
+ String
+ NULL
+
+
+ Subject of the mail
+
+
+
+
+ subjectPrependText
+ String
+ NULL
+
+
+ A summary of number of errors per priority is appended to the
+ subject of the mail
+
+
+
+
+ layout
+ String
+ NULL
+
+
+ An Zend_Layout instance
+
+
+
+
+ layoutOptions
+ Array
+ NULL
+
+
+ See the section
+
+
+
+
+ layoutFormatter
+ String
+ NULL
+
+
+ An Zend_Log_Formatter_Interface instance
+
+
+
+
+
Index: tests/Zend/Log/Writer/_files/layout.phtml
===================================================================
--- tests/Zend/Log/Writer/_files/layout.phtml (revision 0)
+++ tests/Zend/Log/Writer/_files/layout.phtml (revision 0)
@@ -0,0 +1 @@
+layout()->events;
\ No newline at end of file
Index: library/Zend/Log/Writer/Mail.php
===================================================================
--- library/Zend/Log/Writer/Mail.php (revision 22797)
+++ library/Zend/Log/Writer/Mail.php (working copy)
@@ -101,6 +101,18 @@
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 @@
*/
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;
}
/**
Index: tests/Zend/Log/Writer/MailTest.php
===================================================================
--- tests/Zend/Log/Writer/MailTest.php (revision 22824)
+++ tests/Zend/Log/Writer/MailTest.php (working copy)
@@ -59,6 +59,13 @@
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 @@
$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 @@
}
/**
+ * @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 ', $this->_transport->header);
+ $this->assertContains('admin2@domain.com', $this->_transport->header);
+ $this->assertContains('Cc: bug@domain.com', $this->_transport->header);
+ $this->assertContains('project ', $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 @@
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();
-}
+}
\ No newline at end of file