xref: /plugin/notification/helper/cron.php (revision 36cce49dbfdfbcab08b8abbc360dca3597aa831c)
1<?php
2/**
3 * DokuWiki Plugin watchcycle (Helper Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 */
7
8class helper_plugin_notification_cron extends DokuWiki_Plugin
9{
10    /** @var helper_plugin_sqlite */
11    protected $sqlite;
12
13    public function __construct()
14    {
15        /** @var \helper_plugin_notification_db $db_helper */
16        $db_helper = plugin_load('helper', 'notification_db');
17        $this->sqlite = $db_helper->getDB();
18    }
19
20    public function addUsersToCron()
21    {
22        /** @var DokuWiki_Auth_Plugin $auth */
23        global $auth;
24
25        $res = $this->sqlite->query('SELECT user from cron_check');
26        $ourUsers = $this->sqlite->res2arr($res);
27
28        $ourUsers = array_map(function ($item) {
29            return $item['user'];
30        }, $ourUsers);
31
32        $allUsers = array_keys($auth->retrieveUsers());
33
34        $newUsers = array_diff($allUsers, $ourUsers);
35
36        if (!is_array($newUsers) || empty($newUsers)) return;
37
38        foreach ($newUsers as $user) {
39            $this->sqlite->storeEntry('cron_check',
40                ['user' => $user, 'timestamp' => date('c', 0)]);
41        }
42    }
43
44    /**
45     * Gather notification data from plugins
46     *
47     * @param string $user
48     * @return array
49     */
50    public function getNotificationData($user)
51    {
52        $plugins = [];
53        $event = new Doku_Event('PLUGIN_NOTIFICATION_REGISTER_SOURCE', $plugins);
54        $event->trigger();
55        $notifications_data = [
56            'plugins' => $plugins,
57            'user' => $user,
58            'notifications' => []
59        ];
60        $event = new Doku_Event('PLUGIN_NOTIFICATION_GATHER', $notifications_data);
61        $event->trigger();
62
63        if (!empty($notifications_data['notifications'])) {
64            $notifications = $notifications_data['notifications'];
65
66            // get only notifications that have ids
67            $notifications_data['notifications'] = array_filter($notifications, function ($notification) {
68                return array_key_exists('id', $notification);
69            });
70        }
71
72        return $notifications_data;
73    }
74
75    /**
76     * Prune old (already sent) notifications and return only new ones
77     *
78     * @param string $user
79     * @param array $notification_data
80     * @return array
81     */
82    public function getNewNotifications($user, $notification_data)
83    {
84        /** @var \helper_plugin_notification_db $db_helper */
85        $db_helper = plugin_load('helper', 'notification_db');
86        $sqlite = $db_helper->getDB();
87
88        $notifications = $notification_data['notifications'];
89        $plugins = $notification_data['plugins'];
90
91        //get the notifications that have been sent already
92        $res = $sqlite->query('SELECT plugin, notification_id FROM notification WHERE user=?', $user);
93        $sent_notifications = $sqlite->res2arr($res);
94        $sent_notifications_by_plugin = [];
95        foreach ($plugins as $plugin) {
96            $sent_notifications_by_plugin[$plugin] = [];
97        }
98        foreach ($sent_notifications as $sent_notification) {
99            $plugin = $sent_notification['plugin'];
100            $id = $sent_notification['notification_id'];
101            $sent_notifications_by_plugin[$plugin][$id] = true;
102        }
103
104        // keep only notifications not yet sent
105        $new_notifications = [];
106        foreach ($notifications as $notification) {
107            $plugin = $notification['plugin'];
108            $id = $notification['id'];
109            if (!isset($sent_notifications_by_plugin[$plugin][$id])) {
110                $new_notifications[] = $notification;
111            }
112        }
113
114        return $new_notifications;
115    }
116
117    /**
118     * Create text and HTML components of email message
119     *
120     * @param array $new_notifications
121     * @return string[]
122     */
123    public function composeEmail($new_notifications)
124    {
125        $html = '<p>' . $this->getLang('mail content') . '</p>';
126        $html .= '<ul>';
127        $text = $this->getLang('mail content') . "\n\n";
128
129        usort($new_notifications, function($a, $b) {
130            if ($a['timestamp'] == $b['timestamp']) {
131                return 0;
132            }
133            return ($a['timestamp'] > $b['timestamp']) ? -1 : 1;
134        });
135
136        foreach ($new_notifications as $notification) {
137            $content = $notification['full'];
138            $timestamp = $notification['timestamp'];
139
140            $date = strftime('%d.%m %H:%M', $timestamp);
141
142            $html .= "<li class=\"level1\"><div class=\"li\">$date $content</div></li>";
143            $text .= $date . ' ' . strip_tags($content). "\n";
144        }
145        $html .= '</ul>';
146
147        return [$text, $html];
148    }
149
150    /**
151     * Send notification email to the given user
152     *
153     * @param string $user
154     * @param string $text
155     * @param string $html
156     * @return bool true if email was sent successfully
157     */
158    public function sendMail($user, $text, $html)
159    {
160        /** @var DokuWiki_Auth_Plugin $auth */
161        global $auth;
162
163        $mail = new Mailer();
164        $userinfo = $auth->getUserData($user, false);
165        $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>');
166        $mail->subject($this->getLang('mail subject'));
167        $mail->setBody($text, null, null, $html);
168        return $mail->send();
169    }
170
171    /**
172     * Store info about sent notifications
173     *
174     * @param string $user
175     * @param array $notifications
176     */
177    public function storeSentNotifications($user, $notifications)
178    {
179        /** @var \helper_plugin_notification_db $db_helper */
180        $db_helper = plugin_load('helper', 'notification_db');
181        $sqlite = $db_helper->getDB();
182
183        foreach ($notifications as $notification) {
184            $plugin = $notification['plugin'];
185            $id = $notification['id'];
186            $sqlite->storeEntry('notification',
187                ['plugin' => $plugin, 'notification_id' => $id, 'user' => $user, 'sent' => date('c')]);
188        }
189    }
190}
191