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