_layout->events will be set for use in the layout template. * * @param Zend_Mail $mail Mail instance * @param Zend_Layout $layout Layout instance; optional * @return void */ public function __construct(Zend_Mail $mail, Zend_Layout $layout = null) { $this->_mail = $mail; $this->_layout = $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'); } /** * Places event line into array of lines to be used as message body. * * Handles the formatting of both plaintext entries, as well as those * rendered with Zend_Layout. * * @param array $event Event data * @return void */ protected function _write($event) { // Track the number of entries per priority level. if (!isset($this->_numEntriesPerPriority[$event['priorityName']])) { $this->_numEntriesPerPriority[$event['priorityName']] = 1; } else { $this->_numEntriesPerPriority[$event['priorityName']]++; } $formattedEvent = $this->_formatter->format($event); // All plaintext events are to use the standard formatter. $this->_eventsToMail[] = $formattedEvent; // If we have a Zend_Layout instance, use a specific formatter for the // layout if one exists. Otherwise, just use the event with its // default format. if ($this->_layout) { if ($this->_layoutFormatter) { $this->_layoutEventsToMail[] = $this->_layoutFormatter->format($event); } else { $this->_layoutEventsToMail[] = $formattedEvent; } } } /** * Gets instance of Zend_Log_Formatter_Instance used for formatting a * message using Zend_Layout, if applicable. * * @return Zend_Log_Formatter_Interface|null The formatter, or null. */ public function getLayoutFormatter() { return $this->_layoutFormatter; } /** * Sets a specific formatter for use with Zend_Layout events. * * Allows use of a second formatter on lines that will be rendered with * Zend_Layout. In the event that Zend_Layout is not being used, this * formatter cannot be set, so an exception will be thrown. * * @param Zend_Log_Formatter_Interface $formatter * @return Zend_Log_Writer_Mail * @throws Zend_Log_Exception */ public function setLayoutFormatter(Zend_Log_Formatter_Interface $formatter) { if (!$this->_layout) { throw new Zend_Log_Exception( 'cannot set formatter for layout; ' . 'a Zend_Layout instance is not in use'); } $this->_layoutFormatter = $formatter; return $this; } /** * Allows caller to have the mail subject dynamically set to contain the * entry counts per-priority level. * * Sets the text for use in the subject, with entry counts per-priority * level appended to the end. Since a Zend_Mail subject can only be set * once, this method cannot be used if the Zend_Mail object already has a * subject set. * * @param string $subject Subject prepend text. * @return Zend_Log_Writer_Mail */ public function setSubjectPrependText($subject) { if ($this->_mail->getSubject()) { throw new Zend_Log_Exception( 'subject already set on mail; ' . 'cannot set subject prepend text'); } $this->_subjectPrependText = (string) $subject; return $this; } /** * Sends mail to recipient(s) if log entries are present. Note that both * plaintext and HTML portions of email are handled here. * * @return void */ public function shutdown() { // If there are events to mail, use them as message body. Otherwise, // there is no mail to be sent. if (empty($this->_eventsToMail)) { return; } if ($this->_subjectPrependText !== null) { // Tack on the summary of entries per-priority to the subject // line and set it on the Zend_Mail object. $numEntries = $this->_getFormattedNumEntriesPerPriority(); $this->_mail->setSubject( "{$this->_subjectPrependText} ({$numEntries})"); } // Always provide events to mail as plaintext. $this->_mail->setBodyText(implode('', $this->_eventsToMail)); // If a Zend_Layout instance is being used, set its "events" // value to the lines formatted for use with the layout. if ($this->_layout) { // Set the required "messages" value for the layout. Here we // are assuming that the layout is for use with HTML. $this->_layout->events = implode('', $this->_layoutEventsToMail); // If an exception occurs during rendering, convert it to a notice // so we can avoid an exception thrown without a stack frame. try { $this->_mail->setBodyHtml($this->_layout->render()); } catch (Exception $e) { trigger_error( "exception occurred when rendering layout; " . "unable to set html body for message; " . "message = {$e->getMessage()}; " . "code = {$e->getCode()}; " . "exception class = " . get_class($e), E_USER_NOTICE); } } // Finally, send the mail. If an exception occurs, convert it into a // warning-level message so we can avoid an exception thrown without a // stack frame. try { $this->_mail->send(); } catch (Exception $e) { trigger_error( "unable to send log entries via email; " . "message = {$e->getMessage()}; " . "code = {$e->getCode()}; " . "exception class = " . get_class($e), E_USER_WARNING); } } /** * Gets a string of number of entries per-priority level that occurred, or * an emptry string if none occurred. * * @return string */ protected function _getFormattedNumEntriesPerPriority() { $strings = array(); foreach ($this->_numEntriesPerPriority as $priority => $numEntries) { $strings[] = "{$priority}={$numEntries}"; } return implode(', ', $strings); } }