1<?php
2/**
3 * Action sendemail for DokuWiki plugin bureaucracy
4 */
5
6class helper_plugin_bureaucracy_actionmail extends helper_plugin_bureaucracy_action {
7
8    protected $_mail_html = '';
9    protected $_mail_text = '';
10    protected $subject = '';
11    protected $replyto = array();
12    protected $mailtemplate = '';
13
14    /**
15     * Build a nice email from the submitted data and send it
16     *
17     * @param helper_plugin_bureaucracy_field[] $fields
18     * @param string                            $thanks
19     * @param array                             $argv
20     * @return string thanks message
21     * @throws Exception mailing failed
22     */
23    public function run($fields, $thanks, $argv) {
24        global $ID;
25        global $conf;
26
27        $mail = new Mailer();
28
29        $this->prepareNamespacetemplateReplacements();
30        $this->prepareDateTimereplacements();
31        $this->prepareLanguagePlaceholder();
32        $this->prepareNoincludeReplacement();
33        $this->prepareFieldReplacements($fields);
34
35        $evdata = [
36            'fields' => $fields,
37            'values' => &$this->values
38        ];
39        $event = new Doku_Event('PLUGIN_BUREAUCRACY_EMAIL_SEND', $evdata);
40        if($event->advise_before()) {
41            //set default subject
42            $this->subject = sprintf($this->getLang('mailsubject'), $ID);
43
44            //build html&text table, collect replyto and subject
45            list($table_html, $table_text) = $this->processFieldsBuildTable($fields, $mail);
46
47            //Body
48            if($this->mailtemplate) {
49                //show template
50                $this->patterns['__tablehtml__'] = '/@TABLEHTML@/';
51                $this->patterns['__tabletext__'] = '/@TABLETEXT@/';
52                $this->values['__tablehtml__'] = $table_html;
53                $this->values['__tabletext__'] = $table_text;
54
55                list($this->_mail_html, $this->_mail_text) = $this->getContent();
56
57            } else {
58                //show simpel listing
59                $this->_mail_html .= sprintf($this->getLang('mailintro')."<br><br>", dformat());
60                $this->_mail_html .= $table_html;
61
62                $this->_mail_text .= sprintf($this->getLang('mailintro')."\n\n", dformat());
63                $this->_mail_text .= $table_text;
64            }
65            $mail->setBody($this->_mail_text,null,null,$this->_mail_html);
66
67            // Reply-to
68            if(!empty($this->replyto)) {
69                $replyto = $mail->cleanAddress($this->replyto);
70                $mail->setHeader('Reply-To', $replyto, false);
71            }
72
73            // To
74            $to = $this->replace(implode(',',$argv)); // get recipient address(es)
75            $to = $mail->cleanAddress($to);
76            $mail->to($to);
77
78            // From
79            $mail->from($conf['mailfrom']);
80
81            // Subject
82            $this->subject = $this->replace($this->subject);
83            $mail->subject($this->subject);
84
85            if(!$mail->send()) {
86                throw new Exception($this->getLang('e_mail'));
87            }
88        }
89        $event->advise_after();
90
91        return '<p>' . $thanks . '</p>';
92    }
93
94    /**
95     * Create html and plain table of the field
96     * and collect values for subject and replyto
97     *
98     * @param helper_plugin_bureaucracy_field[] $fields
99     * @param Mailer $mail
100     * @return array of html and text table
101     */
102    protected function processFieldsBuildTable($fields, $mail) {
103        global $ID;
104
105        $table_html = '<table>';
106        $table_text = '';
107
108        foreach($fields as $field) {
109            $html = $text = '';
110            $value = $field->getParam('value');
111            $label = $field->getParam('label');
112
113            switch($field->getFieldType()) {
114                case 'fieldset':
115                    if(!empty($field->depends_on)) {
116                        //print fieldset only if depend condition is true
117                        foreach($fields as $field_tmp) {
118                            if($field_tmp->getParam('label') === $field->depends_on[0] && $field_tmp->getParam('value') === $field->depends_on[1] ) {
119                                list($html, $text) =  $this->mail_buildRow($label);
120                            }
121                        }
122                    } else {
123                        list($html, $text) =  $this->mail_buildRow($label);
124                    }
125                    break;
126                case 'file':
127                    if($value === null || $label === null) break; //print attachment only if field was visible
128                    $file = $field->getParam('file');
129                    if(!$file['size']) {
130                        $message = $this->getLang('attachmentMailEmpty');
131                    } else if($file['size'] > $this->getConf('maxEmailAttachmentSize')) {
132                        $message = $file['name'] . ' ' . $this->getLang('attachmentMailToLarge');
133                        msg(sprintf($this->getLang('attachmentMailToLarge_userinfo'), hsc($file['name']), filesize_h($this->getConf('maxEmailAttachmentSize'))), 2);
134                    } else {
135                        $message = $file['name'];
136                        $mail->attachFile($file['tmp_name'], $file['type'], $file['name']);
137                    }
138                    list($html, $text) = $this->mail_buildRow($label, $message);
139                    break;
140                case 'subject':
141                    $this->subject = $label;
142                    break;
143                case 'usemailtemplate':
144                    if (!is_null($field->getParam('template')) ) {
145                        $this->mailtemplate = $this->replace($field->getParam('template'));
146                        resolve_pageid(getNS($ID), $this->mailtemplate, $ignored);
147                    }
148                    break;
149
150                default:
151                    if($value === null || $label === null) break;
152                    if(is_array($value)) $value = implode(', ', $value);
153                    list($html, $text) = $this->mail_buildRow($label, $value);
154
155                    if(!is_null($field->getParam('replyto'))) {
156                        $this->replyto[] = $value;
157                    }
158            }
159            $table_html .= $html;
160            $table_text .= $text;
161        }
162        $table_html .= '</table>';
163
164        return array($table_html, $table_text);
165    }
166
167    /**
168     * Build a row
169     *
170     * @param $column1
171     * @param null $column2
172     * @return array of html and text row
173     */
174    protected function mail_buildRow($column1,$column2=null) {
175        if($column2 === null) {
176            $html = '<tr><td colspan="2"><u>'.hsc($column1).'<u></td></tr>';
177            $text = "\n=====".$column1.'=====';
178        } else {
179            $html = '<tr><td><b>'.hsc($column1).'<b></td><td>'.hsc($column2).'</td></tr>';
180            $text = "\n $column1 \t\t $column2";
181        }
182        return array($html, $text);
183    }
184
185    /**
186     * Parse mail template in html and text, and perform replacements
187     *
188     * @return array html and text content
189     */
190    protected function getContent() {
191        $content = rawWiki($this->mailtemplate);
192        $html = '';
193        $text = '';
194
195        if(preg_match_all('#<code\b(.*?)>(.*?)</code>#is', $content, $matches)) {
196            foreach($matches[1] as $index => $codeoptions) {
197                list($syntax,) = explode(' ', trim($codeoptions), 2);
198                if($syntax == 'html') {
199                    $html = $matches[2][$index];
200                }
201                if($syntax == 'text' || $syntax == '') {
202                    $text = $matches[2][$index];
203                }
204            }
205        }
206        return array(
207            $this->replace($html),
208            $this->replace($text)
209        );
210    }
211}
212// vim:ts=4:sw=4:et:enc=utf-8:
213