Perforce Chronicle 2012.2/486814
API Documentation

Workflow_Workflow_Action_SendEmail Class Reference

A workflow action that sends an email when transition occurs. More...

Inheritance diagram for Workflow_Workflow_Action_SendEmail:
Workflow_ActionAbstract Workflow_PluginAbstract Workflow_ActionInterface

List of all members.

Public Member Functions

 invoke (Workflow_Model_Transition $transition, P4Cms_Record $record)
 Invoke this action for the given transition and record.

Public Attributes

const DEFAULT_TEMPLATE = 'application/workflow/views/scripts/send-email-template.phtml'

Protected Member Functions

 _extract ($input, $separator= ',')
 Convert a string or list of strings with separated items into an array of items.
 _renderTemplate (Workflow_Model_Transition $transition, P4Cms_Record $record)
 Return rendered template.
 _sendEmail ($to, $subject, $bodyText, $bodyHtml)
 Send an email.

Detailed Description

A workflow action that sends an email when transition occurs.

Email is sent as a plain text, where the body contains transition label, from- and to-state labels and, in the case of provided record is an instance of P4Cms_Content class, content's url.

Recognized email parameters specified via action options are:

to - (required if 'toRole' option is not specified) email recipients, can be a string or an array of strings; every value specifies either email address or username that will be expanded to the user email address; value can also contain coma-separated list of emails/users toRole - (required if 'to' option is not specified) role or list of roles that will be expanded to list of email addresses of the member users; value can also contain coma-separated list of roles subject - (optional) email subject, action provides default value if user doesn't specify this parameter template - (optional) name of the template (may include the path relative to BASE_DIR) that will be rendered into email html body. Template will have access to the transition, record and instance of this class via 'transition', 'record' and 'action' variables set to the template's view. If template is not provided by the user, then workflow module provides default one (see _renderTemplate() method for more details). message - (optional) if set, then it will be prepended to the email body

In the case that email cannot be sent from some reason, error message is logged and the action execution is silently terminated.

Copyright:
2011-2012 Perforce Software. All rights reserved
License:
Please see LICENSE.txt in top-level folder of this distribution.
Version:
2012.2/486814

Member Function Documentation

Workflow_Workflow_Action_SendEmail::_extract ( input,
separator = ',' 
) [protected]

Convert a string or list of strings with separated items into an array of items.

Returns null for empty input.

Parameters:
null | string | array$inputstring or list of strings to extract values from.
string$separatoritems separator.
Returns:
null|array array with string values extracted from input or null of no input is given.
    {
        // early exit if no input is given
        if (!$input) {
            return null;
        }

        $input  = (array) $input;
        $output = array();
        foreach ($input as $value) {
            // convert separated list of values into an array
            $values = explode($separator, $value);
            $values = array_map('trim', $values);

            // add values into output list
            $output = array_merge($output, $values);            
        }

        return $output;
    }
Workflow_Workflow_Action_SendEmail::_renderTemplate ( Workflow_Model_Transition transition,
P4Cms_Record record 
) [protected]

Return rendered template.

Parameters:
Workflow_Model_Transition$transitiontransition to invoke this action for.
P4Cms_Record$recordrecord to invoke this action for.
Returns:
string rendered template.
    {
        // assemble list with template candidates; first one that can be rendered
        // by the view script will be returned
        $candidates   = (array) $this->getOption('template');
        $candidates[] = static::DEFAULT_TEMPLATE;

        // we'll render template by the view cloned from MVC instance
        $view = clone Zend_Layout::getMvcInstance()->getView();

        // loop through template candidates and render first one that view
        // script can find in the script paths
        foreach ($candidates as $template) {
            // if template contains path, add path to the view script paths
            $templateDir = dirname($template);
            $name        = basename($template);
            if (strlen($templateDir) && $templateDir !== '.') {
                $path = BASE_PATH . '/' . $templateDir;
                if (is_dir($path) && is_readable($path . '/' . $name)) {
                    $view->addScriptPath($path);
                }
            }

            // return rendered template if view script can find it
            if ($view->getScriptPath(basename($name))) {                
                $view->transition = $transition;
                $view->record     = $record;
                $view->action     = $this;

                return $view->render($name);
            }
        }

        throw new Workflow_Exception("Cannot render template.");
    }
