1<?php
2/**
3 * @license GNU General Public License, version 2
4 */
5
6
7if (!defined('DOKU_INC')) die();
8
9
10/**
11 * Class action_plugin_publish_mail
12 *
13 * @author Michael Große <grosse@cosmocode.de>
14 */
15class action_plugin_publish_mail extends DokuWiki_Action_Plugin {
16
17    /**
18     * @var helper_plugin_publish
19     */
20    private $hlp;
21
22    function __construct() {
23        $this->hlp = plugin_load('helper','publish');
24    }
25
26    public function register(Doku_Event_Handler $controller) {
27
28        $controller->register_hook('IO_WIKIPAGE_WRITE', 'AFTER', $this, 'send_change_mail', array());
29    }
30
31    /**
32     * send an email to inform about a changed page
33     *
34     * @param $event
35     * @param $param
36     * @return bool false if the receiver is invalid or there was an error passing the mail to the MTA
37     */
38    function send_change_mail(&$event, $param) {
39        global $ID;
40        global $ACT;
41        global $INFO;
42        global $conf;
43
44        if ($ACT != 'save') {
45            return true;
46        }
47
48        // IO_WIKIPAGE_WRITE is always called twice when saving a page. This makes sure to only send the mail once.
49        if (!$event->data[3]) {
50            return true;
51        }
52
53        // Does the publish plugin apply to this page?
54        if (!$this->hlp->isActive($ID)) {
55            return true;
56        }
57
58        //are we supposed to send change-mails at all?
59        if ($this->getConf('apr_mail_receiver') === '') {
60            return true;
61        }
62
63        // get mail receiver
64        $receiver = $this->getConf('apr_mail_receiver');
65        $validator                      = new EmailAddressValidator();
66        $validator->allowLocalAddresses = true;
67        if(!$validator->check_email_address($receiver)) {
68            dbglog(sprintf($this->getLang('mail_invalid'),htmlspecialchars($receiver)));
69            return false;
70        }
71
72        // get mail sender
73        $ReplyTo = $INFO['userinfo']['mail'];
74
75        if ($ReplyTo == $receiver) {
76            return true;
77        }
78
79        if ($INFO['isadmin'] == '1') {
80            return true;
81        }
82
83        // get mail subject
84        $timestamp = dformat(filemtime(wikiFN($ID)), $conf['dformat']);
85        $subject = $this->getLang('apr_mail_subject') . ': ' . $ID . ' - ' . $timestamp;
86
87        $body = $this->create_mail_body('change');
88
89        $mail = new Mailer();
90        $mail->to($receiver);
91        $mail->subject($subject);
92        $mail->setBody($body);
93        $mail->setHeader("Reply-To", $ReplyTo);
94        $returnStatus = $mail->send();
95        return $returnStatus;
96    }
97
98    /**
99     * Create the body of mails to inform about a changed or an approved page
100     *
101     * @param string $action Must either be "change" or "approve"
102     * @return bool|string
103     *
104     */
105    public function create_mail_body($action) {
106        global $ID;
107        global $conf;
108        global $INFO;
109
110        // get mail text
111        $rev = filemtime(wikiFN($ID));
112
113        if ($action === 'change') {
114            $body = io_readFile($this->localFN('mailchangetext'));
115
116            //If there is no approved revision show the diff to the revision before. Otherwise show the diff to the last approved revision.
117            if($this->hlp->hasApprovals($INFO['meta'])) {
118                $aprpre = 'Aproved';
119                $oldrev = $this->hlp->getLatestApprovedRevision($ID);
120                $difflink = $this->hlp->getDifflink($ID, $oldrev, $rev);
121            } else {
122                $aprpre = 'Previous';
123                $changelog = new PageChangelog($ID);
124                $oldrev = $changelog->getRelativeRevision($rev, -1);
125                $difflink = $this->hlp->getDifflink($ID, $oldrev, $rev);
126            }
127
128            $body = str_replace('@DIFF@', $difflink, $body);
129            $body = str_replace('@APRPRE@', $aprpre, $body);
130            $summary = $INFO['meta']['last_change']['sum'];
131            $body = str_replace('@SUMMARY@', $summary, $body);
132            if ($oldrev === false ) {
133                $oldlink = '---';
134            } else {
135                $oldlink = $this->revlink($ID, $oldrev);
136            }
137            $body = str_replace('@OLDPAGE@', $oldlink, $body);
138            $newlink = $this->revlink($ID, $rev);
139            $body = str_replace('@NEWPAGE@', $newlink, $body);
140        } elseif ($action === 'approve') {
141            $body = io_readFile($this->localFN('mailapprovetext'));
142            $newlink = $this->revlink($ID, $rev);
143            $body = str_replace('@URL@', $newlink, $body);
144
145            $changelog = new PageChangelog($ID);
146            $revinfo = $changelog->getRevisionInfo($rev);
147            /** @var DokuWiki_Auth_Plugin $auth */
148            global $auth;
149            $userinfo = $auth->getUserData($revinfo['user']);
150            $body = str_replace('@FULLNAME@', $userinfo['name'], $body);
151        } else {
152            return false;
153        }
154
155        $body = str_replace('@DOKUWIKIURL@', DOKU_URL, $body);
156        $body = str_replace('@TITLE@', $conf['title'], $body);
157
158        return $body;
159    }
160
161
162
163    /**
164     * Send approve-mail to editor of the now approved revision
165     *
166     * @return bool false if there was an error passing the mail to the MTA
167     */
168    public function send_approve_mail() {
169        global $ID;
170        global $REV;
171
172        /** @var DokuWiki_Auth_Plugin $auth */
173        global $auth;
174        $data = pageinfo();
175
176        // get mail receiver
177        if (!$REV) {
178            $rev = $data['lastmod'];
179        } else {
180            $rev=$REV;
181        }
182        $changelog = new PageChangelog($ID);
183        $revinfo = $changelog->getRevisionInfo($rev);
184        $userinfo = $auth->getUserData($revinfo['user']);
185        $receiver = $userinfo['mail'];
186
187        // get mail sender
188        $ReplyTo = $data['userinfo']['mail'];
189
190        if ($ReplyTo == $receiver) {
191            return true;
192        }
193
194        // get mail subject
195        $subject = $this->getLang('apr_mail_app_subject');
196
197        // get mail text
198        $body = $this->create_mail_body('approve');
199
200        $mail = new Mailer();
201        $mail->to($receiver);
202        $mail->subject($subject);
203        $mail->setBody($body);
204        $mail->setHeader("Reply-To", $ReplyTo);
205        $returnStatus = $mail->send();
206
207        return $returnStatus;
208    }
209
210    /**
211     * create link to the specified revision
212     *
213     * @param string $id
214     * @param string $rev The timestamp of the revision
215     * @return string
216     */
217    function revlink($id, $rev) {
218
219        $options = array(
220             'rev'=> $rev,
221        );
222        $revlink = wl($id, $options, true, '&');
223
224        return $revlink;
225    }
226
227}
228