1<?php
2/**
3 * Copyright 2002-2017 Horde LLC (http://www.horde.org/)
4 *
5 * See the enclosed file COPYING for license information (GPL). If you
6 * did not receive this file, see http://www.horde.org/licenses/gpl.
7 *
8 * @category  Horde
9 * @copyright 2002-2017 Horde LLC
10 * @license   http://www.horde.org/licenses/gpl GPL
11 * @package   IMP
12 */
13
14/**
15 * Renderer for multipart/report data referring to mail system administrative
16 * messages (RFC 3464).
17 *
18 * @author    Michael Slusarz <slusarz@horde.org>
19 * @category  Horde
20 * @copyright 2002-2017 Horde LLC
21 * @license   http://www.horde.org/licenses/gpl GPL
22 * @package   IMP
23 */
24class IMP_Mime_Viewer_Status extends Horde_Mime_Viewer_Base
25{
26    /**
27     * This driver's display capabilities.
28     *
29     * @var array
30     */
31    protected $_capability = array(
32        'full' => false,
33        'info' => true,
34        'inline' => true,
35        'raw' => false
36    );
37
38    /**
39     * Metadata for the current viewer/data.
40     *
41     * @var array
42     */
43    protected $_metadata = array(
44        'compressed' => false,
45        'embedded' => false,
46        'forceinline' => true
47    );
48
49    /**
50     * Return the rendered inline version of the Horde_Mime_Part object.
51     *
52     * @return array  See parent::render().
53     */
54    protected function _renderInline()
55    {
56        return $this->_renderInfo();
57    }
58
59    /**
60     * Return the rendered information about the Horde_Mime_Part object.
61     *
62     * @return array  See parent::render().
63     */
64    protected function _renderInfo()
65    {
66        $parts = array_keys($this->_mimepart->contentTypeMap());
67
68        /* RFC 3464 [2]: There are three parts to a delivery status
69         * multipart/report message:
70         *   (1) Human readable message
71         *   (2) Machine parsable body part (message/delivery-status)
72         *   (3) Returned message (optional)
73         *
74         * Information on the message status is found in the 'Action' field
75         * located in part #2 (RFC 3464 [2.3.3]). It can be either 'failed',
76         * 'delayed', 'delivered', 'relayed', or 'expanded'. */
77
78        if (count($parts) < 2) {
79            return array();
80        }
81
82        reset($parts);
83        $part1_id = next($parts);
84        $part2_id = Horde_Mime::mimeIdArithmetic($part1_id, 'next');
85        $part3_id = Horde_Mime::mimeIdArithmetic($part2_id, 'next');
86
87        /* Get the action first - it appears in the second part. */
88        $action = null;
89        $part2 = $this->getConfigParam('imp_contents')->getMIMEPart($part2_id);
90
91        // This would be a broken msg, but don't cause an exception because of it
92        if (is_null($part2)) {
93            return array();
94        }
95
96        foreach (explode("\n", $part2->getContents()) as $line) {
97            if (stristr($line, 'Action:') !== false) {
98                $action = strtolower(trim(substr($line, strpos($line, ':') + 1)));
99                if (strpos($action, ' ') !== false) {
100                    $action = substr($action, 0, strpos($action, ' '));
101                }
102                break;
103            }
104        }
105
106        if (is_null($action)) {
107            return array();
108        }
109
110        /* Get the correct text strings for the action type. */
111        switch ($action) {
112        case 'failed':
113        case 'delayed':
114            $status = new IMP_Mime_Status(array(
115                _("ERROR: Your message could not be delivered."),
116                sprintf(_("Technical error details can be viewed %s."), $this->getConfigParam('imp_contents')->linkViewJS($part2, 'view_attach', _("HERE"), array('jstext' => _("Technical details"), 'params' => array('ctype' => 'text/plain', 'mode' => IMP_Contents::RENDER_FULL))))
117            ));
118            $status->action(IMP_Mime_Status::ERROR);
119            $msg_link = _("The text of the returned message can be viewed %s.");
120            $msg_link_status = _("The text of the returned message");
121            break;
122
123        case 'delivered':
124        case 'expanded':
125        case 'relayed':
126            $status = new IMP_Mime_Status(array(
127                _("Your message was successfully delivered."),
128                sprintf(_("Technical message details can be viewed %s."), $this->getConfigParam('imp_contents')->linkViewJS($part2, 'view_attach', _("HERE"), array('jstext' => _("Technical details"), 'params' => array('ctype' => 'text/x-simple', 'mode' => IMP_Contents::RENDER_FULL))))
129            ));
130            $status->action(IMP_Mime_Status::SUCCESS);
131            $msg_link = _("The text of the message can be viewed %s.");
132            $msg_link_status = _("The text of the message");
133            break;
134
135        default:
136            return array();
137        }
138
139        /* Display a link to the returned message, if it exists. */
140        $part3 = $this->getConfigParam('imp_contents')->getMIMEPart($part3_id);
141        if ($part3) {
142            $status->addText(sprintf($msg_link, $this->getConfigParam('imp_contents')->linkViewJS($part3, 'view_attach', _("HERE"), array('jstext' => $msg_link_status, 'params' => array('ctype' => 'message/rfc822')))));
143        }
144
145        $ret = array_fill_keys(array_diff($parts, array($part1_id)), null);
146
147        $ret[$this->_mimepart->getMimeId()] = array(
148            'data' => '',
149            'status' => $status,
150            'type' => 'text/html; charset=' . $this->getConfigParam('charset'),
151            'wrap' => 'mimePartWrap'
152        );
153
154        return $ret;
155    }
156
157}
158