Workflow_Workflow_Action_SendEmail::_sendEmail ( to,
subject,
bodyText,
bodyHtml 
) [protected]

Send an email.

Parameters:
string | array$toemail recipient.
string$subjectemail subject.
string$bodyTextemail body in the text format.
string$bodyHtmlemail body in the html format.
    {
        $mail = new Zend_Mail();
        $mail->addTo($to)
             ->setSubject($subject);

        // set email body
        if ($bodyText) {
            $mail->setBodyText($bodyText);
        }
        if ($bodyHtml) {
            $mail->setBodyHtml($bodyHtml);
        }

        // set active user (if there is any) as sender
        if (P4Cms_User::hasActive()) {
            $user = P4Cms_User::fetchActive();
            $mail->setFrom($user->getEmail(), $user->getFullName());
        }

        // send the email
        try {
            $mail->send();
        } catch (Exception $exception) {
            P4Cms_Log::logException("Error when sending email.", $exception);
        }
    }
Workflow_Workflow_Action_SendEmail::invoke ( Workflow_Model_Transition transition,
P4Cms_Record record 
)

Invoke this action for the given transition and record.

Parameters:
Workflow_Model_Transition$transitiontransition to invoke this action for.
P4Cms_Record$recordrecord to invoke this action for.
Returns:
Workflow_ActionInterface provides fluent interface.

Implements Workflow_ActionInterface.

    {
        // collect email options
        $to         = $this->_extract($this->getOption('to'));
        $toRole     = $this->_extract($this->getOption('toRole'));
        $subject    = $this->getOption('subject');
        $message    = $this->getOption('message');

        // list of email recipients
        $recipients = array();

        // get users from 'to' option (if set)
        if (is_array($to)) {
            // extract email addresses
            $emailValidator = new Zend_Validate_EmailAddress;
            $recipients     = array_filter($to, array($emailValidator, 'isValid'));

            // for other items (representing usernames) get emails from users details
            $usernames = array_diff($to, $recipients);
            if (count($usernames)) {
                foreach (P4Cms_User::fetchAll(array(P4Cms_User::FETCH_BY_NAME => $usernames)) as $user) {
                    $recipients[$user->getFullName()] = $user->getEmail();
                }
            }
        }

        // if toRole is specified, add member users to the recipient list
        if (is_array($toRole)) {
            foreach (P4Cms_User::fetchByRole($toRole) as $user) {
                $recipients[$user->getFullName()] = $user->getEmail();
            }
        }

        // early exit if recipients list is empty
        if (!count($recipients)) {
            P4Cms_Log::log("Cannot send email: no recipients specified.");
            return $this;
        }

        // early exit if from- or to-state is invalid
        try {
            $fromState = $transition->getFromState();
            $toState   = $transition->getToState();
        } catch (Workflow_Exception $e) {
            P4Cms_Log::log("Cannot send email: invalid 'from' or 'to' state.");
            return $this;
        }

        // provide default subject if not set by user
        if (!$subject) {
            $subject = 'Workflow Transition';
            // append record title if possible
            if ($record->hasField('title')) {
                $subject .= ': ' . $record->getValue('title');
            }
        }

        // compose html part of the email body
        try {
            $bodyHtml = $this->_renderTemplate($transition, $record);
        } catch (Exception $exception) {
            P4Cms_Log::logException("Cannot render email template.", $exception);
            return $this;
        }

        // if custom message is set, prepend it to the body
        if ($message) {
            $bodyHtml = '<p>' . $message . '</p>' . $bodyHtml;
        }

        // compose text part of the email body
        $htmlToText = new P4Cms_Filter_HtmlToText;
        $bodyText   = $htmlToText->filter($bodyHtml);

        // send email
        $this->_sendEmail($recipients, $subject, $bodyText, $bodyHtml);

        return $this;
    }

Member Data Documentation

const Workflow_Workflow_Action_SendEmail::DEFAULT_TEMPLATE = 'application/workflow/views/scripts/send-email-template.phtml'

The documentation for this class was generated from the following file: