xref: /plugin/structpublish/helper/notify.php (revision 31e730e145521fb7010758415a11c928f44439b8)
1<?php
2
3use dokuwiki\Extension\AuthPlugin;
4use dokuwiki\plugin\structpublish\meta\Assignments;
5use dokuwiki\plugin\structpublish\meta\Constants;
6use dokuwiki\plugin\structpublish\meta\Revision;
7
8/**
9 * Notification helper
10 */
11class helper_plugin_structpublish_notify extends DokuWiki_Plugin
12{
13    /** @var helper_plugin_structpublish_db  */
14    protected $dbHelper;
15
16    public function __construct()
17    {
18        $this->dbHelper = plugin_load('helper', 'structpublish_db');
19    }
20
21    /**
22     * If activated, send emails on configured status changes.
23     *
24     * @param string $action
25     * @param Revision $newRevision
26     * @return void
27     * @throws Exception
28     */
29    public function sendEmails($action, $newRevision)
30    {
31
32        if (!$this->triggerNotification($action)) {
33            return;
34        }
35
36        // get assignees from DB
37        $assignments = Assignments::getInstance();
38        $assignees = $assignments->getPageAssignments($newRevision->getId(), false);
39
40        // get recipients for the next workflow step
41        $nextAction = Constants::workflowSteps($action)['nextAction'];
42        if (is_null($nextAction)) {
43            return;
44        }
45
46        if (empty($assignees[$nextAction])) {
47            msg($this->getLang('email_error_norecipients'), -1);
48            return;
49        }
50
51        // flatten the array and split into single user or group items
52        $assignees = implode(',', array_values($assignees[$nextAction]));
53        $assignees = explode(',', $assignees);
54
55        // get recipient emails
56        $recipients = $this->resolveRecipients($assignees);
57
58        // prepare mail text
59        $mailText = $this->prepareMailText($newRevision->getStatus());
60
61        $this->sendMail(implode(',', $recipients), $mailText);
62    }
63
64    /**
65     * @param string $recipients Comma separated list of emails
66     * @param string $mailText
67     * @return void
68     */
69    public function sendMail($recipients, $mailText)
70    {
71        $mailer = new Mailer();
72        $mailer->bcc($recipients);
73
74        $subject = $this->getLang('email_subject');
75        $mailer->subject($subject);
76
77        $mailer->setBody($mailText);
78        $mailer->send();
79    }
80
81    /**
82     * Processes an array of (comma separated) recipients
83     * and returns an array of emails
84     * with user groups resolved to individual users
85     *
86     * @param array $recipients
87     * @return array
88     * @throws Exception
89     */
90    public function resolveRecipients($recipients)
91    {
92        $resolved = [];
93
94        $recipients = array_unique($recipients);
95
96        foreach ($recipients as $recipient) {
97            $recipient = trim($recipient);
98
99            if ($recipient[0] === '@') {
100                $this->resolveGroup($resolved, $recipient);
101            } elseif (strpos($recipient, '@') === false) {
102                $this->resolveUser($resolved, $recipient);
103            } else {
104                $resolved[] = $recipient;
105            }
106        }
107        return $resolved;
108    }
109
110    /**
111     * @param array $resolved
112     * @param string $recipient
113     * @return void
114     * @throws Exception
115     */
116    protected function resolveGroup(&$resolved, $recipient)
117    {
118        /** @var AuthPlugin $auth */
119        global $auth;
120        if (!$auth->canDo('getUsers')) {
121            throw new \Exception('Auth cannot fetch users by group.');
122        }
123
124        $users = $auth->retrieveUsers(0, 0, ['grps' => substr($recipient, 1)]);
125        foreach ($users as $user) {
126            $resolved[] = $user['mail'];
127        }
128    }
129
130    /**
131     * @param array $resolved
132     * @param string $recipient
133     * @return void
134     */
135    protected function resolveUser(&$resolved, $recipient)
136    {
137        /** @var AuthPlugin $auth */
138        global $auth;
139        $user = $auth->getUserData($recipient);
140        if ($user) {
141            $resolved[] = $user['mail'];
142        }
143    }
144
145    /**
146     * Check configuration to see if a notification should be triggered.
147     *
148     * @return bool
149     */
150    private function triggerNotification($action)
151    {
152        if (!$this->getConf('email_enable')) {
153            return false;
154        }
155
156        $actions = array_map('trim', explode(',', $this->getConf('email_status')));
157        return in_array($action, $actions);
158    }
159
160    /**
161     * @return string
162     */
163    protected function prepareMailText($status)
164    {
165        global $ID;
166
167        $mailtext = file_get_contents($this->localFN('mail'));
168
169        $vars = [
170            'PAGE' => $ID,
171            'URL' => wl($ID, '', true),
172            'STATUS_CURRENT' => $status,
173        ];
174
175        foreach ($vars as $var => $val) {
176            $mailtext = str_replace('@' . $var . '@', $val, $mailtext);
177        }
178
179        return $mailtext;
180    }
181}
182